mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-11-22 08:04:49 -05:00
Multiple audio support: extend audio output information to UDP/RTP information. New audio preferences dialog
This commit is contained in:
parent
bfce9a4fcc
commit
745e187e2b
@ -63,7 +63,7 @@ AMDemod::AMDemod(DeviceSourceAPI *deviceAPI) :
|
||||
|
||||
m_magsq = 0.0;
|
||||
|
||||
DSPEngine::instance()->getAudioDeviceManager()->addAudioSink(&m_audioFifo);
|
||||
DSPEngine::instance()->getAudioDeviceManager()->addAudioSink(&m_audioFifo, getInputMessageQueue());
|
||||
m_audioNetSink = new AudioNetSink(0); // parent thread allocated dynamically
|
||||
m_audioNetSink->setDestination(m_settings.m_udpAddress, m_settings.m_udpPort);
|
||||
|
||||
|
@ -84,7 +84,7 @@ BFMDemod::BFMDemod(DeviceSourceAPI *deviceAPI) :
|
||||
m_audioBuffer.resize(16384);
|
||||
m_audioBufferFill = 0;
|
||||
|
||||
DSPEngine::instance()->getAudioDeviceManager()->addAudioSink(&m_audioFifo);
|
||||
DSPEngine::instance()->getAudioDeviceManager()->addAudioSink(&m_audioFifo, getInputMessageQueue());
|
||||
m_audioNetSink = new AudioNetSink(0); // parent thread allocated dynamically
|
||||
m_audioNetSink->setDestination(m_settings.m_udpAddress, m_settings.m_udpPort);
|
||||
m_audioNetSink->setStereo(true);
|
||||
|
@ -72,8 +72,8 @@ DSDDemod::DSDDemod(DeviceSourceAPI *deviceAPI) :
|
||||
m_magsqPeak = 0.0f;
|
||||
m_magsqCount = 0;
|
||||
|
||||
DSPEngine::instance()->getAudioDeviceManager()->addAudioSink(&m_audioFifo1);
|
||||
DSPEngine::instance()->getAudioDeviceManager()->addAudioSink(&m_audioFifo2);
|
||||
DSPEngine::instance()->getAudioDeviceManager()->addAudioSink(&m_audioFifo1, getInputMessageQueue());
|
||||
DSPEngine::instance()->getAudioDeviceManager()->addAudioSink(&m_audioFifo2, getInputMessageQueue());
|
||||
|
||||
// m_udpBufferAudio = new UDPSink<AudioSample>(this, m_udpBlockSize, m_settings.m_udpPort);
|
||||
// m_audioFifo1.setUDPSink(m_udpBufferAudio);
|
||||
|
@ -80,7 +80,7 @@ NFMDemod::NFMDemod(DeviceSourceAPI *devieAPI) :
|
||||
m_ctcssDetector.setCoefficients(3000, 6000.0); // 0.5s / 2 Hz resolution
|
||||
m_afSquelch.setCoefficients(24, 600, 48000.0, 200, 0); // 0.5ms test period, 300ms average span, 48kS/s SR, 100ms attack, no decay
|
||||
|
||||
DSPEngine::instance()->getAudioDeviceManager()->addAudioSink(&m_audioFifo);
|
||||
DSPEngine::instance()->getAudioDeviceManager()->addAudioSink(&m_audioFifo, getInputMessageQueue());
|
||||
m_audioNetSink = new AudioNetSink(0); // parent thread allocated dynamically
|
||||
m_audioNetSink->setDestination(m_settings.m_udpAddress, m_settings.m_udpPort);
|
||||
|
||||
|
@ -85,7 +85,7 @@ SSBDemod::SSBDemod(DeviceSourceAPI *deviceAPI) :
|
||||
SSBFilter = new fftfilt(m_LowCutoff / m_audioSampleRate, m_Bandwidth / m_audioSampleRate, ssbFftLen);
|
||||
DSBFilter = new fftfilt((2.0f * m_Bandwidth) / m_audioSampleRate, 2 * ssbFftLen);
|
||||
|
||||
DSPEngine::instance()->getAudioDeviceManager()->addAudioSink(&m_audioFifo);
|
||||
DSPEngine::instance()->getAudioDeviceManager()->addAudioSink(&m_audioFifo, getInputMessageQueue());
|
||||
m_audioNetSink = new AudioNetSink(0); // parent thread allocated dynamically
|
||||
m_audioNetSink->setDestination(m_settings.m_udpAddress, m_settings.m_udpPort);
|
||||
|
||||
|
@ -59,7 +59,7 @@ WFMDemod::WFMDemod(DeviceSourceAPI* deviceAPI) :
|
||||
m_audioBuffer.resize(16384);
|
||||
m_audioBufferFill = 0;
|
||||
|
||||
DSPEngine::instance()->getAudioDeviceManager()->addAudioSink(&m_audioFifo);
|
||||
DSPEngine::instance()->getAudioDeviceManager()->addAudioSink(&m_audioFifo, getInputMessageQueue());
|
||||
m_audioNetSink = new AudioNetSink(0); // parent thread allocated dynamically
|
||||
m_audioNetSink->setDestination(m_settings.m_udpAddress, m_settings.m_udpPort);
|
||||
|
||||
|
@ -543,7 +543,7 @@ void UDPSrc::applySettings(const UDPSrcSettings& settings, bool force)
|
||||
if (settings.m_audioActive)
|
||||
{
|
||||
m_audioBufferFill = 0;
|
||||
DSPEngine::instance()->getAudioDeviceManager()->addAudioSink(&m_audioFifo);
|
||||
DSPEngine::instance()->getAudioDeviceManager()->addAudioSink(&m_audioFifo, getInputMessageQueue());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -66,7 +66,7 @@ AMMod::AMMod(DeviceSinkAPI *deviceAPI) :
|
||||
m_magsq = 0.0;
|
||||
|
||||
m_toneNco.setFreq(1000.0, m_settings.m_audioSampleRate);
|
||||
DSPEngine::instance()->getAudioDeviceManager()->addAudioSource(&m_audioFifo);
|
||||
DSPEngine::instance()->getAudioDeviceManager()->addAudioSource(&m_audioFifo, getInputMessageQueue());
|
||||
|
||||
// CW keyer
|
||||
m_cwKeyer.setSampleRate(m_settings.m_audioSampleRate);
|
||||
|
@ -73,7 +73,7 @@ NFMMod::NFMMod(DeviceSinkAPI *deviceAPI) :
|
||||
|
||||
m_toneNco.setFreq(1000.0, m_settings.m_audioSampleRate);
|
||||
m_ctcssNco.setFreq(88.5, m_settings.m_audioSampleRate);
|
||||
DSPEngine::instance()->getAudioDeviceManager()->addAudioSource(&m_audioFifo);
|
||||
DSPEngine::instance()->getAudioDeviceManager()->addAudioSource(&m_audioFifo, getInputMessageQueue());
|
||||
|
||||
// CW keyer
|
||||
m_cwKeyer.setSampleRate(m_settings.m_audioSampleRate);
|
||||
|
@ -88,7 +88,7 @@ SSBMod::SSBMod(DeviceSinkAPI *deviceAPI) :
|
||||
m_magsq = 0.0;
|
||||
|
||||
m_toneNco.setFreq(1000.0, m_settings.m_audioSampleRate);
|
||||
DSPEngine::instance()->getAudioDeviceManager()->addAudioSource(&m_audioFifo);
|
||||
DSPEngine::instance()->getAudioDeviceManager()->addAudioSource(&m_audioFifo, getInputMessageQueue());
|
||||
|
||||
// CW keyer
|
||||
m_cwKeyer.setSampleRate(m_settings.m_audioSampleRate);
|
||||
|
@ -75,7 +75,7 @@ WFMMod::WFMMod(DeviceSinkAPI *deviceAPI) :
|
||||
|
||||
m_toneNco.setFreq(1000.0, m_settings.m_audioSampleRate);
|
||||
m_toneNcoRF.setFreq(1000.0, m_outputSampleRate);
|
||||
DSPEngine::instance()->getAudioDeviceManager()->addAudioSource(&m_audioFifo);
|
||||
DSPEngine::instance()->getAudioDeviceManager()->addAudioSource(&m_audioFifo, getInputMessageQueue());
|
||||
|
||||
// CW keyer
|
||||
m_cwKeyer.setSampleRate(m_outputSampleRate);
|
||||
|
@ -18,9 +18,11 @@
|
||||
#include "audio/audiodevicemanager.h"
|
||||
#include "util/simpleserializer.h"
|
||||
|
||||
#include <QDataStream>
|
||||
#include <QDebug>
|
||||
|
||||
const float AudioDeviceManager::m_defaultAudioInputVolume = 0.15f;
|
||||
const QString AudioDeviceManager::m_defaultUDPAddress = "127.0.0.1";
|
||||
|
||||
QDataStream& operator<<(QDataStream& ds, const AudioDeviceManager::InputDeviceInfo& info)
|
||||
{
|
||||
@ -34,6 +36,18 @@ QDataStream& operator>>(QDataStream& ds, AudioDeviceManager::InputDeviceInfo& in
|
||||
return ds;
|
||||
}
|
||||
|
||||
QDataStream& operator<<(QDataStream& ds, const AudioDeviceManager::OutputDeviceInfo& info)
|
||||
{
|
||||
ds << info.sampleRate << info.udpAddress << info.udpPort << info.copyToUDP << info.udpStereo << info.udpUseRTP;
|
||||
return ds;
|
||||
}
|
||||
|
||||
QDataStream& operator>>(QDataStream& ds, AudioDeviceManager::OutputDeviceInfo& info)
|
||||
{
|
||||
ds >> info.sampleRate >> info.udpAddress >> info.udpPort >> info.copyToUDP >> info.udpStereo >> info.udpUseRTP;
|
||||
return ds;
|
||||
}
|
||||
|
||||
AudioDeviceManager::AudioDeviceManager()
|
||||
{
|
||||
m_inputDevicesInfo = QAudioDeviceInfo::availableDevices(QAudio::AudioInput);
|
||||
@ -122,7 +136,7 @@ void AudioDeviceManager::serializeInputMap(QByteArray& data) const
|
||||
void AudioDeviceManager::serializeOutputMap(QByteArray& data) const
|
||||
{
|
||||
QDataStream *stream = new QDataStream(&data, QIODevice::WriteOnly);
|
||||
*stream << m_audioOutputSampleRates;
|
||||
*stream << m_audioOutputInfos;
|
||||
delete stream;
|
||||
}
|
||||
|
||||
@ -167,10 +181,10 @@ void AudioDeviceManager::deserializeInputMap(QByteArray& data)
|
||||
void AudioDeviceManager::deserializeOutputMap(QByteArray& data)
|
||||
{
|
||||
QDataStream readStream(&data, QIODevice::ReadOnly);
|
||||
readStream >> m_audioOutputSampleRates;
|
||||
readStream >> m_audioOutputInfos;
|
||||
}
|
||||
|
||||
void AudioDeviceManager::addAudioSink(AudioFifo* audioFifo, int outputDeviceIndex)
|
||||
void AudioDeviceManager::addAudioSink(AudioFifo* audioFifo, MessageQueue *sampleSinkMessageQueue, int outputDeviceIndex)
|
||||
{
|
||||
qDebug("AudioDeviceManager::addAudioSink: %d: %p", outputDeviceIndex, audioFifo);
|
||||
|
||||
@ -198,6 +212,7 @@ void AudioDeviceManager::addAudioSink(AudioFifo* audioFifo, int outputDeviceInde
|
||||
}
|
||||
|
||||
m_audioSinkFifos[audioFifo] = outputDeviceIndex; // register audio FIFO
|
||||
m_sampleSinkMessageQueues[audioFifo] = sampleSinkMessageQueue;
|
||||
}
|
||||
|
||||
void AudioDeviceManager::removeAudioSink(AudioFifo* audioFifo)
|
||||
@ -218,9 +233,10 @@ void AudioDeviceManager::removeAudioSink(AudioFifo* audioFifo)
|
||||
}
|
||||
|
||||
m_audioSinkFifos.remove(audioFifo); // unregister audio FIFO
|
||||
m_sampleSinkMessageQueues.remove(audioFifo);
|
||||
}
|
||||
|
||||
void AudioDeviceManager::addAudioSource(AudioFifo* audioFifo, int inputDeviceIndex)
|
||||
void AudioDeviceManager::addAudioSource(AudioFifo* audioFifo, MessageQueue *sampleSourceMessageQueue, int inputDeviceIndex)
|
||||
{
|
||||
qDebug("AudioDeviceManager::addAudioSource: %d: %p", inputDeviceIndex, audioFifo);
|
||||
|
||||
@ -248,6 +264,7 @@ void AudioDeviceManager::addAudioSource(AudioFifo* audioFifo, int inputDeviceInd
|
||||
}
|
||||
|
||||
m_audioSourceFifos[audioFifo] = inputDeviceIndex; // register audio FIFO
|
||||
m_sampleSourceMessageQueues[audioFifo] = sampleSourceMessageQueue;
|
||||
}
|
||||
|
||||
void AudioDeviceManager::removeAudioSource(AudioFifo* audioFifo)
|
||||
@ -268,23 +285,47 @@ void AudioDeviceManager::removeAudioSource(AudioFifo* audioFifo)
|
||||
}
|
||||
|
||||
m_audioSourceFifos.remove(audioFifo); // unregister audio FIFO
|
||||
m_sampleSourceMessageQueues.remove(audioFifo);
|
||||
}
|
||||
|
||||
void AudioDeviceManager::startAudioOutput(int outputDeviceIndex)
|
||||
{
|
||||
unsigned int sampleRate;
|
||||
QString udpAddress;
|
||||
quint16 udpPort;
|
||||
bool copyAudioToUDP;
|
||||
bool udpStereo;
|
||||
bool udpUseRTP;
|
||||
QString deviceName;
|
||||
|
||||
if (getOutputDeviceName(outputDeviceIndex, deviceName))
|
||||
{
|
||||
if (m_audioOutputSampleRates.find(deviceName) == m_audioOutputSampleRates.end()) {
|
||||
if (m_audioOutputInfos.find(deviceName) == m_audioOutputInfos.end())
|
||||
{
|
||||
sampleRate = m_defaultAudioSampleRate;
|
||||
} else {
|
||||
sampleRate = m_audioOutputSampleRates[deviceName];
|
||||
udpAddress = m_defaultUDPAddress;
|
||||
udpPort = m_defaultUDPPort;
|
||||
copyAudioToUDP = false;
|
||||
udpStereo = false;
|
||||
udpUseRTP = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
sampleRate = m_audioOutputInfos[deviceName].sampleRate;
|
||||
udpAddress = m_audioOutputInfos[deviceName].udpAddress;
|
||||
udpPort = m_audioOutputInfos[deviceName].udpPort;
|
||||
copyAudioToUDP = m_audioOutputInfos[deviceName].copyToUDP;
|
||||
udpStereo = m_audioOutputInfos[deviceName].udpStereo;
|
||||
udpUseRTP = m_audioOutputInfos[deviceName].udpUseRTP;
|
||||
}
|
||||
|
||||
m_audioOutputs[outputDeviceIndex]->start(outputDeviceIndex, sampleRate);
|
||||
m_audioOutputSampleRates[deviceName] = m_audioOutputs[outputDeviceIndex]->getRate(); // update with actual rate
|
||||
m_audioOutputInfos[deviceName].sampleRate = m_audioOutputs[outputDeviceIndex]->getRate(); // update with actual rate
|
||||
m_audioOutputInfos[deviceName].udpAddress = udpAddress;
|
||||
m_audioOutputInfos[deviceName].udpPort = udpPort;
|
||||
m_audioOutputInfos[deviceName].copyToUDP = copyAudioToUDP;
|
||||
m_audioOutputInfos[deviceName].udpStereo = udpStereo;
|
||||
m_audioOutputInfos[deviceName].udpUseRTP = udpUseRTP;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -347,12 +388,17 @@ void AudioDeviceManager::debugAudioInputInfos() const
|
||||
|
||||
void AudioDeviceManager::debugAudioOutputInfos() const
|
||||
{
|
||||
QMap<QString, unsigned int>::const_iterator it = m_audioOutputSampleRates.begin();
|
||||
QMap<QString, OutputDeviceInfo>::const_iterator it = m_audioOutputInfos.begin();
|
||||
|
||||
for (; it != m_audioOutputSampleRates.end(); ++it)
|
||||
for (; it != m_audioOutputInfos.end(); ++it)
|
||||
{
|
||||
qDebug() << "AudioDeviceManager::debugAudioOutputInfos:"
|
||||
<< " name: " << it.key()
|
||||
<< " sampleRate: " << it.value();
|
||||
<< " sampleRate: " << it.value().sampleRate
|
||||
<< " udpAddress: " << it.value().udpAddress
|
||||
<< " udpPort: " << it.value().udpPort
|
||||
<< " copyToUDP: " << it.value().copyToUDP
|
||||
<< " udpStereo: " << it.value().udpStereo
|
||||
<< " udpUseRTP: " << it.value().udpUseRTP;
|
||||
}
|
||||
}
|
||||
|
@ -22,25 +22,51 @@
|
||||
#include <QList>
|
||||
#include <QMap>
|
||||
#include <QAudioDeviceInfo>
|
||||
#include <QDataStream>
|
||||
|
||||
#include "audio/audioinput.h"
|
||||
#include "audio/audiooutput.h"
|
||||
#include "export.h"
|
||||
|
||||
class QDataStream;
|
||||
class AudioFifo;
|
||||
class MessageQueue;
|
||||
|
||||
class SDRBASE_API AudioDeviceManager {
|
||||
public:
|
||||
class InputDeviceInfo
|
||||
{
|
||||
public:
|
||||
InputDeviceInfo() :
|
||||
sampleRate(m_defaultAudioSampleRate),
|
||||
volume(m_defaultAudioInputVolume)
|
||||
{}
|
||||
unsigned 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),
|
||||
udpStereo(false),
|
||||
udpUseRTP(false)
|
||||
{}
|
||||
unsigned int sampleRate;
|
||||
QString udpAddress;
|
||||
quint16 udpPort;
|
||||
bool copyToUDP;
|
||||
bool udpStereo;
|
||||
bool udpUseRTP;
|
||||
friend QDataStream& operator<<(QDataStream& ds, const OutputDeviceInfo& info);
|
||||
friend QDataStream& operator>>(QDataStream& ds, OutputDeviceInfo& info);
|
||||
};
|
||||
|
||||
AudioDeviceManager();
|
||||
~AudioDeviceManager();
|
||||
|
||||
@ -51,24 +77,28 @@ public:
|
||||
bool getOutputDeviceName(int outputDeviceIndex, QString &deviceName) const;
|
||||
bool getInputDeviceName(int outputDeviceIndex, QString &deviceName) const;
|
||||
|
||||
void addAudioSink(AudioFifo* audioFifo, int outputDeviceIndex = -1); //!< Add the audio sink
|
||||
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, int inputDeviceIndex = -1); //!< Add an audio source
|
||||
void addAudioSource(AudioFifo* audioFifo, MessageQueue *sampleSourceMessageQueue, int inputDeviceIndex = -1); //!< Add an audio source
|
||||
void removeAudioSource(AudioFifo* audioFifo); //!< Remove an audio source
|
||||
|
||||
static const unsigned int m_defaultAudioSampleRate = 48000;
|
||||
static const float m_defaultAudioInputVolume;
|
||||
private:
|
||||
static const QString m_defaultUDPAddress;
|
||||
static const quint16 m_defaultUDPPort = 9998;
|
||||
|
||||
private:
|
||||
QList<QAudioDeviceInfo> m_inputDevicesInfo;
|
||||
QList<QAudioDeviceInfo> m_outputDevicesInfo;
|
||||
|
||||
QMap<AudioFifo*, int> m_audioSinkFifos; //< Audio sink FIFO to audio output device index-1 map
|
||||
QMap<AudioFifo*, int> m_audioSinkFifos; //< audio sink FIFO to audio output device index-1 map
|
||||
QMap<AudioFifo*, MessageQueue*> m_sampleSinkMessageQueues; //!< audio sink FIFO to attached sink message queue
|
||||
QMap<int, AudioOutput*> m_audioOutputs; //!< audio device index to audio output map (index -1 is default device)
|
||||
QMap<QString, unsigned int> m_audioOutputSampleRates; //!< audio device name to audio sample rate
|
||||
QMap<QString, OutputDeviceInfo> m_audioOutputInfos; //!< audio device name to audio output info
|
||||
|
||||
QMap<AudioFifo*, int> m_audioSourceFifos; //< Audio source FIFO to audio input device index-1 map
|
||||
QMap<AudioFifo*, int> m_audioSourceFifos; //< audio source FIFO to audio input device index-1 map
|
||||
QMap<AudioFifo*, MessageQueue*> m_sampleSourceMessageQueues; //!< audio source FIFO to attached source message queue
|
||||
QMap<int, AudioInput*> m_audioInputs; //!< audio device index to audio input map (index -1 is default device)
|
||||
QMap<QString, InputDeviceInfo> m_audioInputInfos; //!< audio device name to audio input device info
|
||||
|
||||
@ -94,5 +124,9 @@ private:
|
||||
};
|
||||
|
||||
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
|
||||
|
@ -19,12 +19,16 @@
|
||||
#include <QAudioFormat>
|
||||
#include <QAudioDeviceInfo>
|
||||
#include <QAudioOutput>
|
||||
#include "audio/audiooutput.h"
|
||||
#include "audio/audiofifo.h"
|
||||
#include "audiooutput.h"
|
||||
#include "audiofifo.h"
|
||||
#include "audionetsink.h"
|
||||
|
||||
AudioOutput::AudioOutput() :
|
||||
m_mutex(QMutex::Recursive),
|
||||
m_audioOutput(0),
|
||||
m_audioNetSink(0),
|
||||
m_copyAudioToUdp(false),
|
||||
m_udpStereo(false),
|
||||
m_audioUsageCount(0),
|
||||
m_onExit(false),
|
||||
m_audioFifos()
|
||||
@ -100,6 +104,7 @@ bool AudioOutput::start(int device, int rate)
|
||||
}
|
||||
|
||||
m_audioOutput = new QAudioOutput(devInfo, m_audioFormat);
|
||||
m_audioNetSink = new AudioNetSink(0);
|
||||
|
||||
QIODevice::open(QIODevice::ReadOnly);
|
||||
|
||||
@ -123,6 +128,8 @@ void AudioOutput::stop()
|
||||
QMutexLocker mutexLocker(&m_mutex);
|
||||
m_audioOutput->stop();
|
||||
QIODevice::close();
|
||||
delete m_audioNetSink;
|
||||
m_audioNetSink = 0;
|
||||
delete m_audioOutput;
|
||||
|
||||
// if (m_audioUsageCount > 0)
|
||||
@ -162,6 +169,35 @@ bool AudioOutput::open(OpenMode mode)
|
||||
return false;
|
||||
}*/
|
||||
|
||||
void AudioOutput::setUdpDestination(const QString& address, uint16_t port)
|
||||
{
|
||||
if (m_audioNetSink) {
|
||||
m_audioNetSink->setDestination(address, port);
|
||||
}
|
||||
}
|
||||
|
||||
void AudioOutput::setUdpCopyToUDP(bool copyToUDP)
|
||||
{
|
||||
m_copyAudioToUdp = copyToUDP;
|
||||
}
|
||||
|
||||
void AudioOutput::setUdpStereo(bool stereo)
|
||||
{
|
||||
if (m_audioNetSink) {
|
||||
m_audioNetSink->setStereo(stereo);
|
||||
}
|
||||
|
||||
m_udpStereo = stereo;
|
||||
}
|
||||
|
||||
void AudioOutput::setUdpUseRTP(bool useRTP)
|
||||
{
|
||||
if (m_audioNetSink) {
|
||||
m_audioNetSink->selectType(useRTP ? AudioNetSink::SinkRTP : AudioNetSink::SinkUDP);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
qint64 AudioOutput::readData(char* data, qint64 maxLen)
|
||||
{
|
||||
//qDebug("AudioOutput::readData: %lld", maxLen);
|
||||
|
@ -23,11 +23,13 @@
|
||||
#include <QAudioFormat>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <stdint.h>
|
||||
#include "export.h"
|
||||
|
||||
class QAudioOutput;
|
||||
class AudioFifo;
|
||||
class AudioOutputPipe;
|
||||
class AudioNetSink;
|
||||
|
||||
class SDRBASE_API AudioOutput : QIODevice {
|
||||
public:
|
||||
@ -44,9 +46,17 @@ public:
|
||||
unsigned int getRate() const { return m_audioFormat.sampleRate(); }
|
||||
void setOnExit(bool onExit) { m_onExit = onExit; }
|
||||
|
||||
void setUdpDestination(const QString& address, uint16_t port);
|
||||
void setUdpCopyToUDP(bool copyToUDP);
|
||||
void setUdpStereo(bool stereo);
|
||||
void setUdpUseRTP(bool useRTP);
|
||||
|
||||
private:
|
||||
QMutex m_mutex;
|
||||
QAudioOutput* m_audioOutput;
|
||||
AudioNetSink* m_audioNetSink;
|
||||
bool m_copyAudioToUdp;
|
||||
bool m_udpStereo;
|
||||
uint m_audioUsageCount;
|
||||
bool m_onExit;
|
||||
|
||||
|
@ -23,9 +23,9 @@
|
||||
<item>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="currentIndex">
|
||||
<number>1</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tab_2">
|
||||
<widget class="QWidget" name="tabOutput">
|
||||
<attribute name="title">
|
||||
<string>Audio Output</string>
|
||||
</attribute>
|
||||
@ -39,6 +39,176 @@
|
||||
</column>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="sampleRateLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="outputSampleRateLabel">
|
||||
<property name="text">
|
||||
<string>Rate</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="outputSampleRate">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Audio output sample rate</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>8000</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>192000</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>48000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="outputReset">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Reset values to defaults</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>R</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="udpLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="udpAddressLabel">
|
||||
<property name="text">
|
||||
<string>Addr</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="udpAddress">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>140</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>UDP address</string>
|
||||
</property>
|
||||
<property name="inputMask">
|
||||
<string>000.000.000.000; </string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>127.0.0.1</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="udpPortLabel">
|
||||
<property name="text">
|
||||
<string>Port</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="udpPort">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>UDP port</string>
|
||||
</property>
|
||||
<property name="inputMask">
|
||||
<string>00000; </string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>9998</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ButtonSwitch" name="udpCopy">
|
||||
<property name="toolTip">
|
||||
<string>Copy audio to UDP</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>U</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="udpStereo">
|
||||
<property name="toolTip">
|
||||
<string>Copy to UDP as stereo (no L+R mix)</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>S</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="udpUseRTP">
|
||||
<property name="toolTip">
|
||||
<string>Use RTP protocol</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>R</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tabInput">
|
||||
@ -57,6 +227,41 @@
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="inputVolumeLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="inputSampleRateLabel">
|
||||
<property name="text">
|
||||
<string>Rate</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="inputSampleRate">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>80</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Audio input sample rate</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>8000</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>192000</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>48000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="inputVolumeLabel">
|
||||
<property name="maximumSize">
|
||||
@ -78,6 +283,9 @@
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Input volume</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
</property>
|
||||
@ -118,6 +326,22 @@
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="inputReset">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Reset values to default</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>R</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
@ -136,6 +360,13 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>ButtonSwitch</class>
|
||||
<extends>QToolButton</extends>
|
||||
<header>gui/buttonswitch.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>buttonBox</tabstop>
|
||||
<tabstop>tabWidget</tabstop>
|
||||
|
Loading…
Reference in New Issue
Block a user