Browse Source

Detach shared capture safely while its audio buffer is resizing

master
evgeny 4 days ago
parent
commit
efe9e8311c
  1. 5
      tools/chatgui/src/audio_capture.cpp
  2. 2
      tools/chatgui/src/audio_capture.h
  3. 6
      tools/chatgui/src/radio_audio_engine.cpp

5
tools/chatgui/src/audio_capture.cpp

@ -157,7 +157,7 @@ void AudioCapture::close() {
/* Callback отсоединён в GUI; session и контекст должны жить до завершения ma_device_uninit. */
void AudioCapture::closeAsync() {
if (closing()) return;
if (!m_closeDone.load(std::memory_order_acquire)) return;
if (m_closeThread.joinable()) m_closeThread.join();
auto session = detach();
if (!session) return;
@ -184,6 +184,9 @@ void AudioCapture::closeAsync() {
}
void AudioCapture::recover() { if (m_session) m_session->recover(); }
bool AudioCapture::closing() const {
return !m_closeDone.load(std::memory_order_acquire) || (m_session && m_session->device.closing());
}
bool AudioCapture::running() const {
return m_session && m_prepared && m_session->device.initialized() && ma_device_is_started(m_session->device.device());
}

2
tools/chatgui/src/audio_capture.h

@ -31,7 +31,7 @@ public:
std::function<void()> stopped, Callback callback);
void close();
void closeAsync(); // GUI отсоединяет подписчика; последний backend закрывается в worker.
bool closing() const { return !m_closeDone.load(std::memory_order_acquire); }
bool closing() const; // Включает переоткрытие общего backend для подстройки буфера.
void recover();
bool subscribed() const { return bool(m_session); }
bool running() const;

6
tools/chatgui/src/radio_audio_engine.cpp

@ -48,7 +48,7 @@ RadioAudioEngine::RadioAudioEngine() {
auto* manager = SoundManager::instance();
if (m_captureId != manager->captureDevice()) {
m_captureId = manager->captureDevice();
if (!m_capture.closing()) m_capture.close();
if (m_capture.closing()) m_capture.closeAsync(); else m_capture.close();
m_captureError.clear();
emit stateChanged();
}
@ -192,7 +192,7 @@ void RadioAudioEngine::postSettings(const std::array<int, 9>& values, bool apply
void RadioAudioEngine::reconfigureCapture() {
DEBUG_INFO(DEBUG_CATEGORY_RADIO, "RadioAudio: reconfigure capture group=%016llx manual=%d auto=%d",
(unsigned long long)m_groupId.load(), m_talking.load(), autoEnabled());
if (!m_capture.closing()) m_capture.close();
if (m_capture.closing()) m_capture.closeAsync(); else m_capture.close();
m_wantStereo = chat_setting_get_int(gui_bridge_get_inst(), "radio_capture_stereo", 0) != 0;
updateState();
recoverDevices();
@ -291,7 +291,7 @@ void RadioAudioEngine::pauseDevices() {
void RadioAudioEngine::stop() {
m_recoveryTimer.stop();
if (!m_capture.closing()) m_capture.close();
if (m_capture.closing()) m_capture.closeAsync(); else m_capture.close();
SoundManager::instance()->detachVoice(&m_voice); m_outputAttached = false;
m_voice.stop();
m_microphone.release();

Loading…
Cancel
Save