Use libsndfile for the alplay example

This commit is contained in:
Chris Robinson 2020-03-24 13:36:49 -07:00
parent c24d127229
commit 586bc94d51
3 changed files with 81 additions and 58 deletions

@ -1137,6 +1137,7 @@ IF(ALSOFT_EXAMPLES)
ENDIF()
IF(SDL2_FOUND)
FIND_PACKAGE(SDL_sound)
FIND_PACKAGE(SndFile)
FIND_PACKAGE(FFmpeg COMPONENTS AVFORMAT AVCODEC AVUTIL SWSCALE SWRESAMPLE)
ENDIF()
ENDIF()
@ -1478,14 +1479,23 @@ IF(ALSOFT_EXAMPLES)
MESSAGE(STATUS "Building example programs")
IF(SNDFILE_FOUND)
ADD_EXECUTABLE(alplay examples/alplay.c)
TARGET_INCLUDE_DIRECTORIES(alplay PRIVATE ${SNDFILE_INCLUDE_DIRS})
TARGET_LINK_LIBRARIES(alplay PRIVATE ${LINKER_FLAGS} ${SNDFILE_LIBRARIES} ex-common)
IF(ALSOFT_INSTALL)
INSTALL(TARGETS alplay
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
ENDIF()
MESSAGE(STATUS "Building SndFile example programs")
ENDIF()
IF(SDL2_FOUND)
IF(SDL_SOUND_FOUND)
ADD_EXECUTABLE(alplay examples/alplay.c)
TARGET_INCLUDE_DIRECTORIES(alplay
PRIVATE ${SDL2_INCLUDE_DIR} ${SDL_SOUND_INCLUDE_DIR})
TARGET_LINK_LIBRARIES(alplay
PRIVATE ${LINKER_FLAGS} ${SDL_SOUND_LIBRARIES} ${SDL2_LIBRARY} ex-common)
ADD_EXECUTABLE(alstream examples/alstream.c)
TARGET_INCLUDE_DIRECTORIES(alstream
PRIVATE ${SDL2_INCLUDE_DIR} ${SDL_SOUND_INCLUDE_DIR})
@ -1530,7 +1540,7 @@ IF(ALSOFT_EXAMPLES)
PRIVATE ${LINKER_FLAGS} ${SDL_SOUND_LIBRARIES} ${SDL2_LIBRARY} ex-common ${MATH_LIB})
IF(ALSOFT_INSTALL)
INSTALL(TARGETS alplay alstream alreverb almultireverb allatency alloopback alhrtf
INSTALL(TARGETS alstream alreverb almultireverb allatency alloopback alhrtf
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})

23
cmake/FindSndFile.cmake Normal file

@ -0,0 +1,23 @@
# - Try to find SndFile
# Once done this will define
#
# SNDFILE_FOUND - system has SndFile
# SNDFILE_INCLUDE_DIRS - the SndFile include directory
# SNDFILE_LIBRARIES - Link these to use SndFile
find_path(SNDFILE_INCLUDE_DIR NAMES sndfile.h)
find_library(SNDFILE_LIBRARY NAMES sndfile sndfile-1)
# handle the QUIETLY and REQUIRED arguments and set SNDFILE_FOUND to TRUE if
# all listed variables are TRUE
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(SndFile DEFAULT_MSG SNDFILE_LIBRARY SNDFILE_INCLUDE_DIR)
if(SNDFILE_FOUND)
set(SNDFILE_INCLUDE_DIRS ${SNDFILE_INCLUDE_DIR})
set(SNDFILE_LIBRARIES ${SNDFILE_LIBRARY})
endif()
# show the SNDFILE_INCLUDE_DIR and SNDFILE_LIBRARY variables only in the advanced view
mark_as_advanced(SNDFILE_INCLUDE_DIR SNDFILE_LIBRARY)

@ -24,12 +24,13 @@
/* This file contains an example for playing a sound buffer. */
#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"
@ -41,68 +42,62 @@
*/
static ALuint LoadSound(const char *filename)
{
Sound_Sample *sample;
ALenum err, format;
ALuint buffer;
Uint32 slen;
SNDFILE *sndfile;
SF_INFO sfinfo;
short *membuf;
sf_count_t num_frames;
ALsizei num_bytes;
/* Open the audio file */
sample = Sound_NewSampleFromFile(filename, NULL, 65536);
if(!sample)
/* 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;
}
if(sfinfo.frames < 1 || sfinfo.frames > (sf_count_t)(INT_MAX/sizeof(short))/sfinfo.channels)
{
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(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(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;
}
}
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();
@ -136,14 +131,10 @@ int main(int argc, char **argv)
if(InitAL(&argv, &argc) != 0)
return 1;
/* Initialize SDL_sound. */
Sound_Init();
/* Load the sound into a buffer. */
buffer = LoadSound(argv[0]);
if(!buffer)
{
Sound_Quit();
CloseAL();
return 1;
}
@ -171,7 +162,6 @@ int main(int argc, char **argv)
alDeleteSources(1, &source);
alDeleteBuffers(1, &buffer);
Sound_Quit();
CloseAL();
return 0;