diff --git a/player.c b/player.c index e61ecfd1..50c40e09 100644 --- a/player.c +++ b/player.c @@ -162,6 +162,13 @@ static inline seq_t SUCCESSOR(seq_t x) { return p; } +static inline seq_t PREDECESSOR(seq_t x) { + uint32_t p = (x & 0xffff)+0x10000; + p-=1; + p = p & 0xffff; + return p; +} + static inline uint32_t ORDINATE(seq_t x) { uint32_t p = x & 0xffff; uint32_t q = ab_read & 0x0ffff; @@ -182,6 +189,13 @@ static inline int seq_order(seq_t a, seq_t b) { return d > 0; } +static inline seq_t seq_sum(seq_t a, seq_t b) { + uint32_t p = a & 0xffff; + uint32_t q = b & 0x0ffff; + uint32_t r = (a+b) & 0xffff; + return r; +} + static void alac_decode(short *dest, uint8_t *buf, int len) { unsigned char packet[MAX_PACKET]; unsigned char packetp[MAX_PACKET]; @@ -276,7 +290,7 @@ void player_put_packet(seq_t seqno,uint32_t timestamp, uint8_t *data, int len) { abuf = audio_buffer + BUFIDX(seqno); ab_write = SUCCESSOR(seqno); } else if (seq_order(ab_write, seqno)) { // newer than expected - rtp_request_resend(ab_write+1, seqno-1); + rtp_request_resend(SUCCESSOR(ab_write), PREDECESSOR(seqno)); resend_requests++; abuf = audio_buffer + BUFIDX(seqno); ab_write = SUCCESSOR(seqno); @@ -335,7 +349,6 @@ static abuf_t *buffer_get_frame(void) { int16_t buf_fill; uint64_t local_time_now; // struct timespec tn; - seq_t read, next; abuf_t *abuf = 0; int i; abuf_t *curframe; @@ -384,7 +397,7 @@ static abuf_t *buffer_get_frame(void) { if ((flush_rtp_timestamp) && (flush_rtp_timestamp>=curframe->timestamp)) { // debug(1,"Dropping flushed packet %d",curframe->sequence_number); curframe->ready=0; - ab_read++; + ab_read==SUCCESSOR(ab_read); } else if (ab_buffering) { // if we are getting packets but not yet forwarding them to the player if (first_packet_timestamp==0) { // if this is the very first packet // debug(1,"First frame seen, time %u, with %d frames...",curframe->timestamp,seq_diff(ab_read, ab_write)); @@ -495,15 +508,15 @@ static abuf_t *buffer_get_frame(void) { return 0; } - read = ab_read; - ab_read++; + seq_t read = ab_read; + ab_read=SUCCESSOR(ab_read); // check if t+16, t+32, t+64, t+128, ... (buffer_start_fill / 2) // packets have arrived... last-chance resend if (!ab_buffering) { for (i = 16; i < (seq_diff(ab_read,ab_write) / 2); i = (i * 2)) { - next = ab_read + i; + seq_t next = seq_sum(ab_read,i); abuf = audio_buffer + BUFIDX(next); if (!abuf->ready) { rtp_request_resend(next, next); @@ -691,6 +704,7 @@ static void *player_thread_func(void *arg) { if (inframe) { inbuf = inframe->data; if (inbuf) { + play_number++; // if it's a supplied silent frame, let us know... if (inframe->timestamp==0) { // debug(1,"Player has a supplied silent frame."); @@ -815,8 +829,6 @@ static void *player_thread_func(void *arg) { sync_error_out_of_bounds = 0; } - play_number++; - // debug(1,"Sync error %lld frames. Amount to stuff %d." ,sync_error,amount_to_stuff); // new stats calculation. We want a running average of sync error, drift, adjustment, number of additions+subtractions @@ -858,25 +870,24 @@ static void *player_thread_func(void *arg) { // check sequencing if (last_seqno_read==-1) - last_seqno_read=inframe->sequence_number; - else { - last_seqno_read = (last_seqno_read+1)&0xffff; - if (inframe->sequence_number!=last_seqno_read) - debug(1,"Player: packets out of sequence: expected: %d, got %d.",last_seqno_read,inframe->sequence_number); - last_seqno_read=inframe->sequence_number; // reset warning... - } - - if (play_number%print_interval==0) { - // we can now calculate running averages for sync error (frames), corrections (ppm), insertions plus deletions (ppm), drift (ppm) - double moving_average_sync_error = (1.0*tsum_of_sync_errors)/number_of_statistics; - double moving_average_correction = (1.0*tsum_of_corrections)/number_of_statistics; - double moving_average_insertions_plus_deletions = (1.0*tsum_of_insertions_and_deletions)/number_of_statistics; - double moving_average_drift = (1.0*tsum_of_drifts)/number_of_statistics; - // if ((play_number/print_interval)%20==0) - debug(1,"Sync error: %.1f (frames); net correction: %.1f (ppm); corrections: %.1f (ppm); missing packets %llu; late packets %llu; too late packets %llu; resend requests %llu; min DAC queue size %lli.", moving_average_sync_error, moving_average_correction*1000000/352, moving_average_insertions_plus_deletions*1000000/352,missing_packets,late_packets,too_late_packets,resend_requests,minimum_dac_queue_size); - minimum_dac_queue_size=1000000; // hack reset + last_seqno_read=inframe->sequence_number; + else { + last_seqno_read = (last_seqno_read+1)&0xffff; + if (inframe->sequence_number!=last_seqno_read) + debug(1,"Player: packets out of sequence: expected: %d, got %d.",last_seqno_read,inframe->sequence_number); + last_seqno_read=inframe->sequence_number; // reset warning... } } + if (play_number%print_interval==0) { + // we can now calculate running averages for sync error (frames), corrections (ppm), insertions plus deletions (ppm), drift (ppm) + double moving_average_sync_error = (1.0*tsum_of_sync_errors)/number_of_statistics; + double moving_average_correction = (1.0*tsum_of_corrections)/number_of_statistics; + double moving_average_insertions_plus_deletions = (1.0*tsum_of_insertions_and_deletions)/number_of_statistics; + double moving_average_drift = (1.0*tsum_of_drifts)/number_of_statistics; + // if ((play_number/print_interval)%20==0) + debug(1,"Sync error: %.1f (frames); net correction: %.1f (ppm); corrections: %.1f (ppm); missing packets %llu; late packets %llu; too late packets %llu; resend requests %llu; min DAC queue size %lli.", moving_average_sync_error, moving_average_correction*1000000/352, moving_average_insertions_plus_deletions*1000000/352,missing_packets,late_packets,too_late_packets,resend_requests,minimum_dac_queue_size); + minimum_dac_queue_size=1000000; // hack reset + } } } }