sound, increase resolution for calculating psg sound

This commit is contained in:
kub 2021-10-02 21:13:48 +02:00
parent 86d6fb9a2f
commit 15caa286fc
3 changed files with 26 additions and 26 deletions

View file

@ -396,19 +396,13 @@ void NOINLINE ctl_write_z80reset(u32 d)
static void psg_write_68k(u32 d) static void psg_write_68k(u32 d)
{ {
// look for volume write and update if needed PsndDoPSG(z80_cycles_from_68k());
if ((d & 0x90) == 0x90)
PsndDoPSG(z80_cycles_from_68k());
SN76496Write(d); SN76496Write(d);
} }
static void psg_write_z80(u32 d) static void psg_write_z80(u32 d)
{ {
if ((d & 0x90) == 0x90) { PsndDoPSG(z80_cyclesDone());
PsndDoPSG(z80_cyclesDone());
}
SN76496Write(d); SN76496Write(d);
} }

View file

@ -202,8 +202,7 @@ static void z80_sms_out(unsigned short a, unsigned char d)
case 0x40: case 0x40:
case 0x41: case 0x41:
if ((d & 0x90) == 0x90) PsndDoPSG(z80_cyclesDone());
PsndDoPSG(Pico.m.scanline);
SN76496Write(d); SN76496Write(d);
break; break;
@ -373,6 +372,7 @@ void PicoFrameMS(void)
} }
cycles_aim += cycles_line; cycles_aim += cycles_line;
Pico.t.z80c_aim = cycles_aim >> 8;
cycles_done += z80_run((cycles_aim - cycles_done) >> 8) << 8; cycles_done += z80_run((cycles_aim - cycles_done) >> 8) << 8;
} }

View file

