mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 15:27:46 -04:00
core, revisit Pico sound handling
This commit is contained in:
parent
ba2b97dc24
commit
e348af76ec
3 changed files with 37 additions and 12 deletions
|
@ -475,6 +475,7 @@ struct PicoSound
|
||||||
unsigned int fm_pos; // last FM position in Q20
|
unsigned int fm_pos; // last FM position in Q20
|
||||||
unsigned int psg_pos; // last PSG position in Q16
|
unsigned int psg_pos; // last PSG position in Q16
|
||||||
unsigned int ym2413_pos; // last YM2413 position
|
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
|
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 PsndDoPSG(int cyc_to);
|
||||||
PICO_INTERNAL void PsndDoYM2413(int cyc_to);
|
PICO_INTERNAL void PsndDoYM2413(int cyc_to);
|
||||||
PICO_INTERNAL void PsndDoFM(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 PsndClear(void);
|
||||||
PICO_INTERNAL void PsndGetSamples(int y);
|
PICO_INTERNAL void PsndGetSamples(int y);
|
||||||
PICO_INTERNAL void PsndGetSamplesMS(int y);
|
PICO_INTERNAL void PsndGetSamplesMS(int y);
|
||||||
|
|
|
@ -208,10 +208,9 @@ void SN76496Update(short *buffer, int length, int stereo)
|
||||||
|
|
||||||
if (out > MAX_OUTPUT * STEP) out = MAX_OUTPUT * STEP;
|
if (out > MAX_OUTPUT * STEP) out = MAX_OUTPUT * STEP;
|
||||||
|
|
||||||
if ((out /= STEP)) // will be optimized to shift; max 0x4800 = 18432
|
out /= STEP; // will be optimized to shift; max 0x4800 = 18432
|
||||||
*buffer += out;
|
*buffer++ += out;
|
||||||
if(stereo) buffer+=2; // only left for stereo, to be mixed to right later
|
if (stereo) *buffer++ += out;
|
||||||
else buffer++;
|
|
||||||
|
|
||||||
length--;
|
length--;
|
||||||
}
|
}
|
||||||
|
|
|
@ -269,9 +269,6 @@ PICO_INTERNAL void PsndDoDAC(int cyc_to)
|
||||||
if (len <= 0)
|
if (len <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!PicoIn.sndOut)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// fill buffer, applying a rather weak order 1 bessel IIR on the way
|
// 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)
|
// 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
|
// 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)
|
if (len <= 0)
|
||||||
return;
|
return;
|
||||||
if (!PicoIn.sndOut || !(PicoIn.opt & POPT_EN_PSG))
|
if (!(PicoIn.opt & POPT_EN_PSG))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (PicoIn.opt & POPT_EN_STEREO) {
|
if (PicoIn.opt & POPT_EN_STEREO) {
|
||||||
|
@ -337,7 +334,7 @@ PICO_INTERNAL void PsndDoSMSFM(int cyc_to)
|
||||||
|
|
||||||
if (len <= 0)
|
if (len <= 0)
|
||||||
return;
|
return;
|
||||||
if (!PicoIn.sndOut || !(PicoIn.opt & POPT_EN_YM2413))
|
if (!(PicoIn.opt & POPT_EN_YM2413))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (PicoIn.opt & POPT_EN_STEREO) {
|
if (PicoIn.opt & POPT_EN_STEREO) {
|
||||||
|
@ -382,6 +379,32 @@ PICO_INTERNAL void PsndDoFM(int cyc_to)
|
||||||
PsndFMUpdate(PsndBuffer + pos, len, stereo, 1);
|
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
|
// cdda
|
||||||
static void cdda_raw_update(s32 *buffer, int length, int stereo)
|
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++;
|
if (Pico.snd.len_e_add) len++;
|
||||||
|
|
||||||
// drop pos remainder to avoid rounding errors (not entirely correct though)
|
// 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.sndOut) return;
|
||||||
|
|
||||||
if (PicoIn.opt & POPT_EN_STEREO)
|
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 fmlen = ((Pico.snd.fm_pos+0x80000) >> 20);
|
||||||
int daclen = ((Pico.snd.dac_pos+0x80000) >> 20);
|
int daclen = ((Pico.snd.dac_pos+0x80000) >> 20);
|
||||||
int psglen = ((Pico.snd.psg_pos+0x80000) >> 20);
|
int psglen = ((Pico.snd.psg_pos+0x80000) >> 20);
|
||||||
|
int pcmlen = ((Pico.snd.pcm_pos+0x80000) >> 20);
|
||||||
|
|
||||||
buf32 = PsndBuffer+(offset<<stereo);
|
buf32 = PsndBuffer+(offset<<stereo);
|
||||||
|
|
||||||
|
@ -472,8 +496,8 @@ static int PsndRender(int offset, int length)
|
||||||
|
|
||||||
if (PicoIn.AHW & PAHW_PICO) {
|
if (PicoIn.AHW & PAHW_PICO) {
|
||||||
// always need to render sound for interrupts
|
// always need to render sound for interrupts
|
||||||
s16 *buf16 = PicoIn.sndOut ? PicoIn.sndOut + (offset<<stereo) : NULL;
|
s16 *buf16 = PicoIn.sndOut ? PicoIn.sndOut + (pcmlen<<stereo) : NULL;
|
||||||
PicoPicoPCMUpdate(buf16, length-offset, stereo);
|
PicoPicoPCMUpdate(buf16, length-pcmlen, stereo);
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue