From b7567422e96e6aa455f971abe8c6686f44eeba21 Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Thu, 17 Nov 2022 14:50:16 +0000 Subject: [PATCH] Add support for Qt6 audio --- sdrbase/audio/audiodeviceinfo.cpp | 132 +++++++++++++++++++++++++++ sdrbase/audio/audiodeviceinfo.h | 82 +++++++++++++++++ sdrbase/audio/audiodevicemanager.cpp | 9 +- sdrbase/audio/audiodevicemanager.h | 10 +- sdrbase/audio/audioinputdevice.cpp | 46 ++++++++-- sdrbase/audio/audioinputdevice.h | 8 ++ sdrbase/audio/audiooutputdevice.cpp | 73 ++++++++++++--- sdrbase/audio/audiooutputdevice.h | 9 ++ sdrbase/webapi/webapiadapter.cpp | 9 +- sdrgui/gui/audiodialog.cpp | 12 +-- sdrgui/gui/audioselectdialog.cpp | 9 +- 11 files changed, 353 insertions(+), 46 deletions(-) create mode 100644 sdrbase/audio/audiodeviceinfo.cpp create mode 100644 sdrbase/audio/audiodeviceinfo.h diff --git a/sdrbase/audio/audiodeviceinfo.cpp b/sdrbase/audio/audiodeviceinfo.cpp new file mode 100644 index 000000000..a5f68e2e0 --- /dev/null +++ b/sdrbase/audio/audiodeviceinfo.cpp @@ -0,0 +1,132 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2022 Jon Beniston, M7RCE // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation as version 3 of the License, or // +// (at your option) any later version. // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#include "audiodeviceinfo.h" + +QString AudioDeviceInfo::deviceName() const +{ +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + return m_deviceInfo.description(); +#else + return m_deviceInfo.deviceName(); +#endif +} + +bool AudioDeviceInfo::isFormatSupported(const QAudioFormat &settings) const +{ + return m_deviceInfo.isFormatSupported(settings); +} + +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) +QList AudioDeviceInfo::supportedSampleRates() const +{ + // QAudioDevice is a bit more flexible than QAudioDeviceInfo, in that it supports + // min and max rate, rather than a specific list + // For now, we just list some common rates. + QList sampleRates = {8000, 11025, 22050, 44100, 48000, 96000, 192000}; + QList supportedRates; + for (auto sampleRate : sampleRates) + { + if ((sampleRate <= m_deviceInfo.maximumSampleRate()) && (sampleRate >= m_deviceInfo.minimumSampleRate())) { + supportedRates.append(sampleRate); + } + } + return supportedRates; +} +#else +QList AudioDeviceInfo::supportedSampleRates() const +{ + return m_deviceInfo.supportedSampleRates(); +} +#endif + +QString AudioDeviceInfo::realm() const +{ +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + return ""; // Don't appear to have realms in Qt6 +#else + return m_deviceInfo.realm(); +#endif +} + +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) +QList AudioDeviceInfo::availableInputDevices() +{ + QList devInfos = QMediaDevices::audioInputs(); + QList list; + + for (auto devInfo : devInfos) { + list.append(AudioDeviceInfo(devInfo)); + } + + return list; +} + +QList AudioDeviceInfo::availableOutputDevices() +{ + QList devInfos = QMediaDevices::audioOutputs(); + QList list; + + for (auto devInfo : devInfos) { + list.append(AudioDeviceInfo(devInfo)); + } + + return list; +} +#else +QList AudioDeviceInfo::availableInputDevices() +{ + QList devInfos = QAudioDeviceInfo::availableDevices(QAudio::AudioInput); + QList list; + + for (auto devInfo : devInfos) { + list.append(AudioDeviceInfo(devInfo)); + } + + return list; +} + +QList AudioDeviceInfo::availableOutputDevices() +{ + QList devInfos = QAudioDeviceInfo::availableDevices(QAudio::AudioOutput); + QList list; + + for (auto devInfo : devInfos) { + list.append(AudioDeviceInfo(devInfo)); + } + + return list; +} +#endif + +AudioDeviceInfo AudioDeviceInfo::defaultOutputDevice() +{ +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + return AudioDeviceInfo(QMediaDevices::defaultAudioOutput()); +#else + return AudioDeviceInfo(QAudioDeviceInfo::defaultOutputDevice()); +#endif +} + +AudioDeviceInfo AudioDeviceInfo::defaultInputDevice() +{ +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + return AudioDeviceInfo(QMediaDevices::defaultAudioInput()); +#else + return AudioDeviceInfo(QAudioDeviceInfo::defaultInputDevice()); +#endif +} diff --git a/sdrbase/audio/audiodeviceinfo.h b/sdrbase/audio/audiodeviceinfo.h new file mode 100644 index 000000000..b5df24ec1 --- /dev/null +++ b/sdrbase/audio/audiodeviceinfo.h @@ -0,0 +1,82 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2022 Jon Beniston, M7RCE // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation as version 3 of the License, or // +// (at your option) any later version. // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#ifndef INCLUDE_AUDIODEVICEINFO_H +#define INCLUDE_AUDIODEVICEINFO_H + +#include +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) +#include +#include +#else +#include +#endif + +#include "export.h" + +// Wrapper around QT6's QAudioDevice and and QT5's QAudioDeviceInfo +class SDRBASE_API AudioDeviceInfo { + +public: + +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + AudioDeviceInfo() : + m_deviceInfo() + { + } + + AudioDeviceInfo(QAudioDevice deviceInfo) : + m_deviceInfo(deviceInfo) + { + } + + QAudioDevice deviceInfo() { return m_deviceInfo; } +#else + AudioDeviceInfo() : + m_deviceInfo() + { + } + + AudioDeviceInfo(QAudioDeviceInfo deviceInfo) : + m_deviceInfo(deviceInfo) + { + } + + QAudioDeviceInfo deviceInfo() { return m_deviceInfo; } +#endif + + QString deviceName() const; + QString realm() const; + bool isFormatSupported(const QAudioFormat &settings) const; + QList supportedSampleRates() const; + + static QList availableInputDevices(); + static QList availableOutputDevices(); + static AudioDeviceInfo defaultInputDevice(); + static AudioDeviceInfo defaultOutputDevice(); + +private: + +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + QAudioDevice m_deviceInfo; +#else + QAudioDeviceInfo m_deviceInfo; +#endif + +}; + +#endif // INCLUDE_AUDIODEVICEINFO_H diff --git a/sdrbase/audio/audiodevicemanager.cpp b/sdrbase/audio/audiodevicemanager.cpp index d8101274c..382b756ec 100644 --- a/sdrbase/audio/audiodevicemanager.cpp +++ b/sdrbase/audio/audiodevicemanager.cpp @@ -79,14 +79,15 @@ QDataStream& operator>>(QDataStream& ds, AudioDeviceManager::OutputDeviceInfo& i AudioDeviceManager::AudioDeviceManager() { qDebug("AudioDeviceManager::AudioDeviceManager: scan input devices"); - m_inputDevicesInfo = QAudioDeviceInfo::availableDevices(QAudio::AudioInput); + m_inputDevicesInfo = AudioDeviceInfo::availableInputDevices(); for (int i = 0; i < m_inputDevicesInfo.size(); i++) { qDebug("AudioDeviceManager::AudioDeviceManager: input device #%d: %s", i, qPrintable(m_inputDevicesInfo[i].deviceName())); } qDebug("AudioDeviceManager::AudioDeviceManager: scan output devices"); - m_outputDevicesInfo = QAudioDeviceInfo::availableDevices(QAudio::AudioOutput); + + m_outputDevicesInfo = AudioDeviceInfo::availableOutputDevices(); for (int i = 0; i < m_outputDevicesInfo.size(); i++) { qDebug("AudioDeviceManager::AudioDeviceManager: output device #%d: %s", i, qPrintable(m_outputDevicesInfo[i].deviceName())); @@ -737,7 +738,7 @@ void AudioDeviceManager::inputInfosCleanup() { QSet deviceNames; deviceNames.insert(m_defaultDeviceName); - QList::const_iterator itd = m_inputDevicesInfo.begin(); + QList::const_iterator itd = m_inputDevicesInfo.begin(); for (; itd != m_inputDevicesInfo.end(); ++itd) { @@ -765,7 +766,7 @@ void AudioDeviceManager::outputInfosCleanup() { QSet deviceNames; deviceNames.insert(m_defaultDeviceName); - QList::const_iterator itd = m_outputDevicesInfo.begin(); + QList::const_iterator itd = m_outputDevicesInfo.begin(); for (; itd != m_outputDevicesInfo.end(); ++itd) { diff --git a/sdrbase/audio/audiodevicemanager.h b/sdrbase/audio/audiodevicemanager.h index 2966d6f41..6f260deee 100644 --- a/sdrbase/audio/audiodevicemanager.h +++ b/sdrbase/audio/audiodevicemanager.h @@ -22,10 +22,10 @@ #include #include #include -#include #include "audio/audioinputdevice.h" #include "audio/audiooutputdevice.h" +#include "audio/audiodeviceinfo.h" #include "export.h" class QDataStream; @@ -97,8 +97,8 @@ public: AudioDeviceManager(); ~AudioDeviceManager(); - const QList& getInputDevices() const { return m_inputDevicesInfo; } - const QList& getOutputDevices() const { return m_outputDevicesInfo; } + const QList& getInputDevices() const { return m_inputDevicesInfo; } + const QList& getOutputDevices() const { return m_outputDevicesInfo; } bool getOutputDeviceName(int outputDeviceIndex, QString &deviceName) const; bool getInputDeviceName(int inputDeviceIndex, QString &deviceName) const; @@ -129,8 +129,8 @@ public: static const QString m_defaultDeviceName; private: - QList m_inputDevicesInfo; - QList m_outputDevicesInfo; + QList m_inputDevicesInfo; + QList m_outputDevicesInfo; QMap m_audioSinkFifos; //< audio sink FIFO to audio output device index-1 map QMap m_audioFifoToSinkMessageQueues; //!< audio sink FIFO to attached sink message queue diff --git a/sdrbase/audio/audioinputdevice.cpp b/sdrbase/audio/audioinputdevice.cpp index 2fcc91e10..a1ccb0d70 100644 --- a/sdrbase/audio/audioinputdevice.cpp +++ b/sdrbase/audio/audioinputdevice.cpp @@ -16,10 +16,15 @@ /////////////////////////////////////////////////////////////////////////////////// #include +#include #include -#include +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) +#include +#else #include +#endif #include "audio/audioinputdevice.h" +#include "audio/audiodeviceinfo.h" #include "audio/audiofifo.h" AudioInputDevice::AudioInputDevice() : @@ -50,16 +55,16 @@ bool AudioInputDevice::start(int device, int rate) if (m_audioUsageCount == 0) { QMutexLocker mutexLocker(&m_mutex); - QAudioDeviceInfo devInfo; + AudioDeviceInfo devInfo; if (device < 0) { - devInfo = QAudioDeviceInfo::defaultInputDevice(); + devInfo = AudioDeviceInfo::defaultInputDevice(); qWarning("AudioInputDevice::start: using default device %s", qPrintable(devInfo.defaultInputDevice().deviceName())); } else { - QList devicesInfo = QAudioDeviceInfo::availableDevices(QAudio::AudioInput); + QList devicesInfo = AudioDeviceInfo::availableInputDevices(); if (device < devicesInfo.size()) { @@ -68,7 +73,7 @@ bool AudioInputDevice::start(int device, int rate) } else { - devInfo = QAudioDeviceInfo::defaultInputDevice(); + devInfo = AudioDeviceInfo::defaultInputDevice(); qWarning("AudioInputDevice::start: audio device #%d does not exist. Using default device %s", device, qPrintable(devInfo.deviceName())); } } @@ -77,29 +82,49 @@ bool AudioInputDevice::start(int device, int rate) m_audioFormat.setSampleRate(rate); m_audioFormat.setChannelCount(2); +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + m_audioFormat.setSampleFormat(QAudioFormat::Int16); +#else m_audioFormat.setSampleSize(16); m_audioFormat.setCodec("audio/pcm"); m_audioFormat.setByteOrder(QAudioFormat::LittleEndian); m_audioFormat.setSampleType(QAudioFormat::SignedInt); // Unknown, SignedInt, UnSignedInt, Float +#endif if (!devInfo.isFormatSupported(m_audioFormat)) { - m_audioFormat = devInfo.nearestFormat(m_audioFormat); +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + qWarning("AudioInputDevice::start: %d Hz S16_LE audio format not supported."); +#else + m_audioFormat = devInfo.deviceInfo().nearestFormat(m_audioFormat); qWarning("AudioInputDevice::start: %d Hz S16_LE audio format not supported. Nearest is sampleRate: %d channelCount: %d sampleSize: %d sampleType: %d", rate, m_audioFormat.sampleRate(), m_audioFormat.channelCount(), m_audioFormat.sampleSize(), (int) m_audioFormat.sampleType()); +#endif } else { qInfo("AudioInputDevice::start: audio format OK"); } - if (m_audioFormat.sampleSize() != 16) +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + if (m_audioFormat.sampleFormat() != QAudioFormat::Int16) { - qWarning("AudioInputDevice::start: Audio device '%s' failed", qPrintable(devInfo.defaultInputDevice().deviceName())); + qWarning("AudioInputDevice::start: Audio device '%s' failed", qPrintable(devInfo.deviceName())); return false; } +#else + if (m_audioFormat.sampleSize() != 16) + { + qWarning("AudioInputDevice::start: Audio device '%s' failed", qPrintable(devInfo.deviceName())); + return false; + } +#endif - m_audioInput = new QAudioInput(devInfo, m_audioFormat); +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + m_audioInput = new QAudioSource(devInfo.deviceInfo(), m_audioFormat); +#else + m_audioInput = new QAudioInput(devInfo.deviceInfo(), m_audioFormat); +#endif m_audioInput->setVolume(m_volume); QIODevice::open(QIODevice::ReadWrite); @@ -167,6 +192,8 @@ qint64 AudioInputDevice::writeData(const char *data, qint64 len) // QMutexLocker mutexLocker(&m_mutex); //#endif +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) +#else if ((m_audioFormat.sampleSize() != 16) || (m_audioFormat.sampleType() != QAudioFormat::SignedInt) || (m_audioFormat.byteOrder() != QAudioFormat::LittleEndian)) @@ -174,6 +201,7 @@ qint64 AudioInputDevice::writeData(const char *data, qint64 len) qCritical("AudioInputDevice::writeData: invalid format not S16LE"); return 0; } +#endif if (m_audioFormat.channelCount() != 2) { qCritical("AudioInputDevice::writeData: invalid format not stereo"); diff --git a/sdrbase/audio/audioinputdevice.h b/sdrbase/audio/audioinputdevice.h index 0973ac51b..8f3214a39 100644 --- a/sdrbase/audio/audioinputdevice.h +++ b/sdrbase/audio/audioinputdevice.h @@ -25,7 +25,11 @@ #include #include "export.h" +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) +class QAudioSource; +#else class QAudioInput; +#endif class AudioFifo; class AudioOutputPipe; @@ -48,7 +52,11 @@ public: private: QRecursiveMutex m_mutex; +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + QAudioSource* m_audioInput; +#else QAudioInput* m_audioInput; +#endif uint m_audioUsageCount; bool m_onExit; float m_volume; diff --git a/sdrbase/audio/audiooutputdevice.cpp b/sdrbase/audio/audiooutputdevice.cpp index 4c445e6eb..32d32c840 100644 --- a/sdrbase/audio/audiooutputdevice.cpp +++ b/sdrbase/audio/audiooutputdevice.cpp @@ -18,9 +18,13 @@ #include #include -#include +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) +#include +#else #include +#endif #include "audiooutputdevice.h" +#include "audiodeviceinfo.h" #include "audiofifo.h" #include "audionetsink.h" #include "dsp/wavfilerecord.h" @@ -59,20 +63,19 @@ AudioOutputDevice::~AudioOutputDevice() bool AudioOutputDevice::start(int device, int rate) { - // if (m_audioUsageCount == 0) // { QMutexLocker mutexLocker(&m_mutex); - QAudioDeviceInfo devInfo; + AudioDeviceInfo devInfo; if (device < 0) { - devInfo = QAudioDeviceInfo::defaultOutputDevice(); + devInfo = AudioDeviceInfo::defaultOutputDevice(); qWarning("AudioOutputDevice::start: using system default device %s", qPrintable(devInfo.defaultOutputDevice().deviceName())); } else { - QList devicesInfo = QAudioDeviceInfo::availableDevices(QAudio::AudioOutput); + QList devicesInfo = AudioDeviceInfo::availableOutputDevices(); if (device < devicesInfo.size()) { @@ -81,23 +84,34 @@ bool AudioOutputDevice::start(int device, int rate) } else { - devInfo = QAudioDeviceInfo::defaultOutputDevice(); + devInfo = AudioDeviceInfo::defaultOutputDevice(); qWarning("AudioOutputDevice::start: audio device #%d does not exist. Using system default device %s", device, qPrintable(devInfo.defaultOutputDevice().deviceName())); } } //QAudioDeviceInfo devInfo(QAudioDeviceInfo::defaultOutputDevice()); +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + // Start with a valid format + m_audioFormat = devInfo.deviceInfo().preferredFormat(); +#endif m_audioFormat.setSampleRate(rate); m_audioFormat.setChannelCount(2); +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + m_audioFormat.setSampleFormat(QAudioFormat::Int16); +#else m_audioFormat.setSampleSize(16); m_audioFormat.setCodec("audio/pcm"); m_audioFormat.setByteOrder(QAudioFormat::LittleEndian); m_audioFormat.setSampleType(QAudioFormat::SignedInt); +#endif if (!devInfo.isFormatSupported(m_audioFormat)) { - m_audioFormat = devInfo.nearestFormat(m_audioFormat); +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + qWarning("AudioOutputDevice::start: format %d Hz 2xS16LE audio/pcm not supported.", rate); +#else + m_audioFormat = devInfo.deviceInfo().nearestFormat(m_audioFormat); std::ostringstream os; os << " sampleRate: " << m_audioFormat.sampleRate() << " channelCount: " << m_audioFormat.channelCount() @@ -106,19 +120,32 @@ bool AudioOutputDevice::start(int device, int rate) << " byteOrder: " << (m_audioFormat.byteOrder() == QAudioFormat::BigEndian ? "BE" : "LE") << " sampleType: " << (int) m_audioFormat.sampleType(); qWarning("AudioOutputDevice::start: format %d Hz 2xS16LE audio/pcm not supported. Using: %s", rate, os.str().c_str()); +#endif } else { qInfo("AudioOutputDevice::start: audio format OK"); } - if (m_audioFormat.sampleSize() != 16) +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + if (m_audioFormat.sampleFormat() != QAudioFormat::Int16) { - qWarning("AudioOutputDevice::start: Audio device '%s' failed", qPrintable(devInfo.defaultOutputDevice().deviceName())); + qWarning("AudioOutputDevice::start: Audio device '%s' failed", qPrintable(devInfo.deviceName())); return false; } +#else + if (m_audioFormat.sampleSize() != 16) + { + qWarning("AudioOutputDevice::start: Audio device '%s' failed", qPrintable(devInfo.deviceName())); + return false; + } +#endif - m_audioOutput = new QAudioOutput(devInfo, m_audioFormat); +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + m_audioOutput = new QAudioSink(devInfo.deviceInfo(), m_audioFormat); +#else + m_audioOutput = new QAudioOutput(devInfo.deviceInfo(), m_audioFormat); +#endif m_audioNetSink = new AudioNetSink(0, m_audioFormat.sampleRate(), false); m_wavFileRecord = new WavFileRecord(m_audioFormat.sampleRate()); m_audioOutput->setVolume(m_volume); @@ -129,7 +156,7 @@ bool AudioOutputDevice::start(int device, int rate) m_audioOutput->start(this); if (m_audioOutput->state() != QAudio::ActiveState) { - qWarning("AudioOutputDevice::start: cannot start"); + qWarning() << "AudioOutputDevice::start: cannot start - " << m_audioOutput->error(); } // } // @@ -295,8 +322,6 @@ void AudioOutputDevice::setRecordSilenceTime(int recordSilenceTime) qint64 AudioOutputDevice::readData(char* data, qint64 maxLen) { - //qDebug("AudioOutputDevice::readData: %lld", maxLen); - // Study this mutex on OSX, for now deadlocks possible // Removed as it may indeed cause lockups and is in fact useless. //#ifndef __APPLE__ @@ -475,3 +500,25 @@ void AudioOutputDevice::setVolume(float volume) m_audioOutput->setVolume(m_volume); } } + +// Qt6 requires bytesAvailable to be implemented. Not needed for Qt5. +qint64 AudioOutputDevice::bytesAvailable() const +{ + qint64 available = 0; + for (std::list::const_iterator it = m_audioFifos.begin(); it != m_audioFifos.end(); ++it) + { + qint64 fill = (*it)->fill(); + if (available == 0) { + available = fill; + } else { + available = std::min(fill, available); + } + } + // If we return 0 from this twice in a row, audio will stop. + // So we always return a value, and if we don't have enough data in the FIFOs + // when readData is called, that will output silence + if (available == 0) { + available = 2048; // Is there a better value to use? + } + return available * 2 * 2; // 2 Channels of 16-bit data +} diff --git a/sdrbase/audio/audiooutputdevice.h b/sdrbase/audio/audiooutputdevice.h index 411a00e2b..32e7be13d 100644 --- a/sdrbase/audio/audiooutputdevice.h +++ b/sdrbase/audio/audiooutputdevice.h @@ -27,7 +27,11 @@ #include #include "export.h" +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) +class QAudioSink; +#else class QAudioOutput; +#endif class AudioFifo; class AudioOutputPipe; class AudioNetSink; @@ -79,7 +83,11 @@ public: private: QRecursiveMutex m_mutex; +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + QAudioSink* m_audioOutput; +#else QAudioOutput* m_audioOutput; +#endif AudioNetSink* m_audioNetSink; WavFileRecord* m_wavFileRecord; bool m_copyAudioToUdp; @@ -102,6 +110,7 @@ private: //virtual bool open(OpenMode mode); virtual qint64 readData(char* data, qint64 maxLen); virtual qint64 writeData(const char* data, qint64 len); + virtual qint64 bytesAvailable() const override; void writeSampleToFile(qint16 lSample, qint16 rSample); friend class AudioOutputPipe; diff --git a/sdrbase/webapi/webapiadapter.cpp b/sdrbase/webapi/webapiadapter.cpp index d5960cf89..df865087c 100644 --- a/sdrbase/webapi/webapiadapter.cpp +++ b/sdrbase/webapi/webapiadapter.cpp @@ -24,6 +24,7 @@ #include "maincore.h" #include "loggerwithfile.h" +#include "audio/audiodeviceinfo.h" #include "device/deviceapi.h" #include "device/deviceset.h" #include "device/deviceenumerator.h" @@ -448,8 +449,8 @@ int WebAPIAdapter::instanceAudioGet( { (void) error; DSPEngine *dspEngine = DSPEngine::instance(); - const QList& audioInputDevices = dspEngine->getAudioDeviceManager()->getInputDevices(); - const QList& audioOutputDevices = dspEngine->getAudioDeviceManager()->getOutputDevices(); + const QList& audioInputDevices = dspEngine->getAudioDeviceManager()->getInputDevices(); + const QList& audioOutputDevices = dspEngine->getAudioDeviceManager()->getOutputDevices(); int nbInputDevices = audioInputDevices.size(); int nbOutputDevices = audioOutputDevices.size(); @@ -482,7 +483,7 @@ int WebAPIAdapter::instanceAudioGet( *inputDevices->back()->getName() = audioInputDevices.at(i).deviceName(); inputDevices->back()->setIndex(i); inputDevices->back()->setSampleRate(inputDeviceInfo.sampleRate); - inputDevices->back()->setIsSystemDefault(audioInputDevices.at(i).deviceName() == QAudioDeviceInfo::defaultInputDevice().deviceName() ? 1 : 0); + inputDevices->back()->setIsSystemDefault(audioInputDevices.at(i).deviceName() == AudioDeviceInfo::defaultInputDevice().deviceName() ? 1 : 0); inputDevices->back()->setDefaultUnregistered(found ? 0 : 1); inputDevices->back()->setVolume(inputDeviceInfo.volume); } @@ -517,7 +518,7 @@ int WebAPIAdapter::instanceAudioGet( *outputDevices->back()->getName() = audioOutputDevices.at(i).deviceName(); outputDevices->back()->setIndex(i); outputDevices->back()->setSampleRate(outputDeviceInfo.sampleRate); - outputDevices->back()->setIsSystemDefault(audioOutputDevices.at(i).deviceName() == QAudioDeviceInfo::defaultOutputDevice().deviceName() ? 1 : 0); + outputDevices->back()->setIsSystemDefault(audioOutputDevices.at(i).deviceName() == AudioDeviceInfo::defaultOutputDevice().deviceName() ? 1 : 0); outputDevices->back()->setDefaultUnregistered(found ? 0 : 1); outputDevices->back()->setCopyToUdp(outputDeviceInfo.copyToUDP ? 1 : 0); outputDevices->back()->setUdpUsesRtp(outputDeviceInfo.udpUseRTP ? 1 : 0); diff --git a/sdrgui/gui/audiodialog.cpp b/sdrgui/gui/audiodialog.cpp index 7b8cadd4e..b379aead3 100644 --- a/sdrgui/gui/audiodialog.cpp +++ b/sdrgui/gui/audiodialog.cpp @@ -37,16 +37,16 @@ AudioDialogX::AudioDialogX(AudioDeviceManager* audioDeviceManager, QWidget* pare // out panel AudioDeviceManager::OutputDeviceInfo outDeviceInfo; - QAudioDeviceInfo defaultOutputDeviceInfo = QAudioDeviceInfo::defaultOutputDevice(); + AudioDeviceInfo defaultOutputDeviceInfo = AudioDeviceInfo::defaultOutputDevice(); treeItem = new QTreeWidgetItem(ui->audioOutTree); treeItem->setText(1, AudioDeviceManager::m_defaultDeviceName); bool found = m_audioDeviceManager->getOutputDeviceInfo(AudioDeviceManager::m_defaultDeviceName, outDeviceInfo); treeItem->setText(0, found ? "__" : "_D"); ui->audioOutTree->setCurrentItem(treeItem); - const QList& outputDevices = m_audioDeviceManager->getOutputDevices(); + const QList& outputDevices = m_audioDeviceManager->getOutputDevices(); - for(QList::const_iterator it = outputDevices.begin(); it != outputDevices.end(); ++it) + for(QList::const_iterator it = outputDevices.begin(); it != outputDevices.end(); ++it) { treeItem = new QTreeWidgetItem(ui->audioOutTree); treeItem->setText(1, it->deviceName()); @@ -65,16 +65,16 @@ AudioDialogX::AudioDialogX(AudioDeviceManager* audioDeviceManager, QWidget* pare // in panel AudioDeviceManager::InputDeviceInfo inDeviceInfo; - QAudioDeviceInfo defaultInputDeviceInfo = QAudioDeviceInfo::defaultInputDevice(); + AudioDeviceInfo defaultInputDeviceInfo = AudioDeviceInfo::defaultInputDevice(); treeItem = new QTreeWidgetItem(ui->audioInTree); treeItem->setText(1, AudioDeviceManager::m_defaultDeviceName); found = m_audioDeviceManager->getInputDeviceInfo(AudioDeviceManager::m_defaultDeviceName, inDeviceInfo); treeItem->setText(0, found ? "__" : "_D"); ui->audioInTree->setCurrentItem(treeItem); - const QList& inputDevices = m_audioDeviceManager->getInputDevices(); + const QList& inputDevices = m_audioDeviceManager->getInputDevices(); - for(QList::const_iterator it = inputDevices.begin(); it != inputDevices.end(); ++it) + for(QList::const_iterator it = inputDevices.begin(); it != inputDevices.end(); ++it) { treeItem = new QTreeWidgetItem(ui->audioInTree); treeItem->setText(1, it->deviceName()); diff --git a/sdrgui/gui/audioselectdialog.cpp b/sdrgui/gui/audioselectdialog.cpp index f33a5c89c..a01e7b381 100644 --- a/sdrgui/gui/audioselectdialog.cpp +++ b/sdrgui/gui/audioselectdialog.cpp @@ -33,7 +33,6 @@ AudioSelectDialog::AudioSelectDialog(const AudioDeviceManager* audioDeviceManage // panel - QAudioDeviceInfo defaultDeviceInfo = input ? QAudioDeviceInfo::defaultInputDevice() : QAudioDeviceInfo::defaultOutputDevice(); defaultItem = new QTreeWidgetItem(ui->audioTree); defaultItem->setText(1, AudioDeviceManager::m_defaultDeviceName); bool deviceFound = getDeviceInfos(input, AudioDeviceManager::m_defaultDeviceName, systemDefault, sampleRate); @@ -41,9 +40,9 @@ AudioSelectDialog::AudioSelectDialog(const AudioDeviceManager* audioDeviceManage defaultItem->setText(2, tr("%1").arg(sampleRate)); defaultItem->setTextAlignment(2, Qt::AlignRight); - QList devices = input ? m_audioDeviceManager->getInputDevices() : m_audioDeviceManager->getOutputDevices(); + QList devices = input ? m_audioDeviceManager->getInputDevices() : m_audioDeviceManager->getOutputDevices(); - for(QList::const_iterator it = devices.begin(); it != devices.end(); ++it) + for(QList::const_iterator it = devices.begin(); it != devices.end(); ++it) { treeItem = new QTreeWidgetItem(ui->audioTree); treeItem->setText(1, it->deviceName()); @@ -113,7 +112,7 @@ bool AudioSelectDialog::getDeviceInfos(bool input, const QString& deviceName, bo { AudioDeviceManager::InputDeviceInfo inDeviceInfo; found = m_audioDeviceManager->getInputDeviceInfo(deviceName, inDeviceInfo); - systemDefault = deviceName == QAudioDeviceInfo::defaultInputDevice().deviceName(); + systemDefault = deviceName == AudioDeviceInfo::defaultInputDevice().deviceName(); if (found) { sampleRate = inDeviceInfo.sampleRate; @@ -125,7 +124,7 @@ bool AudioSelectDialog::getDeviceInfos(bool input, const QString& deviceName, bo { AudioDeviceManager::OutputDeviceInfo outDeviceInfo; found = m_audioDeviceManager->getOutputDeviceInfo(deviceName, outDeviceInfo); - systemDefault = deviceName == QAudioDeviceInfo::defaultOutputDevice().deviceName(); + systemDefault = deviceName == AudioDeviceInfo::defaultOutputDevice().deviceName(); if (found) { sampleRate = outDeviceInfo.sampleRate;