From fc916dde9b022989087c9fad6d9d8a6bdd666f05 Mon Sep 17 00:00:00 2001 From: Glenn Maynard Date: Tue, 31 Dec 2002 01:08:35 +0000 Subject: [PATCH] separate buffer size and write-ahead --- stepmania/src/arch/Sound/DSoundHelpers.cpp | 50 ++++++++++++++++++++-- stepmania/src/arch/Sound/DSoundHelpers.h | 6 ++- 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/stepmania/src/arch/Sound/DSoundHelpers.cpp b/stepmania/src/arch/Sound/DSoundHelpers.cpp index f432ecc61e..a58510ac60 100644 --- a/stepmania/src/arch/Sound/DSoundHelpers.cpp +++ b/stepmania/src/arch/Sound/DSoundHelpers.cpp @@ -44,15 +44,18 @@ bool DSound::IsEmulated() const } DSoundBuf::DSoundBuf(DSound &ds, DSoundBuf::hw hardware, - int channels_, int samplerate_, int samplebits_, int buffersize_) + int channels_, int samplerate_, int samplebits_, int writeahead_) { channels = channels_; samplerate = samplerate_; samplebits = samplebits_; - buffersize = buffersize_; + writeahead = writeahead_; buffer_locked = false; last_cursor_pos = write_cursor = 0; + /* The size of the actual DSound buffer. This can be large; we generally + * won't fill it completely. */ + buffersize = 1024*64; WAVEFORMATEX waveformat; memset(&waveformat, 0, sizeof(waveformat)); @@ -119,6 +122,46 @@ bool DSoundBuf::get_output_buf(char **buffer, unsigned *bufsiz, int *play_pos, i int num_bytes_empty = cursor - write_cursor; if(num_bytes_empty <= 0) num_bytes_empty += buffersize; /* unwrap */ + /* XXX We can figure out if we've underrun, and increase the write-ahead + * when it happens. Two problems: + * 1. It's ugly to wait until we actually underrun. (We could store the + * write-ahead, though.) + * 2. We don't want a random underrun (eg. virus scanner starts) to + * permanently increase our write-ahead. We want the smallest possible + * that will give us reliable audio in normal conditions. I'm not sure + * of a robust way to do this. We could decrease the buffer size if + * we seem to be consistently ahead, but that's getting a little messy ... + * + * Also, writeahead should be a static (all buffers write ahead the same + * amount); writeahead in the ctor should be a hint only (initial value), + * and the sound driver should query a sound to get the current writeahead + * in GetLatencySeconds(). + */ +#if 0 + { + /* Figure out the amount of space we're not supposed to write to: */ + int unwritable = write-cursor; + if(unwritable < 0) unwritable += buffersize; /* unwrap */ + + if(writeahead < unwritable) + { + writeahead = unwritable*2; + LOG->Trace("boosted buffersize to %i", writeahead); + } + + /* */ + if(num_bytes_empty > buffersize - unwritable) + { +// writeahead += 512; +// LOG->Trace("underflow; bs now %i", writeahead); + } + } +#endif + + int num_bytes_filled = buffersize - num_bytes_empty; + if(num_bytes_filled > writeahead) + return false; + /* num_bytes_empty is now the actual amount of free buffer space. If it's * too small, come back later. */ if(num_bytes_empty < chunksize) @@ -133,6 +176,8 @@ bool DSoundBuf::get_output_buf(char **buffer, unsigned *bufsiz, int *play_pos, i * we'll give some data soon instead of lots of data later. */ num_bytes_empty = min(num_bytes_empty, chunksize); +// LOG->Trace("gave %i at %i (%i, %i) %i filled", num_bytes_empty, write_cursor, cursor, write, num_bytes_filled ); + /* Lock the audio buffer. */ result = buf->Lock(write_cursor, num_bytes_empty, (LPVOID *)buffer, (DWORD *) bufsiz, NULL, &junk, 0); if ( result == DSERR_BUFFERLOST ) { @@ -155,7 +200,6 @@ bool DSoundBuf::get_output_buf(char **buffer, unsigned *bufsiz, int *play_pos, i buffer_locked = true; -// LOG->Trace("gave %i", num_bytes_empty); return true; } diff --git a/stepmania/src/arch/Sound/DSoundHelpers.h b/stepmania/src/arch/Sound/DSoundHelpers.h index 594d4daffb..e326c235f6 100644 --- a/stepmania/src/arch/Sound/DSoundHelpers.h +++ b/stepmania/src/arch/Sound/DSoundHelpers.h @@ -22,8 +22,10 @@ class DSoundBuf { IDirectSoundBuffer8 *buf; - int channels, samplerate, samplebits, buffersize; + int channels, samplerate, samplebits, writeahead; + int buffersize; + int buffersize_frames() const { return buffersize / samplesize(); } int samplesize() const { return channels*samplebits/8; } @@ -38,7 +40,7 @@ class DSoundBuf public: enum hw { HW_HARDWARE, HW_SOFTWARE, HW_DONT_CARE }; DSoundBuf(DSound &ds, hw hardware, - int channels, int samplerate, int samplebits, int buffersize); + int channels, int samplerate, int samplebits, int writeahead); bool get_output_buf(char **buffer, unsigned *bufsiz, int *play_pos, int chunksize); void release_output_buf(char *buffer, unsigned bufsiz);