From 9f41415dc7a4ba3f0432bef5e7b44b9c7ec27a86 Mon Sep 17 00:00:00 2001 From: evgeny Date: Sat, 3 Oct 2026 13:11:54 +0300 Subject: [PATCH] Expose radio VAD thresholds and independent compressor gains --- tools/chatgui/src/radiosettingspage.cpp | 57 ++++++++++++++++++++++++- tools/chatgui/src/radiosettingspage.h | 9 +++- 2 files changed, 63 insertions(+), 3 deletions(-) diff --git a/tools/chatgui/src/radiosettingspage.cpp b/tools/chatgui/src/radiosettingspage.cpp index 6682ca06..ab78a65b 100644 --- a/tools/chatgui/src/radiosettingspage.cpp +++ b/tools/chatgui/src/radiosettingspage.cpp @@ -1,5 +1,6 @@ #include "radiosettingspage.h" #include "ptt_hotkey_manager.h" +#include "radio_audio_engine.h" #include "../db/db_manager.h" #include "../../lib/debug_config.h" @@ -10,12 +11,44 @@ #include #include #include +#include +#include +#include RadioSettingsPage::RadioSettingsPage(DbManager* db, QWidget* parent) : QWidget(parent), m_db(db) { auto* layout = new QVBoxLayout(this); auto* title = new QLabel("Рация (PTT)", this); title->setStyleSheet("font-weight: bold; font-size: 13px;"); layout->addWidget(title); + m_audioSettings = new QWidget(this); + auto* form = new QFormLayout(m_audioSettings); + form->setContentsMargins(0, 0, 0, 12); + auto add = [&](const QString& label, int min, int max, const QString& suffix) { + auto* spin = new QSpinBox(m_audioSettings); + spin->setRange(min, max); + spin->setSuffix(suffix); + form->addRow(label, spin); + return spin; + }; + m_threshold = add(QStringLiteral("Порог речи VAD:"), 10, 95, QStringLiteral(" %")); + m_threshold->setToolTip(QStringLiteral("Порог вероятности речи: меньше — чувствительнее. Это не порог громкости.")); + m_hangover = add(QStringLiteral("Тишина до окончания передачи:"), 50, 2000, QStringLiteral(" мс")); + m_compressor = new QCheckBox(QStringLiteral("Компрессор передачи и VAD"), m_audioSettings); + form->addRow(m_compressor); + m_txGain = add(QStringLiteral("Max gain передачи:"), 1, 60, QStringLiteral(" dB")); + m_vadGain = add(QStringLiteral("Max gain VAD:"), 1, 60, QStringLiteral(" dB")); + auto* explanation = new QLabel(QStringLiteral("VAD включается кнопкой на панели рации. Буфер начала речи — 0,6 с. " + "Компрессор VAD имеет отдельный max gain; остальные параметры общие с компрессором передачи. " + "Скорость нарастания усиления задаётся в разделе Audio."), m_audioSettings); + explanation->setWordWrap(true); + form->addRow(explanation); + layout->addWidget(m_audioSettings); + connect(RadioAudioEngine::instance(), &RadioAudioEngine::stateChanged, this, [this]() { + auto* engine = RadioAudioEngine::instance(); + m_audioSettings->setEnabled(engine->settingsReady() && !engine->settingsBusy()); + if (!m_audioSettingsLoaded && engine->settingsReady()) loadAudioSettings(); + }); + loadAudioSettings(); if (PttHotkeyManager::usesPortal()) { auto* hint = new QLabel("Глобальные хоткеи работают из любых приложений. " "Назначьте обычную клавишу с Ctrl, Shift, Alt или Win в системном окне. " @@ -142,6 +175,7 @@ void RadioSettingsPage::updateLabel(int index) { } void RadioSettingsPage::loadFromDb() { + loadAudioSettings(); if (m_portalStatus) { updatePortalLabels(); return; } finishCapture(false); QStringList values; @@ -159,10 +193,29 @@ QStringList RadioSettingsPage::hotkeys() const { return values; } -void RadioSettingsPage::apply() { - if (m_portalStatus) return; +bool RadioSettingsPage::apply() { + if (!RadioAudioEngine::instance()->applySettings({ + {QStringLiteral("radio_vad_threshold"), m_threshold->value()}, + {QStringLiteral("radio_vad_hangover_ms"), m_hangover->value()}, + {QStringLiteral("radio_compressor_enabled"), m_compressor->isChecked() ? 1 : 0}, + {QStringLiteral("radio_compressor_max_gain_db"), m_txGain->value()}, + {QStringLiteral("radio_vad_compressor_max_gain_db"), m_vadGain->value()}})) return false; + if (m_portalStatus) return true; finishCapture(false); PttHotkeyManager::instance()->setHotkeys(hotkeys()); + return true; +} + +void RadioSettingsPage::loadAudioSettings() { + auto* engine = RadioAudioEngine::instance(); + m_audioSettings->setEnabled(engine->settingsReady() && !engine->settingsBusy()); + if (!engine->settingsReady()) return; + m_threshold->setValue(engine->setting(QStringLiteral("radio_vad_threshold"))); + m_hangover->setValue(engine->setting(QStringLiteral("radio_vad_hangover_ms"))); + m_compressor->setChecked(engine->setting(QStringLiteral("radio_compressor_enabled")) != 0); + m_txGain->setValue(engine->setting(QStringLiteral("radio_compressor_max_gain_db"))); + m_vadGain->setValue(engine->setting(QStringLiteral("radio_vad_compressor_max_gain_db"))); + m_audioSettingsLoaded = true; } void RadioSettingsPage::updatePortalLabels() { diff --git a/tools/chatgui/src/radiosettingspage.h b/tools/chatgui/src/radiosettingspage.h index 59a44a4b..07a4901f 100644 --- a/tools/chatgui/src/radiosettingspage.h +++ b/tools/chatgui/src/radiosettingspage.h @@ -9,6 +9,8 @@ class QPushButton; class QLabel; class QHideEvent; class QShowEvent; +class QSpinBox; +class QCheckBox; // Запись глобальных сочетаний PTT, включая отдельные левые/правые модификаторы. class RadioSettingsPage : public QWidget { @@ -18,7 +20,7 @@ public: ~RadioSettingsPage() override; void loadFromDb(); QStringList hotkeys() const; - void apply(); + bool apply(); protected: bool eventFilter(QObject* object, QEvent* event) override; @@ -27,6 +29,11 @@ protected: private: void updatePortalLabels(); + void loadAudioSettings(); + QWidget* m_audioSettings = nullptr; + QSpinBox *m_threshold, *m_hangover, *m_txGain, *m_vadGain; + QCheckBox* m_compressor; + bool m_audioSettingsLoaded = false; QLabel* m_portalStatus = nullptr; void startCapture(int index); void finishCapture(bool save);