X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=audio_mixer.cpp;h=c7676b5910f06965c95582fb26ae998a53d64e4b;hb=1caeebce7e0d2b18ae7fb588aaccde7d19117e00;hp=8485d0a6343fec00a97fe2417dd46d7aac0bb248;hpb=b590a9a091974607517a9f872e28cbfa65014e2a;p=nageru diff --git a/audio_mixer.cpp b/audio_mixer.cpp index 8485d0a..c7676b5 100644 --- a/audio_mixer.cpp +++ b/audio_mixer.cpp @@ -13,6 +13,7 @@ #include "db.h" #include "flags.h" #include "mixer.h" +#include "state.pb.h" #include "timebase.h" using namespace bmusb; @@ -162,6 +163,8 @@ AudioMixer::AudioMixer(unsigned num_cards) limiter(OUTPUT_FREQUENCY), correlation(OUTPUT_FREQUENCY) { + global_audio_mixer = this; + for (unsigned bus_index = 0; bus_index < MAX_BUSES; ++bus_index) { locut[bus_index].init(FILTER_HPF, 2); locut_enabled[bus_index] = global_flags.locut_enabled; @@ -178,20 +181,29 @@ AudioMixer::AudioMixer(unsigned num_cards) } set_limiter_enabled(global_flags.limiter_enabled); set_final_makeup_gain_auto(global_flags.final_makeup_gain_auto); - - // Generate a very simple, default input mapping. - InputMapping::Bus input; - input.name = "Main"; - input.device.type = InputSourceType::CAPTURE_CARD; - input.device.index = 0; - input.source_channel[0] = 0; - input.source_channel[1] = 1; + alsa_pool.init(); InputMapping new_input_mapping; - new_input_mapping.buses.push_back(input); - set_input_mapping(new_input_mapping); + if (!global_flags.input_mapping_filename.empty()) { + if (!load_input_mapping_from_file(get_devices(), + global_flags.input_mapping_filename, + &new_input_mapping)) { + fprintf(stderr, "Failed to load input mapping from '%s', exiting.\n", + global_flags.input_mapping_filename.c_str()); + exit(1); + } + } else { + // Generate a very simple, default input mapping. + InputMapping::Bus input; + input.name = "Main"; + input.device.type = InputSourceType::CAPTURE_CARD; + input.device.index = 0; + input.source_channel[0] = 0; + input.source_channel[1] = 1; - alsa_pool.init(); + new_input_mapping.buses.push_back(input); + } + set_input_mapping(new_input_mapping); r128.init(2, OUTPUT_FREQUENCY); r128.integr_start(); @@ -294,6 +306,22 @@ bool AudioMixer::add_silence(DeviceSpec device_spec, unsigned samples_per_frame, return true; } +bool AudioMixer::silence_card(DeviceSpec device_spec, bool silence) +{ + AudioDevice *device = find_audio_device(device_spec); + + unique_lock lock(audio_mutex, defer_lock); + if (!lock.try_lock_for(chrono::milliseconds(10))) { + return false; + } + + if (device->silenced && !silence) { + reset_resampler_mutex_held(device_spec); + } + device->silenced = silence; + return true; +} + AudioMixer::AudioDevice *AudioMixer::find_audio_device(DeviceSpec device) { switch (device.type) { @@ -383,11 +411,15 @@ vector AudioMixer::get_output(double pts, unsigned num_samples, Resamplin for (const DeviceSpec &device_spec : get_active_devices()) { AudioDevice *device = find_audio_device(device_spec); samples_card[device_spec].resize(num_samples * device->interesting_channels.size()); - device->resampling_queue->get_output_samples( - pts, - &samples_card[device_spec][0], - num_samples, - rate_adjustment_policy); + if (device->silenced) { + memset(&samples_card[device_spec][0], 0, samples_card[device_spec].size() * sizeof(float)); + } else { + device->resampling_queue->get_output_samples( + pts, + &samples_card[device_spec][0], + num_samples, + rate_adjustment_policy); + } } vector samples_out, left, right; @@ -721,8 +753,8 @@ map AudioMixer::get_devices() const DeviceSpec spec{ InputSourceType::CAPTURE_CARD, card_index }; const AudioDevice *device = &video_cards[card_index]; DeviceInfo info; - info.name = device->name; - info.num_channels = 8; // FIXME: This is wrong for fake cards. + info.display_name = device->display_name; + info.num_channels = 8; devices.insert(make_pair(spec, info)); } vector available_alsa_devices = alsa_pool.get_devices(); @@ -730,19 +762,40 @@ map AudioMixer::get_devices() const DeviceSpec spec{ InputSourceType::ALSA_INPUT, card_index }; const ALSAPool::Device &device = available_alsa_devices[card_index]; DeviceInfo info; - info.name = device.name + " (" + device.info + ")"; + info.display_name = device.display_name(); info.num_channels = device.num_channels; + info.alsa_name = device.name; + info.alsa_info = device.info; + info.alsa_address = device.address; devices.insert(make_pair(spec, info)); } return devices; } -void AudioMixer::set_name(DeviceSpec device_spec, const string &name) +void AudioMixer::set_display_name(DeviceSpec device_spec, const string &name) { AudioDevice *device = find_audio_device(device_spec); lock_guard lock(audio_mutex); - device->name = name; + device->display_name = name; +} + +void AudioMixer::serialize_device(DeviceSpec device_spec, DeviceSpecProto *device_spec_proto) +{ + lock_guard lock(audio_mutex); + switch (device_spec.type) { + case InputSourceType::SILENCE: + device_spec_proto->set_type(DeviceSpecProto::SILENCE); + break; + case InputSourceType::CAPTURE_CARD: + device_spec_proto->set_type(DeviceSpecProto::CAPTURE_CARD); + device_spec_proto->set_index(device_spec.index); + device_spec_proto->set_display_name(video_cards[device_spec.index].display_name); + break; + case InputSourceType::ALSA_INPUT: + alsa_pool.serialize_device(device_spec.index, device_spec_proto); + break; + } } void AudioMixer::set_input_mapping(const InputMapping &new_input_mapping)