From: kub Date: Sat, 20 Jan 2024 16:23:44 +0000 (+0100) Subject: core, revisit Pico sound handling X-Git-Tag: v2.00~135 X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e348af76ec2d0ae83c7178307425d9305ecaa258;p=picodrive.git core, revisit Pico sound handling --- diff --git a/pico/pico_int.h b/pico/pico_int.h index cbf61e43..52734c62 100644 --- a/pico/pico_int.h +++ b/pico/pico_int.h @@ -475,6 +475,7 @@ struct PicoSound unsigned int fm_pos; // last FM position in Q20 unsigned int psg_pos; // last PSG position in Q16 unsigned int ym2413_pos; // last YM2413 position + unsigned int pcm_pos; // last PCM position in Q16 unsigned int fm_fir_mul, fm_fir_div; // ratio for FM resampling FIR }; @@ -975,6 +976,7 @@ PICO_INTERNAL void PsndDoDAC(int cycle_to); PICO_INTERNAL void PsndDoPSG(int cyc_to); PICO_INTERNAL void PsndDoYM2413(int cyc_to); PICO_INTERNAL void PsndDoFM(int cyc_to); +PICO_INTERNAL void PsndDoPCM(int cyc_to); PICO_INTERNAL void PsndClear(void); PICO_INTERNAL void PsndGetSamples(int y); PICO_INTERNAL void PsndGetSamplesMS(int y); diff --git a/pico/sound/sn76496.c b/pico/sound/sn76496.c index cb383118..3bb5cf74 100644 --- a/pico/sound/sn76496.c +++ b/pico/sound/sn76496.c @@ -208,10 +208,9 @@ void SN76496Update(short *buffer, int length, int stereo) if (out > MAX_OUTPUT * STEP) out = MAX_OUTPUT * STEP; - if ((out /= STEP)) // will be optimized to shift; max 0x4800 = 18432 - *buffer += out; - if(stereo) buffer+=2; // only left for stereo, to be mixed to right later - else buffer++; + out /= STEP; // will be optimized to shift; max 0x4800 = 18432 + *buffer++ += out; + if (stereo) *buffer++ += out; length--; } diff --git a/pico/sound/sound.c b/pico/sound/sound.c index c31c2cf4..5d7fac63 100644 --- a/pico/sound/sound.c +++ b/pico/sound/sound.c @@ -269,9 +269,6 @@ PICO_INTERNAL void PsndDoDAC(int cyc_to) if (len <= 0) return; - if (!PicoIn.sndOut) - return; - // fill buffer, applying a rather weak order 1 bessel IIR on the way // y[n] = (x[n] + x[n-1])*(1/2) (3dB cutoff at 11025 Hz, no gain) // 1 sample delay for correct IIR filtering over audio frame boundaries @@ -307,7 +304,7 @@ PICO_INTERNAL void PsndDoPSG(int cyc_to) if (len <= 0) return; - if (!PicoIn.sndOut || !(PicoIn.opt & POPT_EN_PSG)) + if (!(PicoIn.opt & POPT_EN_PSG)) return; if (PicoIn.opt & POPT_EN_STEREO) { @@ -337,7 +334,7 @@ PICO_INTERNAL void PsndDoSMSFM(int cyc_to) if (len <= 0) return; - if (!PicoIn.sndOut || !(PicoIn.opt & POPT_EN_YM2413)) + if (!(PicoIn.opt & POPT_EN_YM2413)) return; if (PicoIn.opt & POPT_EN_STEREO) { @@ -382,6 +379,32 @@ PICO_INTERNAL void PsndDoFM(int cyc_to) PsndFMUpdate(PsndBuffer + pos, len, stereo, 1); } +PICO_INTERNAL void PsndDoPCM(int cyc_to) +{ + int pos, len; + int stereo = 0; + + // nothing to do if sound is off + if (!PicoIn.sndOut) return; + + // Q20, number of samples since last call + len = (cyc_to * Pico.snd.clkl_mult) - Pico.snd.pcm_pos; + + // update position and calculate buffer offset and length + pos = (Pico.snd.pcm_pos+0x80000) >> 20; + Pico.snd.pcm_pos += len; + len = ((Pico.snd.pcm_pos+0x80000) >> 20) - pos; + if (len <= 0) + return; + + // fill buffer + if (PicoIn.opt & POPT_EN_STEREO) { + stereo = 1; + pos <<= 1; + } + PicoPicoPCMUpdate(PicoIn.sndOut + pos, len, stereo); +} + // cdda static void cdda_raw_update(s32 *buffer, int length, int stereo) { @@ -434,7 +457,7 @@ PICO_INTERNAL void PsndClear(void) if (Pico.snd.len_e_add) len++; // drop pos remainder to avoid rounding errors (not entirely correct though) - Pico.snd.dac_pos = Pico.snd.fm_pos = Pico.snd.psg_pos = Pico.snd.ym2413_pos = 0; + Pico.snd.dac_pos = Pico.snd.fm_pos = Pico.snd.psg_pos = Pico.snd.ym2413_pos = Pico.snd.pcm_pos = 0; if (!PicoIn.sndOut) return; if (PicoIn.opt & POPT_EN_STEREO) @@ -457,6 +480,7 @@ static int PsndRender(int offset, int length) int fmlen = ((Pico.snd.fm_pos+0x80000) >> 20); int daclen = ((Pico.snd.dac_pos+0x80000) >> 20); int psglen = ((Pico.snd.psg_pos+0x80000) >> 20); + int pcmlen = ((Pico.snd.pcm_pos+0x80000) >> 20); buf32 = PsndBuffer+(offset<