From a4b6edbf07266d53be9e1a9c5d4ccb9916bb5b4b Mon Sep 17 00:00:00 2001 From: f4exb Date: Sun, 25 Mar 2018 00:57:14 +0100 Subject: [PATCH] Multiple audio support: added ability to manage more than one audio input --- sdrbase/audio/audiodevicemanager.cpp | 93 ++++++++++++++-------------- sdrbase/audio/audiodevicemanager.h | 27 +++----- sdrgui/gui/audiodialog.cpp | 8 +-- sdrgui/webapi/webapiadaptergui.cpp | 11 ++-- sdrsrv/webapi/webapiadaptersrv.cpp | 11 ++-- 5 files changed, 65 insertions(+), 85 deletions(-) diff --git a/sdrbase/audio/audiodevicemanager.cpp b/sdrbase/audio/audiodevicemanager.cpp index 033aa0b53..54d044cdf 100644 --- a/sdrbase/audio/audiodevicemanager.cpp +++ b/sdrbase/audio/audiodevicemanager.cpp @@ -19,10 +19,7 @@ #include "util/simpleserializer.h" AudioDeviceManager::AudioDeviceManager(unsigned int defaultAudioSampleRate) : - m_defaultAudioSampleRate(defaultAudioSampleRate), - m_inputDeviceIndex(-1), // default device - m_audioInputSampleRate(48000), // Use default input device at 48 kHz - m_inputVolume(1.0f) + m_defaultAudioSampleRate(defaultAudioSampleRate) { m_inputDevicesInfo = QAudioDeviceInfo::availableDevices(QAudio::AudioInput); m_outputDevicesInfo = QAudioDeviceInfo::availableDevices(QAudio::AudioOutput); @@ -39,15 +36,11 @@ AudioDeviceManager::~AudioDeviceManager() void AudioDeviceManager::resetToDefaults() { - m_inputDeviceIndex = -1; - m_inputVolume = 1.0f; } QByteArray AudioDeviceManager::serialize() const { SimpleSerializer s(1); - s.writeS32(1, m_inputDeviceIndex); - s.writeFloat(3, m_inputVolume); return s.final(); } @@ -62,8 +55,6 @@ bool AudioDeviceManager::deserialize(const QByteArray& data) if(d.getVersion() == 1) { - d.readS32(1, &m_inputDeviceIndex, -1); - d.readFloat(3, &m_inputVolume, 1.0f); return true; } else @@ -73,26 +64,6 @@ bool AudioDeviceManager::deserialize(const QByteArray& data) } } -int AudioDeviceManager::getOutputDeviceIndex(AudioFifo* audioFifo) const -{ - if (m_audioSinkFifos.find(audioFifo) == m_audioSinkFifos.end()) { - return -2; // error - } else { - return m_audioSinkFifos[audioFifo]; - } -} - -void AudioDeviceManager::setInputDeviceIndex(int inputDeviceIndex) -{ - int nbDevices = m_inputDevicesInfo.size(); - m_inputDeviceIndex = inputDeviceIndex < -1 ? -1 : inputDeviceIndex >= nbDevices ? nbDevices-1 : inputDeviceIndex; -} - -void AudioDeviceManager::setInputVolume(float inputVolume) -{ - m_inputVolume = inputVolume < 0.0 ? 0.0 : inputVolume > 1.0 ? 1.0 : inputVolume; -} - void AudioDeviceManager::addAudioSink(AudioFifo* audioFifo, int outputDeviceIndex) { qDebug("AudioDeviceManager::addAudioSink: %d: %p", outputDeviceIndex, audioFifo); @@ -145,34 +116,62 @@ void AudioDeviceManager::removeAudioSink(AudioFifo* audioFifo) m_audioSinkFifos.remove(audioFifo); // unregister audio FIFO } -void AudioDeviceManager::addAudioSource(AudioFifo* audioFifo) +void AudioDeviceManager::addAudioSource(AudioFifo* audioFifo, int inputDeviceIndex) { - qDebug("AudioDeviceManager::addAudioSource"); + qDebug("AudioDeviceManager::addAudioSource: %d: %p", inputDeviceIndex, audioFifo); - if (m_audioInput.getNbFifos() == 0) { - startAudioInput(); + if (m_audioInputs.find(inputDeviceIndex) == m_audioInputs.end()) + { + m_audioInputs[inputDeviceIndex] = new AudioInput(); + m_audioInputSampleRates[inputDeviceIndex] = m_defaultAudioSampleRate; } - m_audioInput.addFifo(audioFifo); + if (m_audioInputs[inputDeviceIndex]->getNbFifos() == 0) { + startAudioInput(inputDeviceIndex); + } + + if (m_audioSourceFifos.find(audioFifo) == m_audioSourceFifos.end()) // new FIFO + { + m_audioInputs[inputDeviceIndex]->addFifo(audioFifo); + } + else + { + int audioInputDeviceIndex = m_audioSourceFifos[audioFifo]; + + if (audioInputDeviceIndex != inputDeviceIndex) // change of audio device + { + removeAudioSource(audioFifo); // remove from current + m_audioInputs[inputDeviceIndex]->addFifo(audioFifo); // add to new + } + } + + m_audioSourceFifos[audioFifo] = inputDeviceIndex; // register audio FIFO } void AudioDeviceManager::removeAudioSource(AudioFifo* audioFifo) { - qDebug("AudioDeviceManager::removeAudioSource"); + qDebug("AudioDeviceManager::removeAudioSource: %p", audioFifo); - m_audioInput.removeFifo(audioFifo); - - if (m_audioInput.getNbFifos() == 0) { - stopAudioInput(); + if (m_audioSourceFifos.find(audioFifo) == m_audioSourceFifos.end()) + { + qWarning("AudioDeviceManager::removeAudioSource: audio FIFO %p not found", audioFifo); + return; } + + int audioInputDeviceIndex = m_audioSourceFifos[audioFifo]; + m_audioOutputs[audioInputDeviceIndex]->removeFifo(audioFifo); + + if (m_audioOutputs[audioInputDeviceIndex]->getNbFifos() == 0) { + stopAudioInput(audioInputDeviceIndex); + } + + m_audioSourceFifos.remove(audioFifo); // unregister audio FIFO } void AudioDeviceManager::startAudioOutput(int outputDeviceIndex) { m_audioOutputs[outputDeviceIndex]->start(outputDeviceIndex, m_audioOutputSampleRates[outputDeviceIndex]); m_audioOutputSampleRates[outputDeviceIndex] = m_audioOutputs[outputDeviceIndex]->getRate(); // update with actual rate -// m_audioOutput.start(m_outputDeviceIndex, m_audioOutputSampleRate); -// m_audioOutputSampleRate = m_audioOutput.getRate(); // update with actual rate } void AudioDeviceManager::stopAudioOutput(int outputDeviceIndex) @@ -180,13 +179,13 @@ void AudioDeviceManager::stopAudioOutput(int outputDeviceIndex) m_audioOutputs[outputDeviceIndex]->stop(); } -void AudioDeviceManager::startAudioInput() +void AudioDeviceManager::startAudioInput(int inputDeviceIndex) { - m_audioInput.start(m_inputDeviceIndex, m_audioInputSampleRate); - m_audioInputSampleRate = m_audioInput.getRate(); // update with actual rate + m_audioInputs[inputDeviceIndex]->start(inputDeviceIndex, m_audioInputSampleRates[inputDeviceIndex]); + m_audioInputSampleRates[inputDeviceIndex] = m_audioInputs[inputDeviceIndex]->getRate(); // update with actual rate } -void AudioDeviceManager::stopAudioInput() +void AudioDeviceManager::stopAudioInput(int inputDeviceIndex) { - m_audioInput.stop(); + m_audioInputs[inputDeviceIndex]->stop(); } diff --git a/sdrbase/audio/audiodevicemanager.h b/sdrbase/audio/audiodevicemanager.h index f14f3d415..9a2512daf 100644 --- a/sdrbase/audio/audiodevicemanager.h +++ b/sdrbase/audio/audiodevicemanager.h @@ -37,32 +37,25 @@ public: const QList& getInputDevices() const { return m_inputDevicesInfo; } const QList& getOutputDevices() const { return m_outputDevicesInfo; } - int getOutputDeviceIndex(AudioFifo* audioFifo) const; - int getInputDeviceIndex() const { return m_inputDeviceIndex; } - float getInputVolume() const { return m_inputVolume; } - - void setInputDeviceIndex(int inputDeviceIndex); - void setInputVolume(float inputVolume); - void addAudioSink(AudioFifo* audioFifo, int outputDeviceIndex = -1); //!< Add the audio sink void removeAudioSink(AudioFifo* audioFifo); //!< Remove the audio sink - void addAudioSource(AudioFifo* audioFifo); //!< Add an audio source + void addAudioSource(AudioFifo* audioFifo, int inputDeviceIndex = -1); //!< Add an audio source void removeAudioSource(AudioFifo* audioFifo); //!< Remove an audio source - void setAudioInputVolume(float volume) { m_audioInput.setVolume(volume); } - private: unsigned int m_defaultAudioSampleRate; - QList m_inputDevicesInfo; + + QList m_inputDevicesInfo; QList m_outputDevicesInfo; + QMap m_audioSinkFifos; //< Audio sink FIFO to audio output device index-1 map QMap m_audioOutputs; //!< audio device index-1 to audio output map (index -1 is default device) QMap m_audioOutputSampleRates; //!< audio device index-1 to audio sample rate - int m_inputDeviceIndex; - unsigned int m_audioInputSampleRate; - AudioInput m_audioInput; - float m_inputVolume; + + QMap m_audioSourceFifos; //< Audio source FIFO to audio input device index-1 map + QMap m_audioInputs; //!< audio device index-1 to audio input map (index -1 is default device) + QMap m_audioInputSampleRates; //!< audio device index-1 to audio sample rate void resetToDefaults(); QByteArray serialize() const; @@ -70,8 +63,8 @@ private: void startAudioOutput(int outputDeviceIndex); void stopAudioOutput(int outputDeviceIndex); - void startAudioInput(); - void stopAudioInput(); + void startAudioInput(int inputDeviceIndex); + void stopAudioInput(int inputDeviceIndex); friend class AudioDialog; friend class MainSettings; diff --git a/sdrgui/gui/audiodialog.cpp b/sdrgui/gui/audiodialog.cpp index 6d03a2c44..3f23ac45b 100644 --- a/sdrgui/gui/audiodialog.cpp +++ b/sdrgui/gui/audiodialog.cpp @@ -47,7 +47,7 @@ AudioDialog::AudioDialog(AudioDeviceManager* audioDeviceManager, QWidget* parent treeItem = new QTreeWidgetItem(ui->audioInTree); treeItem->setText(0, qPrintable(it->deviceName())); - if (i == m_audioDeviceManager->getInputDeviceIndex()) + if (i == 0) { ui->audioInTree->setCurrentItem(treeItem); } @@ -65,7 +65,6 @@ AudioDialog::AudioDialog(AudioDeviceManager* audioDeviceManager, QWidget* parent ui->tabWidget->setCurrentIndex(0); - m_inputVolume = m_audioDeviceManager->m_inputVolume; ui->inputVolume->setValue((int) (m_inputVolume * 100.0f)); ui->inputVolumeText->setText(QString("%1").arg(m_inputVolume, 0, 'f', 2)); } @@ -77,11 +76,6 @@ AudioDialog::~AudioDialog() void AudioDialog::accept() { - int inIndex = ui->audioInTree->indexOfTopLevelItem(ui->audioInTree->currentItem()); - - m_audioDeviceManager->m_inputDeviceIndex = inIndex - 1; - m_audioDeviceManager->m_inputVolume = m_inputVolume; - QDialog::accept(); } diff --git a/sdrgui/webapi/webapiadaptergui.cpp b/sdrgui/webapi/webapiadaptergui.cpp index f63f18942..00ff5e649 100644 --- a/sdrgui/webapi/webapiadaptergui.cpp +++ b/sdrgui/webapi/webapiadaptergui.cpp @@ -234,10 +234,10 @@ int WebAPIAdapterGUI::instanceAudioGet( response.init(); response.setNbInputDevices(nbInputDevices); - response.setInputDeviceSelectedIndex(m_mainWindow.m_dspEngine->getAudioDeviceManager()->getInputDeviceIndex()); + response.setInputDeviceSelectedIndex(-1); // FIXME: remove response.setNbOutputDevices(nbOutputDevices); response.setOutputDeviceSelectedIndex(-1); // FIXME: remove - response.setInputVolume(m_mainWindow.m_dspEngine->getAudioDeviceManager()->getInputVolume()); + response.setInputVolume(1.0f); // FIXME: remove QList *inputDevices = response.getInputDevices(); QList *outputDevices = response.getOutputDevices(); @@ -276,11 +276,8 @@ int WebAPIAdapterGUI::instanceAudioPatch( inputIndex = inputIndex < -1 ? -1 : inputIndex > nbInputDevices ? nbInputDevices-1 : inputIndex; outputIndex = outputIndex < -1 ? -1 : outputIndex > nbOutputDevices ? nbOutputDevices-1 : outputIndex; - m_mainWindow.m_dspEngine->getAudioDeviceManager()->setInputVolume(inputVolume); - m_mainWindow.m_dspEngine->getAudioDeviceManager()->setInputDeviceIndex(inputIndex); - - response.setInputVolume(m_mainWindow.m_dspEngine->getAudioDeviceManager()->getInputVolume()); - response.setInputIndex(m_mainWindow.m_dspEngine->getAudioDeviceManager()->getInputDeviceIndex()); + response.setInputVolume(1.0f); // FIXME: remove + response.setInputIndex(-1); // FIXME: remove response.setOutputIndex(-1); // FIXME: remove return 200; diff --git a/sdrsrv/webapi/webapiadaptersrv.cpp b/sdrsrv/webapi/webapiadaptersrv.cpp index a4e6d157a..5abc559ba 100644 --- a/sdrsrv/webapi/webapiadaptersrv.cpp +++ b/sdrsrv/webapi/webapiadaptersrv.cpp @@ -235,10 +235,10 @@ int WebAPIAdapterSrv::instanceAudioGet( response.init(); response.setNbInputDevices(nbInputDevices); - response.setInputDeviceSelectedIndex(m_mainCore.m_dspEngine->getAudioDeviceManager()->getInputDeviceIndex()); + response.setInputDeviceSelectedIndex(-1); // FIXME: remove response.setNbOutputDevices(nbOutputDevices); response.setOutputDeviceSelectedIndex(-1); // FIXME: remove - response.setInputVolume(m_mainCore.m_dspEngine->getAudioDeviceManager()->getInputVolume()); + response.setInputVolume(1.0f); // FIXME: remove QList *inputDevices = response.getInputDevices(); QList *outputDevices = response.getOutputDevices(); @@ -277,11 +277,8 @@ int WebAPIAdapterSrv::instanceAudioPatch( inputIndex = inputIndex < -1 ? -1 : inputIndex > nbInputDevices ? nbInputDevices-1 : inputIndex; outputIndex = outputIndex < -1 ? -1 : outputIndex > nbOutputDevices ? nbOutputDevices-1 : outputIndex; - m_mainCore.m_dspEngine->getAudioDeviceManager()->setInputVolume(inputVolume); - m_mainCore.m_dspEngine->getAudioDeviceManager()->setInputDeviceIndex(inputIndex); - - response.setInputVolume(m_mainCore.m_dspEngine->getAudioDeviceManager()->getInputVolume()); - response.setInputIndex(m_mainCore.m_dspEngine->getAudioDeviceManager()->getInputDeviceIndex()); + response.setInputVolume(1.0f); // FIXME: remove + response.setInputIndex(-1); // FIXME: remove response.setOutputIndex(-1); // FIXME: remove return 200;