]> git.sesse.net Git - nageru/blobdiff - nageru/audio_mixer.cpp
Make it possible to adjust the delay without resetting the resampler.
[nageru] / nageru / audio_mixer.cpp
index 4d7632fad80a8e643840991284728ea61bb353cc..07d10dad3650a9ca037263d661b4d5deca4adbf2 100644 (file)
@@ -228,6 +228,14 @@ void deinterleave_samples(const vector<float> &in, vector<float> *out_l, vector<
        }
 }
 
+double get_delay_seconds(double extra_delay_ms)
+{
+       // Make sure we never get negative delay. Even 1 ms is probably way less than we
+       // could ever hope to actually have; this is just a failsafe.
+       double delay_ms = max(global_flags.audio_queue_length_ms + extra_delay_ms, 1.0);
+       return delay_ms * 0.001;
+}
+
 }  // namespace
 
 AudioMixer::AudioMixer(unsigned num_capture_cards, unsigned num_ffmpeg_inputs)
@@ -301,13 +309,9 @@ void AudioMixer::reset_resampler_mutex_held(DeviceSpec device_spec)
        if (device->interesting_channels.empty()) {
                device->resampling_queue.reset();
        } else {
-               // Make sure we never get negative delay. Even 1 ms is probably way less than we
-               // could ever hope to actually have; this is just a failsafe.
-               double delay_ms = max(global_flags.audio_queue_length_ms + device->extra_delay_ms, 1.0);
-
                device->resampling_queue.reset(new ResamplingQueue(
                        device_spec, device->capture_frequency, OUTPUT_FREQUENCY, device->interesting_channels.size(),
-                       delay_ms * 0.001));
+                       get_delay_seconds(device->extra_delay_ms)));
        }
 }
 
@@ -1237,37 +1241,49 @@ void AudioMixer::set_input_mapping_lock_held(const InputMapping &new_input_mappi
        for (unsigned card_index = 0; card_index < MAX_VIDEO_CARDS; ++card_index) {
                const DeviceSpec device_spec{InputSourceType::CAPTURE_CARD, card_index};
                AudioDevice *device = find_audio_device(device_spec);
-               if (device->interesting_channels != interesting_channels[device_spec] ||
-                   device->extra_delay_ms != new_extra_delay_ms[device_spec]) {
+               double extra_delay_ms = new_extra_delay_ms[device_spec];
+               if (device->interesting_channels != interesting_channels[device_spec]) {
                        device->interesting_channels = interesting_channels[device_spec];
-                       device->extra_delay_ms = new_extra_delay_ms[device_spec];
+                       device->extra_delay_ms = extra_delay_ms;
                        reset_resampler_mutex_held(device_spec);
+               } else if (device->extra_delay_ms != extra_delay_ms &&
+                          device->resampling_queue != nullptr) {
+                       device->extra_delay_ms = extra_delay_ms;
+                       device->resampling_queue->change_expected_delay(get_delay_seconds(extra_delay_ms));
                }
        }
        for (unsigned card_index = 0; card_index < MAX_ALSA_CARDS; ++card_index) {
                const DeviceSpec device_spec{InputSourceType::ALSA_INPUT, card_index};
                AudioDevice *device = find_audio_device(device_spec);
+               double extra_delay_ms = new_extra_delay_ms[device_spec];
                if (interesting_channels[device_spec].empty()) {
                        alsa_pool.release_device(card_index);
                } else {
                        alsa_pool.hold_device(card_index);
                }
-               if (device->interesting_channels != interesting_channels[device_spec] ||
-                   device->extra_delay_ms != new_extra_delay_ms[device_spec]) {
+               if (device->interesting_channels != interesting_channels[device_spec]) {
                        device->interesting_channels = interesting_channels[device_spec];
-                       device->extra_delay_ms = new_extra_delay_ms[device_spec];
+                       device->extra_delay_ms = extra_delay_ms;
                        alsa_pool.reset_device(device_spec.index);
                        reset_resampler_mutex_held(device_spec);
+               } else if (device->extra_delay_ms != extra_delay_ms &&
+                          device->resampling_queue != nullptr) {
+                       device->extra_delay_ms = extra_delay_ms;
+                       device->resampling_queue->change_expected_delay(get_delay_seconds(extra_delay_ms));
                }
        }
        for (unsigned card_index = 0; card_index < num_ffmpeg_inputs; ++card_index) {
                const DeviceSpec device_spec{InputSourceType::FFMPEG_VIDEO_INPUT, card_index};
                AudioDevice *device = find_audio_device(device_spec);
-               if (device->interesting_channels != interesting_channels[device_spec] ||
-                   device->extra_delay_ms != new_extra_delay_ms[device_spec]) {
+               double extra_delay_ms = new_extra_delay_ms[device_spec];
+               if (device->interesting_channels != interesting_channels[device_spec]) {
                        device->interesting_channels = interesting_channels[device_spec];
-                       device->extra_delay_ms = new_extra_delay_ms[device_spec];
+                       device->extra_delay_ms = extra_delay_ms;
                        reset_resampler_mutex_held(device_spec);
+               } else if (device->extra_delay_ms != extra_delay_ms &&
+                          device->resampling_queue != nullptr) {
+                       device->extra_delay_ms = extra_delay_ms;
+                       device->resampling_queue->change_expected_delay(get_delay_seconds(extra_delay_ms));
                }
        }