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());
|
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;
|
goto out;
|
||||||
|
|
||||||
step = (Pico_mcd->pcm_mixpos << 16) / length;
|
step = (Pico_mcd->pcm_mixpos << 16) / length;
|
||||||
|
|
|
@ -311,8 +311,7 @@ static int PicoFrameHints(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// get samples from sound chips
|
// get samples from sound chips
|
||||||
if (PicoIn.sndOut)
|
PsndGetSamples(y);
|
||||||
PsndGetSamples(y);
|
|
||||||
|
|
||||||
timers_cycle();
|
timers_cycle();
|
||||||
|
|
||||||
|
|
|
@ -755,8 +755,7 @@ void PicoFrameMS(void)
|
||||||
z80_exec(Pico.t.z80c_line_start + cycles_line);
|
z80_exec(Pico.t.z80c_line_start + cycles_line);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PicoIn.sndOut)
|
PsndGetSamplesMS(lines);
|
||||||
PsndGetSamplesMS(lines);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PicoFrameDrawOnlyMS(void)
|
void PicoFrameDrawOnlyMS(void)
|
||||||
|
|
|
@ -130,6 +130,9 @@ PICO_INTERNAL void PsndDoDAC(int cyc_to)
|
||||||
int pos, len;
|
int pos, len;
|
||||||
int dout = ym2612.dacout;
|
int dout = ym2612.dacout;
|
||||||
|
|
||||||
|
// nothing to do if sound is off
|
||||||
|
if (!PicoIn.sndOut) return;
|
||||||
|
|
||||||
// number of samples to fill in buffer (Q20)
|
// number of samples to fill in buffer (Q20)
|
||||||
len = (cyc_to * Pico.snd.clkl_mult) - Pico.snd.dac_pos;
|
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 pos, len;
|
||||||
int stereo = 0;
|
int stereo = 0;
|
||||||
|
|
||||||
|
// nothing to do if sound is off
|
||||||
|
if (!PicoIn.sndOut) return;
|
||||||
|
|
||||||
// number of samples to fill in buffer (Q20)
|
// number of samples to fill in buffer (Q20)
|
||||||
len = (cyc_to * Pico.snd.clkl_mult) - Pico.snd.psg_pos;
|
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;
|
int stereo = 0;
|
||||||
short *buf;
|
short *buf;
|
||||||
|
|
||||||
|
// nothing to do if sound is off
|
||||||
|
if (!PicoIn.sndOut) return;
|
||||||
|
|
||||||
// number of samples to fill in buffer (Q20)
|
// number of samples to fill in buffer (Q20)
|
||||||
len = (cyc_to * Pico.snd.clkl_mult) - Pico.snd.ym2413_pos;
|
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 pos, len;
|
||||||
int stereo = 0;
|
int stereo = 0;
|
||||||
|
|
||||||
|
// nothing to do if sound is off
|
||||||
|
if (!PicoIn.sndOut) return;
|
||||||
|
|
||||||
// Q20, number of samples since last call
|
// Q20, number of samples since last call
|
||||||
len = (cyc_to * Pico.snd.clkl_mult) - Pico.snd.fm_pos;
|
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;
|
int len = Pico.snd.len;
|
||||||
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)
|
||||||
|
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)
|
if (PicoIn.opt & POPT_EN_STEREO)
|
||||||
memset32((int *) PicoIn.sndOut, 0, len); // assume PicoIn.sndOut to be aligned
|
memset32((int *) PicoIn.sndOut, 0, len); // assume PicoIn.sndOut to be aligned
|
||||||
else {
|
else {
|
||||||
|
@ -316,14 +333,12 @@ PICO_INTERNAL void PsndClear(void)
|
||||||
}
|
}
|
||||||
if (!(PicoIn.opt & POPT_EN_FM))
|
if (!(PicoIn.opt & POPT_EN_FM))
|
||||||
memset32(PsndBuffer, 0, PicoIn.opt & POPT_EN_STEREO ? len*2 : len);
|
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)
|
static int PsndRender(int offset, int length)
|
||||||
{
|
{
|
||||||
int *buf32;
|
s32 *buf32;
|
||||||
int stereo = (PicoIn.opt & 8) >> 3;
|
int stereo = (PicoIn.opt & 8) >> 3;
|
||||||
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);
|
||||||
|
@ -334,12 +349,14 @@ static int PsndRender(int offset, int length)
|
||||||
pprof_start(sound);
|
pprof_start(sound);
|
||||||
|
|
||||||
if (PicoIn.AHW & PAHW_PICO) {
|
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;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill up DAC output in case of missing samples (Q rounding errors)
|
// 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);
|
short *dacbuf = PicoIn.sndOut + (daclen << stereo);
|
||||||
Pico.snd.dac_pos += (length-daclen) << 20;
|
Pico.snd.dac_pos += (length-daclen) << 20;
|
||||||
*dacbuf++ += Pico.snd.dac_val2;
|
*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
|
// 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);
|
short *psgbuf = PicoIn.sndOut + (psglen << stereo);
|
||||||
Pico.snd.psg_pos += (length-psglen) << 20;
|
Pico.snd.psg_pos += (length-psglen) << 20;
|
||||||
if (PicoIn.opt & POPT_EN_PSG)
|
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
|
// 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);
|
int *fmbuf = buf32 + ((fmlen-offset) << stereo);
|
||||||
Pico.snd.fm_pos += (length-fmlen) << 20;
|
Pico.snd.fm_pos += (length-fmlen) << 20;
|
||||||
if (PicoIn.opt & POPT_EN_FM)
|
if (PicoIn.opt & POPT_EN_FM)
|
||||||
|
@ -389,7 +406,8 @@ static int PsndRender(int offset, int length)
|
||||||
p32x_pwm_update(buf32, length-offset, stereo);
|
p32x_pwm_update(buf32, length-offset, stereo);
|
||||||
|
|
||||||
// convert + limit to normal 16bit output
|
// convert + limit to normal 16bit output
|
||||||
PsndMix_32_to_16l(PicoIn.sndOut+(offset<<stereo), buf32, length-offset);
|
if (PicoIn.sndOut)
|
||||||
|
PsndMix_32_to_16l(PicoIn.sndOut+(offset<<stereo), buf32, length-offset);
|
||||||
|
|
||||||
pprof_end(sound);
|
pprof_end(sound);
|
||||||
|
|
||||||
|
@ -402,7 +420,7 @@ PICO_INTERNAL void PsndGetSamples(int y)
|
||||||
|
|
||||||
curr_pos = PsndRender(0, Pico.snd.len_use);
|
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));
|
PicoIn.writeSound(curr_pos * ((PicoIn.opt & POPT_EN_STEREO) ? 4 : 2));
|
||||||
// clear sound buffer
|
// clear sound buffer
|
||||||
PsndClear();
|
PsndClear();
|
||||||
|
@ -414,6 +432,9 @@ static int PsndRenderMS(int offset, int length)
|
||||||
int psglen = ((Pico.snd.psg_pos+0x80000) >> 20);
|
int psglen = ((Pico.snd.psg_pos+0x80000) >> 20);
|
||||||
int ym2413len = ((Pico.snd.ym2413_pos+0x80000) >> 20);
|
int ym2413len = ((Pico.snd.ym2413_pos+0x80000) >> 20);
|
||||||
|
|
||||||
|
if (!PicoIn.sndOut)
|
||||||
|
return length;
|
||||||
|
|
||||||
pprof_start(sound);
|
pprof_start(sound);
|
||||||
|
|
||||||
// Add in parts of the PSG output not yet done
|
// 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);
|
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));
|
PicoIn.writeSound(curr_pos * ((PicoIn.opt & POPT_EN_STEREO) ? 4 : 2));
|
||||||
PsndClear();
|
PsndClear();
|
||||||
}
|
}
|
||||||
|
|
|
@ -986,7 +986,7 @@ void emu_set_fastforward(int set_on)
|
||||||
set_EmuOpt = currentConfig.EmuOpt;
|
set_EmuOpt = currentConfig.EmuOpt;
|
||||||
PicoIn.sndOut = NULL;
|
PicoIn.sndOut = NULL;
|
||||||
currentConfig.Frameskip = 8;
|
currentConfig.Frameskip = 8;
|
||||||
currentConfig.EmuOpt &= ~4;
|
currentConfig.EmuOpt &= ~EOPT_EN_SOUND;
|
||||||
currentConfig.EmuOpt |= EOPT_NO_FRMLIMIT;
|
currentConfig.EmuOpt |= EOPT_NO_FRMLIMIT;
|
||||||
is_on = 1;
|
is_on = 1;
|
||||||
emu_status_msg("FAST FORWARD");
|
emu_status_msg("FAST FORWARD");
|
||||||
|
@ -997,9 +997,6 @@ void emu_set_fastforward(int set_on)
|
||||||
currentConfig.EmuOpt = set_EmuOpt;
|
currentConfig.EmuOpt = set_EmuOpt;
|
||||||
PsndRerate(1);
|
PsndRerate(1);
|
||||||
is_on = 0;
|
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