X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=audio_mixer.h;h=855295dcd60f0bf207f435c75484a763eba77b89;hb=e4c99b681aceb0d960f1d56acc9dafc83643854b;hp=34e7dc075a1d614073b1a5c430f1f9bccf3e49ee;hpb=f3e2ecc05ad9df6b428b80bd32ad2e8d3f7192a1;p=nageru diff --git a/audio_mixer.h b/audio_mixer.h index 34e7dc0..855295d 100644 --- a/audio_mixer.h +++ b/audio_mixer.h @@ -82,7 +82,6 @@ struct InputMapping { class AudioMixer { public: AudioMixer(unsigned num_cards); - ~AudioMixer(); void reset_resampler(DeviceSpec device_spec); void reset_meters(); @@ -94,10 +93,28 @@ public: bool add_audio(DeviceSpec device_spec, const uint8_t *data, unsigned num_samples, bmusb::AudioFormat audio_format, int64_t frame_length); bool add_silence(DeviceSpec device_spec, unsigned samples_per_frame, unsigned num_frames, int64_t frame_length); + // 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, + // where it will be taken to only output silence. Note that when taking it _out_ + // of silence mode, the resampler will be reset, so that old audio will not + // affect it. Same true/false behavior as add_audio(). + bool silence_card(DeviceSpec device_spec, bool silence); + std::vector get_output(double pts, unsigned num_samples, ResamplingQueue::RateAdjustmentPolicy rate_adjustment_policy); void set_fader_volume(unsigned bus_index, float level_db) { fader_volume_db[bus_index] = level_db; } - std::map get_devices() const; + + // 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. + std::map get_devices(); + + // See comments on ALSAPool::get_card_state(). + ALSAPool::Device::State get_alsa_card_state(unsigned index) + { + return alsa_pool.get_card_state(index); + } + void set_name(DeviceSpec device_spec, const std::string &name); void set_input_mapping(const InputMapping &input_mapping); @@ -253,33 +270,35 @@ private: unsigned capture_frequency = OUTPUT_FREQUENCY; // Which channels we consider interesting (ie., are part of some input_mapping). std::set interesting_channels; - // Only used for ALSA cards, obviously. - std::unique_ptr alsa_device; + bool silenced = false; }; + + const AudioDevice *find_audio_device(DeviceSpec device_spec) const + { + return const_cast(this)->find_audio_device(device_spec); + } + AudioDevice *find_audio_device(DeviceSpec device_spec); void find_sample_src_from_device(const std::map> &samples_card, DeviceSpec device_spec, int source_channel, const float **srcptr, unsigned *stride); void fill_audio_bus(const std::map> &samples_card, const InputMapping::Bus &bus, unsigned num_samples, float *output); void reset_resampler_mutex_held(DeviceSpec device_spec); - void reset_alsa_mutex_held(DeviceSpec device_spec); - std::map get_devices_mutex_held() const; void apply_eq(unsigned bus_index, std::vector *samples_bus); void update_meters(const std::vector &samples); void add_bus_to_master(unsigned bus_index, const std::vector &samples_bus, std::vector *samples_out); 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; unsigned num_cards; mutable std::timed_mutex audio_mutex; + ALSAPool alsa_pool; AudioDevice video_cards[MAX_VIDEO_CARDS]; // Under audio_mutex. - - // TODO: Figure out a better way to unify these two, as they are sharing indexing. AudioDevice alsa_inputs[MAX_ALSA_CARDS]; // Under audio_mutex. - std::vector available_alsa_cards; - std::atomic locut_cutoff_hz; + std::atomic locut_cutoff_hz{120}; StereoFilter locut[MAX_BUSES]; // Default cutoff 120 Hz, 24 dB/oct. std::atomic locut_enabled[MAX_BUSES]; StereoFilter eq[MAX_BUSES][NUM_EQ_BANDS]; // The one for EQBand::MID isn't actually used (see comments in apply_eq()). @@ -326,4 +345,6 @@ private: std::atomic peak{0.0f}; }; +extern AudioMixer *global_audio_mixer; + #endif // !defined(_AUDIO_MIXER_H)