From c77cb9bb0aee1178561b3e387313e10e729585cd Mon Sep 17 00:00:00 2001 From: evgeny Date: Thu, 1 Oct 2026 18:27:44 +0300 Subject: [PATCH] Adopt decoded voice buffers without large copies on the Qt thread --- tools/chatgui/src/sound_manager.cpp | 7 +++++-- tools/chatgui/src/sound_manager.h | 6 +++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/tools/chatgui/src/sound_manager.cpp b/tools/chatgui/src/sound_manager.cpp index 96113581..1c2aca2e 100644 --- a/tools/chatgui/src/sound_manager.cpp +++ b/tools/chatgui/src/sound_manager.cpp @@ -46,6 +46,7 @@ void SoundManager::clearCurrentPcm() { ma_audio_buffer_uninit(buf); delete buf; m_currentPcmBuffer = nullptr; } m_currentPcmSampleRate = 0; + m_currentPcmOwner.reset(); } void SoundManager::shutdown() { @@ -200,13 +201,15 @@ ma_context* SoundManager::context() { return m_context; } -void SoundManager::playRawPcm(const int16_t* pcm, int sampleCount, int sampleRate, int channels) { +void SoundManager::playRawPcm(const int16_t* pcm, int sampleCount, int sampleRate, int channels, + std::shared_ptr> owner) { if (!m_engine || !m_initialized) { DEBUG_WARN(DEBUG_CATEGORY_GENERAL, "SoundManager::playRawPcm: not initialized (engine=%p init=%d)", (void*)m_engine, (int)m_initialized); return; } clearCurrentPcm(); + m_currentPcmOwner = std::move(owner); m_currentPcmSampleRate = sampleRate; DEBUG_DEBUG(DEBUG_CATEGORY_DEBUG, "SoundManager::playRawPcm: %d samples %dHz %dch volume=%.2f", sampleCount, sampleRate, channels, m_volume); @@ -215,7 +218,7 @@ void SoundManager::playRawPcm(const int16_t* pcm, int sampleCount, int sampleRat ma_format_s16, (ma_uint32)channels, (ma_uint64)sampleCount, pcm, NULL); ma_audio_buffer* buf = new ma_audio_buffer; m_currentPcmBuffer = buf; - ma_result r = ma_audio_buffer_init_copy(&bufCfg, buf); + ma_result r = m_currentPcmOwner ? ma_audio_buffer_init(&bufCfg, buf) : ma_audio_buffer_init_copy(&bufCfg, buf); if (r != MA_SUCCESS) { DEBUG_WARN(DEBUG_CATEGORY_GENERAL, "SoundManager: audio_buffer_init_copy failed (%d)", r); delete buf; m_currentPcmBuffer = nullptr; diff --git a/tools/chatgui/src/sound_manager.h b/tools/chatgui/src/sound_manager.h index 6e0f5b56..a05db839 100644 --- a/tools/chatgui/src/sound_manager.h +++ b/tools/chatgui/src/sound_manager.h @@ -5,6 +5,7 @@ #include #include #include +#include #include struct ma_engine; @@ -40,7 +41,9 @@ public: ma_context* context(); - void playRawPcm(const int16_t* pcm, int sampleCount, int sampleRate, int channels); + /* owner удерживает готовый PCM без копии в GUI; без owner короткие буферы копируются. */ + void playRawPcm(const int16_t* pcm, int sampleCount, int sampleRate, int channels, + std::shared_ptr> owner = {}); void pauseCurrentPcm(); void resumeCurrentPcm(); void stopCurrentPcm(); @@ -73,6 +76,7 @@ private: ma_sound* m_currentPcmSound = nullptr; void* m_currentPcmBuffer = nullptr; int m_currentPcmSampleRate = 0; + std::shared_ptr> m_currentPcmOwner; bool m_initialized = false; bool m_enabled = true; float m_volume = 0.8f;