content: /*
   * HalfNES by Andrew Hoffman
   * Licensed under the GNU GPL Version 3. See LICENSE file
   */
  package com.grapeshot.halfnes.audio;
  
  import com.grapeshot.halfnes.utils;
  
  /**
   *
   * @author Andrew
   */
  public class NoiseTimer extends Timer {
  
      private int divider = 0;
      private int[] values = genvalues(1, 1);
      private int prevduty = 1;
      private final static int periodadd = 0;
  
      public NoiseTimer() {
          period = 0;
      }
  
      @Override
      public void setduty(int duty) {
          if (duty != prevduty) {
              values = genvalues(duty, values[position]);
              position = 0;
          }
          prevduty = duty;
      }
  
      @Override
      public final void clock() {
          ++divider;
          // note: stay away from negative division to avoid rounding problems
          int periods = (divider + period + periodadd) / (period + periodadd);
          if (periods < 0) {
              periods = 0; // can happen if period or periodadd were made smaller
          }
          position = (position + periods) % values.length;
          divider -= (period + periodadd) * periods;
      }
  
      @Override
      public final int getval() {
          return (values[position] & 1);
      }
  
      @Override
      public final void reset() {
          position = 0;
      }
  
      @Override
      public final void clock(final int cycles) {
          divider += cycles;
          // note: stay away from negative division to avoid rounding problems
          int periods = (divider + period + periodadd) / (period + periodadd);
          if (periods < 0) {
              periods = 0; // can happen if period or periodadd were made smaller
          }
          position = (position + periods) % values.length;
          divider -= (period + periodadd) * periods;
      }
  
      @Override
      public final void setperiod(final int newperiod) {
          period = newperiod;
      }
  
      public static int[] genvalues(int whichbit, int seed) {
          int[] tehsuck = new int[(whichbit == 1) ? 32767 : 93];
          for (int i = 0; i < tehsuck.length; ++i) {
              seed = (seed >> 1)
                      | ((((seed & (1 << whichbit)) != 0)
                      ^ ((seed & (utils.BIT0)) != 0))
                      ? 16384 : 0);
              tehsuck[i] = seed;
          }
          return tehsuck;
  
      }
  
      @Override
      public void setduty(int[] duty) {
          throw new UnsupportedOperationException("Not supported on noise channel.");
      }
  }