From 90b1fae7991e58037f4526b2fedab7ce30fe8a36 Mon Sep 17 00:00:00 2001 From: f4exb Date: Wed, 18 May 2016 11:32:19 +0200 Subject: [PATCH] Multi device support: moved audio output multi client support to audio output object itself --- sdrbase/audio/audiooutput.cpp | 125 ++++++++++++++++++---------------- sdrbase/audio/audiooutput.h | 1 + sdrbase/dsp/dspengine.cpp | 23 ++----- sdrbase/dsp/dspengine.h | 1 - sdrbase/mainwindow.cpp | 11 ++- 5 files changed, 83 insertions(+), 78 deletions(-) diff --git a/sdrbase/audio/audiooutput.cpp b/sdrbase/audio/audiooutput.cpp index eecfc9901..868eee500 100644 --- a/sdrbase/audio/audiooutput.cpp +++ b/sdrbase/audio/audiooutput.cpp @@ -24,7 +24,8 @@ AudioOutput::AudioOutput() : m_mutex(), - m_audioOutput(NULL), + m_audioOutput(0), + m_audioUsageCount(0), m_audioFifos() { } @@ -47,73 +48,83 @@ bool AudioOutput::start(int device, int rate) { QMutexLocker mutexLocker(&m_mutex); - //Q_UNUSED(device); - //Q_UNUSED(rate); - - QAudioDeviceInfo devInfo; - - if (device < 0) + if (m_audioUsageCount == 0) { - devInfo = QAudioDeviceInfo::defaultOutputDevice(); - qWarning("AudioOutput::start: using default device %s", qPrintable(devInfo.defaultOutputDevice().deviceName())); - } - else - { - QList devicesInfo = QAudioDeviceInfo::availableDevices(QAudio::AudioOutput); + QAudioDeviceInfo devInfo; - if (device < devicesInfo.size()) - { - devInfo = devicesInfo[device]; - qWarning("AudioOutput::start: using audio device #%d: %s", device, qPrintable(devInfo.defaultOutputDevice().deviceName())); - } - else - { - devInfo = QAudioDeviceInfo::defaultOutputDevice(); - qWarning("AudioOutput::start: audio device #%d does not exist. Using default device %s", device, qPrintable(devInfo.defaultOutputDevice().deviceName())); - } + if (device < 0) + { + devInfo = QAudioDeviceInfo::defaultOutputDevice(); + qWarning("AudioOutput::start: using default device %s", qPrintable(devInfo.defaultOutputDevice().deviceName())); + } + else + { + QList devicesInfo = QAudioDeviceInfo::availableDevices(QAudio::AudioOutput); + + if (device < devicesInfo.size()) + { + devInfo = devicesInfo[device]; + qWarning("AudioOutput::start: using audio device #%d: %s", device, qPrintable(devInfo.defaultOutputDevice().deviceName())); + } + else + { + devInfo = QAudioDeviceInfo::defaultOutputDevice(); + qWarning("AudioOutput::start: audio device #%d does not exist. Using default device %s", device, qPrintable(devInfo.defaultOutputDevice().deviceName())); + } + } + + //QAudioDeviceInfo devInfo(QAudioDeviceInfo::defaultOutputDevice()); + + m_audioFormat.setSampleRate(rate); + m_audioFormat.setChannelCount(2); + m_audioFormat.setSampleSize(16); + m_audioFormat.setCodec("audio/pcm"); + m_audioFormat.setByteOrder(QAudioFormat::LittleEndian); + m_audioFormat.setSampleType(QAudioFormat::SignedInt); + + if (!devInfo.isFormatSupported(m_audioFormat)) + { + m_audioFormat = devInfo.nearestFormat(m_audioFormat); + qWarning("AudioOutput::start: %d Hz S16_LE audio format not supported. New rate: %d", rate, m_audioFormat.sampleRate()); + } + + if (m_audioFormat.sampleSize() != 16) + { + qWarning("AudioOutput::start: Audio device ( %s ) failed", qPrintable(devInfo.defaultOutputDevice().deviceName())); + return false; + } + + m_audioOutput = new QAudioOutput(devInfo, m_audioFormat); + + QIODevice::open(QIODevice::ReadOnly); + + m_audioOutput->start(this); + + if (m_audioOutput->state() != QAudio::ActiveState) + { + qWarning("AudioOutput::start: cannot start"); + } } - //QAudioDeviceInfo devInfo(QAudioDeviceInfo::defaultOutputDevice()); - - m_audioFormat.setSampleRate(rate); - m_audioFormat.setChannelCount(2); - m_audioFormat.setSampleSize(16); - m_audioFormat.setCodec("audio/pcm"); - m_audioFormat.setByteOrder(QAudioFormat::LittleEndian); - m_audioFormat.setSampleType(QAudioFormat::SignedInt); - - if (!devInfo.isFormatSupported(m_audioFormat)) - { - m_audioFormat = devInfo.nearestFormat(m_audioFormat); - qWarning("AudioOutput::start: %d Hz S16_LE audio format not supported. New rate: %d", rate, m_audioFormat.sampleRate()); - } - - if (m_audioFormat.sampleSize() != 16) - { - qWarning("AudioOutput::start: Audio device ( %s ) failed", qPrintable(devInfo.defaultOutputDevice().deviceName())); - return false; - } - - m_audioOutput = new QAudioOutput(devInfo, m_audioFormat); - - QIODevice::open(QIODevice::ReadOnly); - - m_audioOutput->start(this); - - if (m_audioOutput->state() != QAudio::ActiveState) - { - qWarning("AudioOutput::start: cannot start"); - } + m_audioUsageCount++; return true; - } void AudioOutput::stop() { QMutexLocker mutexLocker(&m_mutex); - QIODevice::close(); - delete m_audioOutput; + + if (m_audioUsageCount > 0) + { + m_audioUsageCount--; + + if (m_audioUsageCount == 0) + { + QIODevice::close(); + delete m_audioOutput; + } + } } void AudioOutput::addFifo(AudioFifo* audioFifo) diff --git a/sdrbase/audio/audiooutput.h b/sdrbase/audio/audiooutput.h index eeb802333..790ae941f 100644 --- a/sdrbase/audio/audiooutput.h +++ b/sdrbase/audio/audiooutput.h @@ -45,6 +45,7 @@ public: private: QMutex m_mutex; QAudioOutput* m_audioOutput; + uint m_audioUsageCount; typedef std::list AudioFifos; AudioFifos m_audioFifos; diff --git a/sdrbase/dsp/dspengine.cpp b/sdrbase/dsp/dspengine.cpp index 43c06642d..aee4cb648 100644 --- a/sdrbase/dsp/dspengine.cpp +++ b/sdrbase/dsp/dspengine.cpp @@ -21,10 +21,8 @@ DSPEngine::DSPEngine() : m_deviceEnginesUIDSequence(0), - m_audioSampleRate(48000), // Use default output device at 48 kHz - m_audioUsageCount(0) + m_audioSampleRate(48000) // Use default output device at 48 kHz { - //m_deviceEngines.push_back(new DSPDeviceEngine(0)); // TODO: multi device support m_dvSerialSupport = false; } @@ -88,26 +86,13 @@ void DSPEngine::stopAllDeviceEngines() void DSPEngine::startAudio() { - if (m_audioUsageCount == 0) - { - m_audioOutput.start(-1, m_audioSampleRate); - m_audioSampleRate = m_audioOutput.getRate(); // update with actual rate - } - - m_audioUsageCount++; + m_audioOutput.start(-1, m_audioSampleRate); + m_audioSampleRate = m_audioOutput.getRate(); // update with actual rate } void DSPEngine::stopAudio() { - if (m_audioUsageCount > 0) - { - m_audioUsageCount--; - - if (m_audioUsageCount == 0) - { - m_audioOutput.stop(); - } - } + m_audioOutput.stop(); } void DSPEngine::startAudioImmediate() diff --git a/sdrbase/dsp/dspengine.h b/sdrbase/dsp/dspengine.h index e12147d28..07b13cf1e 100644 --- a/sdrbase/dsp/dspengine.h +++ b/sdrbase/dsp/dspengine.h @@ -89,7 +89,6 @@ private: AudioOutput m_audioOutput; uint m_audioSampleRate; bool m_dvSerialSupport; - uint m_audioUsageCount; #ifdef DSD_USE_SERIALDV DVSerialEngine m_dvSerialEngine; #endif diff --git a/sdrbase/mainwindow.cpp b/sdrbase/mainwindow.cpp index aced2e5db..122ccea01 100644 --- a/sdrbase/mainwindow.cpp +++ b/sdrbase/mainwindow.cpp @@ -223,9 +223,18 @@ void MainWindow::removeLastDevice() ui->tabChannels->removeTab(ui->tabChannels->count() - 1); - ui->tabInputsView->removeTab(ui->tabInputsView->count() - 1); ui->tabInputsSelect->removeTab(ui->tabInputsSelect->count() - 1); + m_deviceWidgetTabs.removeLast(); + ui->tabInputsView->clear(); + + for (int i = 0; i < m_deviceWidgetTabs.size(); i++) + { + qDebug("MainWindow::removeLastDevice: adding back tab for %s", m_deviceWidgetTabs[i].displayName.toStdString().c_str()); + ui->tabInputsView->addTab(m_deviceWidgetTabs[i].gui, m_deviceWidgetTabs[i].tabName); + ui->tabInputsView->setTabToolTip(i, m_deviceWidgetTabs[i].displayName); + } + delete m_deviceUIs.back(); lastDeviceEngine->stop();