X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=resampling_queue.cpp;h=06dc6fbf417bb1a13aae39f4cbf527e7740e5b6f;hb=ffd68fbfb90242069af957f2a28908f0559f8348;hp=d7e811d87c4bd4bb7b1325c2e262a5fedbf0cc71;hpb=b4aed34151be7c3b76b7f92e746e1b6a233ec4e9;p=nageru diff --git a/resampling_queue.cpp b/resampling_queue.cpp index d7e811d..06dc6fb 100644 --- a/resampling_queue.cpp +++ b/resampling_queue.cpp @@ -49,6 +49,8 @@ void ResamplingQueue::add_input_samples(steady_clock::time_point ts, const float return; } + assert(duration(ts.time_since_epoch()).count() >= 0.0); + bool good_sample = (rate_adjustment_policy == ADJUST_RATE); if (good_sample && a1.good_sample) { a0 = a1; @@ -77,12 +79,23 @@ 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 // good point. Note that we could be extrapolating backward or // forward, depending on the timing of the calls. const InputPoint &base_point = a1.good_sample ? a1 : a0; + assert(duration(base_point.ts.time_since_epoch()).count() >= 0.0); + + // NOTE: Due to extrapolation, input_samples_received can + // actually go negative here the few first calls (ie., we asked + // about a timestamp where we hadn't actually started producing + // samples yet), but that is harmless. const double input_samples_received = base_point.input_samples_received + current_estimated_freq_in * duration(ts - base_point.ts).count(); @@ -105,9 +118,7 @@ bool ResamplingQueue::get_output_samples(steady_clock::time_point ts, float *sam err += delay_samples_to_add; } else if (err > 0.0) { int delay_samples_to_remove = min(lrintf(err), buffer.size() / num_channels); - for (ssize_t i = 0; i < delay_samples_to_remove * num_channels; ++i) { - buffer.pop_front(); - } + buffer.erase(buffer.begin(), buffer.begin() + delay_samples_to_remove * num_channels); total_consumed_samples += delay_samples_to_remove; err -= delay_samples_to_remove; } @@ -145,8 +156,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. @@ -159,6 +168,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; }