From 2abcf7ccc863eae236de2831a612ce3d2de95c30 Mon Sep 17 00:00:00 2001 From: Albert Zeyer Date: Mon, 11 Apr 2011 12:32:26 +0200 Subject: [PATCH] added PortAudio support (and make it default) --- Makefile | 2 +- hairtunes.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 75 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 8ec08596..fc1c3f22 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -CFLAGS = `pkg-config --cflags --libs ao openssl` +CFLAGS = `pkg-config --cflags --libs openssl` -lportaudio hairtunes: hairtunes.c alac.c gcc hairtunes.c alac.c -D__i386 -lm $(CFLAGS) -o hairtunes diff --git a/hairtunes.c b/hairtunes.c index aa5f08ea..1a1b3eec 100644 --- a/hairtunes.c +++ b/hairtunes.c @@ -33,7 +33,11 @@ #include #include #include +#if HAVE_AO #include +#else +#include +#endif #include #ifdef FANCY_RESAMPLING @@ -233,6 +237,8 @@ int main(int argc, char **argv) { } fprintf(stderr, "bye!\n"); fflush(stderr); + + uninit_output(); } void init_buffer(void) { @@ -583,7 +589,11 @@ int stuff_buffer(double playback_rate, short *inptr, short *outptr) { } void *audio_thread_func(void *arg) { - ao_device *dev = arg; +#if HAVE_AO + ao_device* dev = arg; +#else + PaStream* stream = arg; +#endif int i, play_samples; signed short buf_fill; @@ -626,24 +636,74 @@ void *audio_thread_func(void *arg) { #endif play_samples = stuff_buffer(bf_playback_rate, inbuf, outbuf); +#if HAVE_AO ao_play(dev, (char *)outbuf, play_samples*4); +#else + int err = Pa_WriteStream(stream, (char *)outbuf, play_samples*4); + if( err != paNoError ) { + printf( "PortAudio error: %s\n", Pa_GetErrorText( err ) ); + exit(1); + } +#endif } } +#define NUM_CHANNELS 2 + int init_output(void) { + int err; +#if HAVE_AO ao_initialize(); int driver = ao_default_driver_id(); ao_sample_format fmt; fmt.bits = 16; fmt.rate = sampling_rate; - fmt.channels = 2; + fmt.channels = NUM_CHANNELS; fmt.byte_format = AO_FMT_LITTLE; fmt.matrix = 0; ao_device *dev = ao_open_live(driver, &fmt, 0); + void* arg = dev; +#else + err = Pa_Initialize(); + if( err != paNoError ) { + printf( "PortAudio error: %s\n", Pa_GetErrorText( err ) ); + exit(1); + } - int err; + PaStreamParameters outputParameters; + outputParameters.device = Pa_GetDefaultOutputDevice(); /* default output device */ + outputParameters.channelCount = NUM_CHANNELS; + outputParameters.sampleFormat = paInt16; + outputParameters.suggestedLatency = Pa_GetDeviceInfo( outputParameters.device )->defaultHighOutputLatency; + outputParameters.hostApiSpecificStreamInfo = NULL; + + /* -- setup stream -- */ + PaStream* stream = NULL; + err = Pa_OpenStream( + &stream, + NULL, + &outputParameters, + sampling_rate, + OUTFRAME_BYTES, + paClipOff, /* we won't output out of range samples so don't bother clipping them */ + NULL, /* no callback, use blocking API */ + NULL ); /* no callback, so no callback userData */ + if( err != paNoError ) { + printf( "PortAudio error: %s\n", Pa_GetErrorText( err ) ); + exit(1); + } + + err = Pa_StartStream( stream ); + if( err != paNoError ) { + printf( "PortAudio error: %s\n", Pa_GetErrorText( err ) ); + exit(1); + } + + void* arg = stream; +#endif + #ifdef FANCY_RESAMPLING if (fancy_resampling) src = src_new(SRC_SINC_MEDIUM_QUALITY, 2, &err); @@ -652,5 +712,15 @@ int init_output(void) { #endif pthread_t audio_thread; - pthread_create(&audio_thread, NULL, audio_thread_func, dev); + pthread_create(&audio_thread, NULL, audio_thread_func, arg); +} + +int uninit_output(void) { +#if HAVE_AO +#else + int err = Pa_Terminate(); + if( err != paNoError ) + printf( "PortAudio error: %s\n", Pa_GetErrorText( err ) ); +#endif + return 0; }