From a59eb7b967806b8c8d43f0a416b3134a9d4fbadb Mon Sep 17 00:00:00 2001 From: Kirill Kirilenko Date: Thu, 12 Nov 2020 15:46:05 +0300 Subject: [PATCH] Clear buffers on backend switch sleep_for() replaced with sleep_until() in AudioProcessor::process() Output audio formats in case of error --- src/AudioProcessor.cpp | 16 +++++++++++++++- src/CMakeLists.txt | 8 ++++---- src/MainWindow.cpp | 33 +++++++++++++++------------------ 3 files changed, 34 insertions(+), 23 deletions(-) diff --git a/src/AudioProcessor.cpp b/src/AudioProcessor.cpp index 0e0234f..86e433c 100644 --- a/src/AudioProcessor.cpp +++ b/src/AudioProcessor.cpp @@ -78,6 +78,8 @@ void AudioProcessor::process() { while (doWork_) { + auto waitUntil = std::chrono::high_resolution_clock::now() + std::chrono::milliseconds(5); + const std::size_t bytesToRead = bufferSize_ * format_.sampleSize() / 8 * format_.channelCount(); const std::size_t monitorToRead = @@ -122,7 +124,7 @@ void AudioProcessor::process() emit readyRead(); } - std::this_thread::sleep_for(std::chrono::milliseconds(5)); + std::this_thread::sleep_until(waitUntil); } } @@ -157,6 +159,10 @@ qint64 AudioProcessor::bytesAvailable() const bool AudioProcessor::open(QIODevice::OpenMode mode) { + std::unique_lock lock1(inputMutex_); + std::unique_lock lock2(outputMutex_); + std::unique_lock lock3(monitorMutex_); + inputBuffer_.clear(); outputBuffer_.clear(); monitorBuffer_.clear(); @@ -195,6 +201,14 @@ Backend AudioProcessor::getCurrentBackend() const void AudioProcessor::switchBackend(Backend backend) { + std::unique_lock lock1(inputMutex_); + std::unique_lock lock2(outputMutex_); + std::unique_lock lock3(monitorMutex_); + + inputBuffer_.clear(); + outputBuffer_.clear(); + monitorBuffer_.clear(); + if (backend == Backend::Speex) dsp_.reset(new SpeexDSP(format_, monitorFormat_)); else diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 270ca4e..f6d943f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -9,11 +9,11 @@ file(GLOB SOURCES *.cpp) file(GLOB HEADERS *.h) file(GLOB_RECURSE RESOURCES *.qrc) -if (WIN32 AND CMAKE_BUILD_TYPE STREQUAL "Release") - add_executable(${TARGET_NAME} WIN32 ${SOURCES} ${HEADERS} ${RESOURCES}) -else() +#if (WIN32 AND CMAKE_BUILD_TYPE STREQUAL "Release") +# add_executable(${TARGET_NAME} WIN32 ${SOURCES} ${HEADERS} ${RESOURCES}) +#else() add_executable(${TARGET_NAME} ${SOURCES} ${HEADERS} ${RESOURCES}) -endif() +#endif() target_link_libraries(${TARGET_NAME} speexdsp diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index da6d281..1043388 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -85,6 +85,18 @@ MainWindow::~MainWindow() stopRecording(); } +void fixFormatForDevice(QAudioFormat& format, const QAudioDeviceInfo& info) +{ + if (!info.isFormatSupported(format)) + { + QAudioFormat newFormat = info.nearestFormat(format); + qWarning(Gui).nospace() << "Preferred format " << format << " is not supported by device " + << info.deviceName() << "."; + qWarning(Gui) << "Trying to use nearest format" << newFormat; + format = newFormat; + } +} + void MainWindow::initializeAudio(const QAudioDeviceInfo& inputDeviceInfo, const QAudioDeviceInfo& outputDeviceInfo, const QAudioDeviceInfo& monitorDeviceInfo) @@ -94,24 +106,9 @@ void MainWindow::initializeAudio(const QAudioDeviceInfo& inputDeviceInfo, auto outputFormat = getOutputFormat(); auto monitorFormat = getMonitorFormat(); - if (!inputDeviceInfo.isFormatSupported(captureFormat)) - { - qWarning(Gui) - << "Preferred format is not supported by input device - trying to use nearest"; - captureFormat = inputDeviceInfo.nearestFormat(captureFormat); - } - if (!monitorDeviceInfo.isFormatSupported(monitorFormat)) - { - qWarning(Gui) - << "Preferred format is not supported by monitor device - trying to use nearest"; - monitorFormat = inputDeviceInfo.nearestFormat(monitorFormat); - } - if (!outputDeviceInfo.isFormatSupported(outputFormat)) - { - qWarning(Gui) - << "Preferred format is not supported by output device - trying to use nearest"; - outputFormat = inputDeviceInfo.nearestFormat(outputFormat); - } + fixFormatForDevice(captureFormat, inputDeviceInfo); + fixFormatForDevice(outputFormat, outputDeviceInfo); + fixFormatForDevice(monitorFormat, monitorDeviceInfo); audioInput_.reset(new QAudioInput(inputDeviceInfo, captureFormat)); audioOutput_.reset(new QAudioOutput(outputDeviceInfo, outputFormat));