Files
abaddon/src/audio/manager.hpp

155 lines
3.7 KiB
C++

#pragma once
#ifdef WITH_VOICE
// clang-format off
#include <array>
#include <atomic>
#include <deque>
#include <gtkmm/treemodel.h>
#include <mutex>
#include <thread>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <miniaudio.h>
#include <opus.h>
#include <sigc++/sigc++.h>
#ifdef WITH_RNNOISE
#include <rnnoise.h>
#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<uint8_t> &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);
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<int> 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<uint32_t, std::pair<std::deque<int16_t>, OpusDecoder *>> m_sources;
OpusEncoder *m_encoder;
uint8_t *m_opus_buffer = nullptr;
std::atomic<bool> m_should_capture = true;
std::atomic<bool> m_should_playback = true;
std::atomic<double> m_capture_gate = 0.0;
std::atomic<double> m_capture_gain = 1.0;
std::atomic<double> m_prob_threshold = 0.5;
std::unordered_set<uint32_t> m_muted_ssrcs;
std::unordered_map<uint32_t, double> m_volume_ssrc;
mutable std::mutex m_vol_mtx;
std::unordered_map<uint32_t, double> m_volumes;
AudioDevices m_devices;
VADMethod m_vad_method;
#ifdef WITH_RNNOISE
DenoiseState *m_rnnoise;
#endif
std::atomic<uint32_t> m_rtp_timestamp = 0;
public:
using type_signal_opus_packet = sigc::signal<void(int payload_size)>;
type_signal_opus_packet signal_opus_packet();
private:
type_signal_opus_packet m_signal_opus_packet;
};
#endif