diff options
author | Chris Robinson <[email protected]> | 2020-03-24 15:46:47 -0700 |
---|---|---|
committer | Chris Robinson <[email protected]> | 2020-03-24 15:46:47 -0700 |
commit | cae78e79e81afbc47a9a5802c4cfcc62dbc07f8e (patch) | |
tree | 521ff02314133b3508bb3701a4bd898b376e4834 /examples | |
parent | 586bc94d513125a63e61922ac0805a71c6ef1950 (diff) |
Convert the examples from SDL_sound to libsndfile
Diffstat (limited to 'examples')
-rw-r--r-- | examples/alhrtf.c | 95 | ||||
-rw-r--r-- | examples/allatency.c | 97 | ||||
-rw-r--r-- | examples/almultireverb.c | 96 | ||||
-rw-r--r-- | examples/alplay.c | 2 | ||||
-rw-r--r-- | examples/alreverb.c | 97 | ||||
-rw-r--r-- | examples/alstream.c | 133 | ||||
-rw-r--r-- | examples/alstreamcb.cpp | 145 |
7 files changed, 271 insertions, 394 deletions
diff --git a/examples/alhrtf.c b/examples/alhrtf.c index 2be28a91..bea87f56 100644 --- a/examples/alhrtf.c +++ b/examples/alhrtf.c @@ -25,13 +25,14 @@ /* This file contains an example for selecting an HRTF. */ #include <assert.h> +#include <inttypes.h> +#include <limits.h> #include <math.h> #include <stdio.h> +#include <stdlib.h> #include <string.h> -#include "SDL_sound.h" -#include "SDL_audio.h" -#include "SDL_stdinc.h" +#include "sndfile.h" #include "AL/al.h" #include "AL/alc.h" @@ -52,68 +53,62 @@ static LPALCRESETDEVICESOFT alcResetDeviceSOFT; */ static ALuint LoadSound(const char *filename) { - Sound_Sample *sample; ALenum err, format; ALuint buffer; - Uint32 slen; - - /* Open the audio file */ - sample = Sound_NewSampleFromFile(filename, NULL, 65536); - if(!sample) + SNDFILE *sndfile; + SF_INFO sfinfo; + short *membuf; + sf_count_t num_frames; + ALsizei num_bytes; + + /* Open the audio file and check that it's usable. */ + sndfile = sf_open(filename, SFM_READ, &sfinfo); + if(!sndfile) { - fprintf(stderr, "Could not open audio in %s\n", filename); + fprintf(stderr, "Could not open audio in %s: %s\n", filename, sf_strerror(sndfile)); return 0; } - - /* Get the sound format, and figure out the OpenAL format */ - if(sample->actual.channels == 1) - { - if(sample->actual.format == AUDIO_U8) - format = AL_FORMAT_MONO8; - else if(sample->actual.format == AUDIO_S16SYS) - format = AL_FORMAT_MONO16; - else - { - fprintf(stderr, "Unsupported sample format: 0x%04x\n", sample->actual.format); - Sound_FreeSample(sample); - return 0; - } - } - else if(sample->actual.channels == 2) + if(sfinfo.frames < 1 || sfinfo.frames > (sf_count_t)(INT_MAX/sizeof(short))/sfinfo.channels) { - if(sample->actual.format == AUDIO_U8) - format = AL_FORMAT_STEREO8; - else if(sample->actual.format == AUDIO_S16SYS) - format = AL_FORMAT_STEREO16; - else - { - fprintf(stderr, "Unsupported sample format: 0x%04x\n", sample->actual.format); - Sound_FreeSample(sample); - return 0; - } + fprintf(stderr, "Bad sample count in %s (%" PRId64 ")\n", filename, sfinfo.frames); + sf_close(sndfile); + return 0; } + + /* Get the sound format, and figure out the OpenAL format */ + if(sfinfo.channels == 1) + format = AL_FORMAT_MONO16; + else if(sfinfo.channels == 2) + format = AL_FORMAT_STEREO16; else { - fprintf(stderr, "Unsupported channel count: %d\n", sample->actual.channels); - Sound_FreeSample(sample); + fprintf(stderr, "Unsupported channel count: %d\n", sfinfo.channels); + sf_close(sndfile); return 0; } - /* Decode the whole audio stream to a buffer. */ - slen = Sound_DecodeAll(sample); - if(!sample->buffer || slen == 0) + /* Decode the whole audio file to a buffer. */ + membuf = malloc((size_t)(sfinfo.frames * sfinfo.channels) * sizeof(short)); + + num_frames = sf_readf_short(sndfile, membuf, sfinfo.frames); + if(num_frames < 1) { - fprintf(stderr, "Failed to read audio from %s\n", filename); - Sound_FreeSample(sample); + free(membuf); + sf_close(sndfile); + fprintf(stderr, "Failed to read samples in %s (%" PRId64 ")\n", filename, num_frames); return 0; } + num_bytes = (ALsizei)(num_frames * sfinfo.channels) * (ALsizei)sizeof(short); /* Buffer the audio data into a new buffer object, then free the data and - * close the file. */ + * close the file. + */ buffer = 0; alGenBuffers(1, &buffer); - alBufferData(buffer, format, sample->buffer, (ALsizei)slen, (ALsizei)sample->actual.rate); - Sound_FreeSample(sample); + alBufferData(buffer, format, membuf, num_bytes, sfinfo.samplerate); + + free(membuf); + sf_close(sndfile); /* Check if an error occured, and clean up if so. */ err = alGetError(); @@ -240,14 +235,10 @@ int main(int argc, char **argv) } fflush(stdout); - /* Initialize SDL_sound. */ - Sound_Init(); - /* Load the sound into a buffer. */ buffer = LoadSound(soundname); if(!buffer) { - Sound_Quit(); CloseAL(); return 1; } @@ -291,11 +282,9 @@ int main(int argc, char **argv) alGetSourcei(source, AL_SOURCE_STATE, &state); } while(alGetError() == AL_NO_ERROR && state == AL_PLAYING); - /* All done. Delete resources, and close down SDL_sound and OpenAL. */ + /* All done. Delete resources, and close down OpenAL. */ alDeleteSources(1, &source); alDeleteBuffers(1, &buffer); - - Sound_Quit(); CloseAL(); return 0; diff --git a/examples/allatency.c b/examples/allatency.c index a61fb820..7ece01eb 100644 --- a/examples/allatency.c +++ b/examples/allatency.c @@ -24,12 +24,13 @@ /* This file contains an example for checking the latency of a sound. */ -#include <stdio.h> #include <assert.h> +#include <inttypes.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> -#include "SDL_sound.h" -#include "SDL_audio.h" -#include "SDL_stdinc.h" +#include "sndfile.h" #include "AL/al.h" #include "AL/alext.h" @@ -55,68 +56,62 @@ static LPALGETSOURCEI64VSOFT alGetSourcei64vSOFT; */ static ALuint LoadSound(const char *filename) { - Sound_Sample *sample; ALenum err, format; ALuint buffer; - Uint32 slen; - - /* Open the audio file */ - sample = Sound_NewSampleFromFile(filename, NULL, 65536); - if(!sample) + SNDFILE *sndfile; + SF_INFO sfinfo; + short *membuf; + sf_count_t num_frames; + ALsizei num_bytes; + + /* Open the audio file and check that it's usable. */ + sndfile = sf_open(filename, SFM_READ, &sfinfo); + if(!sndfile) { - fprintf(stderr, "Could not open audio in %s\n", filename); + fprintf(stderr, "Could not open audio in %s: %s\n", filename, sf_strerror(sndfile)); return 0; } - - /* Get the sound format, and figure out the OpenAL format */ - if(sample->actual.channels == 1) - { - if(sample->actual.format == AUDIO_U8) - format = AL_FORMAT_MONO8; - else if(sample->actual.format == AUDIO_S16SYS) - format = AL_FORMAT_MONO16; - else - { - fprintf(stderr, "Unsupported sample format: 0x%04x\n", sample->actual.format); - Sound_FreeSample(sample); - return 0; - } - } - else if(sample->actual.channels == 2) + if(sfinfo.frames < 1 || sfinfo.frames > (sf_count_t)(INT_MAX/sizeof(short))/sfinfo.channels) { - if(sample->actual.format == AUDIO_U8) - format = AL_FORMAT_STEREO8; - else if(sample->actual.format == AUDIO_S16SYS) - format = AL_FORMAT_STEREO16; - else - { - fprintf(stderr, "Unsupported sample format: 0x%04x\n", sample->actual.format); - Sound_FreeSample(sample); - return 0; - } + fprintf(stderr, "Bad sample count in %s (%" PRId64 ")\n", filename, sfinfo.frames); + sf_close(sndfile); + return 0; } + + /* Get the sound format, and figure out the OpenAL format */ + if(sfinfo.channels == 1) + format = AL_FORMAT_MONO16; + else if(sfinfo.channels == 2) + format = AL_FORMAT_STEREO16; else { - fprintf(stderr, "Unsupported channel count: %d\n", sample->actual.channels); - Sound_FreeSample(sample); + fprintf(stderr, "Unsupported channel count: %d\n", sfinfo.channels); + sf_close(sndfile); return 0; } - /* Decode the whole audio stream to a buffer. */ - slen = Sound_DecodeAll(sample); - if(!sample->buffer || slen == 0) + /* Decode the whole audio file to a buffer. */ + membuf = malloc((size_t)(sfinfo.frames * sfinfo.channels) * sizeof(short)); + + num_frames = sf_readf_short(sndfile, membuf, sfinfo.frames); + if(num_frames < 1) { - fprintf(stderr, "Failed to read audio from %s\n", filename); - Sound_FreeSample(sample); + free(membuf); + sf_close(sndfile); + fprintf(stderr, "Failed to read samples in %s (%" PRId64 ")\n", filename, num_frames); return 0; } + num_bytes = (ALsizei)(num_frames * sfinfo.channels) * (ALsizei)sizeof(short); /* Buffer the audio data into a new buffer object, then free the data and - * close the file. */ + * close the file. + */ buffer = 0; alGenBuffers(1, &buffer); - alBufferData(buffer, format, sample->buffer, (ALsizei)slen, (ALsizei)sample->actual.rate); - Sound_FreeSample(sample); + alBufferData(buffer, format, membuf, num_bytes, sfinfo.samplerate); + + free(membuf); + sf_close(sndfile); /* Check if an error occured, and clean up if so. */ err = alGetError(); @@ -173,14 +168,10 @@ int main(int argc, char **argv) LOAD_PROC(LPALGETSOURCEI64VSOFT, alGetSourcei64vSOFT); #undef LOAD_PROC - /* Initialize SDL_sound. */ - Sound_Init(); - /* Load the sound into a buffer. */ buffer = LoadSound(argv[0]); if(!buffer) { - Sound_Quit(); CloseAL(); return 1; } @@ -206,11 +197,9 @@ int main(int argc, char **argv) } while(alGetError() == AL_NO_ERROR && state == AL_PLAYING); printf("\n"); - /* All done. Delete resources, and close down SDL_sound and OpenAL. */ + /* All done. Delete resources, and close down OpenAL. */ alDeleteSources(1, &source); alDeleteBuffers(1, &buffer); - - Sound_Quit(); CloseAL(); return 0; diff --git a/examples/almultireverb.c b/examples/almultireverb.c index a90b3368..eb874061 100644 --- a/examples/almultireverb.c +++ b/examples/almultireverb.c @@ -29,14 +29,16 @@ * listener. */ + #include <assert.h> +#include <inttypes.h> +#include <limits.h> #include <math.h> #include <stdio.h> +#include <stdlib.h> #include <string.h> -#include "SDL_sound.h" -#include "SDL_audio.h" -#include "SDL_stdinc.h" +#include "sndfile.h" #include "AL/al.h" #include "AL/alc.h" @@ -151,68 +153,62 @@ static int LoadEffect(ALuint effect, const EFXEAXREVERBPROPERTIES *reverb) */ static ALuint LoadSound(const char *filename) { - Sound_Sample *sample; ALenum err, format; ALuint buffer; - Uint32 slen; - - /* Open the audio file */ - sample = Sound_NewSampleFromFile(filename, NULL, 65536); - if(!sample) + SNDFILE *sndfile; + SF_INFO sfinfo; + short *membuf; + sf_count_t num_frames; + ALsizei num_bytes; + + /* Open the audio file and check that it's usable. */ + sndfile = sf_open(filename, SFM_READ, &sfinfo); + if(!sndfile) { - fprintf(stderr, "Could not open audio in %s\n", filename); + fprintf(stderr, "Could not open audio in %s: %s\n", filename, sf_strerror(sndfile)); return 0; } - - /* Get the sound format, and figure out the OpenAL format */ - if(sample->actual.channels == 1) - { - if(sample->actual.format == AUDIO_U8) - format = AL_FORMAT_MONO8; - else if(sample->actual.format == AUDIO_S16SYS) - format = AL_FORMAT_MONO16; - else - { - fprintf(stderr, "Unsupported sample format: 0x%04x\n", sample->actual.format); - Sound_FreeSample(sample); - return 0; - } - } - else if(sample->actual.channels == 2) + if(sfinfo.frames < 1 || sfinfo.frames > (sf_count_t)(INT_MAX/sizeof(short))/sfinfo.channels) { - if(sample->actual.format == AUDIO_U8) - format = AL_FORMAT_STEREO8; - else if(sample->actual.format == AUDIO_S16SYS) - format = AL_FORMAT_STEREO16; - else - { - fprintf(stderr, "Unsupported sample format: 0x%04x\n", sample->actual.format); - Sound_FreeSample(sample); - return 0; - } + fprintf(stderr, "Bad sample count in %s (%" PRId64 ")\n", filename, sfinfo.frames); + sf_close(sndfile); + return 0; } + + /* Get the sound format, and figure out the OpenAL format */ + if(sfinfo.channels == 1) + format = AL_FORMAT_MONO16; + else if(sfinfo.channels == 2) + format = AL_FORMAT_STEREO16; else { - fprintf(stderr, "Unsupported channel count: %d\n", sample->actual.channels); - Sound_FreeSample(sample); + fprintf(stderr, "Unsupported channel count: %d\n", sfinfo.channels); + sf_close(sndfile); return 0; } - /* Decode the whole audio stream to a buffer. */ - slen = Sound_DecodeAll(sample); - if(!sample->buffer || slen == 0) + /* Decode the whole audio file to a buffer. */ + membuf = malloc((size_t)(sfinfo.frames * sfinfo.channels) * sizeof(short)); + + num_frames = sf_readf_short(sndfile, membuf, sfinfo.frames); + if(num_frames < 1) { - fprintf(stderr, "Failed to read audio from %s\n", filename); - Sound_FreeSample(sample); + free(membuf); + sf_close(sndfile); + fprintf(stderr, "Failed to read samples in %s (%" PRId64 ")\n", filename, num_frames); return 0; } + num_bytes = (ALsizei)(num_frames * sfinfo.channels) * (ALsizei)sizeof(short); /* Buffer the audio data into a new buffer object, then free the data and - * close the file. */ + * close the file. + */ buffer = 0; alGenBuffers(1, &buffer); - alBufferData(buffer, format, sample->buffer, (ALsizei)slen, (ALsizei)sample->actual.rate); - Sound_FreeSample(sample); + alBufferData(buffer, format, membuf, num_bytes, sfinfo.samplerate); + + free(membuf); + sf_close(sndfile); /* Check if an error occured, and clean up if so. */ err = alGetError(); @@ -561,15 +557,11 @@ int main(int argc, char **argv) LOAD_PROC(LPALGETAUXILIARYEFFECTSLOTFV, alGetAuxiliaryEffectSlotfv); #undef LOAD_PROC - /* Initialize SDL_sound. */ - Sound_Init(); - /* Load the sound into a buffer. */ buffer = LoadSound(argv[0]); if(!buffer) { CloseAL(); - Sound_Quit(); return 1; } @@ -585,7 +577,6 @@ int main(int argc, char **argv) { alDeleteEffects(2, effects); alDeleteBuffers(1, &buffer); - Sound_Quit(); CloseAL(); return 1; } @@ -684,14 +675,13 @@ int main(int argc, char **argv) alGetSourcei(source, AL_SOURCE_STATE, &state); } while(alGetError() == AL_NO_ERROR && state == AL_PLAYING && loops < MaxTransitions); - /* All done. Delete resources, and close down SDL_sound and OpenAL. */ + /* All done. Delete resources, and close down OpenAL. */ alDeleteSources(1, &source); alDeleteAuxiliaryEffectSlots(2, slots); alDeleteEffects(2, effects); alDeleteFilters(1, &direct_filter); alDeleteBuffers(1, &buffer); - Sound_Quit(); CloseAL(); return 0; diff --git a/examples/alplay.c b/examples/alplay.c index af1c313c..70314d47 100644 --- a/examples/alplay.c +++ b/examples/alplay.c @@ -158,7 +158,7 @@ int main(int argc, char **argv) } while(alGetError() == AL_NO_ERROR && state == AL_PLAYING); printf("\n"); - /* All done. Delete resources, and close down SDL_sound and OpenAL. */ + /* All done. Delete resources, and close down OpenAL. */ alDeleteSources(1, &source); alDeleteBuffers(1, &buffer); diff --git a/examples/alreverb.c b/examples/alreverb.c index d789dffe..1f30a450 100644 --- a/examples/alreverb.c +++ b/examples/alreverb.c @@ -24,12 +24,13 @@ /* This file contains an example for applying reverb to a sound. */ -#include <stdio.h> #include <assert.h> +#include <inttypes.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> -#include "SDL_sound.h" -#include "SDL_audio.h" -#include "SDL_stdinc.h" +#include "sndfile.h" #include "AL/al.h" #include "AL/alc.h" @@ -149,68 +150,62 @@ static ALuint LoadEffect(const EFXEAXREVERBPROPERTIES *reverb) */ static ALuint LoadSound(const char *filename) { - Sound_Sample *sample; ALenum err, format; ALuint buffer; - Uint32 slen; - - /* Open the audio file */ - sample = Sound_NewSampleFromFile(filename, NULL, 65536); - if(!sample) + SNDFILE *sndfile; + SF_INFO sfinfo; + short *membuf; + sf_count_t num_frames; + ALsizei num_bytes; + + /* Open the audio file and check that it's usable. */ + sndfile = sf_open(filename, SFM_READ, &sfinfo); + if(!sndfile) { - fprintf(stderr, "Could not open audio in %s\n", filename); + fprintf(stderr, "Could not open audio in %s: %s\n", filename, sf_strerror(sndfile)); return 0; } - - /* Get the sound format, and figure out the OpenAL format */ - if(sample->actual.channels == 1) - { - if(sample->actual.format == AUDIO_U8) - format = AL_FORMAT_MONO8; - else if(sample->actual.format == AUDIO_S16SYS) - format = AL_FORMAT_MONO16; - else - { - fprintf(stderr, "Unsupported sample format: 0x%04x\n", sample->actual.format); - Sound_FreeSample(sample); - return 0; - } - } - else if(sample->actual.channels == 2) + if(sfinfo.frames < 1 || sfinfo.frames > (sf_count_t)(INT_MAX/sizeof(short))/sfinfo.channels) { - if(sample->actual.format == AUDIO_U8) - format = AL_FORMAT_STEREO8; - else if(sample->actual.format == AUDIO_S16SYS) - format = AL_FORMAT_STEREO16; - else - { - fprintf(stderr, "Unsupported sample format: 0x%04x\n", sample->actual.format); - Sound_FreeSample(sample); - return 0; - } + fprintf(stderr, "Bad sample count in %s (%" PRId64 ")\n", filename, sfinfo.frames); + sf_close(sndfile); + return 0; } + + /* Get the sound format, and figure out the OpenAL format */ + if(sfinfo.channels == 1) + format = AL_FORMAT_MONO16; + else if(sfinfo.channels == 2) + format = AL_FORMAT_STEREO16; else { - fprintf(stderr, "Unsupported channel count: %d\n", sample->actual.channels); - Sound_FreeSample(sample); + fprintf(stderr, "Unsupported channel count: %d\n", sfinfo.channels); + sf_close(sndfile); return 0; } - /* Decode the whole audio stream to a buffer. */ - slen = Sound_DecodeAll(sample); - if(!sample->buffer || slen == 0) + /* Decode the whole audio file to a buffer. */ + membuf = malloc((size_t)(sfinfo.frames * sfinfo.channels) * sizeof(short)); + + num_frames = sf_readf_short(sndfile, membuf, sfinfo.frames); + if(num_frames < 1) { - fprintf(stderr, "Failed to read audio from %s\n", filename); - Sound_FreeSample(sample); + free(membuf); + sf_close(sndfile); + fprintf(stderr, "Failed to read samples in %s (%" PRId64 ")\n", filename, num_frames); return 0; } + num_bytes = (ALsizei)(num_frames * sfinfo.channels) * (ALsizei)sizeof(short); /* Buffer the audio data into a new buffer object, then free the data and - * close the file. */ + * close the file. + */ buffer = 0; alGenBuffers(1, &buffer); - alBufferData(buffer, format, sample->buffer, (ALsizei)slen, (ALsizei)sample->actual.rate); - Sound_FreeSample(sample); + alBufferData(buffer, format, membuf, num_bytes, sfinfo.samplerate); + + free(membuf); + sf_close(sndfile); /* Check if an error occured, and clean up if so. */ err = alGetError(); @@ -278,15 +273,11 @@ int main(int argc, char **argv) LOAD_PROC(LPALGETAUXILIARYEFFECTSLOTFV, alGetAuxiliaryEffectSlotfv); #undef LOAD_PROC - /* Initialize SDL_sound. */ - Sound_Init(); - /* Load the sound into a buffer. */ buffer = LoadSound(argv[0]); if(!buffer) { CloseAL(); - Sound_Quit(); return 1; } @@ -295,7 +286,6 @@ int main(int argc, char **argv) if(!effect) { alDeleteBuffers(1, &buffer); - Sound_Quit(); CloseAL(); return 1; } @@ -330,13 +320,12 @@ int main(int argc, char **argv) alGetSourcei(source, AL_SOURCE_STATE, &state); } while(alGetError() == AL_NO_ERROR && state == AL_PLAYING); - /* All done. Delete resources, and close down SDL_sound and OpenAL. */ + /* All done. Delete resources, and close down OpenAL. */ alDeleteSources(1, &source); alDeleteAuxiliaryEffectSlots(1, &slot); alDeleteEffects(1, &effect); alDeleteBuffers(1, &buffer); - Sound_Quit(); CloseAL(); return 0; diff --git a/examples/alstream.c b/examples/alstream.c index 56505ddb..69be236a 100644 --- a/examples/alstream.c +++ b/examples/alstream.c @@ -24,32 +24,24 @@ /* This file contains a relatively simple streaming audio player. */ -#include <string.h> -#include <stdlib.h> -#include <stdio.h> #include <assert.h> +#include <inttypes.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> -#include "SDL_sound.h" -#include "SDL_audio.h" -#include "SDL_stdinc.h" +#include "sndfile.h" #include "AL/al.h" #include "common/alhelpers.h" -#ifndef SDL_AUDIO_MASK_BITSIZE -#define SDL_AUDIO_MASK_BITSIZE (0xFF) -#endif -#ifndef SDL_AUDIO_BITSIZE -#define SDL_AUDIO_BITSIZE(x) (x & SDL_AUDIO_MASK_BITSIZE) -#endif - /* Define the number of buffers and buffer size (in milliseconds) to use. 4 - * buffers with 200ms each gives a nice per-chunk size, and lets the queue last - * for almost one second. */ + * buffers with 8192 samples each gives a nice per-chunk size, and lets the + * queue last for almost one second at 44.1khz. */ #define NUM_BUFFERS 4 -#define BUFFER_TIME_MS 200 +#define BUFFER_SAMPLES 8192 typedef struct StreamPlayer { /* These are the buffers and source to play out through OpenAL with */ @@ -57,11 +49,12 @@ typedef struct StreamPlayer { ALuint source; /* Handle for the audio file */ - Sound_Sample *sample; + SNDFILE *sndfile; + SF_INFO sfinfo; + short *membuf; - /* The format of the output stream */ + /* The format of the output stream (sample rate is in sfinfo) */ ALenum format; - ALsizei srate; } StreamPlayer; static StreamPlayer *NewPlayer(void); @@ -118,73 +111,46 @@ static void DeletePlayer(StreamPlayer *player) * it will be closed first. */ static int OpenPlayerFile(StreamPlayer *player, const char *filename) { - Uint32 frame_size; + size_t frame_size; ClosePlayerFile(player); - /* Open the file and get the first stream from it */ - player->sample = Sound_NewSampleFromFile(filename, NULL, 0); - if(!player->sample) + /* Open the audio file and check that it's usable. */ + player->sndfile = sf_open(filename, SFM_READ, &player->sfinfo); + if(!player->sndfile) { - fprintf(stderr, "Could not open audio in %s\n", filename); - goto error; + fprintf(stderr, "Could not open audio in %s: %s\n", filename, sf_strerror(NULL)); + return 0; } - /* Get the stream format, and figure out the OpenAL format */ - if(player->sample->actual.channels == 1) - { - if(player->sample->actual.format == AUDIO_U8) - player->format = AL_FORMAT_MONO8; - else if(player->sample->actual.format == AUDIO_S16SYS) - player->format = AL_FORMAT_MONO16; - else - { - fprintf(stderr, "Unsupported sample format: 0x%04x\n", player->sample->actual.format); - goto error; - } - } - else if(player->sample->actual.channels == 2) - { - if(player->sample->actual.format == AUDIO_U8) - player->format = AL_FORMAT_STEREO8; - else if(player->sample->actual.format == AUDIO_S16SYS) - player->format = AL_FORMAT_STEREO16; - else - { - fprintf(stderr, "Unsupported sample format: 0x%04x\n", player->sample->actual.format); - goto error; - } - } + /* Get the sound format, and figure out the OpenAL format */ + if(player->sfinfo.channels == 1) + player->format = AL_FORMAT_MONO16; + else if(player->sfinfo.channels == 2) + player->format = AL_FORMAT_STEREO16; else { - fprintf(stderr, "Unsupported channel count: %d\n", player->sample->actual.channels); - goto error; + fprintf(stderr, "Unsupported channel count: %d\n", player->sfinfo.channels); + sf_close(player->sndfile); + player->sndfile = NULL; + return 0; } - player->srate = (ALsizei)player->sample->actual.rate; - - frame_size = player->sample->actual.channels * - SDL_AUDIO_BITSIZE(player->sample->actual.format) / 8; - /* Set the buffer size, given the desired millisecond length. */ - Sound_SetBufferSize(player->sample, (Uint32)((Uint64)player->srate*BUFFER_TIME_MS/1000) * - frame_size); + frame_size = (size_t)(BUFFER_SAMPLES * player->sfinfo.channels) * sizeof(short); + player->membuf = malloc(frame_size); return 1; - -error: - if(player->sample) - Sound_FreeSample(player->sample); - player->sample = NULL; - - return 0; } /* Closes the audio file stream */ static void ClosePlayerFile(StreamPlayer *player) { - if(player->sample) - Sound_FreeSample(player->sample); - player->sample = NULL; + if(player->sndfile) + sf_close(player->sndfile); + player->sndfile = NULL; + + free(player->membuf); + player->membuf = NULL; } @@ -201,11 +167,12 @@ static int StartPlayer(StreamPlayer *player) for(i = 0;i < NUM_BUFFERS;i++) { /* Get some data to give it to the buffer */ - Uint32 slen = Sound_Decode(player->sample); - if(slen == 0) break; + sf_count_t slen = sf_readf_short(player->sndfile, player->membuf, BUFFER_SAMPLES); + if(slen < 1) break; - alBufferData(player->buffers[i], player->format, player->sample->buffer, (ALsizei)slen, - player->srate); + slen *= player->sfinfo.channels * (sf_count_t)sizeof(short); + alBufferData(player->buffers[i], player->format, player->membuf, (ALsizei)slen, + player->sfinfo.samplerate); } if(alGetError() != AL_NO_ERROR) { @@ -242,21 +209,19 @@ static int UpdatePlayer(StreamPlayer *player) while(processed > 0) { ALuint bufid; - Uint32 slen; + sf_count_t slen; alSourceUnqueueBuffers(player->source, 1, &bufid); processed--; - if((player->sample->flags&(SOUND_SAMPLEFLAG_EOF|SOUND_SAMPLEFLAG_ERROR))) - continue; - /* Read the next chunk of data, refill the buffer, and queue it * back on the source */ - slen = Sound_Decode(player->sample); + slen = sf_readf_short(player->sndfile, player->membuf, BUFFER_SAMPLES); if(slen > 0) { - alBufferData(bufid, player->format, player->sample->buffer, (ALsizei)slen, - player->srate); + slen *= player->sfinfo.channels * (sf_count_t)sizeof(short); + alBufferData(bufid, player->format, player->membuf, (ALsizei)slen, + player->sfinfo.samplerate); alSourceQueueBuffers(player->source, 1, &bufid); } if(alGetError() != AL_NO_ERROR) @@ -304,8 +269,6 @@ int main(int argc, char **argv) if(InitAL(&argv, &argc) != 0) return 1; - Sound_Init(); - player = NewPlayer(); /* Play each file listed on the command line */ @@ -323,7 +286,8 @@ int main(int argc, char **argv) else namepart = argv[i]; - printf("Playing: %s (%s, %dhz)\n", namepart, FormatName(player->format), player->srate); + printf("Playing: %s (%s, %dhz)\n", namepart, FormatName(player->format), + player->sfinfo.samplerate); fflush(stdout); if(!StartPlayer(player)) @@ -340,11 +304,10 @@ int main(int argc, char **argv) } printf("Done.\n"); - /* All files done. Delete the player, and close down SDL_sound and OpenAL */ + /* All files done. Delete the player, and close down OpenAL */ DeletePlayer(player); player = NULL; - Sound_Quit(); CloseAL(); return 0; diff --git a/examples/alstreamcb.cpp b/examples/alstreamcb.cpp index fbc3d02d..8fb1f102 100644 --- a/examples/alstreamcb.cpp +++ b/examples/alstreamcb.cpp @@ -36,9 +36,7 @@ #include <thread> #include <vector> -#include "SDL_sound.h" -#include "SDL_audio.h" -#include "SDL_stdinc.h" +#include "sndfile.h" #include "AL/al.h" #include "AL/alc.h" @@ -46,14 +44,6 @@ #include "common/alhelpers.h" -#ifndef SDL_AUDIO_MASK_BITSIZE -#define SDL_AUDIO_MASK_BITSIZE (0xFF) -#endif -#ifndef SDL_AUDIO_BITSIZE -#define SDL_AUDIO_BITSIZE(x) (x & SDL_AUDIO_MASK_BITSIZE) -#endif - - #ifndef AL_SOFT_callback_buffer #define AL_SOFT_callback_buffer typedef unsigned int ALbitfieldSOFT; @@ -87,13 +77,12 @@ struct StreamPlayer { size_t mStartOffset{0}; /* Handle for the audio file to decode. */ - Sound_Sample *mSample{nullptr}; - Uint32 mAvailableData{0}; + SNDFILE *mSndfile{nullptr}; + SF_INFO mSfInfo{}; size_t mDecoderOffset{0}; /* The format of the callback samples. */ ALenum mFormat; - ALsizei mSampleRate; StreamPlayer() { @@ -111,18 +100,18 @@ struct StreamPlayer { { alDeleteSources(1, &mSource); alDeleteBuffers(1, &mBuffer); - if(mSample) - Sound_FreeSample(mSample); + if(mSndfile) + sf_close(mSndfile); } void close() { - if(mSample) + if(mSndfile) { alSourceRewind(mSource); alSourcei(mSource, AL_BUFFER, 0); - Sound_FreeSample(mSample); - mSample = nullptr; + sf_close(mSndfile); + mSndfile = nullptr; } } @@ -130,50 +119,30 @@ struct StreamPlayer { { close(); - /* Open the file in its normal format. */ - mSample = Sound_NewSampleFromFile(filename, nullptr, 0); - if(!mSample) + /* Open the file and figure out the OpenAL format. */ + mSndfile = sf_open(filename, SFM_READ, &mSfInfo); + if(!mSndfile) { - fprintf(stderr, "Could not open audio in %s\n", filename); + fprintf(stderr, "Could not open audio in %s: %s\n", filename, sf_strerror(mSndfile)); return false; } - /* Figure out the OpenAL format from the sample's format. */ mFormat = AL_NONE; - if(mSample->actual.channels == 1) - { - if(mSample->actual.format == AUDIO_U8) - mFormat = AL_FORMAT_MONO8; - else if(mSample->actual.format == AUDIO_S16SYS) - mFormat = AL_FORMAT_MONO16; - } - else if(mSample->actual.channels == 2) - { - if(mSample->actual.format == AUDIO_U8) - mFormat = AL_FORMAT_STEREO8; - else if(mSample->actual.format == AUDIO_S16SYS) - mFormat = AL_FORMAT_STEREO16; - } - if(!mFormat) + if(mSfInfo.channels == 1) + mFormat = AL_FORMAT_MONO16; + else if(mSfInfo.channels == 2) + mFormat = AL_FORMAT_STEREO16; + else { - fprintf(stderr, "Unsupported sample format: 0x%04x, %d channels\n", - mSample->actual.format, mSample->actual.channels); - Sound_FreeSample(mSample); - mSample = nullptr; + fprintf(stderr, "Unsupported channel count: %d\n", mSfInfo.channels); + sf_close(mSndfile); + mSndfile = nullptr; return false; } - mSampleRate = static_cast<ALsizei>(mSample->actual.rate); - - const auto frame_size = Uint32{mSample->actual.channels} * - SDL_AUDIO_BITSIZE(mSample->actual.format) / 8; - - /* Set a 50ms decode buffer size. */ - Sound_SetBufferSize(mSample, static_cast<Uint32>(mSampleRate)*50/1000 * frame_size); - mAvailableData = 0; /* Set a 1s ring buffer size. */ - mBufferDataSize = static_cast<Uint32>(mSampleRate) * size_t{frame_size}; + mBufferDataSize = static_cast<ALuint>(mSfInfo.samplerate*mSfInfo.channels) * sizeof(short); mBufferData.reset(new ALbyte[mBufferDataSize]); mReadPos.store(0, std::memory_order_relaxed); mWritePos.store(0, std::memory_order_relaxed); @@ -239,34 +208,27 @@ struct StreamPlayer { bool prepare() { - alBufferCallbackSOFT(mBuffer, mFormat, mSampleRate, bufferCallbackC, this, 0); + alBufferCallbackSOFT(mBuffer, mFormat, mSfInfo.samplerate, bufferCallbackC, this, 0); alSourcei(mSource, AL_BUFFER, static_cast<ALint>(mBuffer)); if(ALenum err{alGetError()}) { fprintf(stderr, "Failed to set callback: %s (0x%04x)\n", alGetString(err), err); return false; } - - mAvailableData = Sound_Decode(mSample); - if(!mAvailableData) - fprintf(stderr, "Failed to decode any samples: %s\n", Sound_GetError()); - return mAvailableData != 0; + return true; } bool update() { - constexpr int BadFlags{SOUND_SAMPLEFLAG_EOF | SOUND_SAMPLEFLAG_ERROR}; - ALenum state; ALint pos; alGetSourcei(mSource, AL_SAMPLE_OFFSET, &pos); alGetSourcei(mSource, AL_SOURCE_STATE, &state); + const size_t frame_size{static_cast<ALuint>(mSfInfo.channels) * sizeof(short)}; size_t woffset{mWritePos.load(std::memory_order_acquire)}; if(state != AL_INITIAL) { - const auto frame_size = Uint32{mSample->actual.channels} * - SDL_AUDIO_BITSIZE(mSample->actual.format) / 8; const size_t roffset{mReadPos.load(std::memory_order_relaxed)}; const size_t readable{((woffset >= roffset) ? woffset : (mBufferDataSize+woffset)) - roffset}; @@ -276,15 +238,17 @@ struct StreamPlayer { * the playback offset the source was started with. */ const size_t curtime{((state==AL_STOPPED) ? (mDecoderOffset-readable) / frame_size - : (static_cast<ALuint>(pos) + mStartOffset/frame_size)) / mSample->actual.rate}; + : (static_cast<ALuint>(pos) + mStartOffset/frame_size)) + / static_cast<ALuint>(mSfInfo.samplerate)}; printf("\r%3zus (%3zu%% full)", curtime, readable * 100 / mBufferDataSize); } else fputs("Starting...", stdout); fflush(stdout); - while(mAvailableData > 0) + while(!sf_error(mSndfile)) { + size_t read_bytes; const size_t roffset{mReadPos.load(std::memory_order_relaxed)}; if(roffset > woffset) { @@ -294,45 +258,39 @@ struct StreamPlayer { * instead of full. */ const size_t writable{roffset-woffset-1}; - /* Don't copy the sample data if it can't all fit. */ - if(writable < mAvailableData) break; + if(writable < frame_size) break; + + sf_count_t num_frames{sf_readf_short(mSndfile, + reinterpret_cast<short*>(&mBufferData[woffset]), + static_cast<sf_count_t>(writable/frame_size))}; + if(num_frames < 1) break; - memcpy(&mBufferData[woffset], mSample->buffer, mAvailableData); - woffset += mAvailableData; + read_bytes = static_cast<size_t>(num_frames) * frame_size; + woffset += read_bytes; } else { /* If the read offset is at or behind the write offset, the * writeable area (might) wrap around. Make sure the sample - * data can fit, and calculate how much goes in front and in - * back. + * data can fit, and calculate how much can go in front before + * wrapping. */ - const size_t writable{mBufferDataSize+roffset-woffset-1}; - if(writable < mAvailableData) break; + const size_t writable{!roffset ? mBufferDataSize-woffset-1 : + (mBufferDataSize-woffset)}; + if(writable < frame_size) break; - const size_t todo1{std::min<size_t>(mAvailableData, mBufferDataSize-woffset)}; - const size_t todo2{mAvailableData - todo1}; + sf_count_t num_frames{sf_readf_short(mSndfile, + reinterpret_cast<short*>(&mBufferData[woffset]), + static_cast<sf_count_t>(writable/frame_size))}; + if(num_frames < 1) break; - memcpy(&mBufferData[woffset], mSample->buffer, todo1); - woffset += todo1; + read_bytes = static_cast<size_t>(num_frames) * frame_size; + woffset += read_bytes; if(woffset == mBufferDataSize) - { woffset = 0; - if(todo2 > 0) - { - memcpy(&mBufferData[woffset], static_cast<ALbyte*>(mSample->buffer)+todo1, - todo2); - woffset += todo2; - } - } } mWritePos.store(woffset, std::memory_order_release); - mDecoderOffset += mAvailableData; - - if(!(mSample->flags&BadFlags)) - mAvailableData = Sound_Decode(mSample); - else - mAvailableData = 0; + mDecoderOffset += read_bytes; } if(state != AL_PLAYING && state != AL_PAUSED) @@ -364,15 +322,14 @@ struct StreamPlayer { int main(int argc, char **argv) { - /* A simple RAII container for OpenAL and SDL_sound startup and shutdown. */ + /* A simple RAII container for OpenAL startup and shutdown. */ struct AudioManager { AudioManager(char ***argv_, int *argc_) { if(InitAL(argv_, argc_) != 0) throw std::runtime_error{"Failed to initialize OpenAL"}; - Sound_Init(); } - ~AudioManager() { Sound_Quit(); CloseAL(); } + ~AudioManager() { CloseAL(); } }; /* Print out usage if no arguments were specified */ @@ -413,7 +370,7 @@ int main(int argc, char **argv) namepart = argv[i]; printf("Playing: %s (%s, %dhz)\n", namepart, FormatName(player->mFormat), - player->mSampleRate); + player->mSfInfo.samplerate); fflush(stdout); if(!player->prepare()) |