Skip to content

Instantly share code, notes, and snippets.

@armornick
Created August 24, 2012 07:31
Show Gist options
  • Save armornick/3447121 to your computer and use it in GitHub Desktop.
Save armornick/3447121 to your computer and use it in GitHub Desktop.
Play a sound with SDL2 (no SDL_Mixer)
#include <SDL2/SDL.h>
#define MUS_PATH "Roland-GR-1-Trumpet-C5.wav"
// prototype for our audio callback
// see the implementation for more information
void my_audio_callback(void *userdata, Uint8 *stream, int len);
// variable declarations
static Uint8 *audio_pos; // global pointer to the audio buffer to be played
static Uint32 audio_len; // remaining length of the sample we have to play
/*
** PLAYING A SOUND IS MUCH MORE COMPLICATED THAN IT SHOULD BE
*/
int main(int argc, char* argv[]){
// Initialize SDL.
if (SDL_Init(SDL_INIT_AUDIO) < 0)
return 1;
// local variables
static Uint32 wav_length; // length of our sample
static Uint8 *wav_buffer; // buffer containing our audio file
static SDL_AudioSpec wav_spec; // the specs of our piece of music
/* Load the WAV */
// the specs, length and buffer of our wav are filled
if( SDL_LoadWAV(MUS_PATH, &wav_spec, &wav_buffer, &wav_length) == NULL ){
return 1;
}
// set the callback function
wav_spec.callback = my_audio_callback;
wav_spec.userdata = NULL;
// set our global static variables
audio_pos = wav_buffer; // copy sound buffer
audio_len = wav_length; // copy file length
/* Open the audio device */
if ( SDL_OpenAudio(&wav_spec, NULL) < 0 ){
fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError());
exit(-1);
}
/* Start playing */
SDL_PauseAudio(0);
// wait until we're don't playing
while ( audio_len > 0 ) {
SDL_Delay(100);
}
// shut everything down
SDL_CloseAudio();
SDL_FreeWAV(wav_buffer);
}
// audio callback function
// here you have to copy the data of your audio buffer into the
// requesting audio buffer (stream)
// you should only copy as much as the requested length (len)
void my_audio_callback(void *userdata, Uint8 *stream, int len) {
if (audio_len ==0)
return;
len = ( len > audio_len ? audio_len : len );
//SDL_memcpy (stream, audio_pos, len); // simply copy from one buffer into the other
SDL_MixAudio(stream, audio_pos, len, SDL_MIX_MAXVOLUME);// mix from one buffer into another
audio_pos += len;
audio_len -= len;
}
@nesteruk
Copy link

This doesn't work for me. Instead of playing the sound once, it fails to play it on first call, then plays it about 5 times when I call this again.

@matozoid
Copy link

Works great, but I think it would be better to have line 72 commented instead of line 71, since I thought everything was broken :-)

@NguyenMVo
Copy link

NguyenMVo commented Apr 15, 2020

The code doesn't work for me. It's keep repeating the first few seconds over and over . Can anyone help me ? (I'm using SDL 2.0.12 with Code::Blocks 17.12)

@htmlcsjs
Copy link

Same thing happend to me @NguyenMVo

@armornick
Copy link
Author

I haven't touched this code in years, so I can't help anyone with their problems. Personally, I would suggest using SDL_Mixer or something more modern like SFML or raylib.

@Axilot
Copy link

Axilot commented Sep 26, 2020

I haven't touched this code in years, so I can't help anyone with their problems. Personally, I would suggest using SDL_Mixer or something more modern like SFML or raylib.

Can i use vulkan to render my windows in raylib?

@its-theo
Copy link

oh god thats a lot of code xD

@alpheratz0
Copy link

Thanks!!

@haojie1
Copy link

haojie1 commented Jun 11, 2023

Works great, but I think it would be better to have line 72 commented instead of line 71, since I thought everything was broken :-)

Agree!!!, Commenting line 72 makes a lot noise for me.

@idontcares31249
Copy link

Since SDL 2.0.4 you can use SDL_QueueAudio to not use callbacks

SDL_AudioSpec spec;
Uint8 *data;
Uint32 len;
SDL_LoadWAV("sound.wav", &spec, &data, &len);
SDL_OpenAudio(&spec, NULL);
SDL_QueueAudio(1, data, len);
SDL_PauseAudio(0);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment