Am I using SDL_QueueAudio wrong?


Hi have audio data, which I get with the SDL_LoadWAV() function.
Since I need the int values for further computation (and yeah, they are int values) and the SDL_LoadWav() function returns bytes and not the int values, I create 16 bit ints like this:

    //wavBuffer = original byte data
    int16_t* destA = new int16_t[audioSpec.wavLength / 2];
   //wavLength = Length of the original audio buffer
    for (int i = 0; i < audioSpec.wavLength - 4; i += 2)
        destA[i / 2] = (audioSpec.wavBuffer[i + 1] << (int8_t)8) | (audioSpec.wavBuffer[i] & (int8_t)0xff);

If I play the audio like this, everything works fine:

SDL_AudioDeviceID deviceId = SDL_OpenAudioDevice(NULL, 0, &audioSpec.wavSpec, NULL, 0);
SDL_PauseAudioDevice(deviceId, 0);
SDL_QueueAudio(deviceId, destA, audioSpec.wavLength);

As I mentioned I have some computing to do, so I don’t have all the data from the destA array available. I have a destB Array (int16_t), which holds the data for (let’s say) the next second (88200 samples for two channels).
But if I try to feed the queue like this

    int offset = 0;
    int length = audioChannels * freq; //88200
    while (isRunning)
        //here the computing is done. The for-loop is just a place holder in this example
        for (int i = 0; i < length; i++)
            destB[i] = destA[offset + i];
        offset += length;
        SDL_QueueAudio(deviceId, destB, length);

it doesn’t work anymore, bc the audio sounds trimmed and the volume is changing. However, the second variant works again when I work with the original byte data.

Can anyone think of why? I mean, if it wouldn’t work at all, bc of the casting into an int16_t I would assume the audio queue (for some reason) needs the data bytewise. But considering the fact it’s just not working, after I copy data from destA to destB and it is working without the casting in the beginning, I just don’t know, what I am doing wrong.


It’s somewhat misleading to say “the SDL_LoadWav() function returns bytes and not the int values”. It returns ‘data’, whether it’s bytes or 16-bit ints is just a matter of interpretation; what’s actually in memory is exactly the same. So there should be no need to copy the data, just cast it.

The third parameter should be length*2 (i.e. the number of bytes).

oh god thx. The way you explained it is totally logical and it works.

1 Like