Double-buffered waveOutWrite() stuttering like hell

  • 1 year ago
Comment

ChatGPTChatGPT
1 / 1

Stuttering or audio glitches in audio playback using waveOutWrite() in Windows can occur due to various reasons. It's essential to ensure smooth audio playback by optimizing the audio buffer size and the data you pass to waveOutWrite(). Here are some common tips to reduce stuttering:

  1. Optimize Buffer Size: Adjust the buffer size to balance between latency and performance. Smaller buffer sizes reduce latency but might increase the overhead of calling waveOutWrite(). Larger buffer sizes reduce the number of calls to waveOutWrite() but can increase latency.

  2. Fill Buffers Asynchronously: Avoid blocking the audio playback thread when filling the audio buffer. Use a separate thread or asynchronous processing to fill the audio buffer with data.

  3. Pre-buffering: Pre-fill the audio buffer with enough data before starting audio playback to avoid underflow and potential glitches.

  4. Use Event Callbacks: Instead of polling the audio buffer for data, use callback functions to be notified when the buffer is running low, and it's time to fill more data.

  5. Avoid Heavy Processing in the Audio Thread: Ensure that the audio processing does not consume too much CPU time. Heavy processing in the audio thread can lead to buffer underruns.

  6. Avoid Sharing Resources: Avoid sharing the audio resources with other processes or applications that might compete for system resources and cause interruptions.

  7. Update Audio Clock: If possible, update the audio clock to prevent drift between the audio playback and the system clock.

  8. Use Direct Sound: Consider using Direct Sound instead of waveOut API, as it provides better support for low-latency audio.

Here's a simple example of how you can use a separate thread to asynchronously fill the audio buffer using waveOutWrite():

c
#include <stdio.h>
#include <windows.h>
#include <mmsystem.h>

HWAVEOUT hWaveOut;
WAVEHDR waveHdr;
BYTE buffer[/* Your buffer size */];

void CALLBACK WaveOutProc(HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) {
if (uMsg == WOM_DONE) {
// Fill the buffer again with new data
waveOutWrite(hWaveOut, &waveHdr, sizeof(WAVEHDR));
}
}

int main() {
// Open audio device
WAVEFORMATEX format;
format.wFormatTag = WAVE_FORMAT_PCM;
format.nChannels = 2;
format.nSamplesPerSec = 44100;
format.nAvgBytesPerSec = format.nSamplesPerSec * 4;
format.nBlockAlign = 4;
format.wBitsPerSample = 16;
format.cbSize = 0;

waveOutOpen(&hWaveOut, WAVE_MAPPER, &format, (DWORD_PTR)WaveOutProc, 0, CALLBACK_FUNCTION);

// Prepare audio buffer
waveHdr.lpData = buffer;
waveHdr.dwBufferLength = sizeof(buffer);
waveOutPrepareHeader(hWaveOut, &waveHdr, sizeof(WAVEHDR));

// Start audio playback
waveOutWrite(hWaveOut, &waveHdr, sizeof(WAVEHDR));

// Do other tasks or wait for playback to complete

// Clean up
waveOutUnprepareHeader(hWaveOut, &waveHdr, sizeof(WAVEHDR));
waveOutClose(hWaveOut);

return 0;
}

Remember that stuttering or audio glitches can also be caused by system resource limitations, driver issues, or other external factors. If you are still facing issues after optimizing your code, consider investigating these other possibilities.