void Nes_Vrc6_Apu::run_square( Vrc6_Osc& osc, blip_time_t end_time ) { Blip_Buffer* output = osc.output; if ( !output ) return; int volume = osc.regs [0] & 15; if ( !(osc.regs [2] & 0x80) ) volume = 0; int gate = osc.regs [0] & 0x80; int duty = ((osc.regs [0] >> 4) & 7) + 1; int delta = ((gate || osc.phase < duty) ? volume : 0) - osc.last_amp; blip_time_t time = last_time; if ( delta ) { osc.last_amp += delta; output->set_modified(); square_synth.offset( time, delta, output ); } time += osc.delay; osc.delay = 0; int period = osc.period(); if ( volume && !gate && period > 4 ) { if ( time < end_time ) { int phase = osc.phase; output->set_modified(); do { phase++; if ( phase == 16 ) { phase = 0; osc.last_amp = volume; square_synth.offset( time, volume, output ); } if ( phase == duty ) { osc.last_amp = 0; square_synth.offset( time, -volume, output ); } time += period; } while ( time < end_time ); osc.phase = phase; } osc.delay = time - end_time; } }
void Nes_Vrc7_Apu::end_frame( blip_time_t time ) { if ( time > next_time ) run_until( time ); next_time -= time; assert( next_time >= 0 ); for ( int i = osc_count; --i >= 0; ) { Blip_Buffer* output = oscs [i].output; if ( output ) output->set_modified(); } }
void Nes_Vrc6_Apu::run_saw( blip_time_t end_time ) { Vrc6_Osc& osc = oscs [2]; Blip_Buffer* output = osc.output; if ( !output ) return; output->set_modified(); int amp = osc.amp; int amp_step = osc.regs [0] & 0x3F; blip_time_t time = last_time; int last_amp = osc.last_amp; if ( !(osc.regs [2] & 0x80) || !(amp_step | amp) ) { osc.delay = 0; int delta = (amp >> 3) - last_amp; last_amp = amp >> 3; saw_synth.offset( time, delta, output ); }