From ec010b19cac1d5aea5393a687a91431f2e541101 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Tue, 14 Oct 2008 23:20:29 +0100 Subject: Initial import --- src/audio.c | 159 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 src/audio.c (limited to 'src/audio.c') diff --git a/src/audio.c b/src/audio.c new file mode 100644 index 0000000..ed37a89 --- /dev/null +++ b/src/audio.c @@ -0,0 +1,159 @@ +/* + * audio.c + * + * Moo like a cow + * + * (c) 2008 Thomas White + * + * This file is part of OpenMooCow - accelerometer moobox simulator + * + * OpenMooCow is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * OpenMooCow is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with OpenMooCow. If not, see . + * + */ + +//#ifdef HAVE_CONFIG_H +//#include +//#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "types.h" + +static void audio_mix(void *data, Uint8 *stream8, int len) { + + AudioContext *a = data; + int j; + Sint16 *stream = (Sint16 *)stream8; + Sint16 samp; + + len /= 2; /* Number of samples to write */ + + for ( j=0; jmoo_pos < a->moo_len ) { + samp = a->moo_buf[a->moo_pos++]; + stream[j] += samp; + } + + } + +} + +void audio_trigger_moo(AudioContext *a) { + + if ( a->aplay_fallback ) { + + pid_t pid; + int status; + + pid = fork(); + if ( !( (pid != 0) && (pid != -1) ) ) { + if ( pid == -1 ) { + fprintf(stderr, "fork() failed.\n"); + return; + } else { + /* Forked successfully, child process */ + execlp("aplay", "aplay", DATADIR"/openmoocow/moo.wav", NULL); + } + } /* else forked successfully, parent process */ + printf("Waiting...\n"); fflush(stdout); + waitpid(pid, &status, 0); + printf("Done mooing\n"); fflush(stdout); + + } else { + if ( a->moo_pos == a->moo_len ) { + a->moo_pos = 0; + } + } + +} + +/* SDL audio initial setup */ +AudioContext *audio_setup() { + + AudioContext *a; + SDL_AudioSpec fmt; + SDL_AudioSpec wave; + Uint8 *data; + Uint32 dlen; + SDL_AudioCVT cvt; + + /* Create audio context */ + a = malloc(sizeof(AudioContext)); + if ( a == NULL ) return NULL; + + /* 16-bit mono audio at 44.1 kHz */ + fmt.freq = 44100; + fmt.format = AUDIO_S16; + fmt.channels = 1; + fmt.samples = 512; + fmt.callback = audio_mix; + fmt.userdata = a; + fmt.silence = 0; + + if ( SDL_OpenAudio(&fmt, NULL) < 0 ) { + fprintf(stderr, "Unable to open audio: %s\n", SDL_GetError()); + a->aplay_fallback = 1; + return a; + } + a->aplay_fallback = 0; + + if ( SDL_LoadWAV(DATADIR"/openmoocow/moo.wav", &wave, &data, &dlen) == NULL ) { + fprintf(stderr, "Couldn't load moo sound: %s\n", SDL_GetError()); + return a; + } + SDL_BuildAudioCVT(&cvt, wave.format, wave.channels, wave.freq, AUDIO_S16, 1, 44100); + cvt.buf = malloc(dlen*cvt.len_mult); + if ( cvt.buf == NULL ) { + fprintf(stderr, "Not enough memory to convert audio \n"); + return a; + } + memcpy(cvt.buf, data, dlen); + cvt.len = dlen; + SDL_ConvertAudio(&cvt); + SDL_FreeWAV(data); + + a->moo_len = cvt.len_cvt/2 - 2; /* Convert bytes to samples */ + a->moo_pos = a->moo_len; /* Play nothing to start with */ + a->moo_buf = (Sint16 *)cvt.buf; + + SDL_PauseAudio(0); + + return a; + +} + +void audio_shutdown(AudioContext *a) { + + if ( a == NULL ) return; + + if ( !a->aplay_fallback ) { + SDL_CloseAudio(); + } + + /* Now this can be freed */ + free(a); + +} + -- cgit v1.2.3