From c887aafdf00c17bec01444f3899bf7b8393cddc7 Mon Sep 17 00:00:00 2001 From: Mke Brady Date: Thu, 21 May 2015 09:09:37 +0100 Subject: [PATCH] Very broken player mod. --- player.c | 202 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 109 insertions(+), 93 deletions(-) diff --git a/player.c b/player.c index 8c6d7797..72622f79 100644 --- a/player.c +++ b/player.c @@ -849,117 +849,133 @@ static void *player_thread_func(void *arg) { } else { td_in_frames = -((-td*44100)>>32); } + + // This is the timing error for the next audio frame in the DAC, if applicable + int64_t sync_error =0; + + int amount_to_stuff = 0; + + // check sequencing + if (last_seqno_read==-1) + last_seqno_read=inframe->sequence_number; + else { + last_seqno_read = (SUCCESSOR(last_seqno_read) & 0xffff); + if (inframe->sequence_number!=last_seqno_read) { + debug(1,"Player: packets out of sequence: expected: %d, got: %d, sync error: %d frames.",last_seqno_read,inframe->sequence_number,sync_error); + last_seqno_read=inframe->sequence_number; // reset warning... + } + } + if (config.output->delay) { current_delay = config.output->delay(); if (current_delay==-1) { debug(1,"Delay error when checking running latency."); current_delay=0; } - } else { - current_delay = 0; - } - if (current_delaymaximum_buffer_occupancy) - maximum_buffer_occupancy=bo; - - // this is the actual delay, including the latency we actually want, which will fluctuate a good bit about a potentially rising or falling trend. - int64_t delay = td_in_frames+rt-(nt-current_delay); - - // This is the timing error for the next audio frame in the DAC. - int64_t sync_error = delay-config.latency; - - // before we finally commit to this frame, check its sequencing and timing - // check sequencing - if (last_seqno_read==-1) - last_seqno_read=inframe->sequence_number; - else { - last_seqno_read = (SUCCESSOR(last_seqno_read) & 0xffff); - if (inframe->sequence_number!=last_seqno_read) - debug(1,"Player: packets out of sequence: expected: %d, got: %d, sync error: %d frames.",last_seqno_read,inframe->sequence_number,sync_error); - last_seqno_read=inframe->sequence_number; // reset warning... - } - - int amount_to_stuff = 0; - // require a certain error before bothering to fix it... - if (sync_error>config.tolerance) { - amount_to_stuff = -1; - } - if (sync_error<-config.tolerance) { - amount_to_stuff = 1; - } - - // only allow stuffing if there is enough time to do it -- check DAC buffer... - if (current_delay352) - amount_to_stuff=0; - } +// } else { +// current_delay = 0; +// } + if (current_delayplay(inbuf, frame_size); - } else { + uint32_t bo = seq_diff(ab_read,ab_write); + + if (bomaximum_buffer_occupancy) + maximum_buffer_occupancy=bo; + + // this is the actual delay, including the latency we actually want, which will fluctuate a good bit about a potentially rising or falling trend. + int64_t delay = td_in_frames+rt-(nt-current_delay); + + // This is the timing error for the next audio frame in the DAC. + sync_error = delay-config.latency; + + // before we finally commit to this frame, check its sequencing and timing + + // require a certain error before bothering to fix it... + if (sync_error>config.tolerance) { + amount_to_stuff = -1; + } + if (sync_error<-config.tolerance) { + amount_to_stuff = 1; + } + + // only allow stuffing if there is enough time to do it -- check DAC buffer... + if (current_delay352) + amount_to_stuff=0; + } + + if ((amount_to_stuff==0) && (fix_volume==0x10000)) { + // if no stuffing needed and no volume adjustment, then + // don't send to stuff_buffer_* and don't copy to outbuf; just send directly to the output device... + config.output->play(inbuf, frame_size); + } else { #ifdef HAVE_LIBSOXR - switch (config.packet_stuffing) { - case ST_basic: + switch (config.packet_stuffing) { + case ST_basic: // if (amount_to_stuff) debug(1,"Basic stuff..."); - play_samples = stuff_buffer_basic(inbuf, outbuf,amount_to_stuff); - break; - case ST_soxr: + play_samples = stuff_buffer_basic(inbuf, outbuf,amount_to_stuff); + break; + case ST_soxr: // if (amount_to_stuff) debug(1,"Soxr stuff..."); - play_samples = stuff_buffer_soxr(inbuf, outbuf,amount_to_stuff); - break; - } + play_samples = stuff_buffer_soxr(inbuf, outbuf,amount_to_stuff); + break; + } #else // if (amount_to_stuff) debug(1,"Standard stuff..."); - play_samples = stuff_buffer_basic(inbuf, outbuf,amount_to_stuff); + play_samples = stuff_buffer_basic(inbuf, outbuf,amount_to_stuff); #endif - /* - { - int co; - int is_silent=1; - short *p = outbuf; - for (co=0;coplay(outbuf, play_samples); + /* + { + int co; + int is_silent=1; + short *p = outbuf; + for (co=0;cotimestamp!=0) && (!please_stop) && (config.resyncthreshold!=0) && (abs(sync_error)>config.resyncthreshold)) { - sync_error_out_of_bounds++; - // debug(1,"Sync error out of bounds: Error: %lld; previous error: %lld; DAC: %lld; timestamp: %llx, time now %llx",sync_error,previous_sync_error,current_delay,inframe->timestamp,local_time_now); - if (sync_error_out_of_bounds>3) { - debug(1,"Lost sync with source for %d consecutive packets -- flushing and resyncing. Error: %lld.",sync_error_out_of_bounds,sync_error); + if (is_silent) + debug(1,"Silence!"); + } + */ + + config.output->play(outbuf, play_samples); + } + + // check for loss of sync + // timestamp of zero means an inserted silent frame in place of a missing frame + if ((inframe->timestamp!=0) && (!please_stop) && (config.resyncthreshold!=0) && (abs(sync_error)>config.resyncthreshold)) { + sync_error_out_of_bounds++; + // debug(1,"Sync error out of bounds: Error: %lld; previous error: %lld; DAC: %lld; timestamp: %llx, time now %llx",sync_error,previous_sync_error,current_delay,inframe->timestamp,local_time_now); + if (sync_error_out_of_bounds>3) { + debug(1,"Lost sync with source for %d consecutive packets -- flushing and resyncing. Error: %lld.",sync_error_out_of_bounds,sync_error); + sync_error_out_of_bounds = 0; + player_flush(nt); + } + } else { sync_error_out_of_bounds = 0; - player_flush(nt); - } + } } else { - sync_error_out_of_bounds = 0; + // if there is no delay procedure, there can be no synchronising + if (fix_volume==0x10000) + config.output->play(inbuf, frame_size); + else { + play_samples = stuff_buffer_basic(inbuf, outbuf,0); + config.output->play(outbuf, frame_size); + } } // mark the frame as finished