]> git.sesse.net Git - nageru/blobdiff - nageru/audio_mixer.cpp
Support delaying audio sources selectively.
[nageru] / nageru / audio_mixer.cpp
index 360689b83406b04e6737cb6b7815d4092aca0a90..a095c177d6265467922f2bc58c4033c5da9cd71e 100644 (file)
@@ -300,9 +300,13 @@ 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(),
-                       global_flags.audio_queue_length_ms * 0.001));
+                       delay_ms * 0.001));
        }
 }
 
@@ -1213,11 +1217,14 @@ void AudioMixer::set_input_mapping_lock_held(const InputMapping &new_input_mappi
        }
 
        // Reset resamplers for all cards that don't have the exact same state as before.
+       map<DeviceSpec, double> new_extra_delay_ms = new_input_mapping.extra_delay_ms;  // Convenience so we can use [].
        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]) {
+               if (device->interesting_channels != interesting_channels[device_spec] ||
+                   device->extra_delay_ms != new_extra_delay_ms[device_spec]) {
                        device->interesting_channels = interesting_channels[device_spec];
+                       device->extra_delay_ms = new_extra_delay_ms[device_spec];
                        reset_resampler_mutex_held(device_spec);
                }
        }
@@ -1229,8 +1236,10 @@ void AudioMixer::set_input_mapping_lock_held(const InputMapping &new_input_mappi
                } else {
                        alsa_pool.hold_device(card_index);
                }
-               if (device->interesting_channels != interesting_channels[device_spec]) {
+               if (device->interesting_channels != interesting_channels[device_spec] ||
+                   device->extra_delay_ms != new_extra_delay_ms[device_spec]) {
                        device->interesting_channels = interesting_channels[device_spec];
+                       device->extra_delay_ms = new_extra_delay_ms[device_spec];
                        alsa_pool.reset_device(device_spec.index);
                        reset_resampler_mutex_held(device_spec);
                }
@@ -1238,8 +1247,10 @@ void AudioMixer::set_input_mapping_lock_held(const InputMapping &new_input_mappi
        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]) {
+               if (device->interesting_channels != interesting_channels[device_spec] ||
+                   device->extra_delay_ms != new_extra_delay_ms[device_spec]) {
                        device->interesting_channels = interesting_channels[device_spec];
+                       device->extra_delay_ms = new_extra_delay_ms[device_spec];
                        reset_resampler_mutex_held(device_spec);
                }
        }