X-Git-Url: https://git.distorted.org.uk/~mdw/disorder/blobdiff_plain/7a2c706849ecf6cee19d9e502f8491ffac3322e0..c35b92797182124e4a9f4e5f0088230ec57883e7:/clients/playrtp.c diff --git a/clients/playrtp.c b/clients/playrtp.c index f1eaebc..9647437 100644 --- a/clients/playrtp.c +++ b/clients/playrtp.c @@ -104,7 +104,7 @@ unsigned minbuffer = 2 * 44100 / 10; /* 0.2 seconds */ /** @brief Buffer high watermark * * We'll only start playing when this many samples are available. */ -static unsigned readahead = 2 * 2 * 44100; +static unsigned readahead = 44100; /* 0.5 seconds */ /** @brief Maximum buffer size * @@ -216,6 +216,7 @@ static const struct option options[] = { { "core-audio", no_argument, 0, 'c' }, #endif { "dump", required_argument, 0, 'r' }, + { "command", required_argument, 0, 'e' }, { "socket", required_argument, 0, 's' }, { "config", required_argument, 0, 'C' }, { 0, 0, 0, 0 } @@ -399,7 +400,7 @@ static void *listen_thread(void attribute((unused)) *arg) { if(header.mpt & 0x80) p->flags |= IDLE; switch(header.mpt & 0x7F) { - case 10: + case 10: /* L16 */ p->nsamples = (n - sizeof header) / sizeof(uint16_t); break; /* TODO support other RFC3551 media types (when the speaker does) */ @@ -474,7 +475,7 @@ struct packet *playrtp_next_packet(void) { /* display usage message and terminate */ static void help(void) { xprintf("Usage:\n" - " disorder-playrtp [OPTIONS] ADDRESS [PORT]\n" + " disorder-playrtp [OPTIONS] [[ADDRESS] PORT]\n" "Options:\n" " --device, -D DEVICE Output device\n" " --min, -m FRAMES Buffer low water mark\n" @@ -491,6 +492,7 @@ static void help(void) { #if HAVE_COREAUDIO_AUDIOHARDWARE_H " --core-audio, -c Use Core Audio to play audio\n" #endif + " --command, -e COMMAND Pipe audio to command\n" " --help, -h Display usage message\n" " --version, -V Display version number\n" ); @@ -498,7 +500,7 @@ static void help(void) { exit(0); } -static size_t playrtp_callback(int16_t *buffer, +static size_t playrtp_callback(void *buffer, size_t max_samples, void attribute((unused)) *userdata) { size_t samples; @@ -543,12 +545,12 @@ static size_t playrtp_callback(int16_t *buffer, if(samples > max_samples) samples = max_samples; //info("infill by %zu", samples); - memset(buffer, 0, samples * sizeof *buffer); + memset(buffer, 0, samples * uaudio_sample_size); } /* Debug dump */ if(dump_buffer) { for(size_t i = 0; i < samples; ++i) { - dump_buffer[dump_index++] = buffer[i]; + dump_buffer[dump_index++] = ((int16_t *)buffer)[i]; dump_index %= dump_size; } } @@ -577,7 +579,6 @@ int main(int argc, char **argv) { }; union any_sockaddr mgroup; const char *dumpfile = 0; - const char *device = 0; pthread_t ltid; static const struct addrinfo prefs = { @@ -590,12 +591,12 @@ int main(int argc, char **argv) { mem_init(); if(!setlocale(LC_CTYPE, "")) fatal(errno, "error calling setlocale"); backend = uaudio_apis[0]; - while((n = getopt_long(argc, argv, "hVdD:m:b:x:L:R:M:aocC:r", options, 0)) >= 0) { + while((n = getopt_long(argc, argv, "hVdD:m:b:x:L:R:M:aocC:re:", options, 0)) >= 0) { switch(n) { case 'h': help(); case 'V': version("disorder-playrtp"); case 'd': debugging = 1; break; - case 'D': device = optarg; break; + case 'D': uaudio_set("device", optarg); break; case 'm': minbuffer = 2 * atol(optarg); break; case 'b': readahead = 2 * atol(optarg); break; case 'x': maxbuffer = 2 * atol(optarg); break; @@ -613,6 +614,7 @@ int main(int argc, char **argv) { case 'C': configfile = optarg; break; case 's': control_socket = optarg; break; case 'r': dumpfile = optarg; break; + case 'e': backend = &uaudio_command; uaudio_set("command", optarg); break; default: fatal(0, "invalid option"); } } @@ -742,10 +744,10 @@ int main(int argc, char **argv) { fatal(errno, "mapping %s", dumpfile); info("dumping to %s", dumpfile); } - /* Choose output device */ - if(device) - uaudio_set("device", device); - /* Set up output */ + /* Set up output. Currently we only support L16 so there's no harm setting + * the format before we know what it is! */ + uaudio_set_format(44100/*Hz*/, 2/*channels*/, + 16/*bits/channel*/, 1/*signed*/); backend->start(playrtp_callback, NULL); /* We receive and convert audio data in a background thread */ if((err = pthread_create(<id, 0, listen_thread, 0))) @@ -765,8 +767,9 @@ int main(int argc, char **argv) { /* Wait until the buffer empties out */ while(nsamples >= minbuffer || (nsamples > 0 - && contains(pheap_first(&packets), next_timestamp))) + && contains(pheap_first(&packets), next_timestamp))) { pthread_cond_wait(&cond, &lock); + } /* Stop playing for a bit until the buffer re-fills */ backend->deactivate(); active = 0;