X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=resampling_queue.h;h=f0e2499cbf3300e9b4340430b85bf33f25862006;hb=refs%2Fheads%2Fmjpeg;hp=c085eceb6755838ea12001cf6aa6d39a6f21e1d5;hpb=e2d886719370306464e2c67574bb6eef62a0a64e;p=nageru
diff --git a/resampling_queue.h b/resampling_queue.h
index c085ece..f0e2499 100644
--- a/resampling_queue.h
+++ b/resampling_queue.h
@@ -4,8 +4,8 @@
// Takes in samples from an input source, possibly with jitter, and outputs a fixed number
// of samples every iteration. Used to a) change sample rates if needed, and b) deal with
// input sources that don't have audio locked to video. For every input video
-// frame, you call add_input_samples() with the pts (measured in seconds) of the video frame,
-// taken to be the start point of the frame's audio. When you want to _output_ a finished
+// frame, you call add_input_samples() with the received time point of the video frame,
+// taken to be the _end_ point of the frame's audio. When you want to _output_ a finished
// frame with audio, you get_output_samples() with the number of samples you want, and will
// get exactly that number of samples back. If the input and output clocks are not in sync,
// the audio will be stretched for you. (If they are _very_ out of sync, this will come through
@@ -38,50 +38,77 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
-#include
-#include
#include
#include
+#include
#include
#include
+#include "defs.h"
+#include "input_mapping.h"
+
class ResamplingQueue {
public:
- ResamplingQueue(unsigned freq_in, unsigned freq_out, unsigned num_channels = 2);
+ // device_spec is for debugging outputs only.
+ ResamplingQueue(DeviceSpec device_spec, unsigned freq_in, unsigned freq_out, unsigned num_channels, double expected_delay_seconds);
+
+ // If policy is DO_NOT_ADJUST_RATE, the resampling rate will not be changed.
+ // This is primarily useful if you have an extraordinary situation, such as
+ // dropped frames.
+ enum RateAdjustmentPolicy {
+ DO_NOT_ADJUST_RATE,
+ ADJUST_RATE
+ };
- // Note: pts is always in seconds.
- void add_input_samples(double pts, const float *samples, ssize_t num_samples);
- bool get_output_samples(double pts, float *samples, ssize_t num_samples); // Returns false if underrun.
+ void add_input_samples(std::chrono::steady_clock::time_point ts, const float *samples, ssize_t num_samples, RateAdjustmentPolicy rate_adjustment_policy);
+ // Returns false if underrun.
+ bool get_output_samples(std::chrono::steady_clock::time_point ts, float *samples, ssize_t num_samples, RateAdjustmentPolicy rate_adjustment_policy);
private:
void init_loop_filter(double bandwidth_hz);
VResampler vresampler;
+ DeviceSpec device_spec;
unsigned freq_in, freq_out, num_channels;
- bool first_input = true, first_output = true;
- double last_input_pts; // Start of last input block, in seconds.
- double last_output_pts;
+ bool first_output = true;
- ssize_t k_a0 = 0; // Total amount of samples inserted _before_ the last call to add_input_samples().
- ssize_t k_a1 = 0; // Total amount of samples inserted _after_ the last call to add_input_samples().
+ struct InputPoint {
+ // Equivalent to t_a0 or t_a1 in the paper.
+ std::chrono::steady_clock::time_point ts;
- ssize_t total_consumed_samples = 0;
+ // Number of samples that have been written to the queue (in total)
+ // at this time point. Equivalent to k_a0 or k_a1 in the paper.
+ size_t input_samples_received = 0;
+
+ // Set to false if we should not use the timestamp from this sample
+ // (e.g. if it is from a dropped frame and thus bad). In particular,
+ // we will not use it for updateing current_estimated_freq_in.
+ bool good_sample = false;
+ };
+ InputPoint a0, a1;
- // Duration of last input block, in seconds.
- double last_input_len;
+ // The current rate at which we seem to get input samples, in Hz.
+ // For an ideal input, identical to freq_in.
+ double current_estimated_freq_in;
+
+ ssize_t total_consumed_samples = 0;
// Filter state for the loop filter.
double z1 = 0.0, z2 = 0.0, z3 = 0.0;
// Ratio between the two frequencies.
- double ratio;
+ const double ratio;
+
+ // Current correction ratio. ratio * rcorr gives the true ratio,
+ // so values above 1.0 means to pitch down (consume input samples slower).
+ double rcorr = 1.0;
// How much delay we are expected to have, in input samples.
// If actual delay drifts too much away from this, we will start
// changing the resampling ratio to compensate.
- double expected_delay = 4800.0;
+ const double expected_delay;
// Input samples not yet fed into the resampler.
// TODO: Use a circular buffer instead, for efficiency.