X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=nageru%2Faudio_mixer.h;h=a1d81e200b3a7fefd3e569229295e8667c1ac0e5;hb=ecaec75dd52d076ba53cafa1fed716ebc0d93da6;hp=9793646c9bac3493651e39643a610c7df75c5d0f;hpb=9b7d691b4cc5db7dbfc18c82e86c1207fcac4722;p=nageru diff --git a/nageru/audio_mixer.h b/nageru/audio_mixer.h index 9793646..a1d81e2 100644 --- a/nageru/audio_mixer.h +++ b/nageru/audio_mixer.h @@ -22,8 +22,9 @@ #include #include "alsa_pool.h" +#include "card_type.h" #include "correlation_measurer.h" -#include "db.h" +#include "decibel.h" #include "defs.h" #include "ebu_r128_proc.h" #include "filter.h" @@ -37,6 +38,10 @@ namespace bmusb { struct AudioFormat; } // namespace bmusb +// Convert the given audio from {16,24,32}-bit M-channel to 32-bit N-channel PCM. +// Assumes little-endian and chunky, signed PCM throughout. +std::vector convert_audio_to_fixed32(const uint8_t *data, unsigned num_samples, bmusb::AudioFormat audio_format, unsigned num_destination_channels); + enum EQBand { EQ_BAND_BASS = 0, EQ_BAND_MID, @@ -46,7 +51,7 @@ enum EQBand { class AudioMixer { public: - AudioMixer(unsigned num_capture_cards, unsigned num_ffmpeg_inputs); + AudioMixer(); void reset_resampler(DeviceSpec device_spec); void reset_meters(); @@ -54,9 +59,9 @@ public: // the lock wasn't successfully taken; if so, you should simply try again. // (This is to avoid a deadlock where a card hangs on the mutex in add_audio() // while we are trying to shut it down from another thread that also holds - // the mutex.) frame_length is in TIMEBASE units. - bool add_audio(DeviceSpec device_spec, const uint8_t *data, unsigned num_samples, bmusb::AudioFormat audio_format, int64_t frame_length, std::chrono::steady_clock::time_point frame_time); - bool add_silence(DeviceSpec device_spec, unsigned samples_per_frame, unsigned num_frames, int64_t frame_length); + // the mutex.) + bool add_audio(DeviceSpec device_spec, const uint8_t *data, unsigned num_samples, bmusb::AudioFormat audio_format, std::chrono::steady_clock::time_point frame_time); + bool add_silence(DeviceSpec device_spec, unsigned samples_per_frame, unsigned num_frames); // If a given device is offline for whatever reason and cannot deliver audio // (by means of add_audio() or add_silence()), you can call put it in silence mode, @@ -91,7 +96,9 @@ public: return DeviceSpec{InputSourceType::ALSA_INPUT, dead_card_index}; } - void set_display_name(DeviceSpec device_spec, const std::string &name); + // NOTE: The display name is not overridden if active == false. + void set_device_parameters(DeviceSpec device_spec, const std::string &display_name, CardType card_type, unsigned num_channels, bool active); + bool get_active(DeviceSpec device_spec); // Note: The card should be held (currently this isn't enforced, though). void serialize_device(DeviceSpec device_spec, DeviceSpecProto *device_spec_proto); @@ -208,51 +215,51 @@ public: void set_gain_staging_db(unsigned bus_index, float gain_db) { - std::unique_lock lock(compressor_mutex); + std::lock_guard lock(compressor_mutex); level_compressor_enabled[bus_index] = false; gain_staging_db[bus_index] = gain_db; } float get_gain_staging_db(unsigned bus_index) const { - std::unique_lock lock(compressor_mutex); + std::lock_guard lock(compressor_mutex); return gain_staging_db[bus_index]; } void set_gain_staging_auto(unsigned bus_index, bool enabled) { - std::unique_lock lock(compressor_mutex); + std::lock_guard lock(compressor_mutex); level_compressor_enabled[bus_index] = enabled; } bool get_gain_staging_auto(unsigned bus_index) const { - std::unique_lock lock(compressor_mutex); + std::lock_guard lock(compressor_mutex); return level_compressor_enabled[bus_index]; } void set_final_makeup_gain_db(float gain_db) { - std::unique_lock lock(compressor_mutex); + std::lock_guard lock(compressor_mutex); final_makeup_gain_auto = false; final_makeup_gain = from_db(gain_db); } float get_final_makeup_gain_db() { - std::unique_lock lock(compressor_mutex); + std::lock_guard lock(compressor_mutex); return to_db(final_makeup_gain); } void set_final_makeup_gain_auto(bool enabled) { - std::unique_lock lock(compressor_mutex); + std::lock_guard lock(compressor_mutex); final_makeup_gain_auto = enabled; } bool get_final_makeup_gain_auto() const { - std::unique_lock lock(compressor_mutex); + std::lock_guard lock(compressor_mutex); return final_makeup_gain_auto; } @@ -320,6 +327,9 @@ private: // Which channels we consider interesting (ie., are part of some input_mapping). std::set interesting_channels; bool silenced = false; + CardType card_type; + unsigned num_channels = 2; // Ignored for ALSA cards, which check the device directly. + bool active = false; // Only really relevant for capture cards (not ALSA cards). }; const AudioDevice *find_audio_device(DeviceSpec device_spec) const @@ -339,15 +349,13 @@ private: void send_audio_level_callback(); std::vector get_active_devices() const; void set_input_mapping_lock_held(const InputMapping &input_mapping); - - unsigned num_capture_cards, num_ffmpeg_inputs; + std::string spec_to_string(DeviceSpec device_spec) const; mutable std::timed_mutex audio_mutex; ALSAPool alsa_pool; AudioDevice video_cards[MAX_VIDEO_CARDS]; // Under audio_mutex. AudioDevice alsa_inputs[MAX_ALSA_CARDS]; // Under audio_mutex. - std::unique_ptr ffmpeg_inputs; // Under audio_mutex. std::atomic locut_cutoff_hz{120}; StereoFilter locut[MAX_BUSES]; // Default cutoff 120 Hz, 24 dB/oct.