public APU(NESCore nes, int sampleRate) { this.nes = nes; this.sampleRate = sampleRate; switch (nes.nesRegion) { default: case SystemType.NTSC: CPUClock = 1789773; FPS = (CPUClock * 3.0) / 89341.5; modeZeroDelay = 7459;//http://nesdev.parodius.com/bbs/viewtopic.php?p=64281#64281 modeZeroFrameLengths = new int[] { 7456, 7458, 7458, 7458 }; modeOneDelay = 1; modeOneFrameLengths = new int[] { 7458, 7456, 7458, 7458, 7452 }; break; case SystemType.PAL: CPUClock = 1662607; FPS = (CPUClock * 3.2) / 106392; modeZeroDelay = 8315; modeZeroFrameLengths = new int[] { 8314, 8312, 8314, 8314 }; modeOneDelay = 1; modeOneFrameLengths = new int[] { 8314, 8314, 8312, 8314, 8312 }; break; } if (this.sampleRate == -1) { this.sampleRate = CPUClock; } rollingAveWindow = this.sampleRate / 10; SetFPS(FPS); output = new short[this.sampleRate]; //the buffers really don't need to be this large, but it should prevent overflows when the FPS is set exceptionally low. for (int i = 0; i < 32; i++) { pulseTable[i] = ((95.52 / (8128.0 / i + 100.0))); pulseTableShort[i] = (int)(pulseTable[i] * 0x7FFF); //Half the range for internal channels, half for external. } for (int i = 0; i < 204; i++) { tndTable[i] = ((163.67 / (24329.0 / i + 100.0))); tndTableShort[i] = (int)(tndTable[i] * 0x7FFF); } volume.square1 = 1; volume.square2 = 1; volume.triangle = 1; volume.noise = 1; volume.dmc = 1; volume.external = 1; square1 = new Channels.Square(nes, true, true); square2 = new Channels.Square(nes, true, false); triangle = new Channels.Triangle(nes); noise = new Channels.Noise(nes); dmc = new Channels.DMC(nes, CPUClock); external = new Channels.External(); }
public APU(NESCore nes, int sampleRate) { this.nes = nes; this.sampleRate = sampleRate; switch (nes.nesRegion) { default: case SystemType.NTSC: CPUClock = 1789773; FPS = (CPUClock * 3.0) / 89341.5; modeZeroDelay = 7459;//http://nesdev.parodius.com/bbs/viewtopic.php?p=64281#64281 modeZeroFrameLengths = new int[] { 7456, 7458, 7458, 7458}; modeOneDelay = 1; modeOneFrameLengths = new int[] { 7458, 7456, 7458, 7458, 7452}; break; case SystemType.PAL: CPUClock = 1662607; FPS = (CPUClock * 3.2) / 106392; modeZeroDelay = 8315; modeZeroFrameLengths = new int[] { 8314, 8312, 8314, 8314 }; modeOneDelay = 1; modeOneFrameLengths = new int[] { 8314, 8314, 8312, 8314, 8312 }; break; } if (this.sampleRate == -1) this.sampleRate = CPUClock; rollingAveWindow = this.sampleRate / 10; SetFPS(FPS); output = new short[this.sampleRate]; //the buffers really don't need to be this large, but it should prevent overflows when the FPS is set exceptionally low. for (int i = 0; i < 32; i++) { pulseTable[i] = ((95.52 / (8128.0 / i + 100.0))); pulseTableShort[i] = (int)(pulseTable[i] * 0x7FFF); //Half the range for internal channels, half for external. } for (int i = 0; i < 204; i++) { tndTable[i] = ((163.67 / (24329.0 / i + 100.0))); tndTableShort[i] = (int)(tndTable[i] * 0x7FFF); } volume.square1 = 1; volume.square2 = 1; volume.triangle = 1; volume.noise = 1; volume.dmc = 1; volume.external = 1; square1 = new Channels.Square(nes, true, true); square2 = new Channels.Square(nes, true, false); triangle = new Channels.Triangle(nes); noise = new Channels.Noise(nes); dmc = new Channels.DMC(nes, CPUClock); external = new Channels.External(); }