audio: change output rate to 47340Hz, add resampler with small margin to elimiate pops/clicks due to output rate fluctuation

output rate is picked such that 1024 samples at that rate equal exactly 710 samples at the SPU's output rate
This commit is contained in:
StapleButter 2017-12-11 18:41:05 +01:00
parent c639152541
commit 73bf4471ee
3 changed files with 51 additions and 11 deletions

View File

@ -684,19 +684,26 @@ void Mix(u32 samples)
}
void ReadOutput(s16* data, int samples)
int ReadOutput(s16* data, int samples)
{
if (OutputReadOffset == OutputWriteOffset)
return 0;
for (int i = 0; i < samples; i++)
{
*data++ = OutputBuffer[OutputReadOffset];
*data++ = OutputBuffer[OutputReadOffset + 1];
if (OutputReadOffset != OutputWriteOffset)
//if (OutputReadOffset != OutputWriteOffset)
{
OutputReadOffset += 2;
OutputReadOffset &= ((2*OutputBufferSize)-1);
}
if (OutputReadOffset == OutputWriteOffset)
return i+1;
}
return samples;
}

View File

@ -31,7 +31,7 @@ void SetBias(u16 bias);
void Mix(u32 samples);
void ReadOutput(s16* data, int samples);
int ReadOutput(s16* data, int samples);
u8 Read8(u32 addr);
u16 Read16(u32 addr);

View File

@ -96,7 +96,46 @@ void UpdateWindowTitle(void* data)
void AudioCallback(void* data, Uint8* stream, int len)
{
SPU::ReadOutput((s16*)stream, len>>2);
// resampling:
// buffer length is 1024 samples
// which is 710 samples at the original sample rate
//SPU::ReadOutput((s16*)stream, len>>2);
s16 buf_in[710*2];
s16* buf_out = (s16*)stream;
int num_in = SPU::ReadOutput(buf_in, 710);
int num_out = 1024;
int margin = 6;
if (num_in < 710-margin)
{
int last = num_in-1;
if (last < 0) last = 0;
for (int i = num_in; i < 710-margin; i++)
((u32*)buf_in)[i] = ((u32*)buf_in)[last];
num_in = 710-margin;
}
float res_incr = num_in / (float)num_out;
float res_timer = 0;
int res_pos = 0;
for (int i = 0; i < 1024; i++)
{
// TODO: interp!!
buf_out[i*2 ] = buf_in[res_pos*2 ];
buf_out[i*2+1] = buf_in[res_pos*2+1];
res_timer += res_incr;
while (res_timer >= 1.0)
{
res_timer -= 1.0;
res_pos++;
}
}
}
int EmuThreadFunc(void* burp)
@ -111,15 +150,9 @@ int EmuThreadFunc(void* burp)
ScreenDrawInited = false;
Touching = false;
// DS:
// 547.060546875 samples per frame
// 32823.6328125 samples per second
//
// 48000 samples per second:
// 800 samples per frame
SDL_AudioSpec whatIwant, whatIget;
memset(&whatIwant, 0, sizeof(SDL_AudioSpec));
whatIwant.freq = 32824; // 32823.6328125
whatIwant.freq = 47340;
whatIwant.format = AUDIO_S16LSB;
whatIwant.channels = 2;
whatIwant.samples = 1024;