From ca9d1384f20ed0b5cf7dfd8a2234a15d7d0eac7b Mon Sep 17 00:00:00 2001 From: Evgeny Date: Sun, 26 Jul 2026 22:01:46 +0300 Subject: [PATCH] fix: PCM copy, device name encoding, double shutdown - playRawPcm: ma_audio_buffer_init_copy instead of ma_audio_buffer_ref (copies PCM) - enumerateDevices: fromLocal8Bit instead of fromUtf8 for device names - AudioRecorder: m_deviceStarted flag prevents double ma_device_uninit - stopMicTest: delete instead of deleteLater to avoid deferred double shutdown --- tools/chatgui/src/audiodevicesettingspage.cpp | 2 +- tools/chatgui/src/audiorecorder.cpp | 16 +++++++++----- tools/chatgui/src/audiorecorder.h | 1 + tools/chatgui/src/sound_manager.cpp | 21 ++++++++++--------- 4 files changed, 24 insertions(+), 16 deletions(-) diff --git a/tools/chatgui/src/audiodevicesettingspage.cpp b/tools/chatgui/src/audiodevicesettingspage.cpp index ffeedf69..773b1406 100644 --- a/tools/chatgui/src/audiodevicesettingspage.cpp +++ b/tools/chatgui/src/audiodevicesettingspage.cpp @@ -214,7 +214,7 @@ void AudioDeviceSettingsPage::stopMicTest() { if (m_testRecorder) { m_testRecorder->stopRecording(); m_testRecorder->shutdown(); - m_testRecorder->deleteLater(); + delete m_testRecorder; m_testRecorder = nullptr; } m_micTestActive = false; diff --git a/tools/chatgui/src/audiorecorder.cpp b/tools/chatgui/src/audiorecorder.cpp index dbc0247a..b28e73ed 100644 --- a/tools/chatgui/src/audiorecorder.cpp +++ b/tools/chatgui/src/audiorecorder.cpp @@ -56,11 +56,13 @@ bool AudioRecorder::init() { } void AudioRecorder::shutdown() { + if (!m_initialized) return; if (m_recording) stopRecording(); - if (m_device) { - delete m_device; - m_device = nullptr; + if (m_deviceStarted) { + m_deviceStarted = false; + if (m_device) { ma_device_stop(m_device); ma_device_uninit(m_device); } } + if (m_device) { delete m_device; m_device = nullptr; } m_initialized = false; qDebug("AudioRecorder: shutdown"); } @@ -113,6 +115,7 @@ void AudioRecorder::startRecording() { } m_recording = true; + m_deviceStarted = true; m_durationTimer.start(); qDebug("AudioRecorder: recording started"); emit recordingStarted(); @@ -122,8 +125,11 @@ void AudioRecorder::stopRecording() { if (!m_recording) return; m_durationTimer.stop(); - ma_device_stop(m_device); - ma_device_uninit(m_device); + if (m_deviceStarted) { + ma_device_stop(m_device); + ma_device_uninit(m_device); + m_deviceStarted = false; + } m_recording = false; int duration = m_elapsedMs; diff --git a/tools/chatgui/src/audiorecorder.h b/tools/chatgui/src/audiorecorder.h index af390be7..652479b5 100644 --- a/tools/chatgui/src/audiorecorder.h +++ b/tools/chatgui/src/audiorecorder.h @@ -39,6 +39,7 @@ private: ma_device* m_device = nullptr; bool m_initialized = false; bool m_recording = false; + bool m_deviceStarted = false; int m_sampleRate = 48000; int m_channels = 1; int m_captureDeviceIndex = -1; diff --git a/tools/chatgui/src/sound_manager.cpp b/tools/chatgui/src/sound_manager.cpp index 20df3878..2d09d470 100644 --- a/tools/chatgui/src/sound_manager.cpp +++ b/tools/chatgui/src/sound_manager.cpp @@ -143,21 +143,22 @@ ma_context* SoundManager::context() { void SoundManager::playRawPcm(const int16_t* pcm, int sampleCount, int sampleRate, int channels) { if (!m_engine || !m_initialized) return; - ma_audio_buffer_ref* ref = new ma_audio_buffer_ref; - ma_result r = ma_audio_buffer_ref_init(ma_format_s16, (ma_uint32)channels, - pcm, (ma_uint64)sampleCount, ref); + ma_audio_buffer_config bufCfg = ma_audio_buffer_config_init( + ma_format_s16, (ma_uint32)channels, (ma_uint64)sampleCount, pcm, NULL); + ma_audio_buffer* buf = new ma_audio_buffer; + ma_result r = ma_audio_buffer_init_copy(&bufCfg, buf); if (r != MA_SUCCESS) { - qWarning("SoundManager: audio_buffer_ref_init failed (%d)", r); - delete ref; + qWarning("SoundManager: audio_buffer_init_copy failed (%d)", r); + delete buf; return; } ma_sound* sound = new ma_sound; - r = ma_sound_init_from_data_source(m_engine, (ma_data_source*)ref, 0, nullptr, sound); + r = ma_sound_init_from_data_source(m_engine, (ma_data_source*)buf, 0, nullptr, sound); if (r != MA_SUCCESS) { qWarning("SoundManager: PCM sound init failed (%d)", r); - ma_audio_buffer_ref_uninit(ref); - delete ref; + ma_audio_buffer_uninit(buf); + delete buf; delete sound; return; } @@ -176,7 +177,7 @@ QVector SoundManager::enumeratePlaybackDevices() { ma_uint32 count = 0; if (ma_context_get_devices(ctx, &pDevices, &count, nullptr, nullptr) != MA_SUCCESS) return result; for (ma_uint32 i = 0; i < count; i++) - result.append({QString::fromUtf8(pDevices[i].name), pDevices[i].isDefault != MA_FALSE}); + result.append({QString::fromLocal8Bit(pDevices[i].name), pDevices[i].isDefault != MA_FALSE}); return result; } @@ -189,6 +190,6 @@ QVector SoundManager::enumerateCaptureDevices() { ma_uint32 count = 0; if (ma_context_get_devices(ctx, nullptr, nullptr, &pDevices, &count) != MA_SUCCESS) return result; for (ma_uint32 i = 0; i < count; i++) - result.append({QString::fromUtf8(pDevices[i].name), pDevices[i].isDefault != MA_FALSE}); + result.append({QString::fromLocal8Bit(pDevices[i].name), pDevices[i].isDefault != MA_FALSE}); return result; }