} else {
// TODO: ResamplingQueue should probably take the full device spec.
// (It's only used for console output, though.)
- device->resampling_queue.reset(new ResamplingQueue(device_spec.index, device->capture_frequency, OUTPUT_FREQUENCY, device->interesting_channels.size()));
+ device->resampling_queue.reset(new ResamplingQueue(
+ device_spec.index, device->capture_frequency, OUTPUT_FREQUENCY, device->interesting_channels.size(),
+ global_flags.audio_queue_length_ms * 0.001));
}
device->next_local_pts = 0;
}
OPTION_ENABLE_MAKEUP_GAIN_AUTO,
OPTION_DISABLE_ALSA_OUTPUT,
OPTION_NO_FLUSH_PBOS,
- OPTION_PRINT_VIDEO_LATENCY
+ OPTION_PRINT_VIDEO_LATENCY,
+ OPTION_AUDIO_QUEUE_LENGTH_MS
};
void usage()
fprintf(stderr, " (will give display corruption, but makes it\n");
fprintf(stderr, " possible to run with apitrace in real time)\n");
fprintf(stderr, " --print-video-latency print out measurements of video latency on stdout\n");
+ fprintf(stderr, " --audio-queue-length-ms length of audio resampling queue (default 100.0)\n");
}
void parse_flags(int argc, char * const argv[])
{ "disable-alsa-output", no_argument, 0, OPTION_DISABLE_ALSA_OUTPUT },
{ "no-flush-pbos", no_argument, 0, OPTION_NO_FLUSH_PBOS },
{ "print-video-latency", no_argument, 0, OPTION_PRINT_VIDEO_LATENCY },
+ { "audio-queue-length-ms", required_argument, 0, OPTION_AUDIO_QUEUE_LENGTH_MS },
{ 0, 0, 0, 0 }
};
vector<string> theme_dirs;
case OPTION_PRINT_VIDEO_LATENCY:
global_flags.print_video_latency = true;
break;
+ case OPTION_AUDIO_QUEUE_LENGTH_MS:
+ global_flags.audio_queue_length_ms = atof(optarg);
+ break;
case OPTION_HELP:
usage();
exit(0);
std::string input_mapping_filename; // Empty for none.
std::string midi_mapping_filename; // Empty for none.
bool print_video_latency = false;
+ double audio_queue_length_ms = 100.0;
};
extern Flags global_flags;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- const int64_t av_delay = TIMEBASE / 10; // Corresponds to the fixed delay in resampling_queue.h. TODO: Make less hard-coded.
+ const int64_t av_delay = lrint(global_flags.audio_queue_length_ms * 0.001 * TIMEBASE); // Corresponds to the delay in ResamplingQueue.
RefCountedGLsync fence = video_encoder->end_frame(pts_int + av_delay, duration, theme_main_chain.input_frames);
// The live frame just shows the RGBA texture we just rendered.
using namespace std;
-ResamplingQueue::ResamplingQueue(unsigned card_num, unsigned freq_in, unsigned freq_out, unsigned num_channels)
+ResamplingQueue::ResamplingQueue(unsigned card_num, unsigned freq_in, unsigned freq_out, unsigned num_channels, double expected_delay_seconds)
: card_num(card_num), freq_in(freq_in), freq_out(freq_out), num_channels(num_channels),
- ratio(double(freq_out) / double(freq_in))
+ ratio(double(freq_out) / double(freq_in)), expected_delay(expected_delay_seconds * OUTPUT_FREQUENCY)
{
vresampler.setup(ratio, num_channels, /*hlen=*/32);
class ResamplingQueue {
public:
// card_num is for debugging outputs only.
- ResamplingQueue(unsigned card_num, unsigned freq_in, unsigned freq_out, unsigned num_channels = 2);
+ ResamplingQueue(unsigned card_num, 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
// 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 = OUTPUT_FREQUENCY * 0.1; // 100 ms.
+ double expected_delay;
// Input samples not yet fed into the resampler.
// TODO: Use a circular buffer instead, for efficiency.