/////////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany // // written by Christian Daniel // // Copyright (C) 2015-2020, 2022-2023 Edouard Griffiths, F4EXB // // 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_AUDIODEVICEMANGER_H #define INCLUDE_AUDIODEVICEMANGER_H #include #include #include #include #include "audio/audioinputdevice.h" #include "audio/audiooutputdevice.h" #include "audio/audiodeviceinfo.h" #include "util/messagequeue.h" #include "export.h" class QThread; class QDataStream; class AudioFifo; class SDRBASE_API AudioDeviceManager : public QObject { Q_OBJECT public: class InputDeviceInfo { public: InputDeviceInfo() : sampleRate(m_defaultAudioSampleRate), volume(m_defaultAudioInputVolume) {} void resetToDefaults() { sampleRate = m_defaultAudioSampleRate; volume = m_defaultAudioInputVolume; } int sampleRate; float volume; friend QDataStream& operator<<(QDataStream& ds, const InputDeviceInfo& info); friend QDataStream& operator>>(QDataStream& ds, InputDeviceInfo& info); }; class OutputDeviceInfo { public: OutputDeviceInfo() : sampleRate(m_defaultAudioSampleRate), udpAddress(m_defaultUDPAddress), udpPort(m_defaultUDPPort), copyToUDP(false), udpUseRTP(false), udpChannelMode(AudioOutputDevice::UDPChannelLeft), udpChannelCodec(AudioOutputDevice::UDPCodecL16), udpDecimationFactor(1), recordToFile(false), recordSilenceTime(0) {} void resetToDefaults() { sampleRate = m_defaultAudioSampleRate; udpAddress = m_defaultUDPAddress; udpPort = m_defaultUDPPort; copyToUDP = false; udpUseRTP = false; udpChannelMode = AudioOutputDevice::UDPChannelLeft; udpChannelCodec = AudioOutputDevice::UDPCodecL16; udpDecimationFactor = 1; fileRecordName.clear(); recordToFile = false; recordSilenceTime = 0; } int sampleRate; QString udpAddress; quint16 udpPort; bool copyToUDP; bool udpUseRTP; AudioOutputDevice::UDPChannelMode udpChannelMode; AudioOutputDevice::UDPChannelCodec udpChannelCodec; uint32_t udpDecimationFactor; QString fileRecordName; bool recordToFile; int recordSilenceTime; //!< 100's ms friend QDataStream& operator<<(QDataStream& ds, const OutputDeviceInfo& info); friend QDataStream& operator>>(QDataStream& ds, OutputDeviceInfo& info); }; AudioDeviceManager(); ~AudioDeviceManager(); bool getOutputDeviceName(int outputDeviceIndex, QString &deviceName) const; bool getInputDeviceName(int inputDeviceIndex, QString &deviceName) const; int getOutputDeviceIndex(const QString &deviceName) const; int getInputDeviceIndex(const QString &deviceName) const; void addAudioSink(AudioFifo* audioFifo, MessageQueue *sampleSinkMessageQueue, int outputDeviceIndex = -1); //!< Add the audio sink void removeAudioSink(AudioFifo* audioFifo); //!< Remove the audio sink void addAudioSource(AudioFifo* audioFifo, MessageQueue *sampleSourceMessageQueue, int inputDeviceIndex = -1); //!< Add an audio source void removeAudioSource(AudioFifo* audioFifo); //!< Remove an audio source bool getInputDeviceInfo(const QString& deviceName, InputDeviceInfo& deviceInfo) const; bool getOutputDeviceInfo(const QString& deviceName, OutputDeviceInfo& deviceInfo) const; int getInputSampleRate(int inputDeviceIndex = -1); int getOutputSampleRate(int outputDeviceIndex = -1); void setInputDeviceInfo(int inputDeviceIndex, const InputDeviceInfo& deviceInfo); void setOutputDeviceInfo(int outputDeviceIndex, const OutputDeviceInfo& deviceInfo); void unsetInputDeviceInfo(int inputDeviceIndex); void unsetOutputDeviceInfo(int outputDeviceIndex); void inputInfosCleanup(); //!< Remove input info from map for input devices not present void outputInfosCleanup(); //!< Remove output info from map for output devices not present bool setInputDeviceVolume(float volume, int inputDeviceIndex); bool setOutputDeviceVolume(float volume, int outputDeviceIndex); static const int m_defaultAudioSampleRate = 48000; static const float m_defaultAudioInputVolume; static const QString m_defaultUDPAddress; static const quint16 m_defaultUDPPort = 9998; static const QString m_defaultDeviceName; private: QMap m_audioSinkFifos; //< audio sink FIFO to audio output device index-1 map QMap m_audioFifoToSinkMessageQueues; //!< audio sink FIFO to attached sink message queue QMap > m_outputDeviceSinkMessageQueues; //!< sink message queues attached to device QMap m_audioOutputs; //!< audio device index to audio output map (index -1 is default device) QMap m_audioOutputThreads; //!< audio device index to audio output threads map QMap m_audioOutputInfos; //!< audio device name to audio output info QMap m_audioSourceFifos; //< audio source FIFO to audio input device index-1 map QMap m_audioFifoToSourceMessageQueues; //!< audio source FIFO to attached source message queue QMap > m_inputDeviceSourceMessageQueues; //!< sink message queues attached to device QMap m_audioInputs; //!< audio device index to audio input map (index -1 is default device) QMap m_audioInputThreads; //!< audio device index to audio input threads map QMap m_audioInputInfos; //!< audio device name to audio input device info bool m_defaultOutputStarted; //!< True if the default audio output (-1) has already been started bool m_defaultInputStarted; //!< True if the default audio input (-1) has already been started MessageQueue m_inputMessageQueue; void resetToDefaults(); QByteArray serialize() const; bool deserialize(const QByteArray& data); void startAudioOutput(int outputDeviceIndex); void stopAudioOutput(int outputDeviceIndex); void startAudioInput(int inputDeviceIndex); void stopAudioInput(int inputDeviceIndex); void serializeInputMap(QByteArray& data) const; void deserializeInputMap(QByteArray& data); void debugAudioInputInfos() const; void serializeOutputMap(QByteArray& data) const; void deserializeOutputMap(QByteArray& data); void debugAudioOutputInfos() const; bool handleMessage(const Message& cmd); friend class MainSettings; private slots: void handleInputMessages(); }; QDataStream& operator<<(QDataStream& ds, const AudioDeviceManager::InputDeviceInfo& info); QDataStream& operator>>(QDataStream& ds, AudioDeviceManager::InputDeviceInfo& info); QDataStream& operator<<(QDataStream& ds, const AudioDeviceManager::OutputDeviceInfo& info); QDataStream& operator>>(QDataStream& ds, AudioDeviceManager::OutputDeviceInfo& info); #endif // INCLUDE_AUDIODEVICEMANGER_H