You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
68 lines
2.6 KiB
68 lines
2.6 KiB
#pragma once |
|
|
|
#include <QObject> |
|
#include <atomic> |
|
#include <cstdint> |
|
#include <vector> |
|
#include <QTimer> |
|
#include "audio_device.h" |
|
#include "voice_audio_io.h" |
|
|
|
struct ma_device; |
|
|
|
/* Desktop-контур звонка: GUI владеет capture device и жизненным циклом. |
|
* Hardware callback копирует PCM в ограниченную очередь VoiceAudioIo. |
|
* Capture worker выполняет AEC и упорядочивает PCM/PTT/mute; независимый RX worker |
|
* получает готовый голос из сервисного слоя. SoundManager смешивает его со всеми |
|
* звуками приложения на том же выходе и возвращает итоговый stereo reference. |
|
* Stop: close capture → join capture worker → detach output → join RX → release core. */ |
|
class CallAudioEngine : public QObject { |
|
Q_OBJECT |
|
public: |
|
static CallAudioEngine* instance(); |
|
|
|
/* Запустить полнодуплекс для звонка (после ACCEPTED). 0 = успех. */ |
|
int start(quint64 callId); |
|
|
|
/* По CALL_ENDED: тон завершения (~450мс), затем авто-teardown. */ |
|
void beginEnd(quint64 callId); |
|
|
|
/* Немедленный teardown (device + освобождение call_audio). */ |
|
void stop(); |
|
|
|
bool isActive() const { return m_active.load(); } |
|
quint64 callId() const { return m_callId.load(); } |
|
|
|
/* Mute: пир слышит тишину (отправляем нулевые кадры вместо захваченного PCM). */ |
|
void setMuted(bool muted); |
|
bool isMuted() const { return m_muted.load(); } |
|
|
|
/* Backend ID (пустой = default). Смена пересоздаёт только соответствующее устройство. */ |
|
void setPlaybackDevice(const QString& id); |
|
QString playbackDevice() const { return m_playbackId; } |
|
void setCaptureDevice(const QString& id); |
|
|
|
/* Hardware capture callback: без DSP и растущих буферов. */ |
|
void dataCallback(const void* in, void* out, unsigned int frames); |
|
|
|
private: |
|
CallAudioEngine(); |
|
bool openCapture(); |
|
void recoverDevices(); |
|
void pauseDevices(); |
|
|
|
std::atomic<bool> m_active{false}; |
|
std::atomic<uint64_t> m_callId{0}; |
|
std::atomic<bool> m_muted{false}; |
|
|
|
QString m_playbackId; /* только GUI-поток */ |
|
|
|
QString m_captureId; |
|
AudioDevice m_capture; |
|
VoiceAudioIo m_voice; |
|
bool m_outputAttached = false; |
|
QTimer m_recoveryTimer; |
|
uint64_t m_generation = 0; |
|
bool m_ending = false; |
|
|
|
};
|
|
|