Skip to content

Commit

Permalink
This fixes #2, added SDL_AUDIO_ALLOW_CHANGES config flag and added pa…
Browse files Browse the repository at this point in the history
…use and unpause functions
  • Loading branch information
jakebesworth committed Apr 23, 2017
1 parent 03cec49 commit ac3ae61
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 15 deletions.
27 changes: 24 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,22 @@
## How to use

* Include audio.c and audio.h into your project
* test.c shows how to simply load wave files as music or sound
* test.c shows how to simply load wave files as music or sound, and a simple pause and unpause function

## API Functions:

```c
void initAudio(void);
void endAudio(void);
void playSound(const char * filename, int volume);
void playMusic(const char * filename, int volume);
void pauseAudio(void);
void unpauseAudio(void);
```
## Music vs Sound
* Only one music can play at a time, and it loops (to close music you can just run endAudio() lazily, or write your own pause function which is not difficult).
* Only one music can play at a time, and it loops (to close music you can just run `endAudio()`, or use `pauseAudio()` and `unpauseAudio()`).
* If you add another music when one is playing, the first one fades out before ending, and then playing the second.
* If you play more than 2 music at once, the first fades as expected, only the last music queued before the first fade out is used
Expand All @@ -22,7 +33,16 @@
* This implementation uses SDL_MixAudioFormat for mixing for simplicity. It's noted "Do not use this function for mixing together more than two streams of sample data". While only playing 1 music removes a lot of these issues, if you need something more powerful you should write your own mixing function.
* Multiple Music cannot be mixed together, only music and sound
* This implementation ONLY plays WAV files, and they must all be of the same format, see the top of audio.c to set the format, stereo vs mono etc... No conversion
* This implementation ONLY plays WAV files, and they should all be the same format, but can have differing formats if you play around with `SDL_AUDIO_ALLOW_CHANGES` in `audio.c`, see the top of audio.c to set the format, stereo vs mono etc... No conversion
## Features to add
- Pause / unpause only music, only sound or ~~both~~
- Current implementation uses callback method, however in SDL 2.0.4 there exists `SDL_QueueAudio()` (no callback)
## Emscripten Compatibility
* [Github Issue - Solution](https://github.com/jakebesworth/Simple-SDL2-Audio/issues/2)
## Resources
Expand All @@ -34,3 +54,4 @@
* [Jake Besworth](https://github.com/jakebesworth)
* [Lorenzo Mancini](https://github.com/lmancini)
* [Ted](https://github.com/claimred)
52 changes: 40 additions & 12 deletions src/audio.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,18 @@
/* Specifies a unit of audio data to be used at a time. Must be a power of 2 */
#define AUDIO_SAMPLES 4096

/* Flags OR'd together, which specify how SDL should behave when a device cannot offer a specific feature
* If flag is set, SDL will change the format in the actual audio file structure (as opposed to gDevice->want)
*
* Note: If you're having issues with Emscripten / EMCC play around with these flags
*
* 0 Allow no changes
* SDL_AUDIO_ALLOW_FREQUENCY_CHANGE Allow frequency changes (e.g. AUDIO_FREQUENCY is 48k, but allow files to play at 44.1k
* SDL_AUDIO_ALLOW_FORMAT_CHANGE Allow Format change (e.g. AUDIO_FORMAT may be S32LSB, but allow wave files of S16LSB to play)
* SDL_AUDIO_ALLOW_CHANNELS_CHANGE Allow any number of channels (e.g. AUDIO_CHANNELS being 2, allow actual 1)
* SDL_AUDIO_ALLOW_ANY_CHANGE Allow all changes above
*/
#define SDL_AUDIO_ALLOW_CHANGES SDL_AUDIO_ALLOW_ANY_CHANGE
/*
* Queue structure for all loaded sounds
*
Expand Down Expand Up @@ -184,20 +196,17 @@ void initAudio(void)
Sound * global;
gDevice = calloc(1, sizeof(PrivateAudioDevice));

if(!(SDL_WasInit(SDL_INIT_AUDIO) & SDL_INIT_AUDIO))
if(gDevice == NULL)
{
fprintf(stderr, "[%s: %d]Error: SDL_INIT_AUDIO not initialized\n", __FILE__, __LINE__);
gDevice->audioEnabled = 0;
fprintf(stderr, "[%s: %d]Fatal Error: Memory c-allocation error\n", __FILE__, __LINE__);
return;
}
else
{
gDevice->audioEnabled = 1;
}

if(gDevice == NULL)
gDevice->audioEnabled = 0;

if(!(SDL_WasInit(SDL_INIT_AUDIO) & SDL_INIT_AUDIO))
{
fprintf(stderr, "[%s: %d]Fatal Error: Memory c-allocation error\n", __FILE__, __LINE__);
fprintf(stderr, "[%s: %d]Error: SDL_INIT_AUDIO not initialized\n", __FILE__, __LINE__);
return;
}

Expand All @@ -222,22 +231,25 @@ void initAudio(void)
global->next = NULL;

/* want.userdata = new; */
if((gDevice->device = SDL_OpenAudioDevice(NULL, 0, &(gDevice->want), NULL, SDL_AUDIO_ALLOW_ANY_CHANGE)) == 0)
if((gDevice->device = SDL_OpenAudioDevice(NULL, 0, &(gDevice->want), NULL, SDL_AUDIO_ALLOW_CHANGES)) == 0)
{
fprintf(stderr, "[%s: %d]Warning: failed to open audio device: %s\n", __FILE__, __LINE__, SDL_GetError());
}
else
{
/* Set audio device enabled global flag */
gDevice->audioEnabled = 1;

/* Unpause active audio stream */
SDL_PauseAudioDevice(gDevice->device, 0);
unpauseAudio();
}
}

void endAudio(void)
{
if(gDevice->audioEnabled)
{
SDL_PauseAudioDevice(gDevice->device, 1);
pauseAudio();

freeSound((Sound *) (gDevice->want).userdata);

Expand All @@ -248,6 +260,22 @@ void endAudio(void)
free(gDevice);
}

void pauseAudio(void)
{
if(gDevice->audioEnabled)
{
SDL_PauseAudioDevice(gDevice->device, 1);
}
}

void unpauseAudio(void)
{
if(gDevice->audioEnabled)
{
SDL_PauseAudioDevice(gDevice->device, 0);
}
}

static Sound * createSound(const char * filename, uint8_t loop, int volume)
{
Sound * new = calloc(1, sizeof(Sound));
Expand Down
13 changes: 13 additions & 0 deletions src/audio.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ void playMusic(const char * filename, int volume);

/*
* Free all audio related variables
* Note, this needs to be run even if initAudio fails, because it frees the global audio device
*
*/
void endAudio(void);
Expand All @@ -61,6 +62,18 @@ void endAudio(void);
*/
void initAudio(void);

/*
* Pause audio from playing
*
*/
void pauseAudio(void);

/*
* Unpause audio from playing
*
*/
void unpauseAudio(void);

#ifdef __cplusplus
}
#endif
Expand Down
4 changes: 4 additions & 0 deletions src/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ int main(void)
playMusic("music/road.wav", SDL_MIX_MAXVOLUME);
SDL_Delay(2000);

pauseAudio();
SDL_Delay(2000);
unpauseAudio();

playSound("sounds/door2.wav", SDL_MIX_MAXVOLUME / 2);
SDL_Delay(7000);

Expand Down

0 comments on commit ac3ae61

Please sign in to comment.