radio: PTT-радио в каналах (src/radio + chatgui + chatgui-android)

Новый модуль src/radio (radio/radio_audio/radio_headless) — push-to-talk
радио поверх topo-групп, доставка аудио в канал, headless-режим и тесты.
Интеграция в chatgui (ptt_hotkey_manager, radio_audio_engine, радионастройки,
вызовы) и chatgui-android (RadioAudioEngine, RadioOverlayService, UI).
This commit is contained in:
evgeny committed 2026-09-19 17:09:00 +03:00
1 parent 398078a28f
commit b96ed8bd00
69 files changed
+5372 -51

No files matched your search

+16
View File
@@ -19,6 +19,7 @@
#include "voicemessageencoder.h"
#include "callwindow.h"
#include "call_audio_engine.h"
#include "ptt_hotkey_manager.h"
extern "C" {
#include "../../lib/audio_compressor.h"
@@ -385,6 +386,7 @@ void MainWindow::setupBridgeCallbacks() {
s_mainWindow->m_db->setDb(chat_core_get_db(gui_bridge_get_inst()));
s_mainWindow->m_channelList->loadChannels();
s_mainWindow->restoreWindowGeometry();
PttHotkeyManager::instance()->init(s_mainWindow->m_db); /* глобальные PTT-хоткеи */
QString lastCid = s_mainWindow->m_db->getUiState("last_channel_id");
if (!lastCid.isEmpty()) {
/* восстанавливаем канал только если он реально существует в БД —
@@ -446,6 +448,15 @@ void MainWindow::setupBridgeCallbacks() {
gui_bridge_set_call_declined_cb([](uint64_t call_id, uint8_t reason) {
if (s_mainWindow) s_mainWindow->onCallEnded(call_id, reason);
});
gui_bridge_set_call_path_cb([](uint64_t call_id, const char* text, int len) {
if (s_mainWindow) s_mainWindow->onCallPath(call_id, QString::fromUtf8(text, len));
});
/* ── рация: индикация говорящего ── */
gui_bridge_set_radio_talk_cb([](uint64_t group_id, uint64_t src_node_id, uint8_t on) {
if (s_mainWindow && s_mainWindow->m_messageList)
s_mainWindow->m_messageList->onRadioTalk((quint64)group_id, (quint64)src_node_id, on != 0);
});
/* ── DM (p2p чат) ── */
gui_bridge_set_dm_conv_updated_cb([](const char* conv_id, int conv_id_len) {
@@ -573,6 +584,11 @@ void MainWindow::onCallEnded(quint64 callId, uint8_t reason) {
closeCallWindow(callId);
}
void MainWindow::onCallPath(quint64 callId, const QString& path) {
CallWindow* w = m_activeCalls.value(callId, nullptr);
if (w) w->setBgpPath(path);
}
void MainWindow::closeCallWindow(quint64 callId) {
SoundManager::instance()->stopLoop();
CallWindow* w = m_activeCalls.take(callId);