Compare commits
3 commits
Author | SHA1 | Date | |
---|---|---|---|
|
007bf2335a | ||
|
d8f5641e5b | ||
|
9add1555a2 |
7 changed files with 52 additions and 22 deletions
|
@ -569,8 +569,8 @@ static ULONG Spkr_SubmitWaveBuffer_FullSpeed(short* pSpeakerBuffer, ULONG nNumSa
|
||||||
UINT nBytesFree = g_dwDSSpkrBufferSize - nBytesRemaining; // Calc free buffer space
|
UINT nBytesFree = g_dwDSSpkrBufferSize - nBytesRemaining; // Calc free buffer space
|
||||||
ULONG nNumSamplesToUse = nNumSamples + nNumPadSamples;
|
ULONG nNumSamplesToUse = nNumSamples + nNumPadSamples;
|
||||||
|
|
||||||
if(nNumSamplesToUse * sizeof(short) > nBytesFree)
|
if(nNumSamplesToUse * sizeof(short) >= nBytesFree)
|
||||||
nNumSamplesToUse = nBytesFree / sizeof(short);
|
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
|
UINT nBytesFree = g_dwDSSpkrBufferSize - nBytesRemaining; // Calc free buffer space
|
||||||
ULONG nNumSamplesToUse = nNumSamples;
|
ULONG nNumSamplesToUse = nNumSamples;
|
||||||
|
|
||||||
if(nNumSamplesToUse * sizeof(short) > nBytesFree)
|
if(nNumSamplesToUse * sizeof(short) >= nBytesFree)
|
||||||
nNumSamplesToUse = nBytesFree / sizeof(short);
|
nNumSamplesToUse = nBytesFree / sizeof(short) - 1;
|
||||||
|
|
||||||
if(bBufferError)
|
if(bBufferError)
|
||||||
pSpeakerBuffer = &pSpeakerBuffer[nNumSamples - nNumSamplesToUse];
|
pSpeakerBuffer = &pSpeakerBuffer[nNumSamples - nNumSamplesToUse];
|
||||||
|
|
|
@ -500,14 +500,24 @@ namespace sa2
|
||||||
|
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
|
||||||
if (ImGui::BeginTable("Devices", 5, ImGuiTableFlags_RowBg))
|
int size;
|
||||||
|
getAudioBufferSize(size);
|
||||||
|
if (ImGui::SliderInt("Buffer size", &size, 0, 1000, "%d ms"))
|
||||||
|
{
|
||||||
|
setAudioBufferSize(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
|
if (ImGui::BeginTable("Devices", 6, ImGuiTableFlags_RowBg))
|
||||||
{
|
{
|
||||||
myAudioInfo = getAudioInfo();
|
myAudioInfo = getAudioInfo();
|
||||||
ImGui::TableSetupColumn("Running");
|
ImGui::TableSetupColumn("Running");
|
||||||
ImGui::TableSetupColumn("Channels");
|
ImGui::TableSetupColumn("Channels");
|
||||||
ImGui::TableSetupColumn("Volume");
|
ImGui::TableSetupColumn("Volume");
|
||||||
ImGui::TableSetupColumn("Buffer");
|
ImGui::TableSetupColumn("Direct");
|
||||||
ImGui::TableSetupColumn("Queue");
|
ImGui::TableSetupColumn("SDL");
|
||||||
|
ImGui::TableSetupColumn("Total");
|
||||||
ImGui::TableHeadersRow();
|
ImGui::TableHeadersRow();
|
||||||
|
|
||||||
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true); // this requires imgui_internal.h
|
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true); // this requires imgui_internal.h
|
||||||
|
@ -523,6 +533,9 @@ namespace sa2
|
||||||
ImGui::SliderFloat("", &device.buffer, 0.0f, device.size, "%.3f");
|
ImGui::SliderFloat("", &device.buffer, 0.0f, device.size, "%.3f");
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
ImGui::SliderFloat("", &device.queue, 0.0f, device.size, "%.3f");
|
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);
|
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, false);
|
||||||
|
|
||||||
|
|
|
@ -140,13 +140,13 @@ void run_sdl(int argc, const char * argv [])
|
||||||
frameTimer.tic();
|
frameTimer.tic();
|
||||||
|
|
||||||
eventTimer.tic();
|
eventTimer.tic();
|
||||||
sa2::writeAudio();
|
|
||||||
processEventsUthernet2(5);
|
processEventsUthernet2(5);
|
||||||
frame->ProcessEvents(quit);
|
frame->ProcessEvents(quit);
|
||||||
eventTimer.toc();
|
eventTimer.toc();
|
||||||
|
|
||||||
cpuTimer.tic();
|
cpuTimer.tic();
|
||||||
frame->ExecuteOneFrame(oneFrame);
|
frame->ExecuteOneFrame(oneFrame);
|
||||||
|
sa2::writeAudio();
|
||||||
cpuTimer.toc();
|
cpuTimer.toc();
|
||||||
|
|
||||||
if (!options.headless)
|
if (!options.headless)
|
||||||
|
|
|
@ -24,6 +24,8 @@ namespace
|
||||||
void printInfo() const;
|
void printInfo() const;
|
||||||
sa2::SoundInfo getInfo() const;
|
sa2::SoundInfo getInfo() const;
|
||||||
|
|
||||||
|
static int ourBufferSize;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IDirectSoundBuffer * myBuffer;
|
IDirectSoundBuffer * myBuffer;
|
||||||
|
|
||||||
|
@ -33,6 +35,7 @@ namespace
|
||||||
SDL_AudioSpec myAudioSpec;
|
SDL_AudioSpec myAudioSpec;
|
||||||
|
|
||||||
int myBytesPerSecond;
|
int myBytesPerSecond;
|
||||||
|
int myBytesPerUnit;
|
||||||
|
|
||||||
void close();
|
void close();
|
||||||
bool isRunning() const;
|
bool isRunning() const;
|
||||||
|
@ -41,6 +44,7 @@ namespace
|
||||||
void mixBuffer(const void * ptr, const size_t size);
|
void mixBuffer(const void * ptr, const size_t size);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int DirectSoundGenerator::ourBufferSize = 200;
|
||||||
|
|
||||||
std::unordered_map<IDirectSoundBuffer *, std::shared_ptr<DirectSoundGenerator>> activeSoundGenerators;
|
std::unordered_map<IDirectSoundBuffer *, std::shared_ptr<DirectSoundGenerator>> activeSoundGenerators;
|
||||||
|
|
||||||
|
@ -48,6 +52,7 @@ namespace
|
||||||
: myBuffer(buffer)
|
: myBuffer(buffer)
|
||||||
, myAudioDevice(0)
|
, myAudioDevice(0)
|
||||||
, myBytesPerSecond(0)
|
, myBytesPerSecond(0)
|
||||||
|
, myBytesPerUnit(0)
|
||||||
{
|
{
|
||||||
SDL_memset(&myAudioSpec, 0, sizeof(myAudioSpec));
|
SDL_memset(&myAudioSpec, 0, sizeof(myAudioSpec));
|
||||||
}
|
}
|
||||||
|
@ -95,7 +100,8 @@ namespace
|
||||||
if (myAudioDevice)
|
if (myAudioDevice)
|
||||||
{
|
{
|
||||||
const int bitsPerSample = myAudioSpec.format & SDL_AUDIO_MASK_BITSIZE;
|
const int bitsPerSample = myAudioSpec.format & SDL_AUDIO_MASK_BITSIZE;
|
||||||
myBytesPerSecond = myAudioSpec.freq * myAudioSpec.channels * bitsPerSample / 8;
|
myBytesPerUnit = myAudioSpec.channels * bitsPerSample / 8;
|
||||||
|
myBytesPerSecond = myAudioSpec.freq * myBytesPerUnit;
|
||||||
|
|
||||||
SDL_PauseAudioDevice(myAudioDevice, 0);
|
SDL_PauseAudioDevice(myAudioDevice, 0);
|
||||||
return true;
|
return true;
|
||||||
|
@ -133,7 +139,7 @@ namespace
|
||||||
const float coeff = 1.0 / myBytesPerSecond;
|
const float coeff = 1.0 / myBytesPerSecond;
|
||||||
info.buffer = bytesInBuffer * coeff;
|
info.buffer = bytesInBuffer * coeff;
|
||||||
info.queue = bytesInQueue * coeff;
|
info.queue = bytesInQueue * coeff;
|
||||||
info.size = myBuffer->bufferSize * coeff;
|
info.size = std::max(myBuffer->bufferSize * coeff, float(ourBufferSize / 1000.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
|
@ -177,14 +183,17 @@ namespace
|
||||||
// otherwise AW starts generating a lot of samples
|
// otherwise AW starts generating a lot of samples
|
||||||
// and we loose sync
|
// and we loose sync
|
||||||
|
|
||||||
// assume SDL's buffer is the same size as AW's
|
const int queued = SDL_GetQueuedAudioSize(myAudioDevice);
|
||||||
const int bytesFree = myBuffer->bufferSize - SDL_GetQueuedAudioSize(myAudioDevice);
|
const int bufferSize = myBytesPerSecond * DirectSoundGenerator::ourBufferSize / 1000;
|
||||||
|
|
||||||
if (bytesFree > 0)
|
if (queued < bufferSize) // trigger is already <= target
|
||||||
{
|
{
|
||||||
|
// make sure we only copy full frames
|
||||||
|
const int bytesToCopy = ((bufferSize - queued) / myBytesPerUnit) * myBytesPerUnit;
|
||||||
|
|
||||||
LPVOID lpvAudioPtr1, lpvAudioPtr2;
|
LPVOID lpvAudioPtr1, lpvAudioPtr2;
|
||||||
DWORD dwAudioBytes1, dwAudioBytes2;
|
DWORD dwAudioBytes1, dwAudioBytes2;
|
||||||
myBuffer->Read(bytesFree, &lpvAudioPtr1, &dwAudioBytes1, &lpvAudioPtr2, &dwAudioBytes2);
|
myBuffer->Read(bytesToCopy, &lpvAudioPtr1, &dwAudioBytes1, &lpvAudioPtr2, &dwAudioBytes2);
|
||||||
|
|
||||||
if (lpvAudioPtr1 && dwAudioBytes1)
|
if (lpvAudioPtr1 && dwAudioBytes1)
|
||||||
{
|
{
|
||||||
|
@ -260,4 +269,14 @@ namespace sa2
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void getAudioBufferSize(int & size)
|
||||||
|
{
|
||||||
|
size = DirectSoundGenerator::ourBufferSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setAudioBufferSize(const int size)
|
||||||
|
{
|
||||||
|
DirectSoundGenerator::ourBufferSize = size;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,4 +22,7 @@ namespace sa2
|
||||||
void writeAudio();
|
void writeAudio();
|
||||||
void printAudioInfo();
|
void printAudioInfo();
|
||||||
std::vector<SoundInfo> getAudioInfo();
|
std::vector<SoundInfo> getAudioInfo();
|
||||||
|
|
||||||
|
void getAudioBufferSize(int & size);
|
||||||
|
void setAudioBufferSize(const int size);
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,11 +55,6 @@ HRESULT IDirectSoundBuffer::Stop()
|
||||||
return DS_OK;
|
return DS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT IDirectSoundBuffer::SetCurrentPosition( DWORD dwNewPosition )
|
|
||||||
{
|
|
||||||
return DS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT IDirectSoundBuffer::Play( DWORD dwReserved1, DWORD dwReserved2, DWORD dwFlags )
|
HRESULT IDirectSoundBuffer::Play( DWORD dwReserved1, DWORD dwReserved2, DWORD dwFlags )
|
||||||
{
|
{
|
||||||
this->myStatus |= DSBSTATUS_PLAYING;
|
this->myStatus |= DSBSTATUS_PLAYING;
|
||||||
|
@ -102,6 +97,7 @@ HRESULT IDirectSoundBuffer::Lock( DWORD dwWriteCursor, DWORD dwWriteBytes, LPVOI
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
myWritePosition = dwWriteCursor;
|
||||||
const DWORD availableInFirstPart = this->mySoundBuffer.size() - dwWriteCursor;
|
const DWORD availableInFirstPart = this->mySoundBuffer.size() - dwWriteCursor;
|
||||||
|
|
||||||
*lplpvAudioPtr1 = this->mySoundBuffer.data() + dwWriteCursor;
|
*lplpvAudioPtr1 = this->mySoundBuffer.data() + dwWriteCursor;
|
||||||
|
|
|
@ -78,8 +78,8 @@ class IDirectSoundBuffer : public IUnknown
|
||||||
const std::unique_ptr<IDirectSoundNotify> mySoundNotify;
|
const std::unique_ptr<IDirectSoundNotify> mySoundNotify;
|
||||||
std::vector<char> mySoundBuffer;
|
std::vector<char> mySoundBuffer;
|
||||||
|
|
||||||
size_t myPlayPosition = 0;
|
size_t myPlayPosition = 0x0000;
|
||||||
size_t myWritePosition = 0;
|
size_t myWritePosition = 0x0100;
|
||||||
WORD myStatus = 0;
|
WORD myStatus = 0;
|
||||||
LONG myVolume = DSBVOLUME_MAX;
|
LONG myVolume = DSBVOLUME_MAX;
|
||||||
|
|
||||||
|
@ -95,7 +95,6 @@ class IDirectSoundBuffer : public IUnknown
|
||||||
|
|
||||||
HRESULT QueryInterface(int riid, void **ppvObject);
|
HRESULT QueryInterface(int riid, void **ppvObject);
|
||||||
|
|
||||||
HRESULT SetCurrentPosition( DWORD dwNewPosition );
|
|
||||||
HRESULT GetCurrentPosition( LPDWORD lpdwCurrentPlayCursor, LPDWORD lpdwCurrentWriteCursor );
|
HRESULT GetCurrentPosition( LPDWORD lpdwCurrentPlayCursor, LPDWORD lpdwCurrentWriteCursor );
|
||||||
|
|
||||||
// Read is NOT part of Windows API
|
// Read is NOT part of Windows API
|
||||||
|
|
Loading…
Add table
Reference in a new issue