The buffer length/wanted latency in the dsound2 audio player are now tweakable in config.dat; the options are called "audio dsound buffer latency" and "audio dsound buffer length" respectively. Defaults to 100/5 respectively (should work for the people who used to get buffer errors); for better responsiveness try 80/4.

Originally committed to SVN as r2905.
This commit is contained in:
Karl Blomster 2009-05-07 14:47:36 +00:00
parent 4d83215690
commit 732ccbbb26
3 changed files with 30 additions and 11 deletions

View File

@ -48,6 +48,7 @@
#include "utils.h" #include "utils.h"
#include "main.h" #include "main.h"
#include "frame_main.h" #include "frame_main.h"
#include "options.h"
#include "audio_player_dsound2.h" #include "audio_player_dsound2.h"
@ -131,12 +132,15 @@ class DirectSoundPlayer2Thread {
int64_t start_frame; int64_t start_frame;
int64_t end_frame; int64_t end_frame;
int wanted_latency;
int buffer_length;
DWORD last_playback_restart; DWORD last_playback_restart;
AudioProvider *provider; AudioProvider *provider;
public: public:
DirectSoundPlayer2Thread(AudioProvider *provider); DirectSoundPlayer2Thread(AudioProvider *provider, int WantedLatency, int BufferLength);
~DirectSoundPlayer2Thread(); ~DirectSoundPlayer2Thread();
void Play(int64_t start, int64_t count); void Play(int64_t start, int64_t count);
@ -159,11 +163,6 @@ unsigned int __stdcall DirectSoundPlayer2Thread::ThreadProc(void *parameter)
} }
#define WANTED_LATENCY 80
#define BUFFER_LENGTH 4
// The buffer will hold BUFFER_LENGTH times WANTED_LATENCY milliseconds of audio
void DirectSoundPlayer2Thread::Run() void DirectSoundPlayer2Thread::Run()
{ {
#define REPORT_ERROR(msg) { error_message = _T("DirectSoundPlayer2Thread: ") _T(msg); SetEvent(error_happened); return; } #define REPORT_ERROR(msg) { error_message = _T("DirectSoundPlayer2Thread: ") _T(msg); SetEvent(error_happened); return; }
@ -194,7 +193,7 @@ void DirectSoundPlayer2Thread::Run()
waveFormat.cbSize = sizeof(waveFormat); waveFormat.cbSize = sizeof(waveFormat);
// And the buffer itself // And the buffer itself
int aim = waveFormat.nAvgBytesPerSec * (WANTED_LATENCY*BUFFER_LENGTH)/1000; int aim = waveFormat.nAvgBytesPerSec * (wanted_latency*buffer_length)/1000;
int min = DSBSIZE_MIN; int min = DSBSIZE_MIN;
int max = DSBSIZE_MAX; int max = DSBSIZE_MAX;
DWORD bufSize = MIN(MAX(min,aim),max); // size of entier playback buffer DWORD bufSize = MIN(MAX(min,aim),max); // size of entier playback buffer
@ -239,7 +238,7 @@ void DirectSoundPlayer2Thread::Run()
while (running) while (running)
{ {
DWORD wait_result = WaitForMultipleObjects(sizeof(events_to_wait)/sizeof(HANDLE), events_to_wait, FALSE, WANTED_LATENCY); DWORD wait_result = WaitForMultipleObjects(sizeof(events_to_wait)/sizeof(HANDLE), events_to_wait, FALSE, wanted_latency);
switch (wait_result) switch (wait_result)
{ {
@ -475,7 +474,7 @@ void DirectSoundPlayer2Thread::CheckError()
} }
DirectSoundPlayer2Thread::DirectSoundPlayer2Thread(AudioProvider *provider) DirectSoundPlayer2Thread::DirectSoundPlayer2Thread(AudioProvider *provider, int _WantedLatency, int _BufferLength)
{ {
event_start_playback = CreateEvent(0, FALSE, FALSE, 0); event_start_playback = CreateEvent(0, FALSE, FALSE, 0);
event_stop_playback = CreateEvent(0, FALSE, FALSE, 0); event_stop_playback = CreateEvent(0, FALSE, FALSE, 0);
@ -492,6 +491,9 @@ DirectSoundPlayer2Thread::DirectSoundPlayer2Thread(AudioProvider *provider)
start_frame = 0; start_frame = 0;
end_frame = 0; end_frame = 0;
wanted_latency = _WantedLatency;
buffer_length = _BufferLength;
this->provider = provider; this->provider = provider;
thread_handle = (HANDLE)_beginthreadex(0, 0, ThreadProc, this, 0, 0); thread_handle = (HANDLE)_beginthreadex(0, 0, ThreadProc, this, 0, 0);
@ -613,6 +615,16 @@ double DirectSoundPlayer2Thread::GetVolume()
DirectSoundPlayer2::DirectSoundPlayer2() DirectSoundPlayer2::DirectSoundPlayer2()
{ {
thread = 0; thread = 0;
// The buffer will hold BufferLength times WantedLatency milliseconds of audio
WantedLatency = Options.AsInt(_T("Audio dsound buffer latency"));
BufferLength = Options.AsInt(_T("Audio dsound buffer length"));
// sanity checking
if (WantedLatency <= 0)
WantedLatency = 100;
if (BufferLength <= 0)
BufferLength = 5;
} }
@ -628,7 +640,7 @@ void DirectSoundPlayer2::OpenStream()
try try
{ {
thread = new DirectSoundPlayer2Thread(GetProvider()); thread = new DirectSoundPlayer2Thread(GetProvider(), WantedLatency, BufferLength);
} }
catch (const wxChar *msg) catch (const wxChar *msg)
{ {
@ -661,7 +673,7 @@ void DirectSoundPlayer2::SetProvider(AudioProvider *provider)
if (thread && provider != GetProvider()) if (thread && provider != GetProvider())
{ {
delete thread; delete thread;
thread = new DirectSoundPlayer2Thread(provider); thread = new DirectSoundPlayer2Thread(provider, WantedLatency, BufferLength);
} }
AudioPlayer::SetProvider(provider); AudioPlayer::SetProvider(provider);

View File

@ -45,6 +45,10 @@ class DirectSoundPlayer2Thread;
class DirectSoundPlayer2 : public AudioPlayer { class DirectSoundPlayer2 : public AudioPlayer {
DirectSoundPlayer2Thread *thread; DirectSoundPlayer2Thread *thread;
protected:
int WantedLatency;
int BufferLength;
public: public:
DirectSoundPlayer2(); DirectSoundPlayer2();
~DirectSoundPlayer2(); ~DirectSoundPlayer2();

View File

@ -219,6 +219,9 @@ void OptionsManager::LoadDefaults(bool onlyDefaults,bool doOverride) {
SetInt(_T("Audio Spectrum Cutoff"),0); SetInt(_T("Audio Spectrum Cutoff"),0);
SetInt(_T("Audio Spectrum Quality"),1); SetInt(_T("Audio Spectrum Quality"),1);
SetInt(_T("Audio Spectrum Memory Max"),128); // megabytes SetInt(_T("Audio Spectrum Memory Max"),128); // megabytes
// and this one could do with just reiniting the audio player
SetInt(_T("Audio dsound buffer latency"), 100);
SetInt(_T("Audio dsound buffer length"), 5);
// Automation // Automation
// The path changes only take effect when a script is (re)loaded but Automatic should be good enough, it certainly doesn't warrart a restart // The path changes only take effect when a script is (re)loaded but Automatic should be good enough, it certainly doesn't warrart a restart