diff options
-rw-r--r-- | configure.ac | 39 | ||||
-rw-r--r-- | src/audio.c | 126 | ||||
-rw-r--r-- | src/audio.h | 2 | ||||
-rw-r--r-- | src/types.h | 1 |
4 files changed, 139 insertions, 29 deletions
diff --git a/configure.ac b/configure.ac index 7cbf67a..01b7e6d 100644 --- a/configure.ac +++ b/configure.ac @@ -32,34 +32,39 @@ if $PKG_CONFIG sdl ; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([not found]) - AC_MSG_ERROR([ -*** SDL not found. Do you have 'libsdl-dev' or similar installed?]) + AC_MSG_ERROR([*** SDL not found. Do you have 'libsdl-dev' or similar installed?]) fi AC_CHECK_LIB(GL, main, [OPENGL_CFLAGS=-I/usr/include/GL -OPENGL_LIBS=-lGL], AC_MSG_ERROR([ -*** OpenGL not found. Do you have 'libgl-dev' or similar installed?])) +OPENGL_LIBS=-lGL], AC_MSG_ERROR([*** OpenGL not found. Do you have 'libgl-dev' or similar installed?])) -AC_CHECK_LIB(GLU, main, [GLU_LIBS=-lGLU], AC_MSG_ERROR([ -*** GLU not found. Do you have 'libglu-dev' or similar installed?])) +AC_CHECK_LIB(GLU, main, [GLU_LIBS=-lGLU], AC_MSG_ERROR([*** GLU not found. Do you have 'libglu-dev' or similar installed?])) -AC_CHECK_LIB(GLEW, main, [GLEW_LIBS=-lGLEW], AC_MSG_ERROR([ -*** GLEW not found. Do you have 'libglew-dev' or similar installed?])) +AC_CHECK_LIB(GLEW, main, [GLEW_LIBS=-lGLEW], AC_MSG_ERROR([*** GLEW not found. Do you have 'libglew-dev' or similar installed?])) AC_MSG_CHECKING([libpng]) if $PKG_CONFIG --atleast-version 1.2.0 libpng ; then - LIBPNG_VERSION=`$PKG_CONFIG --modversion libpng` - AC_MSG_RESULT($LIBPNG_VERSION) - LIBPNG_CFLAGS=`$PKG_CONFIG --cflags libpng` - LIBPNG_LIBS=`$PKG_CONFIG --libs libpng` + LIBPNG_VERSION=`$PKG_CONFIG --modversion libpng` + AC_MSG_RESULT($LIBPNG_VERSION) + LIBPNG_CFLAGS=`$PKG_CONFIG --cflags libpng` + LIBPNG_LIBS=`$PKG_CONFIG --libs libpng` else - AC_MSG_RESULT([Lower than 1.2.0 or not found]) - AC_MSG_ERROR([ -*** libPNG not found. Do you have 'libpng-dev' or similar installed?]) + AC_MSG_RESULT([Lower than 1.2.0 or not found]) + AC_MSG_ERROR([*** libPNG not found. Do you have 'libpng-dev' or similar installed?]) fi -CFLAGS="$CFLAGS $LIBSDL_CFLAGS $OPENGL_CFLAGS $LIBPNG_CFLAGS" -LIBS="$LIBS $LIBSDL_LIBS $OPENGL_LIBS $GLU_LIBS $GLEW_LIBS $LIBPNG_LIBS" +AC_MSG_CHECKING([vorbisfile]) +if $PKG_CONFIG --exists vorbisfile ; then + VORBISFILE_CFLAGS=`$PKG_CONFIG --cflags vorbisfile` + VORBISFILE_LIBS=`$PKG_CONFIG --libs vorbisfile` + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) + AC_MSG_ERROR([*** vorbisfile not found. Do you have 'libvorbis-dev' or similar installed?]) +fi + +CFLAGS="$CFLAGS $LIBSDL_CFLAGS $OPENGL_CFLAGS $LIBPNG_CFLAGS $VORBISFILE_CFLAGS" +LIBS="$LIBS $LIBSDL_LIBS $OPENGL_LIBS $GLU_LIBS $GLEW_LIBS $LIBPNG_LIBS $VORBISFILE_LIBS" AC_OUTPUT(Makefile src/Makefile data/Makefile) diff --git a/src/audio.c b/src/audio.c index c71b995..dc89927 100644 --- a/src/audio.c +++ b/src/audio.c @@ -13,8 +13,13 @@ #include <config.h> #endif +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/errno.h> #include <SDL.h> #include <SDL_audio.h> +#include <vorbis/vorbisfile.h> +#include <vorbis/codec.h> #include "types.h" @@ -24,7 +29,7 @@ static void audio_mix(void *data, Uint8 *stream8, int len) { int i, j, clip_count; Sint16 *stream = (Sint16 *)stream8; - len /= 2; /* Samples */ + len /= 2; /* Number of samples to write */ /* Zero the buffer */ for ( j=0; j<len; j++ ) { @@ -88,30 +93,27 @@ static void audio_mix(void *data, Uint8 *stream8, int len) { } -void audio_play(AudioContext *a, char *file, float volume, int repeat) { +static void audio_play_wav(AudioContext *a, char *filename, float volume, int repeat) { int idx; SDL_AudioSpec wave; Uint8 *data; Uint32 dlen; SDL_AudioCVT cvt; - char filename[128]; /* Look for an empty sound slot */ for ( idx=0; idx<AUDIO_MAX_SOUNDS; idx++ ) { if ( !a->sounds[idx].inuse ) break; } - if ( a->debug ) printf("AU: Selected channel %i for sound '%s'\n", idx, file); + if ( a->debug ) printf("AU: Selected channel %i for sound '%s'\n", idx, filename); if ( idx == AUDIO_MAX_SOUNDS ) { - fprintf(stderr, "Not enough audio channels to play '%s'\n", file); + fprintf(stderr, "Not enough audio channels to play '%s'\n", filename); return; } - snprintf(filename, 127, "%s%s.wav", DATADIR"/sound/", file); - - /* Load the sound file and convert it to 16-bit stereo at 22kHz */ + /* Load the sound file and convert it to 16-bit stereo at 44.1 kHz */ if ( SDL_LoadWAV(filename, &wave, &data, &dlen) == NULL ) { - fprintf(stderr, "Couldn't load %s: %s\n", file, SDL_GetError()); + fprintf(stderr, "Couldn't load %s: %s\n", filename, SDL_GetError()); return; } SDL_BuildAudioCVT(&cvt, wave.format, wave.channels, wave.freq, AUDIO_S16, 2, 44100); @@ -133,6 +135,107 @@ void audio_play(AudioContext *a, char *file, float volume, int repeat) { } +static void audio_play_vorbis(AudioContext *a, char *filename, float volume, int repeat) { + + int idx; + char *data; + int len; + OggVorbis_File vf; + vorbis_info *vi; + int finished, err, current_section; + size_t offs; + SDL_AudioCVT cvt; + + /* Look for an empty sound slot */ + for ( idx=0; idx<AUDIO_MAX_SOUNDS; idx++ ) { + if ( !a->sounds[idx].inuse ) break; + } + if ( a->debug ) printf("AU: Selected channel %i for sound '%s'\n", idx, filename); + if ( idx == AUDIO_MAX_SOUNDS ) { + fprintf(stderr, "Not enough audio channels to play '%s'\n", filename); + return; + } + + err = ov_fopen(filename, &vf); + if ( err != 0 ) { + fprintf(stderr, "Couldn't open Vorbis file '%s' (code %i,%i)\n", filename, err, errno); + return; + } + + len = ov_pcm_total(&vf, -1); /* Length in samples 'per channel' */ + if ( a->debug ) printf("AU: Length is %i samples 'per channel'\n", len); + vi = ov_info(&vf,-1); + if ( a->debug ) printf("AU: %i channels, %li Hz\n", vi->channels, vi->rate); + data = malloc(vi->channels*2*len); /* Two bytes per sample per channel */ + + offs = 0; + finished = 0; + if ( a->debug ) printf("AU: Decoding Vorbis stream...\n"); + while ( finished == 0 ) { + long rval; + rval = ov_read(&vf, data+offs, 2*2*len, 0, 2, 1, ¤t_section); + if ( rval == 0 ) { + finished = 1; + } else if ( rval < 0 ) { + fprintf(stderr, "Vorbis stream error\n"); + } else { + offs += rval; + } + } + + /* Convert to 44.1 kHz */ + SDL_BuildAudioCVT(&cvt, AUDIO_S16, vi->channels, vi->rate, AUDIO_S16, 2, 44100); + cvt.buf = malloc(vi->channels*2*len*cvt.len_mult); + memcpy(cvt.buf, data, vi->channels*2*len); + cvt.len = vi->channels*2*len; + SDL_ConvertAudio(&cvt); + + ov_clear(&vf); + + /* Put the sound data in the slot */ + SDL_LockAudio(); + a->sounds[idx].data = (Sint16 *)cvt.buf; + a->sounds[idx].dlen = cvt.len_cvt / 2; + a->sounds[idx].dpos = 0; + a->sounds[idx].inuse = 1; + a->sounds[idx].repeat = repeat; + a->sounds[idx].volume = volume; + SDL_UnlockAudio(); + +} + +void audio_play(AudioContext *a, char *name, float volume, int repeat) { + + char filename[128]; + struct stat statbuf; + + /* Try to find an Ogg/Vorbis file */ + snprintf(filename, 127, "%s%s.ogg", DATADIR"/sound/", name); + if ( stat(filename, &statbuf) == 0 ) { + audio_play_vorbis(a, filename, volume, repeat); + goto done; + } + + /* Try to find a WAV file */ + snprintf(filename, 127, "%s%s.wav", DATADIR"/sound/", name); + if ( stat(filename, &statbuf) == 0 ) { + audio_play_wav(a, filename, volume, repeat); + goto done; + } + + /* Still not found */ + fprintf(stderr, "Couldn't find file for sound '%s'\n", name); + return; + +done: /* Success */ + if ( a->paused == 1 ) { + SDL_PauseAudio(0); + a->paused = 0; + } + return; + +} + /* SDL audio initial setup */ AudioContext *audio_setup(int debug) { @@ -148,6 +251,7 @@ AudioContext *audio_setup(int debug) { a->debug = debug; a->startup = 1; a->startup_volume = 0.0; + a->paused = 1; for ( i=0; i<AUDIO_MAX_SOUNDS; i++ ) { a->sounds[i].inuse = 0; } @@ -166,9 +270,9 @@ AudioContext *audio_setup(int debug) { free(a); return NULL; } - SDL_PauseAudio(0); - audio_play(a, "moan", 0.4, 1); + audio_play(a, "kraftwerk", 1.0, 1); +// audio_play(a, "moan", 0.4, 1); return a; diff --git a/src/audio.h b/src/audio.h index 769b398..e7a5d73 100644 --- a/src/audio.h +++ b/src/audio.h @@ -20,7 +20,7 @@ extern AudioContext *audio_setup(int debug); extern void audio_shutdown(AudioContext *ctx); -extern void audio_play(AudioContext *a, char *file, float volume, int repeat); +extern void audio_play(AudioContext *a, char *name, float volume, int repeat); #endif /* AUDIO_H */ diff --git a/src/types.h b/src/types.h index 959a205..d398899 100644 --- a/src/types.h +++ b/src/types.h @@ -158,6 +158,7 @@ typedef struct { int debug; int startup; float startup_volume; + int paused; } AudioContext; |