separate buffer size and write-ahead
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user