fix waveout underruns cascading into decode underruns because the
decode buffer is smaller than the writeahead
This commit is contained in:
@@ -8,8 +8,7 @@
|
|||||||
|
|
||||||
static const int channels = 2;
|
static const int channels = 2;
|
||||||
static const int bytes_per_frame = channels*2; /* 16-bit */
|
static const int bytes_per_frame = channels*2; /* 16-bit */
|
||||||
|
static int frames_to_buffer;
|
||||||
static const int frames_to_buffer = 4096;
|
|
||||||
|
|
||||||
static const int num_chunks = 8;
|
static const int num_chunks = 8;
|
||||||
static int chunksize() { return frames_to_buffer / num_chunks; }
|
static int chunksize() { return frames_to_buffer / num_chunks; }
|
||||||
@@ -18,7 +17,10 @@ RageSound_Generic_Software::sound::sound()
|
|||||||
{
|
{
|
||||||
snd = NULL;
|
snd = NULL;
|
||||||
state = STOPPED;
|
state = STOPPED;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RageSound_Generic_Software::sound::Init()
|
||||||
|
{
|
||||||
/* Reserve enough blocks in the buffer to hold the buffer; plus some extra, since blocks
|
/* Reserve enough blocks in the buffer to hold the buffer; plus some extra, since blocks
|
||||||
* are partially read by Mix(); plus some more extra, since we can buffer one block
|
* are partially read by Mix(); plus some more extra, since we can buffer one block
|
||||||
* over frames_to_buffer (we buffer until filled >= frames_to_buffer). */
|
* over frames_to_buffer (we buffer until filled >= frames_to_buffer). */
|
||||||
@@ -294,12 +296,25 @@ void RageSound_Generic_Software::StopMixing( RageSoundBase *snd )
|
|||||||
void RageSound_Generic_Software::StartDecodeThread()
|
void RageSound_Generic_Software::StartDecodeThread()
|
||||||
{
|
{
|
||||||
ASSERT( !m_DecodeThread.IsCreated() );
|
ASSERT( !m_DecodeThread.IsCreated() );
|
||||||
|
|
||||||
|
/* Initialize the sound buffers, now that frames_to_buffer is finalized. */
|
||||||
|
for( unsigned i = 0; i < ARRAYSIZE(sounds); ++i )
|
||||||
|
sounds[i].Init();
|
||||||
|
|
||||||
m_DecodeThread.Create( DecodeThread_start, this );
|
m_DecodeThread.Create( DecodeThread_start, this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RageSound_Generic_Software::SetDecodeBufferSize( int frames )
|
||||||
|
{
|
||||||
|
ASSERT( !m_DecodeThread.IsCreated() );
|
||||||
|
|
||||||
|
frames_to_buffer = frames;
|
||||||
|
}
|
||||||
|
|
||||||
RageSound_Generic_Software::RageSound_Generic_Software()
|
RageSound_Generic_Software::RageSound_Generic_Software()
|
||||||
{
|
{
|
||||||
shutdown_decode_thread = false;
|
shutdown_decode_thread = false;
|
||||||
|
SetDecodeBufferSize( 4096 );
|
||||||
|
|
||||||
m_DecodeThread.SetName("Decode thread");
|
m_DecodeThread.SetName("Decode thread");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ class RageSound_Generic_Software: public RageSoundDriver
|
|||||||
} state;
|
} state;
|
||||||
|
|
||||||
sound();
|
sound();
|
||||||
|
void Init();
|
||||||
};
|
};
|
||||||
|
|
||||||
/* List of currently playing sounds: XXX no vector */
|
/* List of currently playing sounds: XXX no vector */
|
||||||
@@ -90,6 +91,12 @@ protected:
|
|||||||
* GetSampleRate will return the correct value. */
|
* GetSampleRate will return the correct value. */
|
||||||
void StartDecodeThread();
|
void StartDecodeThread();
|
||||||
|
|
||||||
|
/* Call this before calling StartDecodeThread to set the desired decoding buffer
|
||||||
|
* size. This is the number of frames that Mix() will try to be able to return
|
||||||
|
* at once. This should generally be slightly larger than the sound writeahead,
|
||||||
|
* to allow filling the buffer after an underrun. The default is 4096 frames. */
|
||||||
|
void SetDecodeBufferSize( int frames );
|
||||||
|
|
||||||
/* Override this to set the priority of the decoding thread, which should be above
|
/* Override this to set the priority of the decoding thread, which should be above
|
||||||
* normal priority but not realtime. */
|
* normal priority but not realtime. */
|
||||||
virtual void SetupDecodingThread() { }
|
virtual void SetupDecodingThread() { }
|
||||||
|
|||||||
@@ -135,6 +135,9 @@ RageSound_WaveOut::RageSound_WaveOut()
|
|||||||
buffers[b].dwFlags |= WHDR_DONE;
|
buffers[b].dwFlags |= WHDR_DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We have a very large writeahead; make sure we have a large enough decode
|
||||||
|
* buffer to recover cleanly from underruns. */
|
||||||
|
SetDecodeBufferSize( buffersize_frames * 3/2 );
|
||||||
StartDecodeThread();
|
StartDecodeThread();
|
||||||
|
|
||||||
MixingThread.SetName("Mixer thread");
|
MixingThread.SetName("Mixer thread");
|
||||||
|
|||||||
Reference in New Issue
Block a user