call: P2P аудиозвонки — сигналинг, релей медиа, аудио-контур, headless/desktop/android
- src/call/: сигналинг (call.c, call_proto.h, ETCP_RT_ID_CALL 0x36) + релей медиа + headless аудио-сокет (call_headless.c, call_audio_bind) + Opus/jitter/тоны - chat: события CHAT_EVT_CALL_* (34–40), CHAT_EVT_DM_MESSAGES (41), DM-трамплины - chatgui: call window, miniaudio I/O, audio_frame_ring, test_audio_jitter - chatgui-android: CallScreen/IncomingCallDialog, аудио-роутинг, JNI, рингтон - tests: test_call, test_call_headless
This commit is contained in:
1 parent
0157f7f96b
commit
b11e77e4c0
78 files changed
+7053
-70
No files matched your search
@@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
struct ma_device;
|
||||
|
||||
/* Аудио-контур звонка (desktop): только miniaudio I/O + захват/воспроизведение.
|
||||
* Весь аудиопроцессинг (Opus, джиттер-буфер, time-stretch, тоны) — в сервисном
|
||||
* слое src/call/call_audio.c; сюда приходит/отсюда уходит финальный PCM.
|
||||
*
|
||||
* Потоки:
|
||||
* - аудио-поток (miniaudio callback): capture → call_audio_feed_pcm,
|
||||
* call_audio_pull_pcm → playback;
|
||||
* - GUI-поток: start()/beginEnd()/stop() по ACCEPTED/ENDED. */
|
||||
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(); }
|
||||
|
||||
/* Устройство вывода звонка (-1 = default). Смена на лету пересоздаёт ma_device. */
|
||||
void setPlaybackDeviceIndex(int index);
|
||||
int playbackDeviceIndex() const { return m_playbackDeviceIndex; }
|
||||
|
||||
/* аудио-поток: miniaudio data callback (захват + воспроизведение) */
|
||||
void dataCallback(const void* in, void* out, unsigned int frames);
|
||||
|
||||
private:
|
||||
CallAudioEngine() = default;
|
||||
void teardownDevice();
|
||||
int initDevice();
|
||||
|
||||
std::atomic<bool> m_active{false};
|
||||
std::atomic<uint64_t> m_callId{0};
|
||||
std::atomic<bool> m_muted{false};
|
||||
|
||||
int m_playbackDeviceIndex = -1; /* только GUI-поток */
|
||||
|
||||
ma_device* m_device = nullptr;
|
||||
bool m_deviceStarted = false;
|
||||
|
||||
std::vector<int16_t> m_captureBuf; /* 960 samples, аудио-поток */
|
||||
int m_capturePos = 0;
|
||||
};
|
||||
Reference in new issue
Block a user