audio: SN76496 fixes

This commit is contained in:
kub 2020-04-24 19:05:27 +02:00
parent fe43bdc334
commit 70aecd15b0
5 changed files with 43 additions and 10 deletions

View file

@ -173,9 +173,12 @@ void SN76496Update(short *buffer, int length, int stereo)
/* If we exit the loop in the middle, Output[i] has to be inverted */
/* and vol[i] incremented only if the exit status of the square */
/* wave is 1. */
left = 0;
while (R->Count[i] <= 0)
{
R->Count[i] += R->Period[i];
if (R->Count[i] + R->Period[i]*4 < R->Period[i])
left+= 4, R->Count[i] += R->Period[i]*4;
else left++, R->Count[i] += R->Period[i];
if (R->Count[i] > 0)
{
R->Output[i] ^= 1;
@ -186,6 +189,9 @@ void SN76496Update(short *buffer, int length, int stereo)
vol[i] += R->Period[i];
}
if (R->Output[i]) vol[i] -= R->Count[i];
/* Cut of anything above the sample freqency. It will only create */
/* aliasing and hearable distortions anyway. */
if (left > 1) vol[i] = STEP/2;
}
left = STEP;

View file

@ -259,6 +259,7 @@ static int PsndRender(int offset, int length)
int stereo = (PicoIn.opt & 8) >> 3;
int fmlen = ((Pico.snd.fm_pos+0x80000) >> 20);
int daclen = ((Pico.snd.dac_pos+0x80000) >> 20);
int psglen = ((Pico.snd.psg_pos+0x8000) >> 16);
buf32 = PsndBuffer+(offset<<stereo);
@ -282,6 +283,14 @@ static int PsndRender(int offset, int length)
Pico.snd.dac_val2 = Pico.snd.dac_val;
}
// Add in parts of the PSG output not yet done
if (length-psglen > 0) {
short *psgbuf = PicoIn.sndOut + (psglen << stereo);
Pico.snd.psg_pos += (length-psglen) << 16;
if (PicoIn.opt & POPT_EN_PSG)
SN76496Update(psgbuf, length-psglen, stereo);
}
// Add in parts of the FM buffer not yet done
if (length-fmlen > 0) {
int *fmbuf = buf32 + ((fmlen-offset) << stereo);
@ -323,8 +332,6 @@ PICO_INTERNAL void PsndGetSamples(int y)
{
static int curr_pos = 0;
PsndDoPSG(y - 1);
curr_pos = PsndRender(0, Pico.snd.len_use);
if (PicoIn.writeSound)
@ -333,11 +340,20 @@ PICO_INTERNAL void PsndGetSamples(int y)
PsndClear();
}
PICO_INTERNAL void PsndGetSamplesMS(int y)
static int PsndRenderMS(int offset, int length)
{
int length = Pico.snd.len_use;
int stereo = (PicoIn.opt & 8) >> 3;
int psglen = ((Pico.snd.psg_pos+0x8000) >> 16);
PsndDoPSG(y - 1);
pprof_start(sound);
// Add in parts of the PSG output not yet done
if (length-psglen > 0) {
short *psgbuf = PicoIn.sndOut + (psglen << stereo);
Pico.snd.psg_pos += (length-psglen) << 16;
if (PicoIn.opt & POPT_EN_PSG)
SN76496Update(psgbuf, length-psglen, stereo);
}
// upmix to "stereo" if needed
if (PicoIn.opt & POPT_EN_STEREO) {
@ -346,8 +362,19 @@ PICO_INTERNAL void PsndGetSamplesMS(int y)
*p |= *p << 16;
}
pprof_end(sound);
return length;
}
PICO_INTERNAL void PsndGetSamplesMS(int y)
{
static int curr_pos = 0;
curr_pos = PsndRenderMS(0, Pico.snd.len_use);
if (PicoIn.writeSound != NULL)
PicoIn.writeSound(length * ((PicoIn.opt & POPT_EN_STEREO) ? 4 : 2));
PicoIn.writeSound(curr_pos * ((PicoIn.opt & POPT_EN_STEREO) ? 4 : 2));
PsndClear();
}