X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=resampling_queue.cpp;h=24811ebe5bbab43fa7cd68471c4ca69f82e673e8;hb=e284d1c7a2e18ee7e4aea082c4a57a3504a0f5e8;hp=188bf7d2d57ccdb98f249f86c59e0360e65b470b;hpb=f0dacf505189f0cadcd89a2b632000fd9d012bd2;p=nageru diff --git a/resampling_queue.cpp b/resampling_queue.cpp index 188bf7d..24811eb 100644 --- a/resampling_queue.cpp +++ b/resampling_queue.cpp @@ -77,6 +77,11 @@ bool ResamplingQueue::get_output_samples(steady_clock::time_point ts, float *sam return true; } + // This can happen when we get dropped frames on the master card. + if (duration(ts.time_since_epoch()).count() <= 0.0) { + rate_adjustment_policy = DO_NOT_ADJUST_RATE; + } + if (rate_adjustment_policy == ADJUST_RATE && (a0.good_sample || a1.good_sample)) { // Estimate the current number of input samples produced at // this instant in time, by extrapolating from the last known @@ -93,15 +98,22 @@ bool ResamplingQueue::get_output_samples(steady_clock::time_point ts, float *sam double actual_delay = input_samples_received - input_samples_consumed; actual_delay += vresampler.inpdist(); // Delay in the resampler itself. double err = actual_delay - expected_delay; - if (first_output && err < 0.0) { + if (first_output) { // Before the very first block, insert artificial delay based on our initial estimate, // so that we don't need a long period to stabilize at the beginning. - int delay_samples_to_add = lrintf(-err); - for (ssize_t i = 0; i < delay_samples_to_add * num_channels; ++i) { - buffer.push_front(0.0f); + if (err < 0.0) { + int delay_samples_to_add = lrintf(-err); + for (ssize_t i = 0; i < delay_samples_to_add * num_channels; ++i) { + buffer.push_front(0.0f); + } + total_consumed_samples -= delay_samples_to_add; // Equivalent to increasing input_samples_received on a0 and a1. + err += delay_samples_to_add; + } else if (err > 0.0) { + int delay_samples_to_remove = min(lrintf(err), buffer.size() / num_channels); + buffer.erase(buffer.begin(), buffer.begin() + delay_samples_to_remove * num_channels); + total_consumed_samples += delay_samples_to_remove; + err -= delay_samples_to_remove; } - total_consumed_samples -= delay_samples_to_add; // Equivalent to increasing input_samples_received on a0 and a1. - err += delay_samples_to_add; } first_output = false; @@ -136,8 +148,6 @@ bool ResamplingQueue::get_output_samples(steady_clock::time_point ts, float *sam if (rcorr < 0.95) rcorr = 0.95; assert(!isnan(rcorr)); vresampler.set_rratio(rcorr); - } else { - assert(rate_adjustment_policy == DO_NOT_ADJUST_RATE); } // Finally actually resample, producing exactly output samples. @@ -150,6 +160,10 @@ bool ResamplingQueue::get_output_samples(steady_clock::time_point ts, float *sam fprintf(stderr, "Card %u: PANIC: Out of input samples to resample, still need %d output samples! (correction factor is %f)\n", card_num, int(vresampler.out_count), rcorr); memset(vresampler.out_data, 0, vresampler.out_count * num_channels * sizeof(float)); + + // Reset the loop filter. + z1 = z2 = z3 = 0.0; + return false; }