Browse Source

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
topo_upd
Evgeny 2 months ago
parent
commit
ca9d1384f2
  1. 2
      tools/chatgui/src/audiodevicesettingspage.cpp
  2. 16
      tools/chatgui/src/audiorecorder.cpp
  3. 1
      tools/chatgui/src/audiorecorder.h
  4. 21
      tools/chatgui/src/sound_manager.cpp

2
tools/chatgui/src/audiodevicesettingspage.cpp

@ -214,7 +214,7 @@ void AudioDeviceSettingsPage::stopMicTest() {
if (m_testRecorder) { if (m_testRecorder) {
m_testRecorder->stopRecording(); m_testRecorder->stopRecording();
m_testRecorder->shutdown(); m_testRecorder->shutdown();
m_testRecorder->deleteLater(); delete m_testRecorder;
m_testRecorder = nullptr; m_testRecorder = nullptr;
} }
m_micTestActive = false; m_micTestActive = false;

16
tools/chatgui/src/audiorecorder.cpp

@ -56,11 +56,13 @@ bool AudioRecorder::init() {
} }
void AudioRecorder::shutdown() { void AudioRecorder::shutdown() {
if (!m_initialized) return;
if (m_recording) stopRecording(); if (m_recording) stopRecording();
if (m_device) { if (m_deviceStarted) {
delete m_device; m_deviceStarted = false;
m_device = nullptr; 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; m_initialized = false;
qDebug("AudioRecorder: shutdown"); qDebug("AudioRecorder: shutdown");
} }
@ -113,6 +115,7 @@ void AudioRecorder::startRecording() {
} }
m_recording = true; m_recording = true;
m_deviceStarted = true;
m_durationTimer.start(); m_durationTimer.start();
qDebug("AudioRecorder: recording started"); qDebug("AudioRecorder: recording started");
emit recordingStarted(); emit recordingStarted();
@ -122,8 +125,11 @@ void AudioRecorder::stopRecording() {
if (!m_recording) return; if (!m_recording) return;
m_durationTimer.stop(); m_durationTimer.stop();
ma_device_stop(m_device); if (m_deviceStarted) {
ma_device_uninit(m_device); ma_device_stop(m_device);
ma_device_uninit(m_device);
m_deviceStarted = false;
}
m_recording = false; m_recording = false;
int duration = m_elapsedMs; int duration = m_elapsedMs;

1
tools/chatgui/src/audiorecorder.h

@ -39,6 +39,7 @@ private:
ma_device* m_device = nullptr; ma_device* m_device = nullptr;
bool m_initialized = false; bool m_initialized = false;
bool m_recording = false; bool m_recording = false;
bool m_deviceStarted = false;
int m_sampleRate = 48000; int m_sampleRate = 48000;
int m_channels = 1; int m_channels = 1;
int m_captureDeviceIndex = -1; int m_captureDeviceIndex = -1;

21
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) { void SoundManager::playRawPcm(const int16_t* pcm, int sampleCount, int sampleRate, int channels) {
if (!m_engine || !m_initialized) return; if (!m_engine || !m_initialized) return;
ma_audio_buffer_ref* ref = new ma_audio_buffer_ref; ma_audio_buffer_config bufCfg = ma_audio_buffer_config_init(
ma_result r = ma_audio_buffer_ref_init(ma_format_s16, (ma_uint32)channels, ma_format_s16, (ma_uint32)channels, (ma_uint64)sampleCount, pcm, NULL);
pcm, (ma_uint64)sampleCount, ref); ma_audio_buffer* buf = new ma_audio_buffer;
ma_result r = ma_audio_buffer_init_copy(&bufCfg, buf);
if (r != MA_SUCCESS) { if (r != MA_SUCCESS) {
qWarning("SoundManager: audio_buffer_ref_init failed (%d)", r); qWarning("SoundManager: audio_buffer_init_copy failed (%d)", r);
delete ref; delete buf;
return; return;
} }
ma_sound* sound = new ma_sound; 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) { if (r != MA_SUCCESS) {
qWarning("SoundManager: PCM sound init failed (%d)", r); qWarning("SoundManager: PCM sound init failed (%d)", r);
ma_audio_buffer_ref_uninit(ref); ma_audio_buffer_uninit(buf);
delete ref; delete buf;
delete sound; delete sound;
return; return;
} }
@ -176,7 +177,7 @@ QVector<SoundManager::DeviceInfo> SoundManager::enumeratePlaybackDevices() {
ma_uint32 count = 0; ma_uint32 count = 0;
if (ma_context_get_devices(ctx, &pDevices, &count, nullptr, nullptr) != MA_SUCCESS) return result; if (ma_context_get_devices(ctx, &pDevices, &count, nullptr, nullptr) != MA_SUCCESS) return result;
for (ma_uint32 i = 0; i < count; i++) 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; return result;
} }
@ -189,6 +190,6 @@ QVector<SoundManager::DeviceInfo> SoundManager::enumerateCaptureDevices() {
ma_uint32 count = 0; ma_uint32 count = 0;
if (ma_context_get_devices(ctx, nullptr, nullptr, &pDevices, &count) != MA_SUCCESS) return result; if (ma_context_get_devices(ctx, nullptr, nullptr, &pDevices, &count) != MA_SUCCESS) return result;
for (ma_uint32 i = 0; i < count; i++) 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; return result;
} }

Loading…
Cancel
Save