added command-line options for named pipes

This commit is contained in:
Matthew Flint
2011-04-18 00:55:42 +01:00
parent 01d8c09738
commit 8f6e213736
2 changed files with 84 additions and 21 deletions
+60 -13
View File
@@ -35,6 +35,8 @@
#include <pthread.h>
#include <openssl/aes.h>
#include <math.h>
#include <sys/stat.h>
#include <fcntl.h>
#if !defined(HAVE_AO)
#define HAVE_AO 1
@@ -73,6 +75,7 @@ int dataport = 0, controlport = 0, timingport = 0;
int fmtp[32];
int sampling_rate;
int frame_size;
char *pipename = 0;
#define FRAME_BYTES (4*frame_size)
// maximal resampling shift - conservative
#define OUTFRAME_BYTES (4*(frame_size+3))
@@ -187,7 +190,10 @@ int main(int argc, char **argv) {
} else
if (!strcasecmp(arg, "host")) {
rtphost = *++argv;
}
} else
if (!strcasecmp(arg, "pipe")) {
pipename = *++argv;
}
#ifdef FANCY_RESAMPLING
else
if (!strcasecmp(arg, "resamp")) {
@@ -659,16 +665,27 @@ int stuff_buffer(double playback_rate, short *inptr, short *outptr) {
void *audio_thread_func(void *arg) {
#if HAVE_AO
ao_device* dev = arg;
ao_device* dev = arg;
#else
PaStream* stream = arg;
PaStream* stream = arg;
#endif
// file handle for named pipe
int fd = -1;
int i __attribute__((unused)), play_samples;
signed short buf_fill __attribute__((unused));
signed short *inbuf, *outbuf;
outbuf = malloc(OUTFRAME_BYTES);
if (pipename) {
fd = open(pipename, O_WRONLY);
if (fd == -1) {
printf( "Pipe open failure: %s\n", pipename );
exit(1);
}
}
#ifdef FANCY_RESAMPLING
float *frame, *outframe;
SRC_DATA srcdat;
@@ -703,17 +720,26 @@ void *audio_thread_func(void *arg) {
play_samples = srcdat.output_frames_gen;
} else
#endif
play_samples = stuff_buffer(bf_playback_rate, inbuf, outbuf);
if (pipename) {
int ret = write(fd, outbuf, play_samples*4);
if (!ret) {
printf( "Pipe write error" );
exit(1);
}
} else {
#if HAVE_AO
ao_play(dev, (char *)outbuf, play_samples*4);
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);
}
int err = Pa_WriteStream(stream, (char *)outbuf, play_samples*4);
if( err != paNoError ) {
printf( "PortAudio error: %s\n", Pa_GetErrorText( err ) );
exit(1);
}
#endif
}
}
return 0;
@@ -721,9 +747,13 @@ void *audio_thread_func(void *arg) {
#define NUM_CHANNELS 2
int init_output(void) {
int err __attribute__((unused));
void* init_pipe(char* pipe) {
mknod(pipe, S_IFIFO | 0644, 0);
return NULL;
}
#if HAVE_AO
void* init_ao() {
ao_initialize();
int driver = ao_default_driver_id();
@@ -736,8 +766,11 @@ int init_output(void) {
fmt.byte_format = AO_FMT_LITTLE;
ao_device *dev = ao_open_live(driver, &fmt, 0);
void* arg = dev;
return dev;
}
#else
void* init_portaudio() {
int err __attribute__((unused));
err = Pa_Initialize();
if( err != paNoError ) {
printf( "PortAudio error: %s\n", Pa_GetErrorText( err ) );
@@ -773,9 +806,23 @@ int init_output(void) {
exit(1);
}
void* arg = stream;
return stream;
}
#endif
int init_output(void) {
void* arg = 0;
if (pipename) {
arg = init_pipe(pipename);
} else {
#if HAVE_AO
arg = init_ao();
#else
arg = init_portaudio();
#endif
}
#ifdef FANCY_RESAMPLING
if (fancy_resampling)
src = src_new(SRC_SINC_MEDIUM_QUALITY, 2, &err);
+24 -8
View File
@@ -48,12 +48,15 @@ my $apname = "ShairPort $$ on " . `hostname`;
# password - required to connect
# for no password, set:
my $password = '';
# output to a pipe?
my $pipepath;
my $daemon;
# suppose hairtunes is under same directory
my $hairtunes_cli = $FindBin::Bin . '/hairtunes';
GetOptions("a|apname=s" => \$apname,
"p|password=s" => \$password,
"i|pipe=s" => \$pipepath,
"d" => \$daemon,
"h|help" => \$help);
@@ -65,6 +68,7 @@ sub usage {
"Options:\n".
" -a, --apname=AirPort Sets AirPort name\n".
" -p, --password=secret Sets password\n",
" -i, --pipe=pipepath Sets the path to a named pipe for output\n",
" -d Daemon mode\n",
" -h, --help This help\n",
"\n";
@@ -334,14 +338,26 @@ sub conn_handle_request {
$resp->header('Session', 'DEADBEEF');
my $dec = sprintf("$hairtunes_cli iv %s key %s fmtp %s cport %s tport %s dport %s host %s",
map { "'$_'" } (
unpack('H*', $conn->{aesiv}),
unpack('H*', $conn->{aeskey}),
$conn->{fmtp},
$cport, $tport, $dport,
'unused'
));
my $dec;
if (defined($pipepath)) {
$dec = sprintf("$hairtunes_cli iv %s key %s fmtp %s cport %s tport %s dport %s host %s pipe %s",
map { "'$_'" } (
unpack('H*', $conn->{aesiv}),
unpack('H*', $conn->{aeskey}),
$conn->{fmtp},
$cport, $tport, $dport,
'unused', $pipepath
));
} else {
$dec = sprintf("$hairtunes_cli iv %s key %s fmtp %s cport %s tport %s dport %s host %s",
map { "'$_'" } (
unpack('H*', $conn->{aesiv}),
unpack('H*', $conn->{aeskey}),
$conn->{fmtp},
$cport, $tport, $dport,
'unused'
));
}
# print "decode command: $dec\n";
my $decoder = open2(my $dec_out, my $dec_in, $dec);