Playing WAV file with native SDL2 Audio


#1

I’m trying to play a simple WAV file using SDL2. Most tutorials seem to opt to use SDL_mixer, but I instead took the masochistic approach of trying to use SDL2’s native functionality for Audio.

I put together bits and pieces from the documentation and came up with this:

#include <SDL.h>

int main(int argc, char ** argv)
{
    SDL_Init(SDL_INIT_AUDIO);

    SDL_AudioSpec wav_spec;
    Uint32 wav_length;
    Uint8 *wav_buffer;

    SDL_AudioSpec desired;
    SDL_AudioSpec obtained;

    SDL_zero(desired);
    desired.freq = 48000;
    desired.format = AUDIO_F32;
    desired.channels = 2;
    desired.samples = 4096;
    desired.callback = NULL;

    if (SDL_LoadWAV("Powerup5.wav", &wav_spec, &wav_buffer, &wav_length))
    {
        SDL_AudioDeviceID deviceId = SDL_OpenAudioDevice(NULL, 0, &desired, &obtained, 0);

        if (deviceId)
        {
            //SDL_PauseAudioDevice(deviceId, 0);
            int success = SDL_QueueAudio(deviceId, wav_buffer, wav_length);
            if (success < 0)
                SDL_ShowSimpleMessageBox(0, "Error", "Failed to queue audio", NULL);

            SDL_Delay(5000);
            SDL_CloseAudioDevice(deviceId);
        }
        else
            SDL_ShowSimpleMessageBox(0, "Error", "Audio driver failed to initialize", NULL);
    }
    else
        SDL_ShowSimpleMessageBox(0, "Error", "wav failed to load", NULL);

    SDL_Quit();

    return 0;
}

Everything is loading fine (I am not getting any message boxes) but no sound is being played. I tried switching the desired AudioSpec with that read from the WAV file, but it didn’t change anything.

Any idea what I’m doing wrong?


#2

//SDL_PauseAudioDevice(deviceId, 0);

This is the function that actually plays the audio, but you have it commented out. Note that passing 1 to the second argument would pause the sound, while how you have it with 0 is what plays it. Also, may I recommend easing up on the nesting of if statements.

Hope this helps.


#3

Hey, thanks for your reply! I did try calling SDL_PauseAudioDevice() (both before and after the SDL_QueueAudio() call), and it still makes no sound.

You’re right about the nesting - it’s a bit of a mess but I’m just experimenting at this point. The code will be nicer when I’m done! :slight_smile:


#4

I managed to make this work by replacing “desired” with wav_spec and “obtained” with NULL. I also added in SDL_FreeWAV() which I had missed. Full working code on Windows:

#include <SDL.h>

int main(int argc, char ** argv)
{
    SDL_Init(SDL_INIT_AUDIO);

    SDL_AudioSpec wav_spec;
    Uint32 wav_length;
    Uint8 *wav_buffer;

    if (SDL_LoadWAV("Powerup5.wav", &wav_spec, &wav_buffer, &wav_length))
    {
        SDL_AudioDeviceID deviceId = SDL_OpenAudioDevice(NULL, 0, NULL, NULL, 0);

        if (deviceId)
        {
            int success = SDL_QueueAudio(deviceId, wav_buffer, wav_length);

            SDL_PauseAudioDevice(deviceId, 0);

            SDL_Delay(3000);
            SDL_CloseAudioDevice(deviceId);
        }
        else
            SDL_ShowSimpleMessageBox(0, "Error", "Audio driver failed to initialize", NULL);

        SDL_FreeWAV(wav_buffer);
    }
    else
        SDL_ShowSimpleMessageBox(0, "Error", "wav failed to load", NULL);

    SDL_Quit();

    return 0;
}