Merge 2377746073
into 9ed7e5803e
This commit is contained in:
commit
2fa421d4ab
|
@ -1045,7 +1045,6 @@ u32 NDS::RunFrame()
|
|||
ARM7Timestamp-SysTimestamp,
|
||||
GPU.GPU3D.Timestamp-SysTimestamp);
|
||||
#endif
|
||||
SPU.TransferOutput();
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
90
src/SPU.cpp
90
src/SPU.cpp
|
@ -207,11 +207,10 @@ SPU::SPU(melonDS::NDS& nds, AudioBitDepth bitdepth, AudioInterpolation interpola
|
|||
ApplyBias = true;
|
||||
Degrade10Bit = false;
|
||||
|
||||
memset(OutputFrontBuffer, 0, 2*OutputBufferSize*2);
|
||||
memset(OutputBuffer, 0, 2*OutputBufferSize*2);
|
||||
|
||||
OutputBackbufferWritePosition = 0;
|
||||
OutputFrontBufferReadPosition = 0;
|
||||
OutputFrontBufferWritePosition = 0;
|
||||
OutputBufferReadPos = 0;
|
||||
OutputBufferWritePos = 0;
|
||||
}
|
||||
|
||||
SPU::~SPU()
|
||||
|
@ -242,11 +241,10 @@ void SPU::Reset()
|
|||
void SPU::Stop()
|
||||
{
|
||||
Platform::Mutex_Lock(AudioLock);
|
||||
memset(OutputFrontBuffer, 0, 2*OutputBufferSize*2);
|
||||
memset(OutputBuffer, 0, 2*OutputBufferSize*2);
|
||||
|
||||
OutputBackbufferWritePosition = 0;
|
||||
OutputFrontBufferReadPosition = 0;
|
||||
OutputFrontBufferWritePosition = 0;
|
||||
OutputBufferReadPos = 0;
|
||||
OutputBufferWritePos = 0;
|
||||
Platform::Mutex_Unlock(AudioLock);
|
||||
}
|
||||
|
||||
|
@ -942,67 +940,49 @@ void SPU::Mix(u32 dummy)
|
|||
rightoutput &= 0xFFFFFFC0;
|
||||
}
|
||||
|
||||
// OutputBufferFrame can never get full because it's
|
||||
// transfered to OutputBuffer at the end of the frame
|
||||
// FIXME: apparently this does happen!!!
|
||||
if (OutputBackbufferWritePosition * 2 < OutputBufferSize - 1)
|
||||
Platform::Mutex_Lock(AudioLock);
|
||||
OutputBuffer[OutputBufferWritePos++] = leftoutput >> 1;
|
||||
OutputBuffer[OutputBufferWritePos++] = rightoutput >> 1;
|
||||
|
||||
OutputBufferWritePos &= ((2*OutputBufferSize)-1);
|
||||
|
||||
if (OutputBufferWritePos == OutputBufferReadPos)
|
||||
{
|
||||
OutputBackbuffer[OutputBackbufferWritePosition ] = leftoutput >> 1;
|
||||
OutputBackbuffer[OutputBackbufferWritePosition + 1] = rightoutput >> 1;
|
||||
OutputBackbufferWritePosition += 2;
|
||||
// advance the read position too, to avoid losing the entire FIFO
|
||||
OutputBufferReadPos += 2;
|
||||
OutputBufferReadPos &= ((2*OutputBufferSize)-1);
|
||||
}
|
||||
Platform::Mutex_Unlock(AudioLock);
|
||||
|
||||
NDS.ScheduleEvent(Event_SPU, true, 1024, 0, 0);
|
||||
}
|
||||
|
||||
void SPU::TransferOutput()
|
||||
{
|
||||
Platform::Mutex_Lock(AudioLock);
|
||||
for (u32 i = 0; i < OutputBackbufferWritePosition; i += 2)
|
||||
{
|
||||
OutputFrontBuffer[OutputFrontBufferWritePosition ] = OutputBackbuffer[i ];
|
||||
OutputFrontBuffer[OutputFrontBufferWritePosition + 1] = OutputBackbuffer[i + 1];
|
||||
|
||||
OutputFrontBufferWritePosition += 2;
|
||||
OutputFrontBufferWritePosition &= OutputBufferSize*2-1;
|
||||
if (OutputFrontBufferWritePosition == OutputFrontBufferReadPosition)
|
||||
{
|
||||
// advance the read position too, to avoid losing the entire FIFO
|
||||
OutputFrontBufferReadPosition += 2;
|
||||
OutputFrontBufferReadPosition &= OutputBufferSize*2-1;
|
||||
}
|
||||
}
|
||||
OutputBackbufferWritePosition = 0;
|
||||
Platform::Mutex_Unlock(AudioLock);;
|
||||
}
|
||||
|
||||
void SPU::TrimOutput()
|
||||
{
|
||||
Platform::Mutex_Lock(AudioLock);
|
||||
const int halflimit = (OutputBufferSize / 2);
|
||||
|
||||
int readpos = OutputFrontBufferWritePosition - (halflimit*2);
|
||||
int readpos = OutputBufferWritePos - (halflimit*2);
|
||||
if (readpos < 0) readpos += (OutputBufferSize*2);
|
||||
|
||||
OutputFrontBufferReadPosition = readpos;
|
||||
OutputBufferReadPos = readpos;
|
||||
Platform::Mutex_Unlock(AudioLock);
|
||||
}
|
||||
|
||||
void SPU::DrainOutput()
|
||||
{
|
||||
Platform::Mutex_Lock(AudioLock);
|
||||
OutputFrontBufferWritePosition = 0;
|
||||
OutputFrontBufferReadPosition = 0;
|
||||
OutputBufferReadPos = 0;
|
||||
OutputBufferWritePos = 0;
|
||||
Platform::Mutex_Unlock(AudioLock);
|
||||
}
|
||||
|
||||
void SPU::InitOutput()
|
||||
{
|
||||
Platform::Mutex_Lock(AudioLock);
|
||||
memset(OutputBackbuffer, 0, 2*OutputBufferSize*2);
|
||||
memset(OutputFrontBuffer, 0, 2*OutputBufferSize*2);
|
||||
OutputFrontBufferReadPosition = 0;
|
||||
OutputFrontBufferWritePosition = 0;
|
||||
memset(OutputBuffer, 0, 2*OutputBufferSize*2);
|
||||
OutputBufferReadPos = 0;
|
||||
OutputBufferWritePos = 0;
|
||||
Platform::Mutex_Unlock(AudioLock);
|
||||
}
|
||||
|
||||
|
@ -1011,10 +991,10 @@ int SPU::GetOutputSize() const
|
|||
Platform::Mutex_Lock(AudioLock);
|
||||
|
||||
int ret;
|
||||
if (OutputFrontBufferWritePosition >= OutputFrontBufferReadPosition)
|
||||
ret = OutputFrontBufferWritePosition - OutputFrontBufferReadPosition;
|
||||
if (OutputBufferWritePos >= OutputBufferReadPos)
|
||||
ret = OutputBufferWritePos - OutputBufferReadPos;
|
||||
else
|
||||
ret = (OutputBufferSize*2) - OutputFrontBufferReadPosition + OutputFrontBufferWritePosition;
|
||||
ret = (OutputBufferSize*2) - OutputBufferReadPos + OutputBufferWritePos;
|
||||
|
||||
ret >>= 1;
|
||||
|
||||
|
@ -1043,10 +1023,10 @@ void SPU::Sync(bool wait)
|
|||
{
|
||||
Platform::Mutex_Lock(AudioLock);
|
||||
|
||||
int readpos = OutputFrontBufferWritePosition - (halflimit*2);
|
||||
int readpos = OutputBufferWritePos - (halflimit*2);
|
||||
if (readpos < 0) readpos += (OutputBufferSize*2);
|
||||
|
||||
OutputFrontBufferReadPosition = readpos;
|
||||
OutputBufferReadPos = readpos;
|
||||
|
||||
Platform::Mutex_Unlock(AudioLock);
|
||||
}
|
||||
|
@ -1055,7 +1035,7 @@ void SPU::Sync(bool wait)
|
|||
int SPU::ReadOutput(s16* data, int samples)
|
||||
{
|
||||
Platform::Mutex_Lock(AudioLock);
|
||||
if (OutputFrontBufferReadPosition == OutputFrontBufferWritePosition)
|
||||
if (OutputBufferReadPos == OutputBufferWritePos)
|
||||
{
|
||||
Platform::Mutex_Unlock(AudioLock);
|
||||
return 0;
|
||||
|
@ -1063,13 +1043,11 @@ int SPU::ReadOutput(s16* data, int samples)
|
|||
|
||||
for (int i = 0; i < samples; i++)
|
||||
{
|
||||
*data++ = OutputFrontBuffer[OutputFrontBufferReadPosition];
|
||||
*data++ = OutputFrontBuffer[OutputFrontBufferReadPosition + 1];
|
||||
*data++ = OutputBuffer[OutputBufferReadPos++];
|
||||
*data++ = OutputBuffer[OutputBufferReadPos++];
|
||||
OutputBufferReadPos &= ((2*OutputBufferSize)-1);
|
||||
|
||||
OutputFrontBufferReadPosition += 2;
|
||||
OutputFrontBufferReadPosition &= ((2*OutputBufferSize)-1);
|
||||
|
||||
if (OutputFrontBufferWritePosition == OutputFrontBufferReadPosition)
|
||||
if (OutputBufferWritePos == OutputBufferReadPos)
|
||||
{
|
||||
Platform::Mutex_Unlock(AudioLock);
|
||||
return i+1;
|
||||
|
|
12
src/SPU.h
12
src/SPU.h
|
@ -241,7 +241,6 @@ public:
|
|||
int GetOutputSize() const;
|
||||
void Sync(bool wait);
|
||||
int ReadOutput(s16* data, int samples);
|
||||
void TransferOutput();
|
||||
|
||||
u8 Read8(u32 addr);
|
||||
u16 Read16(u32 addr);
|
||||
|
@ -251,14 +250,11 @@ public:
|
|||
void Write32(u32 addr, u32 val);
|
||||
|
||||
private:
|
||||
static const u32 OutputBufferSize = 2*2048;
|
||||
static const u32 OutputBufferSize = 2*1024; // TODO: configurable audio buffer sizes?
|
||||
melonDS::NDS& NDS;
|
||||
s16 OutputBackbuffer[2 * OutputBufferSize] {};
|
||||
u32 OutputBackbufferWritePosition = 0;
|
||||
|
||||
s16 OutputFrontBuffer[2 * OutputBufferSize] {};
|
||||
u32 OutputFrontBufferWritePosition = 0;
|
||||
u32 OutputFrontBufferReadPosition = 0;
|
||||
s16 OutputBuffer[2 * OutputBufferSize] {};
|
||||
u32 OutputBufferWritePos = 0;
|
||||
u32 OutputBufferReadPos = 0;
|
||||
|
||||
Platform::Mutex* AudioLock;
|
||||
|
||||
|
|
|
@ -296,6 +296,7 @@ private:
|
|||
|
||||
SDL_AudioDeviceID audioDevice;
|
||||
int audioFreq;
|
||||
int audioBufSize;
|
||||
float audioSampleFrac;
|
||||
bool audioMuted;
|
||||
SDL_cond* audioSyncCond;
|
||||
|
|
|
@ -73,8 +73,8 @@ void EmuInstance::audioCallback(void* data, Uint8* stream, int len)
|
|||
// resample incoming audio to match the output sample rate
|
||||
|
||||
int len_in = inst->audioGetNumSamplesOut(len);
|
||||
if (len_in > 1024) len_in = 1024;
|
||||
s16 buf_in[1024*2];
|
||||
if (len_in > inst->audioBufSize) len_in = inst->audioBufSize;
|
||||
s16 buf_in[inst->audioBufSize*2];
|
||||
int num_in;
|
||||
|
||||
SDL_LockMutex(inst->audioSyncLock);
|
||||
|
@ -416,16 +416,17 @@ void EmuInstance::audioInit()
|
|||
audioSyncCond = SDL_CreateCond();
|
||||
audioSyncLock = SDL_CreateMutex();
|
||||
|
||||
audioFreq = 48000; // TODO: make configurable?
|
||||
audioFreq = 48000; // TODO: make both of these configurable?
|
||||
audioBufSize = 1024;
|
||||
SDL_AudioSpec whatIwant, whatIget;
|
||||
memset(&whatIwant, 0, sizeof(SDL_AudioSpec));
|
||||
whatIwant.freq = audioFreq;
|
||||
whatIwant.format = AUDIO_S16LSB;
|
||||
whatIwant.channels = 2;
|
||||
whatIwant.samples = 1024;
|
||||
whatIwant.samples = audioBufSize;
|
||||
whatIwant.callback = audioCallback;
|
||||
whatIwant.userdata = this;
|
||||
audioDevice = SDL_OpenAudioDevice(NULL, 0, &whatIwant, &whatIget, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE);
|
||||
audioDevice = SDL_OpenAudioDevice(NULL, 0, &whatIwant, &whatIget, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE | SDL_AUDIO_ALLOW_SAMPLES_CHANGE);
|
||||
if (!audioDevice)
|
||||
{
|
||||
Platform::Log(Platform::LogLevel::Error, "Audio init failed: %s\n", SDL_GetError());
|
||||
|
@ -433,7 +434,9 @@ void EmuInstance::audioInit()
|
|||
else
|
||||
{
|
||||
audioFreq = whatIget.freq;
|
||||
audioBufSize = whatIget.samples;
|
||||
Platform::Log(Platform::LogLevel::Info, "Audio output frequency: %d Hz\n", audioFreq);
|
||||
Platform::Log(Platform::LogLevel::Info, "Audio output buffer size: %d samples\n", audioBufSize);
|
||||
SDL_PauseAudioDevice(audioDevice, 1);
|
||||
}
|
||||
|
||||
|
@ -479,7 +482,7 @@ void EmuInstance::audioSync()
|
|||
if (audioDevice)
|
||||
{
|
||||
SDL_LockMutex(audioSyncLock);
|
||||
while (nds->SPU.GetOutputSize() > 1024)
|
||||
while (nds->SPU.GetOutputSize() > audioBufSize)
|
||||
{
|
||||
int ret = SDL_CondWaitTimeout(audioSyncCond, audioSyncLock, 500);
|
||||
if (ret == SDL_MUTEX_TIMEDOUT) break;
|
||||
|
|
Loading…
Reference in New Issue