Changes to Audio.cpp:

- audio buffer is now kept as full as possible with new audio buffering method rather than just half full like before (this is okay now that buffer overruns have been eliminated)
- altered minimum size of audio buffer so that audio still works with a zero latency setting (obviously there will still be some latency)
This commit is contained in:
Nik Henson 2011-09-12 21:03:16 +00:00
parent b0bda2c356
commit 75d446c272

View file

@ -38,8 +38,8 @@ static bool writeWrapped = false; // True if write position has wrapped around
static unsigned underRuns = 0; // Number of buffer under-runs that have occured static unsigned underRuns = 0; // Number of buffer under-runs that have occured
static unsigned overRuns = 0; // Number of buffer over-runs that have occured static unsigned overRuns = 0; // Number of buffer over-runs that have occured
static AudioCallbackFPtr callback = NULL; static AudioCallbackFPtr callback = NULL; // Pointer to audio callback that is called when audio buffer is less than half empty
static void *callbackData = NULL; static void *callbackData = NULL; // Pointer to data to be passed to audio callback when it is called
void SetAudioCallback(AudioCallbackFPtr newCallback, void *newData) void SetAudioCallback(AudioCallbackFPtr newCallback, void *newData)
{ {
@ -147,8 +147,8 @@ static void PlayCallback(void *data, Uint8 *stream, int len)
// Move play position forward for next time // Move play position forward for next time
playPos += len; playPos += len;
bool halfEmpty = adjWritePos + audioBufferSize / 2 - BYTES_PER_FRAME / 2 < playPos + audioBufferSize; bool bufferFull = adjWritePos + 2 * BYTES_PER_FRAME > playPos + audioBufferSize;
// Check if play position has moved past end of buffer // Check if play position has moved past end of buffer
if (playPos >= audioBufferSize) if (playPos >= audioBufferSize)
{ {
@ -157,8 +157,8 @@ static void PlayCallback(void *data, Uint8 *stream, int len)
writeWrapped = false; writeWrapped = false;
} }
// If buffer is more than half empty then call callback // If buffer is not full then call audio callback
if (callback && halfEmpty) if (callback && !bufferFull)
callback(callbackData); callback(callbackData);
} }
@ -228,8 +228,8 @@ bool OpenAudio()
// Create audio buffer // Create audio buffer
audioBufferSize = SAMPLE_RATE * BYTES_PER_SAMPLE * latency / MAX_LATENCY; audioBufferSize = SAMPLE_RATE * BYTES_PER_SAMPLE * latency / MAX_LATENCY;
int roundBuffer = 2 * playSamples; int minBufferSize = 3 * BYTES_PER_FRAME;
audioBufferSize = max<int>(roundBuffer, (audioBufferSize / roundBuffer) * roundBuffer); audioBufferSize = max<int>(minBufferSize, audioBufferSize);
audioBuffer = new(std::nothrow) INT8[audioBufferSize]; audioBuffer = new(std::nothrow) INT8[audioBufferSize];
if (audioBuffer == NULL) if (audioBuffer == NULL)
{ {
@ -240,7 +240,7 @@ bool OpenAudio()
// Set initial play position to be beginning of buffer and initial write position to be half-way into buffer // Set initial play position to be beginning of buffer and initial write position to be half-way into buffer
playPos = 0; playPos = 0;
writePos = (BYTES_PER_FRAME + audioBufferSize) / 2; writePos = min<int>(audioBufferSize - BYTES_PER_FRAME, (BYTES_PER_FRAME + audioBufferSize) / 2);
writeWrapped = false; writeWrapped = false;
// Reset counters // Reset counters
@ -257,8 +257,6 @@ bool OutputAudio(unsigned numSamples, INT16 *leftBuffer, INT16 *rightBuffer)
//printf("OutputAudio(%u) [writePos = %u, writeWrapped = %s, playPos = %u, audioBufferSize = %u]\n", //printf("OutputAudio(%u) [writePos = %u, writeWrapped = %s, playPos = %u, audioBufferSize = %u]\n",
// numSamples, writePos, (writeWrapped ? "true" : "false"), playPos, audioBufferSize); // numSamples, writePos, (writeWrapped ? "true" : "false"), playPos, audioBufferSize);
bool halfFull = false;
UINT32 bytesRemaining; UINT32 bytesRemaining;
UINT32 bytesToCopy; UINT32 bytesToCopy;
INT16 *src; INT16 *src;
@ -323,8 +321,7 @@ bool OutputAudio(unsigned numSamples, INT16 *leftBuffer, INT16 *rightBuffer)
// Check if write position has caught up with play region and now overlaps it (ie buffer over-run) // Check if write position has caught up with play region and now overlaps it (ie buffer over-run)
bool overRun = writePos + numBytes > playPos + audioBufferSize; bool overRun = writePos + numBytes > playPos + audioBufferSize;
if (writePos + audioBufferSize / 2 + BYTES_PER_FRAME / 2 > playPos + audioBufferSize) bool bufferFull = writePos + 2 * BYTES_PER_FRAME > playPos + audioBufferSize;
halfFull = true;
// Move write position back to within buffer // Move write position back to within buffer
if (writePos >= audioBufferSize) if (writePos >= audioBufferSize)
@ -338,7 +335,7 @@ bool OutputAudio(unsigned numSamples, INT16 *leftBuffer, INT16 *rightBuffer)
//printf("Audio buffer over-run #%u in OutputAudio(%u) [writePos = %u, writeWrapped = %s, playPos = %u, audioBufferSize = %u, numBytes = %u]\n", //printf("Audio buffer over-run #%u in OutputAudio(%u) [writePos = %u, writeWrapped = %s, playPos = %u, audioBufferSize = %u, numBytes = %u]\n",
// overRuns, numSamples, writePos, (writeWrapped ? "true" : "false"), playPos, audioBufferSize, numBytes); // overRuns, numSamples, writePos, (writeWrapped ? "true" : "false"), playPos, audioBufferSize, numBytes);
halfFull = true; bufferFull = true;
// Discard current chunk of data // Discard current chunk of data
goto Finish; goto Finish;
@ -400,7 +397,7 @@ Finish:
SDL_UnlockAudio(); SDL_UnlockAudio();
// Return whether buffer is half full // Return whether buffer is half full
return halfFull; return bufferFull;
} }
void CloseAudio() void CloseAudio()