mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-04 23:07:46 -04:00
sound, fix pcm/pwm handling wrt fast forward (mcd, 32x, pico)
This commit is contained in:
parent
8eada9d64c
commit
9f1d5acdb4
5 changed files with 35 additions and 19 deletions
|
@ -128,7 +128,7 @@ void pcd_pcm_update(s32 *buf32, int length, int stereo)
|
|||
|
||||
pcd_pcm_sync(SekCyclesDoneS68k());
|
||||
|
||||
if (!Pico_mcd->pcm_mixbuf_dirty || !(PicoIn.opt & POPT_EN_MCD_PCM))
|
||||
if (!Pico_mcd->pcm_mixbuf_dirty || !(PicoIn.opt & POPT_EN_MCD_PCM) || !buf32)
|
||||
goto out;
|
||||
|
||||
step = (Pico_mcd->pcm_mixpos << 16) / length;
|
||||
|
|
|
@ -311,7 +311,6 @@ static int PicoFrameHints(void)
|
|||
#endif
|
||||
|
||||
// get samples from sound chips
|
||||
if (PicoIn.sndOut)
|
||||
PsndGetSamples(y);
|
||||
|
||||
timers_cycle();
|
||||
|
|
|
@ -755,7 +755,6 @@ void PicoFrameMS(void)
|
|||
z80_exec(Pico.t.z80c_line_start + cycles_line);
|
||||
}
|
||||
|
||||
if (PicoIn.sndOut)
|
||||
PsndGetSamplesMS(lines);
|
||||
}
|
||||
|
||||
|
|
|
@ -130,6 +130,9 @@ PICO_INTERNAL void PsndDoDAC(int cyc_to)
|
|||
int pos, len;
|
||||
int dout = ym2612.dacout;
|
||||
|
||||
// nothing to do if sound is off
|
||||
if (!PicoIn.sndOut) return;
|
||||
|
||||
// number of samples to fill in buffer (Q20)
|
||||
len = (cyc_to * Pico.snd.clkl_mult) - Pico.snd.dac_pos;
|
||||
|
||||
|
@ -169,6 +172,9 @@ PICO_INTERNAL void PsndDoPSG(int cyc_to)
|
|||
int pos, len;
|
||||
int stereo = 0;
|
||||
|
||||
// nothing to do if sound is off
|
||||
if (!PicoIn.sndOut) return;
|
||||
|
||||
// number of samples to fill in buffer (Q20)
|
||||
len = (cyc_to * Pico.snd.clkl_mult) - Pico.snd.psg_pos;
|
||||
|
||||
|
@ -196,6 +202,9 @@ PICO_INTERNAL void PsndDoYM2413(int cyc_to)
|
|||
int stereo = 0;
|
||||
short *buf;
|
||||
|
||||
// nothing to do if sound is off
|
||||
if (!PicoIn.sndOut) return;
|
||||
|
||||
// number of samples to fill in buffer (Q20)
|
||||
len = (cyc_to * Pico.snd.clkl_mult) - Pico.snd.ym2413_pos;
|
||||
|
||||
|
@ -236,6 +245,9 @@ PICO_INTERNAL void PsndDoFM(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.fm_pos;
|
||||
|
||||
|
@ -306,6 +318,11 @@ PICO_INTERNAL void PsndClear(void)
|
|||
{
|
||||
int len = Pico.snd.len;
|
||||
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;
|
||||
if (!PicoIn.sndOut) return;
|
||||
|
||||
if (PicoIn.opt & POPT_EN_STEREO)
|
||||
memset32((int *) PicoIn.sndOut, 0, len); // assume PicoIn.sndOut to be aligned
|
||||
else {
|
||||
|
@ -316,14 +333,12 @@ PICO_INTERNAL void PsndClear(void)
|
|||
}
|
||||
if (!(PicoIn.opt & POPT_EN_FM))
|
||||
memset32(PsndBuffer, 0, PicoIn.opt & POPT_EN_STEREO ? len*2 : 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;
|
||||
}
|
||||
|
||||
|
||||
static int PsndRender(int offset, int length)
|
||||
{
|
||||
int *buf32;
|
||||
s32 *buf32;
|
||||
int stereo = (PicoIn.opt & 8) >> 3;
|
||||
int fmlen = ((Pico.snd.fm_pos+0x80000) >> 20);
|
||||
int daclen = ((Pico.snd.dac_pos+0x80000) >> 20);
|
||||
|
@ -334,12 +349,14 @@ static int PsndRender(int offset, int length)
|
|||
pprof_start(sound);
|
||||
|
||||
if (PicoIn.AHW & PAHW_PICO) {
|
||||
PicoPicoPCMUpdate(PicoIn.sndOut+(offset<<stereo), length-offset, stereo);
|
||||
// XXX ugly hack, need to render sound for interrupts
|
||||
s16 *buf16 = PicoIn.sndOut ? PicoIn.sndOut : (short *)PsndBuffer;
|
||||
PicoPicoPCMUpdate(buf16+(offset<<stereo), length-offset, stereo);
|
||||
return length;
|
||||
}
|
||||
|
||||
// Fill up DAC output in case of missing samples (Q rounding errors)
|
||||
if (length-daclen > 0) {
|
||||
if (length-daclen > 0 && PicoIn.sndOut) {
|
||||
short *dacbuf = PicoIn.sndOut + (daclen << stereo);
|
||||
Pico.snd.dac_pos += (length-daclen) << 20;
|
||||
*dacbuf++ += Pico.snd.dac_val2;
|
||||
|
@ -352,7 +369,7 @@ static int PsndRender(int offset, int length)
|
|||
}
|
||||
|
||||
// Add in parts of the PSG output not yet done
|
||||
if (length-psglen > 0) {
|
||||
if (length-psglen > 0 && PicoIn.sndOut) {
|
||||
short *psgbuf = PicoIn.sndOut + (psglen << stereo);
|
||||
Pico.snd.psg_pos += (length-psglen) << 20;
|
||||
if (PicoIn.opt & POPT_EN_PSG)
|
||||
|
@ -360,7 +377,7 @@ static int PsndRender(int offset, int length)
|
|||
}
|
||||
|
||||
// Add in parts of the FM buffer not yet done
|
||||
if (length-fmlen > 0) {
|
||||
if (length-fmlen > 0 && PicoIn.sndOut) {
|
||||
int *fmbuf = buf32 + ((fmlen-offset) << stereo);
|
||||
Pico.snd.fm_pos += (length-fmlen) << 20;
|
||||
if (PicoIn.opt & POPT_EN_FM)
|
||||
|
@ -389,6 +406,7 @@ static int PsndRender(int offset, int length)
|
|||
p32x_pwm_update(buf32, length-offset, stereo);
|
||||
|
||||
// convert + limit to normal 16bit output
|
||||
if (PicoIn.sndOut)
|
||||
PsndMix_32_to_16l(PicoIn.sndOut+(offset<<stereo), buf32, length-offset);
|
||||
|
||||
pprof_end(sound);
|
||||
|
@ -402,7 +420,7 @@ PICO_INTERNAL void PsndGetSamples(int y)
|
|||
|
||||
curr_pos = PsndRender(0, Pico.snd.len_use);
|
||||
|
||||
if (PicoIn.writeSound)
|
||||
if (PicoIn.writeSound && PicoIn.sndOut)
|
||||
PicoIn.writeSound(curr_pos * ((PicoIn.opt & POPT_EN_STEREO) ? 4 : 2));
|
||||
// clear sound buffer
|
||||
PsndClear();
|
||||
|
@ -414,6 +432,9 @@ static int PsndRenderMS(int offset, int length)
|
|||
int psglen = ((Pico.snd.psg_pos+0x80000) >> 20);
|
||||
int ym2413len = ((Pico.snd.ym2413_pos+0x80000) >> 20);
|
||||
|
||||
if (!PicoIn.sndOut)
|
||||
return length;
|
||||
|
||||
pprof_start(sound);
|
||||
|
||||
// Add in parts of the PSG output not yet done
|
||||
|
@ -456,7 +477,7 @@ PICO_INTERNAL void PsndGetSamplesMS(int y)
|
|||
|
||||
curr_pos = PsndRenderMS(0, Pico.snd.len_use);
|
||||
|
||||
if (PicoIn.writeSound != NULL)
|
||||
if (PicoIn.writeSound != NULL && PicoIn.sndOut)
|
||||
PicoIn.writeSound(curr_pos * ((PicoIn.opt & POPT_EN_STEREO) ? 4 : 2));
|
||||
PsndClear();
|
||||
}
|
||||
|
|
|
@ -986,7 +986,7 @@ void emu_set_fastforward(int set_on)
|
|||
set_EmuOpt = currentConfig.EmuOpt;
|
||||
PicoIn.sndOut = NULL;
|
||||
currentConfig.Frameskip = 8;
|
||||
currentConfig.EmuOpt &= ~4;
|
||||
currentConfig.EmuOpt &= ~EOPT_EN_SOUND;
|
||||
currentConfig.EmuOpt |= EOPT_NO_FRMLIMIT;
|
||||
is_on = 1;
|
||||
emu_status_msg("FAST FORWARD");
|
||||
|
@ -997,9 +997,6 @@ void emu_set_fastforward(int set_on)
|
|||
currentConfig.EmuOpt = set_EmuOpt;
|
||||
PsndRerate(1);
|
||||
is_on = 0;
|
||||
// mainly to unbreak pcm
|
||||
if (PicoIn.AHW & PAHW_MCD)
|
||||
pcd_state_loaded();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue