mirror of
				https://github.com/f4exb/sdrangel.git
				synced 2025-11-04 05:30:32 -05:00 
			
		
		
		
	Audio input: use AudioDeviceManager to handle audio
This commit is contained in:
		
							parent
							
								
									c4debeef8e
								
							
						
					
					
						commit
						8c521f191d
					
				@ -40,6 +40,7 @@ MESSAGE_CLASS_DEFINITION(AudioInput::MsgStartStop, Message)
 | 
				
			|||||||
AudioInput::AudioInput(DeviceAPI *deviceAPI) :
 | 
					AudioInput::AudioInput(DeviceAPI *deviceAPI) :
 | 
				
			||||||
    m_deviceAPI(deviceAPI),
 | 
					    m_deviceAPI(deviceAPI),
 | 
				
			||||||
    m_settings(),
 | 
					    m_settings(),
 | 
				
			||||||
 | 
					    m_audioDeviceIndex(-1),
 | 
				
			||||||
    m_worker(nullptr),
 | 
					    m_worker(nullptr),
 | 
				
			||||||
    m_workerThread(nullptr),
 | 
					    m_workerThread(nullptr),
 | 
				
			||||||
    m_deviceDescription("AudioInput"),
 | 
					    m_deviceDescription("AudioInput"),
 | 
				
			||||||
@ -48,8 +49,10 @@ AudioInput::AudioInput(DeviceAPI *deviceAPI) :
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    m_sampleFifo.setLabel(m_deviceDescription);
 | 
					    m_sampleFifo.setLabel(m_deviceDescription);
 | 
				
			||||||
    m_fifo.setSize(20*AudioInputWorker::m_convBufSamples);
 | 
					    m_fifo.setSize(20*AudioInputWorker::m_convBufSamples);
 | 
				
			||||||
    openDevice();
 | 
					 | 
				
			||||||
    m_deviceAPI->setNbSourceStreams(1);
 | 
					    m_deviceAPI->setNbSourceStreams(1);
 | 
				
			||||||
 | 
					    AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager();
 | 
				
			||||||
 | 
					    m_sampleRate = audioDeviceManager->getInputSampleRate(m_audioDeviceIndex);
 | 
				
			||||||
 | 
					    m_settings.m_deviceName = AudioDeviceManager::m_defaultDeviceName;
 | 
				
			||||||
    m_networkManager = new QNetworkAccessManager();
 | 
					    m_networkManager = new QNetworkAccessManager();
 | 
				
			||||||
    QObject::connect(
 | 
					    QObject::connect(
 | 
				
			||||||
        m_networkManager,
 | 
					        m_networkManager,
 | 
				
			||||||
@ -72,8 +75,6 @@ AudioInput::~AudioInput()
 | 
				
			|||||||
    if (m_running) {
 | 
					    if (m_running) {
 | 
				
			||||||
        stop();
 | 
					        stop();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    closeDevice();
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void AudioInput::destroy()
 | 
					void AudioInput::destroy()
 | 
				
			||||||
@ -81,36 +82,6 @@ void AudioInput::destroy()
 | 
				
			|||||||
    delete this;
 | 
					    delete this;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool AudioInput::openDevice()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if (!openAudioDevice(m_settings.m_deviceName, m_settings.m_sampleRate))
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        qCritical("AudioInput::openDevice: could not open audio source");
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
        return true;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool AudioInput::openAudioDevice(QString deviceName, qint32 sampleRate)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager();
 | 
					 | 
				
			||||||
    const QList<AudioDeviceInfo>& audioList = audioDeviceManager->getInputDevices();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for (const auto &itAudio : audioList)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        if (AudioInputSettings::getFullDeviceName(itAudio) == deviceName)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            // FIXME: getInputDeviceIndex needs a realm parameter (itAudio.realm())
 | 
					 | 
				
			||||||
            int deviceIndex = audioDeviceManager->getInputDeviceIndex(itAudio.deviceName());
 | 
					 | 
				
			||||||
            m_audioInput.start(deviceIndex, sampleRate);
 | 
					 | 
				
			||||||
            m_audioInput.addFifo(&m_fifo);
 | 
					 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return false;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void AudioInput::init()
 | 
					void AudioInput::init()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    applySettings(m_settings, QList<QString>(), true);
 | 
					    applySettings(m_settings, QList<QString>(), true);
 | 
				
			||||||
@ -131,7 +102,9 @@ bool AudioInput::start()
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    qDebug() << "AudioInput::start";
 | 
					    qDebug() << "AudioInput::start";
 | 
				
			||||||
    applySettings(m_settings, QList<QString>(), true, true);
 | 
					
 | 
				
			||||||
 | 
					    AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager();
 | 
				
			||||||
 | 
					    audioDeviceManager->addAudioSource(&m_fifo, getInputMessageQueue(), m_audioDeviceIndex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    m_workerThread = new QThread();
 | 
					    m_workerThread = new QThread();
 | 
				
			||||||
    m_worker = new AudioInputWorker(&m_sampleFifo, &m_fifo);
 | 
					    m_worker = new AudioInputWorker(&m_sampleFifo, &m_fifo);
 | 
				
			||||||
@ -145,19 +118,14 @@ bool AudioInput::start()
 | 
				
			|||||||
    m_worker->setIQMapping(m_settings.m_iqMapping);
 | 
					    m_worker->setIQMapping(m_settings.m_iqMapping);
 | 
				
			||||||
    m_worker->startWork();
 | 
					    m_worker->startWork();
 | 
				
			||||||
    m_workerThread->start();
 | 
					    m_workerThread->start();
 | 
				
			||||||
 | 
					 | 
				
			||||||
    qDebug("AudioInput::started");
 | 
					 | 
				
			||||||
    m_running = true;
 | 
					    m_running = true;
 | 
				
			||||||
 | 
						mutexLocker.unlock();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    qDebug("AudioInput::start: started");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void AudioInput::closeDevice()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    m_audioInput.removeFifo(&m_fifo);
 | 
					 | 
				
			||||||
    m_audioInput.stop();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void AudioInput::stop()
 | 
					void AudioInput::stop()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    QMutexLocker mutexLocker(&m_mutex);
 | 
					    QMutexLocker mutexLocker(&m_mutex);
 | 
				
			||||||
@ -177,6 +145,8 @@ void AudioInput::stop()
 | 
				
			|||||||
        m_worker = nullptr;
 | 
					        m_worker = nullptr;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager();
 | 
				
			||||||
 | 
					    audioDeviceManager->removeAudioSource(&m_fifo);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
QByteArray AudioInput::serialize() const
 | 
					QByteArray AudioInput::serialize() const
 | 
				
			||||||
@ -259,7 +229,7 @@ bool AudioInput::handleMessage(const Message& message)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void AudioInput::applySettings(const AudioInputSettings& settings, QList<QString> settingsKeys, bool force, bool starting)
 | 
					void AudioInput::applySettings(const AudioInputSettings& settings, QList<QString> settingsKeys, bool force)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    bool forwardChange = false;
 | 
					    bool forwardChange = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -267,19 +237,25 @@ void AudioInput::applySettings(const AudioInputSettings& settings, QList<QString
 | 
				
			|||||||
        << " force:" << force
 | 
					        << " force:" << force
 | 
				
			||||||
        << settings.getDebugString(settingsKeys, force);
 | 
					        << settings.getDebugString(settingsKeys, force);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (settingsKeys.contains("deviceName")
 | 
					
 | 
				
			||||||
        || settingsKeys.contains("sampleRate") || force)
 | 
					    if (settingsKeys.contains("deviceName") || settingsKeys.contains("sampleRate") || force)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        // Don't call openAudioDevice if called from start(), otherwise ::AudioInput
 | 
					        AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager();
 | 
				
			||||||
        // will be created on wrong thread and we'll crash after ::AudioInput::stop calls delete
 | 
					        m_audioDeviceIndex = audioDeviceManager->getInputDeviceIndex(settings.m_deviceName);
 | 
				
			||||||
        if (!starting)
 | 
					        AudioDeviceManager::InputDeviceInfo deviceInfo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (audioDeviceManager->getInputDeviceInfo(settings.m_deviceName, deviceInfo))
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            closeDevice();
 | 
					            deviceInfo.sampleRate = settings.m_sampleRate;
 | 
				
			||||||
            if (openAudioDevice(settings.m_deviceName, settings.m_sampleRate))
 | 
					            audioDeviceManager->setInputDeviceInfo(m_audioDeviceIndex, deviceInfo);
 | 
				
			||||||
                qDebug() << "AudioInput::applySettings: opened device " << settings.m_deviceName << " with sample rate " << m_audioInput.getRate();
 | 
					 | 
				
			||||||
            else
 | 
					 | 
				
			||||||
                qCritical() << "AudioInput::applySettings: failed to open device " << settings.m_deviceName;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        audioDeviceManager->removeAudioSource(&m_fifo);
 | 
				
			||||||
 | 
					        audioDeviceManager->addAudioSource(&m_fifo, getInputMessageQueue(), m_audioDeviceIndex);
 | 
				
			||||||
 | 
					        m_sampleRate = audioDeviceManager->getInputSampleRate(m_audioDeviceIndex);
 | 
				
			||||||
 | 
					        qDebug("AudioInput::applySettings: audioDeviceName: %s audioDeviceIndex: %d sampleRate: %d",
 | 
				
			||||||
 | 
					            qPrintable(settings.m_deviceName), m_audioDeviceIndex, m_sampleRate);
 | 
				
			||||||
 | 
					        forwardChange = true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (settingsKeys.contains("sampleRate") || force) {
 | 
					    if (settingsKeys.contains("sampleRate") || force) {
 | 
				
			||||||
@ -288,8 +264,13 @@ void AudioInput::applySettings(const AudioInputSettings& settings, QList<QString
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    if (settingsKeys.contains("volume") || force)
 | 
					    if (settingsKeys.contains("volume") || force)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        m_audioInput.setVolume(settings.m_volume);
 | 
					        AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager();
 | 
				
			||||||
        qDebug() << "AudioInput::applySettings: set volume to " << settings.m_volume;
 | 
					
 | 
				
			||||||
 | 
					        if (audioDeviceManager->setInputDeviceVolume(settings.m_volume, m_audioDeviceIndex)) {
 | 
				
			||||||
 | 
					            qDebug("AudioInput::applySettings: set volume of %d to %f", m_audioDeviceIndex, settings.m_volume);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            qWarning("AudioInput::applySettings: failed to set volume of %d to %f", m_audioDeviceIndex, settings.m_volume);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (settingsKeys.contains("log2Decim") || force)
 | 
					    if (settingsKeys.contains("log2Decim") || force)
 | 
				
			||||||
 | 
				
			|||||||
@ -27,7 +27,6 @@
 | 
				
			|||||||
#include <QMutex>
 | 
					#include <QMutex>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "dsp/devicesamplesource.h"
 | 
					#include "dsp/devicesamplesource.h"
 | 
				
			||||||
#include "audio/audioinputdevice.h"
 | 
					 | 
				
			||||||
#include "audio/audiofifo.h"
 | 
					#include "audio/audiofifo.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "audioinputsettings.h"
 | 
					#include "audioinputsettings.h"
 | 
				
			||||||
@ -136,10 +135,10 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
    DeviceAPI *m_deviceAPI;
 | 
					    DeviceAPI *m_deviceAPI;
 | 
				
			||||||
    AudioInputDevice m_audioInput;
 | 
					 | 
				
			||||||
    AudioFifo m_fifo;
 | 
					    AudioFifo m_fifo;
 | 
				
			||||||
    QMutex m_mutex;
 | 
					    QMutex m_mutex;
 | 
				
			||||||
    AudioInputSettings m_settings;
 | 
					    AudioInputSettings m_settings;
 | 
				
			||||||
 | 
					    int m_audioDeviceIndex;
 | 
				
			||||||
    AudioInputWorker* m_worker;
 | 
					    AudioInputWorker* m_worker;
 | 
				
			||||||
    QThread *m_workerThread;
 | 
					    QThread *m_workerThread;
 | 
				
			||||||
    QString m_deviceDescription;
 | 
					    QString m_deviceDescription;
 | 
				
			||||||
@ -149,10 +148,7 @@ private:
 | 
				
			|||||||
    QNetworkAccessManager *m_networkManager;
 | 
					    QNetworkAccessManager *m_networkManager;
 | 
				
			||||||
    QNetworkRequest m_networkRequest;
 | 
					    QNetworkRequest m_networkRequest;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool openDevice();
 | 
					    void applySettings(const AudioInputSettings& settings, QList<QString> settingsKeys, bool force);
 | 
				
			||||||
    void closeDevice();
 | 
					 | 
				
			||||||
    bool openAudioDevice(QString deviceName, int sampleRate);
 | 
					 | 
				
			||||||
    void applySettings(const AudioInputSettings& settings, QList<QString> settingsKeys, bool force, bool starting=false);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void webapiReverseSendSettings(const QList<QString>& deviceSettingsKeys, const AudioInputSettings& settings, bool force);
 | 
					    void webapiReverseSendSettings(const QList<QString>& deviceSettingsKeys, const AudioInputSettings& settings, bool force);
 | 
				
			||||||
    void webapiReverseSendStartStop(bool start);
 | 
					    void webapiReverseSendStartStop(bool start);
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user