#pragma once #ifdef WITH_VOICE // clang-format off #include #include #include #include #include #include #include #include #include #include #include #include #ifdef WITH_RNNOISE #include #endif #include "devices.hpp" // clang-format on class AudioManager { public: AudioManager(); ~AudioManager(); void AddSSRC(uint32_t ssrc); void RemoveSSRC(uint32_t ssrc); void RemoveAllSSRCs(); void SetOpusBuffer(uint8_t *ptr); void FeedMeOpus(uint32_t ssrc, const std::vector &data); void StartCaptureDevice(); void StopCaptureDevice(); void SetPlaybackDevice(const Gtk::TreeModel::iterator &iter); void SetCaptureDevice(const Gtk::TreeModel::iterator &iter); void SetCapture(bool capture); void SetPlayback(bool playback); void SetCaptureGate(double gate); void SetCaptureGain(double gain); double GetCaptureGate() const noexcept; double GetCaptureGain() const noexcept; void SetMuteSSRC(uint32_t ssrc, bool mute); void SetVolumeSSRC(uint32_t ssrc, double volume); double GetVolumeSSRC(uint32_t ssrc) const; void SetEncodingApplication(int application); int GetEncodingApplication(); void SetSignalHint(int signal); int GetSignalHint(); void SetBitrate(int bitrate); int GetBitrate(); void Enumerate(); bool OK() const; double GetCaptureVolumeLevel() const noexcept; double GetSSRCVolumeLevel(uint32_t ssrc) const noexcept; AudioDevices &GetDevices(); uint32_t GetRTPTimestamp() const noexcept; enum class VADMethod { Gate, RNNoise, }; void SetVADMethod(const std::string &method); void SetVADMethod(VADMethod method); VADMethod GetVADMethod() const; float GetCurrentVADProbability() const; private: void OnCapturedPCM(const int16_t *pcm, ma_uint32 frames); void UpdateReceiveVolume(uint32_t ssrc, const int16_t *pcm, int frames); void UpdateCaptureVolume(const int16_t *pcm, ma_uint32 frames); std::atomic m_capture_peak_meter = 0; bool DecayVolumeMeters(); bool CheckVADVoiceGate(); #ifdef WITH_RNNOISE bool CheckVADRNNoise(const int16_t *pcm); void RNNoiseInitialize(); void RNNoiseUninitialize(); #endif friend void data_callback(ma_device *, void *, const void *, ma_uint32); friend void capture_data_callback(ma_device *, void *, const void *, ma_uint32); std::thread m_thread; bool m_ok; // playback ma_device m_playback_device; ma_device_config m_playback_config; ma_device_id m_playback_id; // capture ma_device m_capture_device; ma_device_config m_capture_config; ma_device_id m_capture_id; ma_context m_context; mutable std::mutex m_mutex; mutable std::mutex m_enc_mutex; std::unordered_map, OpusDecoder *>> m_sources; OpusEncoder *m_encoder; uint8_t *m_opus_buffer = nullptr; std::atomic m_should_capture = true; std::atomic m_should_playback = true; std::atomic m_capture_gate = 0.0; std::atomic m_capture_gain = 1.0; std::atomic m_prob_threshold = 0.5; std::atomic m_vad_prob = 0.0; std::unordered_set m_muted_ssrcs; std::unordered_map m_volume_ssrc; mutable std::mutex m_vol_mtx; std::unordered_map m_volumes; AudioDevices m_devices; VADMethod m_vad_method; #ifdef WITH_RNNOISE DenoiseState *m_rnnoise; #endif std::atomic m_rtp_timestamp = 0; public: using type_signal_opus_packet = sigc::signal; type_signal_opus_packet signal_opus_packet(); private: type_signal_opus_packet m_signal_opus_packet; }; #endif