/* * HalfNES by Andrew Hoffman * Licensed under the GNU GPL Version 3. See LICENSE file */ package com.grapeshot.halfnes.audio; /** * * @author Andrew */ public class TriangleTimer extends Timer { private int divider = 0; private final static int periodadd = 1; private final static int[] triangle = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}; public TriangleTimer() { period = 0; position = 0; } @Override public final void reset() { //no way to reset the triangle } @Override public final void clock() { if (period == 0) { return; } ++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) & 0x1F; divider -= (period + periodadd) * periods; } @Override public final void clock(final int cycles) { if (period == 0) { return; } 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) & 0x1F; divider -= (period + periodadd) * periods; } @Override public final int getval() { return (period == 0) ? 7 : triangle[position]; //needed to avoid screech when period is zero } @Override public final void setperiod(final int newperiod) { period = newperiod; if (period == 0) { position = 7; } } @Override public void setduty(int duty) { throw new UnsupportedOperationException("Triangle counter has no duty setting."); } @Override public void setduty(int[] duty) { throw new UnsupportedOperationException("Triangle counter has no duty setting."); } }