mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 07:17:45 -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 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);
|
||||
|
|
|
@ -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--;
|
||||
}
|
||||
|
|
|
@ -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<<stereo);
|
||||
|
||||
|
@ -472,8 +496,8 @@ static int PsndRender(int offset, int length)
|
|||
|
||||
if (PicoIn.AHW & PAHW_PICO) {
|
||||
// always need to render sound for interrupts
|
||||
s16 *buf16 = PicoIn.sndOut ? PicoIn.sndOut + (offset<<stereo) : NULL;
|
||||
PicoPicoPCMUpdate(buf16, length-offset, stereo);
|
||||
s16 *buf16 = PicoIn.sndOut ? PicoIn.sndOut + (pcmlen<<stereo) : NULL;
|
||||
PicoPicoPCMUpdate(buf16, length-pcmlen, stereo);
|
||||
return length;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue