From 007bf2335af41e9c0a07cab75780ebbf203bc791 Mon Sep 17 00:00:00 2001 From: Andrea Odetti Date: Sun, 11 Jul 2021 14:33:26 +0100 Subject: [PATCH] 1) make sure AW does not fill the DS buffer, as semantics are unclear 2) process audio sooner, rather than a frame later 3) only 1 SDL buffer control (its size) 4) DS: Lock-Unlock probably reset the write cursor (in Windows) 5) DS: AW does not like DS buffer to be empty (or full??) at the begin --- source/Speaker.cpp | 8 +++---- source/frontends/sdl/imgui/sdlsettings.cpp | 20 ++++++++--------- source/frontends/sdl/main.cpp | 2 +- source/frontends/sdl/sdirectsound.cpp | 25 +++++++++------------- source/frontends/sdl/sdirectsound.h | 4 ++-- source/linux/windows/dsound.cpp | 1 + source/linux/windows/dsound.h | 4 ++-- 7 files changed, 29 insertions(+), 35 deletions(-) diff --git a/source/Speaker.cpp b/source/Speaker.cpp index e13ed33c..20eca087 100644 --- a/source/Speaker.cpp +++ b/source/Speaker.cpp @@ -569,8 +569,8 @@ static ULONG Spkr_SubmitWaveBuffer_FullSpeed(short* pSpeakerBuffer, ULONG nNumSa UINT nBytesFree = g_dwDSSpkrBufferSize - nBytesRemaining; // Calc free buffer space ULONG nNumSamplesToUse = nNumSamples + nNumPadSamples; - if(nNumSamplesToUse * sizeof(short) > nBytesFree) - nNumSamplesToUse = nBytesFree / sizeof(short); + if(nNumSamplesToUse * sizeof(short) >= nBytesFree) + nNumSamplesToUse = nBytesFree / sizeof(short) - 1; // @@ -766,8 +766,8 @@ static ULONG Spkr_SubmitWaveBuffer(short* pSpeakerBuffer, ULONG nNumSamples) UINT nBytesFree = g_dwDSSpkrBufferSize - nBytesRemaining; // Calc free buffer space ULONG nNumSamplesToUse = nNumSamples; - if(nNumSamplesToUse * sizeof(short) > nBytesFree) - nNumSamplesToUse = nBytesFree / sizeof(short); + if(nNumSamplesToUse * sizeof(short) >= nBytesFree) + nNumSamplesToUse = nBytesFree / sizeof(short) - 1; if(bBufferError) pSpeakerBuffer = &pSpeakerBuffer[nNumSamples - nNumSamplesToUse]; diff --git a/source/frontends/sdl/imgui/sdlsettings.cpp b/source/frontends/sdl/imgui/sdlsettings.cpp index 9bcd7a42..c1aaa4bb 100644 --- a/source/frontends/sdl/imgui/sdlsettings.cpp +++ b/source/frontends/sdl/imgui/sdlsettings.cpp @@ -500,22 +500,16 @@ namespace sa2 ImGui::Separator(); - int trigger; - int target; - getAudioBufferSizes(trigger, target); - if (ImGui::SliderInt("Trigger", &trigger, 0, 1000, "%d ms")) + int size; + getAudioBufferSize(size); + if (ImGui::SliderInt("Buffer size", &size, 0, 1000, "%d ms")) { - target = std::max(trigger, target); + setAudioBufferSize(size); } - if (ImGui::SliderInt("Target", &target, 0, 1000, "%d ms")) - { - trigger = std::min(trigger, target); - } - setAudioBufferSizes(trigger, target); ImGui::Separator(); - if (ImGui::BeginTable("Devices", 5, ImGuiTableFlags_RowBg)) + if (ImGui::BeginTable("Devices", 6, ImGuiTableFlags_RowBg)) { myAudioInfo = getAudioInfo(); ImGui::TableSetupColumn("Running"); @@ -523,6 +517,7 @@ namespace sa2 ImGui::TableSetupColumn("Volume"); ImGui::TableSetupColumn("Direct"); ImGui::TableSetupColumn("SDL"); + ImGui::TableSetupColumn("Total"); ImGui::TableHeadersRow(); ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true); // this requires imgui_internal.h @@ -538,6 +533,9 @@ namespace sa2 ImGui::SliderFloat("", &device.buffer, 0.0f, device.size, "%.3f"); ImGui::TableNextColumn(); ImGui::SliderFloat("", &device.queue, 0.0f, device.size, "%.3f"); + ImGui::TableNextColumn(); + float total = device.buffer + device.queue; + ImGui::SliderFloat("", &total, 0.0f, 2 * device.size, "%.3f"); } ImGui::PushItemFlag(ImGuiItemFlags_Disabled, false); diff --git a/source/frontends/sdl/main.cpp b/source/frontends/sdl/main.cpp index d16d73b2..d9cd5756 100644 --- a/source/frontends/sdl/main.cpp +++ b/source/frontends/sdl/main.cpp @@ -140,13 +140,13 @@ void run_sdl(int argc, const char * argv []) frameTimer.tic(); eventTimer.tic(); - sa2::writeAudio(); processEventsUthernet2(5); frame->ProcessEvents(quit); eventTimer.toc(); cpuTimer.tic(); frame->ExecuteOneFrame(oneFrame); + sa2::writeAudio(); cpuTimer.toc(); if (!options.headless) diff --git a/source/frontends/sdl/sdirectsound.cpp b/source/frontends/sdl/sdirectsound.cpp index 5163cff0..1d9cb70c 100644 --- a/source/frontends/sdl/sdirectsound.cpp +++ b/source/frontends/sdl/sdirectsound.cpp @@ -24,8 +24,7 @@ namespace void printInfo() const; sa2::SoundInfo getInfo() const; - static int ourTrigger; - static int ourTarget; + static int ourBufferSize; private: IDirectSoundBuffer * myBuffer; @@ -45,8 +44,7 @@ namespace void mixBuffer(const void * ptr, const size_t size); }; - int DirectSoundGenerator::ourTrigger = 200; - int DirectSoundGenerator::ourTarget = 200; + int DirectSoundGenerator::ourBufferSize = 200; std::unordered_map> activeSoundGenerators; @@ -141,7 +139,7 @@ namespace const float coeff = 1.0 / myBytesPerSecond; info.buffer = bytesInBuffer * coeff; info.queue = bytesInQueue * coeff; - info.size = myBuffer->bufferSize * coeff; + info.size = std::max(myBuffer->bufferSize * coeff, float(ourBufferSize / 1000.0)); } return info; @@ -186,13 +184,12 @@ namespace // and we loose sync const int queued = SDL_GetQueuedAudioSize(myAudioDevice); - const int trigger = myBytesPerSecond * DirectSoundGenerator::ourTrigger / 1000; + const int bufferSize = myBytesPerSecond * DirectSoundGenerator::ourBufferSize / 1000; - if (queued < trigger) // trigger is already <= target + if (queued < bufferSize) // trigger is already <= target { - const int target = myBytesPerSecond * DirectSoundGenerator::ourTarget / 1000; // make sure we only copy full frames - const int bytesToCopy = ((target - queued) / myBytesPerUnit) * myBytesPerUnit; + const int bytesToCopy = ((bufferSize - queued) / myBytesPerUnit) * myBytesPerUnit; LPVOID lpvAudioPtr1, lpvAudioPtr2; DWORD dwAudioBytes1, dwAudioBytes2; @@ -272,16 +269,14 @@ namespace sa2 return info; } - void getAudioBufferSizes(int & trigger, int & target) + void getAudioBufferSize(int & size) { - trigger = DirectSoundGenerator::ourTrigger; - target = DirectSoundGenerator::ourTarget; + size = DirectSoundGenerator::ourBufferSize; } - void setAudioBufferSizes(const int trigger, const int target) + void setAudioBufferSize(const int size) { - DirectSoundGenerator::ourTrigger = std::min(trigger, target); - DirectSoundGenerator::ourTarget = target; + DirectSoundGenerator::ourBufferSize = size; } } diff --git a/source/frontends/sdl/sdirectsound.h b/source/frontends/sdl/sdirectsound.h index fea1b0ac..de4d50be 100644 --- a/source/frontends/sdl/sdirectsound.h +++ b/source/frontends/sdl/sdirectsound.h @@ -23,6 +23,6 @@ namespace sa2 void printAudioInfo(); std::vector getAudioInfo(); - void getAudioBufferSizes(int & trigger, int & target); - void setAudioBufferSizes(const int trigger, const int target); + void getAudioBufferSize(int & size); + void setAudioBufferSize(const int size); } diff --git a/source/linux/windows/dsound.cpp b/source/linux/windows/dsound.cpp index e2a26b55..6e991963 100644 --- a/source/linux/windows/dsound.cpp +++ b/source/linux/windows/dsound.cpp @@ -97,6 +97,7 @@ HRESULT IDirectSoundBuffer::Lock( DWORD dwWriteCursor, DWORD dwWriteBytes, LPVOI } else { + myWritePosition = dwWriteCursor; const DWORD availableInFirstPart = this->mySoundBuffer.size() - dwWriteCursor; *lplpvAudioPtr1 = this->mySoundBuffer.data() + dwWriteCursor; diff --git a/source/linux/windows/dsound.h b/source/linux/windows/dsound.h index 5387f8af..dc5ff99a 100644 --- a/source/linux/windows/dsound.h +++ b/source/linux/windows/dsound.h @@ -78,8 +78,8 @@ class IDirectSoundBuffer : public IUnknown const std::unique_ptr mySoundNotify; std::vector mySoundBuffer; - size_t myPlayPosition = 0; - size_t myWritePosition = 0; + size_t myPlayPosition = 0x0000; + size_t myWritePosition = 0x0100; WORD myStatus = 0; LONG myVolume = DSBVOLUME_MAX;