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
This commit is contained in:
parent
d8f5641e5b
commit
007bf2335a
7 changed files with 29 additions and 35 deletions
|
@ -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];
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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<IDirectSoundBuffer *, std::shared_ptr<DirectSoundGenerator>> 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,6 +23,6 @@ namespace sa2
|
|||
void printAudioInfo();
|
||||
std::vector<SoundInfo> getAudioInfo();
|
||||
|
||||
void getAudioBufferSizes(int & trigger, int & target);
|
||||
void setAudioBufferSizes(const int trigger, const int target);
|
||||
void getAudioBufferSize(int & size);
|
||||
void setAudioBufferSize(const int size);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -78,8 +78,8 @@ class IDirectSoundBuffer : public IUnknown
|
|||
const std::unique_ptr<IDirectSoundNotify> mySoundNotify;
|
||||
std::vector<char> mySoundBuffer;
|
||||
|
||||
size_t myPlayPosition = 0;
|
||||
size_t myWritePosition = 0;
|
||||
size_t myPlayPosition = 0x0000;
|
||||
size_t myWritePosition = 0x0100;
|
||||
WORD myStatus = 0;
|
||||
LONG myVolume = DSBVOLUME_MAX;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue