unsigned int fm_pos; // last FM position in Q20\r
unsigned int psg_pos; // last PSG position in Q16\r
unsigned int ym2413_pos; // last YM2413 position\r
+ unsigned int pcm_pos; // last PCM position in Q16\r
unsigned int fm_fir_mul, fm_fir_div; // ratio for FM resampling FIR\r
};\r
\r
PICO_INTERNAL void PsndDoPSG(int cyc_to);\r
PICO_INTERNAL void PsndDoYM2413(int cyc_to);\r
PICO_INTERNAL void PsndDoFM(int cyc_to);\r
+PICO_INTERNAL void PsndDoPCM(int cyc_to);\r
PICO_INTERNAL void PsndClear(void);\r
PICO_INTERNAL void PsndGetSamples(int y);\r
PICO_INTERNAL void PsndGetSamplesMS(int y);\r
if (len <= 0)\r
return;\r
\r
- if (!PicoIn.sndOut)\r
- return;\r
-\r
// fill buffer, applying a rather weak order 1 bessel IIR on the way\r
// y[n] = (x[n] + x[n-1])*(1/2) (3dB cutoff at 11025 Hz, no gain)\r
// 1 sample delay for correct IIR filtering over audio frame boundaries\r
\r
if (len <= 0)\r
return;\r
- if (!PicoIn.sndOut || !(PicoIn.opt & POPT_EN_PSG))\r
+ if (!(PicoIn.opt & POPT_EN_PSG))\r
return;\r
\r
if (PicoIn.opt & POPT_EN_STEREO) {\r
\r
if (len <= 0)\r
return;\r
- if (!PicoIn.sndOut || !(PicoIn.opt & POPT_EN_YM2413))\r
+ if (!(PicoIn.opt & POPT_EN_YM2413))\r
return;\r
\r
if (PicoIn.opt & POPT_EN_STEREO) {\r
PsndFMUpdate(PsndBuffer + pos, len, stereo, 1);\r
}\r
\r
+PICO_INTERNAL void PsndDoPCM(int cyc_to)\r
+{\r
+ int pos, len;\r
+ int stereo = 0;\r
+\r
+ // nothing to do if sound is off\r
+ if (!PicoIn.sndOut) return;\r
+\r
+ // Q20, number of samples since last call\r
+ len = (cyc_to * Pico.snd.clkl_mult) - Pico.snd.pcm_pos;\r
+\r
+ // update position and calculate buffer offset and length\r
+ pos = (Pico.snd.pcm_pos+0x80000) >> 20;\r
+ Pico.snd.pcm_pos += len;\r
+ len = ((Pico.snd.pcm_pos+0x80000) >> 20) - pos;\r
+ if (len <= 0)\r
+ return;\r
+\r
+ // fill buffer\r
+ if (PicoIn.opt & POPT_EN_STEREO) {\r
+ stereo = 1;\r
+ pos <<= 1;\r
+ }\r
+ PicoPicoPCMUpdate(PicoIn.sndOut + pos, len, stereo);\r
+}\r
+\r
// cdda\r
static void cdda_raw_update(s32 *buffer, int length, int stereo)\r
{\r
if (Pico.snd.len_e_add) len++;\r
\r
// drop pos remainder to avoid rounding errors (not entirely correct though)\r
- Pico.snd.dac_pos = Pico.snd.fm_pos = Pico.snd.psg_pos = Pico.snd.ym2413_pos = 0;\r
+ Pico.snd.dac_pos = Pico.snd.fm_pos = Pico.snd.psg_pos = Pico.snd.ym2413_pos = Pico.snd.pcm_pos = 0;\r
if (!PicoIn.sndOut) return;\r
\r
if (PicoIn.opt & POPT_EN_STEREO)\r
int fmlen = ((Pico.snd.fm_pos+0x80000) >> 20);\r
int daclen = ((Pico.snd.dac_pos+0x80000) >> 20);\r
int psglen = ((Pico.snd.psg_pos+0x80000) >> 20);\r
+ int pcmlen = ((Pico.snd.pcm_pos+0x80000) >> 20);\r
\r
buf32 = PsndBuffer+(offset<<stereo);\r
\r
\r
if (PicoIn.AHW & PAHW_PICO) {\r
// always need to render sound for interrupts\r
- s16 *buf16 = PicoIn.sndOut ? PicoIn.sndOut + (offset<<stereo) : NULL;\r
- PicoPicoPCMUpdate(buf16, length-offset, stereo);\r
+ s16 *buf16 = PicoIn.sndOut ? PicoIn.sndOut + (pcmlen<<stereo) : NULL;\r
+ PicoPicoPCMUpdate(buf16, length-pcmlen, stereo);\r
return length;\r
}\r
\r