Posted on

Playing sound with SDL/C++

In my ongoing adventure to get up to speed on C++, I succeeded in getting a tutorial to work and play audio on my machine using only code (via SDL).

Unfortunately the tutorial kind of sucks at explaining the process of actually getting up and running.  If you just throw the code in, it won’t work.  Having rarely worked with C++ before, I had to learn the concept of includes and linking.

If you have no idea what I’m talking about, go through the tutorial I linked and use this blog as a reference to help you.  I’ll give you all the code so you can copypasta as you wish.  Keep in mind, this post is focused on Windows users only.

Step One: Install Visual Studio 2017  Include Visual C++ libraries in your installation.

Step Two: Grab the Development Library of SDL2

Step Three: Unzip that library in a project agnostic location.  I used C:\Development Libraries\SDL2

Step Four: Start a new project/solution in Visual Studio like below:

Make sure to create an empty project when using the wizard that pops up after this screen.

Step Five: Add a .cpp file to your project

Step Six: Right click your solution and select “Properties” at the bottom

Step Seven: Go to “General” under “C/C++” and add the “SDL2/include” folder to your “Additional Include Directories” as shown below:

Step Eight: Go to “General” under “Linker” and add the “SDL2/lib” for your build target (x86 or x64) to the “Additional Library Directories” section as shown below:

Step Nine: Go to “Input” under “Linker” add “SDL2.lib” and “SDL2main.lib” to the “Additional Dependencies” section as shown below:

Step Ten: Add the source code below to your .cpp file.  This source code is (mostly) explained in the tutorial video.  Be sure to use your own audio file!

[code language=”cpp”]

#include <iostream>
#include <SDL.h>

using namespace std;

struct AudioData
{
Uint8* position;
Uint32 length;
};

void audioCallback(void* userData, Uint8* stream, int streamLength)
{
AudioData* audio = (AudioData*)userData;

if (audio->length == 0)
{
return;
}

Uint32 length = (Uint32)streamLength;

length = (length > audio->length ? audio->length : length);

SDL_memcpy(stream, audio->position, length);

audio->position += length;
audio->length -= length;
}

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

SDL_AudioSpec wavSpec;
Uint8* wavStart;
Uint32 wavLength;
char* filePath = "ADD YOUR FILE PATH HERE";

if(SDL_LoadWAV(filePath, &wavSpec, &wavStart, &wavLength) == NULL)
{
cerr << "Error: file could not be loaded as an audio file." << endl;
}

AudioData audio;
audio.position = wavStart;
audio.length = wavLength;

wavSpec.callback = audioCallback;
wavSpec.userdata = &audio;

SDL_AudioDeviceID audioDevice;
audioDevice = SDL_OpenAudioDevice(NULL, 0, &wavSpec, NULL, SDL_AUDIO_ALLOW_ANY_CHANGE);

if (audioDevice == 0)
{
cerr << "Error: " << SDL_GetError() << endl;
return 1;
}

SDL_PauseAudioDevice(audioDevice, 0);

while (audio.length > 0)
{
SDL_Delay(100);
}

SDL_CloseAudioDevice(audioDevice);
SDL_FreeWAV(wavStart);
SDL_Quit();

return 0;
}

[/code]


Copyright 2016-2021, NIR LLC, all rights reserved.