diff --git a/audio_pipe.c b/audio_pipe.c index df54bbd4..b218d787 100644 --- a/audio_pipe.c +++ b/audio_pipe.c @@ -39,13 +39,10 @@ char *pipename = NULL; static void start(int sample_rate) { debug(1,"Pipename to start is \"%s\"",pipename); - fd = open(pipename, O_WRONLY | O_NONBLOCK); - /* - if (fd < 0) { - perror("open"); - die("could not open specified pipe for writing"); - } - */ + if (strcasecmp(pipename,"STDOUT")==0) + fd = STDOUT_FILENO; + else + fd = open(pipename, O_WRONLY); } static void play(short buf[], int samples) { @@ -53,6 +50,7 @@ static void play(short buf[], int samples) { } static void stop(void) { + if (fd!=STDOUT_FILENO) close(fd); } @@ -72,10 +70,12 @@ static int init(int argc, char **argv, config_t *cfgp) { if (argc==1) pipename = strdup(argv[0]); - + + // here, create the pipe - if (mkfifo(pipename, 0644) && errno != EEXIST) - die("Could not create metadata FIFO %s", pipename); + if (strcasecmp(pipename,"STDOUT")!=0) + if (mkfifo(pipename, 0644) && errno != EEXIST) + die("Could not create metadata FIFO %s", pipename); debug(1,"Pipename is \"%s\"",pipename); @@ -88,14 +88,12 @@ static int init(int argc, char **argv, config_t *cfgp) { } static void deinit(void) { - if (fd > 0) + if ((fd > 0) && (fd!=STDOUT_FILENO)) close(fd); - if (pipename) - free(pipename); } static void help(void) { - printf(" pipe takes 1 argument: the name of the FIFO to write to.\n"); + printf(" pipe takes 1 argument: the name of the FIFO to write to, which can be \"stdout\".\n"); } audio_output audio_pipe = { diff --git a/player.c b/player.c index 72622f79..6840e8ff 100644 --- a/player.c +++ b/player.c @@ -573,8 +573,31 @@ static abuf_t *buffer_get_frame(void) { } } } - wait = (ab_buffering || (dac_delay>=config.dac_buffer_queue_desired_length) || (!ab_synced)) && (!please_stop); -// wait = (ab_buffering || (seq_diff(ab_read, ab_write) < (config.latency-22000)/(352)) || (!ab_synced)) && (!please_stop); + + // here, we work out whether to wait or not + // if we are getting feedback from the backend, we can use that. + // otherwise we have to release a buffer when the time is right. + + if (config.output->delay) + wait = (ab_buffering || (dac_delay>=config.dac_buffer_queue_desired_length) || (!ab_synced)) && (!please_stop); + else { + int do_wait = 1; + if ((curframe) && (curframe->ready) && (curframe->timestamp)) { + uint32_t reference_timestamp; + uint64_t reference_timestamp_time; + get_reference_timestamp_stuff(&reference_timestamp,&reference_timestamp_time); + if (reference_timestamp) { // if we have a reference time + uint32_t packet_timestamp=curframe->timestamp; + int64_t delta = ((int64_t)packet_timestamp-(int64_t)reference_timestamp); + int64_t time_to_play = reference_timestamp_time+((delta+(int64_t)(config.latency-config.dac_buffer_queue_desired_length))<<32)/44100; // using the latency requested... + if (local_time_now>=time_to_play) { + do_wait = 0; + } + } + } + wait = (ab_buffering || (do_wait!=0) || (!ab_synced)) && (!please_stop); +// wait = (ab_buffering || (seq_diff(ab_read, ab_write) < (config.latency-22000)/(352)) || (!ab_synced)) && (!please_stop); + } if (wait) { uint64_t time_to_wait_for_wakeup_fp = ((uint64_t)1<<32)/44100; // this is time period of one frame time_to_wait_for_wakeup_fp *= 4*352; // four full 352-frame packets @@ -873,9 +896,6 @@ static void *player_thread_func(void *arg) { debug(1,"Delay error when checking running latency."); current_delay=0; } -// } else { -// current_delay = 0; -// } if (current_delay