I have read about people having problems with waveOutWrite( ) stuttering in Windows Vista. This problems has hit me now, so I have done a bit of research. First, here is what I have tested on:
We have three hardware varying machines with Vista Business loaded on them, along with four different soundchip brands. Two of the soundchip brands are internal to the machines, and the other two we used are USB sound devices. I tried combinations off all machines/sound cards to see if it would make a difference. The stuttering problem happens regardless of the match up, so for now, I'm going to assume it is not a hardware problem.
Our application sends about 300 bytes at a time to the sound card (very low latency is required). After doing a lot of testing with buffers and timing in our application, I was suddenly able to make the stuttering problem go away by caching over 1k of sound data before sending it with waveOutWrite( ). However, as this introduced latency, it was not a solution, so I kept searching for what could be causing this problem.
My next test was showing that my audio data was sent using waveOutWrite( ), but it was not playing through the speakers. So I tried a test to see what would happen if I called waveOutWrite( ) 100 times in a row in rapid succession. Nothing played until I finished calling waveOutWrite( ) 100 times, and then the entire sound played from start to end. I then tried the experiment again, but this time I added a Sleep(50) between each call to waveOutWrite( ). Now I hear a stuttering sound, but it starts playing immediately.
These tests indicate that waveOutWrite( ) is dynamically buffering my sound if I call it too fast in rapid succession. This means that waveOutWrite( ) is not starting to play a sound the moment it is sent the first block.
Can anyone verify the waveOutWrite( ) behavior changes from earlier OS's to Vista?
I just found something out VERY interesting. If I call waveOutWrite( ) and send a different buffer pointer each time, it will cache it until I send the first buffer pointer again (it thinks I have circled through all my buffers), at which time it starts playing the sound. So the sound will start playing on two conditions. One, you send the first pointer again (i.e cycling through your buffers), or putting in a pause (i.e. Sleep(50))
Why is waveOutWrite( ) looking at my pointers? It shouldn't care when I have cycled through all of my sound buffers, it should just play what I send to it when I send it.
char *ptr; //pointer to at least 3 MB of PCM audio data (make sure it is lengthy enough to cover this example without crashing)This is a snippet from what I am using to test this.
bufferIndex=0; //start at first buffer
count=300; //300 bytes per waveOutWrite( )
buffers.SetSize(1000); //1000 pointers to our sound buffers
PWaveBuffer &buffer = buffers[bufferIndex];
memcpy(buffer.GetPointer(), ptr, count)
waveOutPrepareHeader(hWaveOut, &buffer.header, sizeof(buffer.header));
waveOutWrite(hWaveOut, &buffer.header, sizeof(WAVEHDR));
bufferIndex = (bufferIndex+1)%100; //notice that I am restarting the bufferindex at 100, if you raise this number, the pause is longer before the audio begins playing, this indicates that waveOutWrite( ) is checking the pointer of my buffer to see when I am back to the first one!
ptr += count;
You're not the only one having these problems. Read my post about .WAV files playing. We depend on these and XP,98,ME,2000 have never caused a problem but now we stutter but only on certain computers. The one computer we upgraded to Vista is working and all of the virgin installs seem to fail with the sound files. If you find out the cause let me know too!