]> git.sesse.net Git - nageru/blobdiff - audio_mixer.h
Move ALSAPool into its own file; it is pretty large now.
[nageru] / audio_mixer.h
index 855295dcd60f0bf207f435c75484a763eba77b89..279436700e4a8a4ce95505a1f3f3aab43bf68c9c 100644 (file)
 #include <zita-resampler/resampler.h>
 
 #include "alsa_input.h"
+#include "alsa_pool.h"
 #include "bmusb/bmusb.h"
 #include "correlation_measurer.h"
 #include "db.h"
 #include "defs.h"
 #include "ebu_r128_proc.h"
 #include "filter.h"
+#include "input_mapping.h"
 #include "resampling_queue.h"
 #include "stereocompressor.h"
 
@@ -32,26 +34,6 @@ namespace bmusb {
 struct AudioFormat;
 }  // namespace bmusb
 
-enum class InputSourceType { SILENCE, CAPTURE_CARD, ALSA_INPUT };
-struct DeviceSpec {
-       InputSourceType type;
-       unsigned index;
-
-       bool operator== (const DeviceSpec &other) const {
-               return type == other.type && index == other.index;
-       }
-
-       bool operator< (const DeviceSpec &other) const {
-               if (type != other.type)
-                       return type < other.type;
-               return index < other.index;
-       }
-};
-struct DeviceInfo {
-       std::string name;
-       unsigned num_channels;
-};
-
 enum EQBand {
        EQ_BAND_BASS = 0,
        EQ_BAND_MID,
@@ -59,26 +41,6 @@ enum EQBand {
        NUM_EQ_BANDS
 };
 
-static inline uint64_t DeviceSpec_to_key(const DeviceSpec &device_spec)
-{
-       return (uint64_t(device_spec.type) << 32) | device_spec.index;
-}
-
-static inline DeviceSpec key_to_DeviceSpec(uint64_t key)
-{
-       return DeviceSpec{ InputSourceType(key >> 32), unsigned(key & 0xffffffff) };
-}
-
-struct InputMapping {
-       struct Bus {
-               std::string name;
-               DeviceSpec device;
-               int source_channel[2] { -1, -1 };  // Left and right. -1 = none.
-       };
-
-       std::vector<Bus> buses;
-};
-
 class AudioMixer {
 public:
        AudioMixer(unsigned num_cards);
@@ -102,6 +64,7 @@ public:
 
        std::vector<float> get_output(double pts, unsigned num_samples, ResamplingQueue::RateAdjustmentPolicy rate_adjustment_policy);
 
+       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; }
 
        // Note: This operation holds all ALSA devices (see ALSAPool::get_devices()).
@@ -115,7 +78,17 @@ public:
                return alsa_pool.get_card_state(index);
        }
 
-       void set_name(DeviceSpec device_spec, const std::string &name);
+       // See comments on ALSAPool::create_dead_card().
+       DeviceSpec create_dead_card(const std::string &name, const std::string &info, unsigned num_channels)
+       {
+               unsigned dead_card_index = alsa_pool.create_dead_card(name, info, num_channels);
+               return DeviceSpec{InputSourceType::ALSA_INPUT, dead_card_index};
+       }
+
+       void set_display_name(DeviceSpec device_spec, const std::string &name);
+
+       // Note: The card should be held (currently this isn't enforced, though).
+       void serialize_device(DeviceSpec device_spec, DeviceSpecProto *device_spec_proto);
 
        void set_input_mapping(const InputMapping &input_mapping);
        InputMapping get_input_mapping() const;
@@ -262,11 +235,45 @@ public:
                audio_level_callback = callback;
        }
 
+       typedef std::function<void()> state_changed_callback_t;
+       void set_state_changed_callback(state_changed_callback_t callback)
+       {
+               state_changed_callback = callback;
+       }
+
+       state_changed_callback_t get_state_changed_callback() const
+       {
+               return state_changed_callback;
+       }
+
+       void trigger_state_changed_callback()
+       {
+               if (state_changed_callback != nullptr) {
+                       state_changed_callback();
+               }
+       }
+
+       // 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 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<ResamplingQueue> resampling_queue;
                int64_t next_local_pts = 0;
-               std::string name;
+               std::string display_name;
                unsigned capture_frequency = OUTPUT_FREQUENCY;
                // Which channels we consider interesting (ie., are part of some input_mapping).
                std::set<unsigned> interesting_channels;
@@ -338,6 +345,7 @@ private:
        std::atomic<float> 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;
        mutable std::mutex audio_measure_mutex;
        Ebu_r128_proc r128;  // Under audio_measure_mutex.
        CorrelationMeasurer correlation;  // Under audio_measure_mutex.