/* End of frame update, return the number of samples run so far. */ int sound_update(unsigned int cycles) { int size, avail; /* run PSG & FM chips until end of frame */ cycles <<= 11; psg_update(cycles); fm_update(cycles); /* check number of available FM samples */ if (config.hq_fm) { size = Fir_Resampler_avail(); } else { size = (snd.fm.pos - snd.fm.buffer) >> 1; } #ifdef LOGSOUND error("%d FM samples available\n",size); #endif /* check number of available PSG samples */ avail = snd.psg.pos - snd.psg.buffer; #ifdef LOGSOUND error("%d PSG samples available\n", avail); #endif /* resynchronize FM & PSG chips */ if (size > avail) { /* FM chip is ahead */ fm_cycles_count += SN76489_Clocks(size - avail) * psg_cycles_ratio; /* return number of available samples */ size = avail; } else { /* PSG chip is ahead */ psg_cycles_count += SN76489_Clocks(avail - size) * psg_cycles_ratio; } #ifdef LOGSOUND error("%lu PSG cycles run\n",psg_cycles_count); error("%lu FM cycles run \n",fm_cycles_count); #endif /* adjust PSG & FM cycle counts for next frame */ psg_cycles_count -= cycles; fm_cycles_count -= cycles; #ifdef LOGSOUND error("%lu PSG cycles left\n",psg_cycles_count); error("%lu FM cycles left\n",fm_cycles_count); #endif return size; }
unsigned int fm_read(unsigned int cycles, unsigned int address) { /* synchronize FM chip with CPU */ fm_update(cycles); /* read FM status (YM2612 only) */ return YM2612Read(); }
void fm_reset(unsigned int cycles) { /* synchronize FM chip with CPU */ fm_update(cycles); /* reset FM chip */ YM_Reset(); }
void fm_write(unsigned int cycles, unsigned int address, unsigned int data) { /* synchronize FM chip with CPU (on data port write only) */ if (address & 1) { fm_update(cycles); } /* write FM register */ YM_Write(address, data); }
int sound_update(unsigned int cycles) { int delta, preamp, time, l, r, *ptr; /* Run PSG & FM chips until end of frame */ SN76489_Update(cycles); fm_update(cycles); /* FM output pre-amplification */ preamp = config.fm_preamp; /* FM frame initial timestamp */ time = fm_cycles_start; /* Restore last FM outputs from previous frame */ l = fm_last[0]; r = fm_last[1]; /* FM buffer start pointer */ ptr = fm_buffer; /* flush FM samples */ if (config.hq_fm) { /* high-quality Band-Limited synthesis */ do { /* left channel */ delta = ((*ptr++ * preamp) / 100) - l; l += delta; blip_add_delta(snd.blips[0][0], time, delta); /* right channel */ delta = ((*ptr++ * preamp) / 100) - r; r += delta; blip_add_delta(snd.blips[0][1], time, delta); /* increment time counter */ time += fm_cycles_ratio; } while (time < cycles); } else { /* faster Linear Interpolation */ do { /* left channel */ delta = ((*ptr++ * preamp) / 100) - l; l += delta; blip_add_delta_fast(snd.blips[0][0], time, delta); /* right channel */ delta = ((*ptr++ * preamp) / 100) - r; r += delta; blip_add_delta_fast(snd.blips[0][1], time, delta); /* increment time counter */ time += fm_cycles_ratio; } while (time < cycles); } /* reset FM buffer pointer */ fm_ptr = fm_buffer; /* save last FM output for next frame */ fm_last[0] = l; fm_last[1] = r; /* adjust FM cycle counters for next frame */ fm_cycles_count = fm_cycles_start = time - cycles; /* end of blip buffers time frame */ blip_end_frame(snd.blips[0][0], cycles); blip_end_frame(snd.blips[0][1], cycles); /* return number of available samples */ return blip_samples_avail(snd.blips[0][0]); }
/* Read FM status (YM2612 only) */ unsigned int fm_read(unsigned int cycles, unsigned int address) { fm_update(cycles << 11); return YM2612Read(); }
/* Write FM chip */ void fm_write(unsigned int cycles, unsigned int address, unsigned int data) { if (address & 1) fm_update(cycles << 11); YM_Write(address, data); }
/* Reset FM chip */ void fm_reset(unsigned int cycles) { fm_update(cycles << 11); YM_Reset(); }