aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortaw27 <taw27@84d2e878-0bd5-11dd-ad15-13eda11d74c5>2008-06-30 11:50:04 +0000
committertaw27 <taw27@84d2e878-0bd5-11dd-ad15-13eda11d74c5>2008-06-30 11:50:04 +0000
commitf65ea1c43238b6e75c49a87b3aee3156fd00343e (patch)
treee7defa4d9693bd8d0c65909a6414fa6e8079a5e3
parent5be16d1333327c22f9e61e03de1d478fa56ae5c5 (diff)
Interface to libvorbis :)
git-svn-id: svn://cook.msm.cam.ac.uk:745/thrust3d/thrust3d@121 84d2e878-0bd5-11dd-ad15-13eda11d74c5
-rw-r--r--configure.ac39
-rw-r--r--src/audio.c126
-rw-r--r--src/audio.h2
-rw-r--r--src/types.h1
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, &current_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;