@ -130,6 +130,10 @@ PICO_INTERNAL void PsndDoDAC(int cyc_to)
// 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;
// don't do this too often (about once every 2 scanlines)
if (len <= PicoIn.sndRate << 3) // Q16, (PicoIn.sndRate << 16) >> 13
return;
// update position and calculate buffer offset and length // update position and calculate buffer offset and length
pos = (Pico.snd.dac_pos+0x80000) >> 20; pos = (Pico.snd.dac_pos+0x80000) >> 20;
Pico.snd.dac_pos += len; Pico.snd.dac_pos += len;
@ -169,17 +173,17 @@ PICO_INTERNAL void PsndDoPSG(int cyc_to)
// 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;
// don't do this too often (about once every 2 scanlines)
if (len <= PicoIn.sndRate << 3) // Q16, (PicoIn.sndRate << 16) >> 13
return;
// update position and calculate buffer offset and length // update position and calculate buffer offset and length
pos = (Pico.snd.psg_pos+0x80000) >> 20; pos = (Pico.snd.psg_pos+0x80000) >> 20;
Pico.snd.psg_pos += len; Pico.snd.psg_pos += len;
len = ((Pico.snd.psg_pos+0x80000) >> 20) - pos; len = ((Pico.snd.psg_pos+0x80000) >> 20) - pos;
// avoid loss of the 1st sample of a new block (Q rounding issues)
if (pos+len == 0)
len = 1, Pico.snd.psg_pos += 0x80000;
if (len <= 0) if (len <= 0)
return; return;
if (!PicoIn.sndOut || !(PicoIn.opt & POPT_EN_PSG)) if (!PicoIn.sndOut || !(PicoIn.opt & POPT_EN_PSG))
return; return;
@ -200,17 +204,17 @@ PICO_INTERNAL void PsndDoYM2413(int cyc_to)
// 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;
// don't do this too often (about once every 2 scanlines)
if (len <= PicoIn.sndRate << 3) // Q16, (PicoIn.sndRate << 16) >> 13
return;
// update position and calculate buffer offset and length // update position and calculate buffer offset and length
pos = (Pico.snd.ym2413_pos+0x80000) >> 20; pos = (Pico.snd.ym2413_pos+0x80000) >> 20;
Pico.snd.ym2413_pos += len; Pico.snd.ym2413_pos += len;
len = ((Pico.snd.ym2413_pos+0x80000) >> 20) - pos; len = ((Pico.snd.ym2413_pos+0x80000) >> 20) - pos;
// avoid loss of the 1st sample of a new block (Q rounding issues)
if (pos+len == 0)
len = 1, Pico.snd.ym2413_pos += 0x80000;
if (len <= 0) if (len <= 0)
return; return;
if (!PicoIn.sndOut || !(PicoIn.opt & POPT_EN_YM2413)) if (!PicoIn.sndOut || !(PicoIn.opt & POPT_EN_YM2413))
return; return;
@ -244,14 +248,16 @@ PICO_INTERNAL void PsndDoFM(int cyc_to)
// Q16, number of samples since last call // Q16, 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;
// don't do this too often (about once every 4 scanlines) // don't do this too often (about once every 2 scanlines)
if (len <= PicoIn.sndRate << 4) // Q16, (PicoIn.sndRate << 16) >> 12 if (len <= PicoIn.sndRate << 3) // Q16, (PicoIn.sndRate << 16) >> 13
return; return;
// update position and calculate buffer offset and length // update position and calculate buffer offset and length
pos = (Pico.snd.fm_pos+0x80000) >> 20; pos = (Pico.snd.fm_pos+0x80000) >> 20;
Pico.snd.fm_pos += len; Pico.snd.fm_pos += len;
len = ((Pico.snd.fm_pos+0x80000) >> 20) - pos; len = ((Pico.snd.fm_pos+0x80000) >> 20) - pos;
if (len <= 0)
return;
// fill buffer // fill buffer
if (PicoIn.opt & POPT_EN_STEREO) { if (PicoIn.opt & POPT_EN_STEREO) {
@ -334,7 +340,7 @@ static int PsndRender(int offset, int length)
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);
int psglen = ((Pico.snd.psg_pos+0x8000) >> 16); int psglen = ((Pico.snd.psg_pos+0x80000) >> 20);
buf32 = PsndBuffer+(offset<<stereo); buf32 = PsndBuffer+(offset<<stereo);
@ -361,7 +367,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) {
short *psgbuf = PicoIn.sndOut + (psglen << stereo); short *psgbuf = PicoIn.sndOut + (psglen << stereo);
Pico.snd.psg_pos += (length-psglen) << 16; Pico.snd.psg_pos += (length-psglen) << 20;
if (PicoIn.opt & POPT_EN_PSG) if (PicoIn.opt & POPT_EN_PSG)
SN76496Update(psgbuf, length-psglen, stereo); SN76496Update(psgbuf, length-psglen, stereo);
} }
@ -418,22 +424,22 @@ PICO_INTERNAL void PsndGetSamples(int y)
static int PsndRenderMS(int offset, int length) static int PsndRenderMS(int offset, int length)
{ {
int stereo = (PicoIn.opt & 8) >> 3; int stereo = (PicoIn.opt & 8) >> 3;
int psglen = ((Pico.snd.psg_pos+0x8000) >> 16); int psglen = ((Pico.snd.psg_pos+0x80000) >> 20);
int ym2413len = ((Pico.snd.ym2413_pos+0x8000) >> 16); int ym2413len = ((Pico.snd.ym2413_pos+0x80000) >> 20);
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
if (length-psglen > 0) { if (length-psglen > 0) {
short *psgbuf = PicoIn.sndOut + (psglen << stereo); short *psgbuf = PicoIn.sndOut + (psglen << stereo);
Pico.snd.psg_pos += (length-psglen) << 16; Pico.snd.psg_pos += (length-psglen) << 20;
if (PicoIn.opt & POPT_EN_PSG) if (PicoIn.opt & POPT_EN_PSG)
SN76496Update(psgbuf, length-psglen, stereo); SN76496Update(psgbuf, length-psglen, stereo);
} }
if (length-ym2413len > 0) { if (length-ym2413len > 0) {
short *ym2413buf = PicoIn.sndOut + (ym2413len << stereo); short *ym2413buf = PicoIn.sndOut + (ym2413len << stereo);
Pico.snd.ym2413_pos += (length-ym2413len) << 16; Pico.snd.ym2413_pos += (length-ym2413len) << 20;
int len = (length-ym2413len); int len = (length-ym2413len);
if (PicoIn.opt & POPT_EN_YM2413){ if (PicoIn.opt & POPT_EN_YM2413){
while (len-- > 0) { while (len-- > 0) {