/* * 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."); } }