X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=resampling_queue.cpp;h=c1945d27ab2a2f304edf7292d34334e00d8416e2;hb=b2e477539ae7bb9ff11ccf97ceb08c5d4f3530cd;hp=80d12297ce4e90c74d183eae747de34ccdb98fa6;hpb=e2d886719370306464e2c67574bb6eef62a0a64e;p=nageru diff --git a/resampling_queue.cpp b/resampling_queue.cpp index 80d1229..c1945d2 100644 --- a/resampling_queue.cpp +++ b/resampling_queue.cpp @@ -1,5 +1,6 @@ -// Parts of the code is adapted from Adriaensen's project Zita-ajbridge, -// although it has been heavily reworked for this use case. Original copyright follows: +// Parts of the code is adapted from Adriaensen's project Zita-ajbridge +// (as of November 2015), although it has been heavily reworked for this use +// case. Original copyright follows: // // Copyright (C) 2012-2015 Fons Adriaensen // @@ -18,14 +19,15 @@ #include "resampling_queue.h" +#include #include #include #include #include #include -ResamplingQueue::ResamplingQueue(unsigned freq_in, unsigned freq_out, unsigned num_channels) - : freq_in(freq_in), freq_out(freq_out), num_channels(num_channels), +ResamplingQueue::ResamplingQueue(unsigned card_num, unsigned freq_in, unsigned freq_out, unsigned num_channels) + : card_num(card_num), freq_in(freq_in), freq_out(freq_out), num_channels(num_channels), ratio(double(freq_out) / double(freq_in)) { vresampler.setup(ratio, num_channels, /*hlen=*/32); @@ -38,6 +40,9 @@ ResamplingQueue::ResamplingQueue(unsigned freq_in, unsigned freq_out, unsigned n void ResamplingQueue::add_input_samples(double pts, const float *samples, ssize_t num_samples) { + if (num_samples == 0) { + return; + } if (first_input) { // Synthesize a fake length. last_input_len = double(num_samples) / freq_in; @@ -58,6 +63,13 @@ void ResamplingQueue::add_input_samples(double pts, const float *samples, ssize_ bool ResamplingQueue::get_output_samples(double pts, float *samples, ssize_t num_samples) { + assert(num_samples > 0); + if (first_input) { + // No data yet, just return zeros. + memset(samples, 0, num_samples * 2 * sizeof(float)); + return true; + } + double last_output_len; if (first_output) { // Synthesize a fake length. @@ -70,6 +82,7 @@ bool ResamplingQueue::get_output_samples(double pts, float *samples, ssize_t num // Using the time point since just before the last call to add_input_samples() as a base, // estimate actual delay based on activity since then, measured in number of input samples: double actual_delay = 0.0; + assert(last_input_len != 0); actual_delay += (k_a1 - k_a0) * last_output_len / last_input_len; // Inserted samples since k_a0, rescaled for the different time periods. actual_delay += k_a0 - total_consumed_samples; // Samples inserted before k_a0 but not consumed yet. actual_delay += vresampler.inpdist(); // Delay in the resampler itself. @@ -83,8 +96,8 @@ bool ResamplingQueue::get_output_samples(double pts, float *samples, ssize_t num } total_consumed_samples -= delay_samples_to_add; // Equivalent to increasing k_a0 and k_a1. err += delay_samples_to_add; - first_output = false; } + first_output = false; // Compute loop filter coefficients for the two filters. We need to compute them // every time, since they depend on the number of samples the user asked for. @@ -107,6 +120,7 @@ bool ResamplingQueue::get_output_samples(double pts, float *samples, ssize_t num double rcorr = 1.0 - z2 - z3; if (rcorr > 1.05) rcorr = 1.05; if (rcorr < 0.95) rcorr = 0.95; + assert(!isnan(rcorr)); vresampler.set_rratio(rcorr); // Finally actually resample, consuming exactly output samples. @@ -116,9 +130,9 @@ bool ResamplingQueue::get_output_samples(double pts, float *samples, ssize_t num if (buffer.empty()) { // This should never happen unless delay is set way too low, // or we're dropping a lot of data. - fprintf(stderr, "PANIC: Out of input samples to resample, still need %d output samples!\n", - int(vresampler.out_count)); - memset(vresampler.out_data, 0, vresampler.out_count * sizeof(float)); + 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 * 2 * sizeof(float)); return false; } @@ -134,7 +148,8 @@ bool ResamplingQueue::get_output_samples(double pts, float *samples, ssize_t num vresampler.inp_count = num_input_samples; vresampler.inp_data = inbuf; - vresampler.process(); + int err = vresampler.process(); + assert(err == 0); size_t consumed_samples = num_input_samples - vresampler.inp_count; total_consumed_samples += consumed_samples;