X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=audio_mixer.h;h=85f9aedf96a77779b31e3e9a5433710076659208;hb=02f65224836f4e7ccecfb89ccd8dc38ee32f319a;hp=faa0cc52b025b23e6fe541e993e6ee1e085427a0;hpb=61116d03f84a53e96445c2b5d8686f2ea7e7c855;p=nageru diff --git a/audio_mixer.h b/audio_mixer.h index faa0cc5..85f9aed 100644 --- a/audio_mixer.h +++ b/audio_mixer.h @@ -8,18 +8,19 @@ // // All operations on AudioMixer (except destruction) are thread-safe. -#include +#include #include +#include #include +#include #include #include #include #include +#include #include -#include -#include "alsa_input.h" -#include "bmusb/bmusb.h" +#include "alsa_pool.h" #include "correlation_measurer.h" #include "db.h" #include "defs.h" @@ -29,6 +30,8 @@ #include "resampling_queue.h" #include "stereocompressor.h" +class DeviceSpecProto; + namespace bmusb { struct AudioFormat; } // namespace bmusb @@ -66,6 +69,9 @@ public: float get_fader_volume(unsigned bus_index) const { return fader_volume_db[bus_index]; } void set_fader_volume(unsigned bus_index, float level_db) { fader_volume_db[bus_index] = level_db; } + bool get_mute(unsigned bus_index) const { return mute[bus_index]; } + void set_mute(unsigned bus_index, bool muted) { mute[bus_index] = muted; } + // Note: This operation holds all ALSA devices (see ALSAPool::get_devices()). // You will need to call set_input_mapping() to get the hold state correctly, // or every card will be held forever. @@ -89,9 +95,32 @@ public: // Note: The card should be held (currently this isn't enforced, though). void serialize_device(DeviceSpec device_spec, DeviceSpecProto *device_spec_proto); + enum class MappingMode { + // A single bus, only from a video card (no ALSA devices), + // only channel 1 and 2, locked to +0 dB. Note that this is + // only an UI abstraction around exactly the same audio code + // as MULTICHANNEL; it's just less flexible. + SIMPLE, + + // Full, arbitrary mappings. + MULTICHANNEL + }; + + // Automatically sets mapping mode to MappingMode::SIMPLE. + void set_simple_input(unsigned card_index); + + // If mapping mode is not representable as a MappingMode::SIMPLE type + // mapping, returns numeric_limits::max(). + unsigned get_simple_input() const; + + // Implicitly sets mapping mode to MappingMode::MULTICHANNEL. void set_input_mapping(const InputMapping &input_mapping); + + MappingMode get_mapping_mode() const; InputMapping get_input_mapping() const; + unsigned num_buses() const; + void set_locut_cutoff(float cutoff_hz) { locut_cutoff_hz = cutoff_hz; @@ -252,6 +281,23 @@ public: } } + // A combination of all settings for a bus. Useful if you want to get + // or store them as a whole without bothering to call all of the get_* + // or set_* functions for that bus. + struct BusSettings { + float fader_volume_db; + bool muted; + bool locut_enabled; + float eq_level_db[NUM_EQ_BANDS]; + float gain_staging_db; + bool level_compressor_enabled; + float compressor_threshold_dbfs; + bool compressor_enabled; + }; + static BusSettings get_default_bus_settings(); + BusSettings get_bus_settings(unsigned bus_index) const; + void set_bus_settings(unsigned bus_index, const BusSettings &settings); + private: struct AudioDevice { std::unique_ptr resampling_queue; @@ -279,6 +325,7 @@ private: void measure_bus_levels(unsigned bus_index, const std::vector &left, const std::vector &right); void send_audio_level_callback(); std::vector get_active_devices() const; + void set_input_mapping_lock_held(const InputMapping &input_mapping); unsigned num_cards; @@ -297,6 +344,7 @@ private: mutable std::mutex compressor_mutex; std::unique_ptr level_compressor[MAX_BUSES]; // Under compressor_mutex. Used to set/override gain_staging_db if . float gain_staging_db[MAX_BUSES]; // Under compressor_mutex. + float last_gain_staging_db[MAX_BUSES]; // Under compressor_mutex. bool level_compressor_enabled[MAX_BUSES]; // Under compressor_mutex. static constexpr float ref_level_dbfs = -14.0f; // Chosen so that we end up around 0 LU in practice. @@ -322,10 +370,13 @@ private: double final_makeup_gain = 1.0; // Under compressor_mutex. Read/write by the user. Note: Not in dB, we want the numeric precision so that we can change it slowly. bool final_makeup_gain_auto = true; // Under compressor_mutex. + MappingMode current_mapping_mode; // Under audio_mutex. InputMapping input_mapping; // Under audio_mutex. std::atomic fader_volume_db[MAX_BUSES] {{ 0.0f }}; + std::atomic mute[MAX_BUSES] {{ false }}; float last_fader_volume_db[MAX_BUSES] { 0.0f }; // Under audio_mutex. std::atomic eq_level_db[MAX_BUSES][NUM_EQ_BANDS] {{{ 0.0f }}}; + float last_eq_level_db[MAX_BUSES][NUM_EQ_BANDS] {{ 0.0f }}; audio_level_callback_t audio_level_callback = nullptr; state_changed_callback_t state_changed_callback = nullptr;