diff --git a/tools/chatgui/src/audiodevicesettingspage.cpp b/tools/chatgui/src/audiodevicesettingspage.cpp index 17d90b8c..d582e832 100644 --- a/tools/chatgui/src/audiodevicesettingspage.cpp +++ b/tools/chatgui/src/audiodevicesettingspage.cpp @@ -11,9 +11,7 @@ extern "C" { #include "../db/db_manager.h" #include "../transport/gui_bridge.h" #include "../transport/config_updater.h" -#include "../../lib/mem.h" extern "C" { -#include "chat/chat_core.h" #include "call/call_video_rate.h" } #include @@ -279,95 +277,40 @@ void AudioDeviceSettingsPage::applyAndSave() { QCoreApplication::translate("ChatGui", "Could not save the call video bitrate range.")); return; } - auto* rangeArg = static_cast(u_calloc(1, sizeof(chat_setting_arg))); - if (!rangeArg) { DEBUG_ERROR(DEBUG_CATEGORY_CALL, "video bitrate range command allocation failed"); return; } - rangeArg->inst = gui_bridge_get_inst(); - memcpy(rangeArg->data, rangeKey, strlen(rangeKey) + 1); - QByteArray rangeBytes = range.toUtf8(); - memcpy(rangeArg->data + strlen(rangeKey) + 1, rangeBytes.constData(), rangeBytes.size() + 1); - gui_bridge_post_uasync_fn(chat_core_set_setting_trampoline, rangeArg); + gui_bridge_post_setting(GUI_SETTING_CHAT, rangeKey, range.toUtf8().constData()); QString outputId = m_outputCombo->currentData().toString(); QString inputId = m_inputCombo->currentData().toString(); int codecPreset = m_codecPresetCombo->currentData().toInt(); - auto saveKey = [](const char* key, int val) { - QByteArray v = QByteArray::number(val); - size_t klen = strlen(key), vlen = (size_t)v.size(); - size_t total = klen + 1 + vlen + 1; - if (total > 256) return; - struct save_ui_state_arg* arg = (struct save_ui_state_arg*)u_malloc(sizeof(struct save_ui_state_arg)); - if (!arg) return; - arg->inst = gui_bridge_get_inst(); - memcpy(arg->data, key, klen + 1); - memcpy(arg->data + klen + 1, v.constData(), vlen + 1); - gui_bridge_post_uasync_fn(chat_core_save_ui_state_trampoline, arg); - }; - auto saveText = [](const char* key, const QString& id) { - QByteArray value = id.toUtf8(); - size_t keyLen = strlen(key), valueLen = value.size(); - auto* arg = static_cast(u_calloc(1, sizeof(save_ui_state_arg))); - if (!arg) { DEBUG_ERROR(DEBUG_CATEGORY_CONFIG, "settings save allocation failed key=%s", key); return; } - if (keyLen + valueLen + 2 > sizeof(arg->data)) { - DEBUG_ERROR(DEBUG_CATEGORY_CONFIG, "settings value too long key=%s bytes=%zu", key, valueLen); - u_free(arg); return; - } - arg->inst = gui_bridge_get_inst(); - memcpy(arg->data, key, keyLen + 1); - memcpy(arg->data + keyLen + 1, value.constData(), valueLen + 1); - gui_bridge_post_uasync_fn(chat_core_save_ui_state_trampoline, arg); - }; - saveText("audio_output_id", outputId); - saveText("audio_input_id", inputId); - saveText(rangeKey, range); + const QPair textSettings[] = {{"audio_output_id", outputId}, {"audio_input_id", inputId}, {rangeKey, range}}; + for (const auto& setting : textSettings) + gui_bridge_post_setting(GUI_SETTING_UI_STATE, setting.first, setting.second.toUtf8().constData()); SoundManager::instance()->setDevices(outputId, inputId); - saveKey("opus_codec_preset", codecPreset); - VoiceEncoder::setPreset(codecPreset); int radioOpusMode = m_radioOpusModeCombo->currentData().toInt(); int radioOpusBitrate = m_radioOpusBitrateCombo->currentData().toInt(); int radioCaptureStereo = m_radioCaptureStereoCb->isChecked() ? 1 : 0; - saveKey("radio_opus_mode", radioOpusMode); - saveKey("radio_opus_bitrate", radioOpusBitrate); - saveKey("radio_capture_stereo", radioCaptureStereo); - int compEnabled = m_compressorEnabledCb->isChecked() ? 1 : 0; int compMaxGain = m_compressorMaxGainSlider->value(); int compRiseRate = m_compressorRiseRateSlider->value(); - saveKey("compressor_enabled", compEnabled); - saveKey("compressor_max_gain_db", compMaxGain); - saveKey("compressor_rise_rate", compRiseRate); - int jitterReserveMs = (int)std::lround(m_jitterReserveSpin->value() * 1000); - saveKey("call_jitter_max_reserve_ms", jitterReserveMs); int aecEnabled = m_aecEnabledCb->isChecked() ? 1 : 0; - saveKey("aec_enabled", aecEnabled); - - /* also update [chat] config section + live apply for headless-compat settings */ - if (!m_configPath.isEmpty()) { - auto postChat = [](const QString& path, const char* name, int val) { - config_update_option(path, "chatserver", name, QString::number(val), CONFIG_UPDATE_REPLACE); - QByteArray v = QByteArray::number(val); - size_t nlen = strlen(name), vlen = (size_t)v.size(), total = nlen + 1 + vlen + 1; - if (total > 256) return; - struct chat_setting_arg* arg = (struct chat_setting_arg*)u_malloc(sizeof(struct chat_setting_arg)); - if (!arg) return; - arg->inst = gui_bridge_get_inst(); - memcpy(arg->data, name, nlen + 1); - memcpy(arg->data + nlen + 1, v.constData(), vlen + 1); - gui_bridge_post_uasync_fn(chat_core_set_setting_trampoline, arg); - }; - postChat(m_configPath, "opus_codec_preset", codecPreset); - postChat(m_configPath, "radio_opus_mode", radioOpusMode); - postChat(m_configPath, "radio_opus_bitrate", radioOpusBitrate); - postChat(m_configPath, "radio_capture_stereo", radioCaptureStereo); - postChat(m_configPath, "compressor_enabled", compEnabled); - postChat(m_configPath, "compressor_max_gain_db", compMaxGain); - postChat(m_configPath, "compressor_rise_rate", compRiseRate); - postChat(m_configPath, "aec_enabled", aecEnabled); - postChat(m_configPath, "call_jitter_max_reserve_ms", jitterReserveMs); + const QPair numericSettings[] = { + {"opus_codec_preset", codecPreset}, {"radio_opus_mode", radioOpusMode}, {"radio_opus_bitrate", radioOpusBitrate}, + {"radio_capture_stereo", radioCaptureStereo}, {"compressor_enabled", compEnabled}, {"compressor_max_gain_db", compMaxGain}, + {"compressor_rise_rate", compRiseRate}, {"call_jitter_max_reserve_ms", jitterReserveMs}, {"aec_enabled", aecEnabled} + }; + for (const auto& setting : numericSettings) { + const QByteArray value = QByteArray::number(setting.second); + gui_bridge_post_setting(GUI_SETTING_UI_STATE, setting.first, value.constData()); + if (m_configPath.isEmpty()) continue; + if (!config_update_option(m_configPath, "chatserver", setting.first, QString::fromLatin1(value))) { + DEBUG_ERROR(DEBUG_CATEGORY_CONFIG, "Audio settings: config save failed key=%s", setting.first); continue; + } + gui_bridge_post_setting(GUI_SETTING_CHAT, setting.first, value.constData()); } m_savedOutputId = outputId; @@ -381,7 +324,7 @@ void AudioDeviceSettingsPage::applyAndSave() { m_savedCompressorRiseRate = compRiseRate; m_savedAecEnabled = aecEnabled; DEBUG_DEBUG(DEBUG_CATEGORY_CONFIG, - "saved output_default=%d input_default=%d codec=%d radioOpus=%d/%dkbps stereo=%d compressor=%d gain=%ddB rise=%.1fx aec=%d", + "requested output_default=%d input_default=%d codec=%d radioOpus=%d/%dkbps stereo=%d compressor=%d gain=%ddB rise=%.1fx aec=%d", outputId.isEmpty(), inputId.isEmpty(), codecPreset, radioOpusMode, radioOpusBitrate, radioCaptureStereo, compEnabled, compMaxGain, (float)compRiseRate, aecEnabled); diff --git a/tools/chatgui/src/audiodevicesettingspage.h b/tools/chatgui/src/audiodevicesettingspage.h index 7d6b35a1..f7a7b64b 100644 --- a/tools/chatgui/src/audiodevicesettingspage.h +++ b/tools/chatgui/src/audiodevicesettingspage.h @@ -1,5 +1,6 @@ /* Настройки capture/playback, Opus, компрессора, AEC и рации; тест микрофона и динамика. - * loadFromDb заполняет форму, applyAndSave применяет выбранные значения. */ + * GUI: loadFromDb заполняет форму, applyAndSave применяет локальные настройки и передаёт собственные снимки мосту. + * INI сохраняется синхронно, ui_state/live chat_setting — асинхронно; ошибки логируются, возврат не подтверждает запись в БД. */ #pragma once #include #include