summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlbert Zeyer <albert.zeyer@rwth-aachen.de>2011-04-11 12:32:26 +0200
committerAlbert Zeyer <albert.zeyer@rwth-aachen.de>2011-04-11 12:32:26 +0200
commit2abcf7ccc863eae236de2831a612ce3d2de95c30 (patch)
treee71cd60238a893b1e48519add70b8cb7019cc54c
parent31cf954da5ad71ad5fe74bc8e912ad11a75cb758 (diff)
added PortAudio support (and make it default)
-rw-r--r--Makefile2
-rw-r--r--hairtunes.c80
2 files changed, 76 insertions, 6 deletions
diff --git a/Makefile b/Makefile
index 8ec0859..fc1c3f2 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 aa5f08e..1a1b3ee 100644
--- a/hairtunes.c
+++ b/hairtunes.c
@@ -33,7 +33,11 @@
#include <netinet/in.h>
#include <pthread.h>
#include <openssl/aes.h>
+#if HAVE_AO
#include <ao/ao.h>
+#else
+#include <portaudio.h>
+#endif
#include <math.h>
#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);
-
- int err;
+ void* arg = dev;
+#else
+ err = Pa_Initialize();
+ if( err != paNoError ) {
+ printf( "PortAudio error: %s\n", Pa_GetErrorText( err ) );
+ exit(1);
+ }
+
+ 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;
}