kopia lustrzana https://github.com/f4exb/sdrangel
Multiple audio support: New audio preferences dialog (3). Application to AM demod
rodzic
677c598347
commit
095ab14a14
|
@ -64,6 +64,7 @@ AMDemod::AMDemod(DeviceSourceAPI *deviceAPI) :
|
|||
m_magsq = 0.0;
|
||||
|
||||
DSPEngine::instance()->getAudioDeviceManager()->addAudioSink(&m_audioFifo, getInputMessageQueue());
|
||||
m_audioSampleRate = DSPEngine::instance()->getAudioDeviceManager()->getOutputSampleRate();
|
||||
m_audioNetSink = new AudioNetSink(0); // parent thread allocated dynamically
|
||||
m_audioNetSink->setDestination(m_settings.m_udpAddress, m_settings.m_udpPort);
|
||||
|
||||
|
@ -205,12 +206,45 @@ bool AMDemod::handleMessage(const Message& cmd)
|
|||
{
|
||||
return true;
|
||||
}
|
||||
else if (DSPConfigureAudio::match(cmd))
|
||||
{
|
||||
DSPConfigureAudio& cfg = (DSPConfigureAudio&) cmd;
|
||||
uint32_t sampleRate = cfg.getSampleRate();
|
||||
|
||||
qDebug() << "AMDemod::handleMessage: DSPConfigureAudio:"
|
||||
<< " sampleRate: " << sampleRate;
|
||||
|
||||
if (sampleRate != m_audioSampleRate) {
|
||||
applyAudioSampleRate(sampleRate);
|
||||
}
|
||||
|
||||
AMDemodSettings settings = m_settings;
|
||||
applyAudioSampleRate(cfg.getSampleRate());
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void AMDemod::applyAudioSampleRate(int sampleRate)
|
||||
{
|
||||
MsgConfigureChannelizer* channelConfigMsg = MsgConfigureChannelizer::create(
|
||||
sampleRate, m_settings.m_inputFrequencyOffset);
|
||||
m_inputMessageQueue.push(channelConfigMsg);
|
||||
|
||||
m_settingsMutex.lock();
|
||||
m_interpolator.create(16, m_inputSampleRate, m_settings.m_rfBandwidth / 2.2f);
|
||||
m_interpolatorDistanceRemain = 0;
|
||||
m_interpolatorDistance = (Real) m_inputSampleRate / (Real) sampleRate;
|
||||
m_bandpass.create(301, sampleRate, 300.0, m_settings.m_rfBandwidth / 2.0f);
|
||||
m_settingsMutex.unlock();
|
||||
|
||||
m_audioSampleRate = sampleRate;
|
||||
}
|
||||
|
||||
void AMDemod::applyChannelSettings(int inputSampleRate, int inputFrequencyOffset, bool force)
|
||||
{
|
||||
qDebug() << "AMDemod::applyChannelSettings:"
|
||||
|
@ -228,7 +262,7 @@ void AMDemod::applyChannelSettings(int inputSampleRate, int inputFrequencyOffset
|
|||
m_settingsMutex.lock();
|
||||
m_interpolator.create(16, inputSampleRate, m_settings.m_rfBandwidth / 2.2f);
|
||||
m_interpolatorDistanceRemain = 0;
|
||||
m_interpolatorDistance = (Real) inputSampleRate / (Real) m_settings.m_audioSampleRate;
|
||||
m_interpolatorDistance = (Real) inputSampleRate / (Real) m_audioSampleRate;
|
||||
m_settingsMutex.unlock();
|
||||
}
|
||||
|
||||
|
@ -252,14 +286,13 @@ void AMDemod::applySettings(const AMDemodSettings& settings, bool force)
|
|||
<< " force: " << force;
|
||||
|
||||
if((m_settings.m_rfBandwidth != settings.m_rfBandwidth) ||
|
||||
(m_settings.m_audioSampleRate != settings.m_audioSampleRate) ||
|
||||
(m_settings.m_bandpassEnable != settings.m_bandpassEnable) || force)
|
||||
{
|
||||
m_settingsMutex.lock();
|
||||
m_interpolator.create(16, m_inputSampleRate, settings.m_rfBandwidth / 2.2f);
|
||||
m_interpolatorDistanceRemain = 0;
|
||||
m_interpolatorDistance = (Real) m_inputSampleRate / (Real) settings.m_audioSampleRate;
|
||||
m_bandpass.create(301, settings.m_audioSampleRate, 300.0, settings.m_rfBandwidth / 2.0f);
|
||||
m_interpolatorDistance = (Real) m_inputSampleRate / (Real) m_audioSampleRate;
|
||||
m_bandpass.create(301, m_audioSampleRate, 300.0, settings.m_rfBandwidth / 2.0f);
|
||||
m_settingsMutex.unlock();
|
||||
}
|
||||
|
||||
|
@ -341,9 +374,6 @@ int AMDemod::webapiSettingsPutPatch(
|
|||
if (channelSettingsKeys.contains("audioMute")) {
|
||||
settings.m_audioMute = response.getAmDemodSettings()->getAudioMute() != 0;
|
||||
}
|
||||
if (channelSettingsKeys.contains("audioSampleRate")) {
|
||||
settings.m_audioSampleRate = response.getAmDemodSettings()->getAudioSampleRate();
|
||||
}
|
||||
if (channelSettingsKeys.contains("copyAudioToUDP")) {
|
||||
settings.m_copyAudioToUDP = response.getAmDemodSettings()->getCopyAudioToUdp() != 0;
|
||||
}
|
||||
|
@ -383,7 +413,7 @@ int AMDemod::webapiSettingsPutPatch(
|
|||
if (frequencyOffsetChanged)
|
||||
{
|
||||
MsgConfigureChannelizer* channelConfigMsg = MsgConfigureChannelizer::create(
|
||||
48000, settings.m_inputFrequencyOffset);
|
||||
m_audioSampleRate, settings.m_inputFrequencyOffset);
|
||||
m_inputMessageQueue.push(channelConfigMsg);
|
||||
}
|
||||
|
||||
|
@ -415,7 +445,6 @@ int AMDemod::webapiReportGet(
|
|||
void AMDemod::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& response, const AMDemodSettings& settings)
|
||||
{
|
||||
response.getAmDemodSettings()->setAudioMute(settings.m_audioMute ? 1 : 0);
|
||||
response.getAmDemodSettings()->setAudioSampleRate(settings.m_audioSampleRate);
|
||||
response.getAmDemodSettings()->setCopyAudioToUdp(settings.m_copyAudioToUDP ? 1 : 0);
|
||||
response.getAmDemodSettings()->setCopyAudioUseRtp(settings.m_copyAudioUseRTP ? 1 : 0);
|
||||
response.getAmDemodSettings()->setInputFrequencyOffset(settings.m_inputFrequencyOffset);
|
||||
|
@ -447,5 +476,6 @@ void AMDemod::webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response)
|
|||
|
||||
response.getAmDemodReport()->setChannelPowerDb(CalcDb::dbPower(magsqAvg));
|
||||
response.getAmDemodReport()->setSquelch(m_squelchOpen ? 1 : 0);
|
||||
response.getAmDemodReport()->setAudioSampleRate(m_audioSampleRate);
|
||||
}
|
||||
|
||||
|
|
|
@ -115,6 +115,7 @@ public:
|
|||
SWGSDRangel::SWGChannelReport& response,
|
||||
QString& errorMessage);
|
||||
|
||||
uint32_t getAudioSampleRate() const { return m_audioSampleRate; }
|
||||
double getMagSq() const { return m_magsq; }
|
||||
bool getSquelchOpen() const { return m_squelchOpen; }
|
||||
|
||||
|
@ -146,6 +147,7 @@ private:
|
|||
int m_inputSampleRate;
|
||||
int m_inputFrequencyOffset;
|
||||
AMDemodSettings m_settings;
|
||||
uint32_t m_audioSampleRate;
|
||||
bool m_running;
|
||||
|
||||
NCO m_nco;
|
||||
|
@ -176,6 +178,7 @@ private:
|
|||
|
||||
void applyChannelSettings(int inputSampleRate, int inputFrequencyOffset, bool force = false);
|
||||
void applySettings(const AMDemodSettings& settings, bool force = false);
|
||||
void applyAudioSampleRate(int sampleRate);
|
||||
void webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& response, const AMDemodSettings& settings);
|
||||
void webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response);
|
||||
|
||||
|
@ -197,7 +200,7 @@ private:
|
|||
|
||||
if (m_magsq >= m_squelchLevel)
|
||||
{
|
||||
if (m_squelchCount <= m_settings.m_audioSampleRate / 10)
|
||||
if (m_squelchCount <= m_audioSampleRate / 10)
|
||||
{
|
||||
m_squelchCount++;
|
||||
}
|
||||
|
@ -212,7 +215,7 @@ private:
|
|||
|
||||
qint16 sample;
|
||||
|
||||
if ((m_squelchCount >= m_settings.m_audioSampleRate / 20) && !m_settings.m_audioMute)
|
||||
if ((m_squelchCount >= m_audioSampleRate / 20) && !m_settings.m_audioMute)
|
||||
{
|
||||
Real demod = sqrt(magsq);
|
||||
m_volumeAGC.feed(demod);
|
||||
|
@ -224,7 +227,7 @@ private:
|
|||
demod /= 301.0f;
|
||||
}
|
||||
|
||||
Real attack = (m_squelchCount - 0.05f * m_settings.m_audioSampleRate) / (0.05f * m_settings.m_audioSampleRate);
|
||||
Real attack = (m_squelchCount - 0.05f * m_audioSampleRate) / (0.05f * m_audioSampleRate);
|
||||
sample = demod * attack * 2048 * m_settings.m_volume;
|
||||
if (m_settings.m_copyAudioToUDP) {
|
||||
m_audioNetSink->write(demod * attack * 32768.0f);
|
||||
|
|
|
@ -281,7 +281,7 @@ void AMDemodGUI::applySettings(bool force)
|
|||
if (m_doApplySettings)
|
||||
{
|
||||
AMDemod::MsgConfigureChannelizer* channelConfigMsg = AMDemod::MsgConfigureChannelizer::create(
|
||||
48000, m_channelMarker.getCenterFrequency());
|
||||
m_amDemod->getAudioSampleRate(), m_channelMarker.getCenterFrequency());
|
||||
m_amDemod->getInputMessageQueue()->push(channelConfigMsg);
|
||||
|
||||
|
||||
|
|
|
@ -33,7 +33,6 @@ void AMDemodSettings::resetToDefaults()
|
|||
m_rfBandwidth = 5000;
|
||||
m_squelch = -40.0;
|
||||
m_volume = 2.0;
|
||||
m_audioSampleRate = DSPEngine::instance()->getDefaultAudioSampleRate();
|
||||
m_audioMute = false;
|
||||
m_bandpassEnable = false;
|
||||
m_copyAudioToUDP = false;
|
||||
|
|
|
@ -27,7 +27,6 @@ struct AMDemodSettings
|
|||
Real m_rfBandwidth;
|
||||
Real m_squelch;
|
||||
Real m_volume;
|
||||
quint32 m_audioSampleRate;
|
||||
bool m_audioMute;
|
||||
bool m_bandpassEnable;
|
||||
bool m_copyAudioToUDP;
|
||||
|
|
|
@ -17,12 +17,16 @@
|
|||
|
||||
#include "audio/audiodevicemanager.h"
|
||||
#include "util/simpleserializer.h"
|
||||
#include "util/messagequeue.h"
|
||||
#include "dsp/dspcommands.h"
|
||||
|
||||
#include <QDataStream>
|
||||
#include <QSet>
|
||||
#include <QDebug>
|
||||
|
||||
const float AudioDeviceManager::m_defaultAudioInputVolume = 0.15f;
|
||||
const QString AudioDeviceManager::m_defaultUDPAddress = "127.0.0.1";
|
||||
const QString AudioDeviceManager::m_defaultDeviceName = "System default device";
|
||||
|
||||
QDataStream& operator<<(QDataStream& ds, const AudioDeviceManager::InputDeviceInfo& info)
|
||||
{
|
||||
|
@ -67,7 +71,7 @@ bool AudioDeviceManager::getOutputDeviceName(int outputDeviceIndex, QString &dev
|
|||
{
|
||||
if (outputDeviceIndex < 0)
|
||||
{
|
||||
deviceName = "System default device";
|
||||
deviceName = m_defaultDeviceName;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
@ -88,7 +92,7 @@ bool AudioDeviceManager::getInputDeviceName(int inputDeviceIndex, QString &devic
|
|||
{
|
||||
if (inputDeviceIndex < 0)
|
||||
{
|
||||
deviceName = "System default device";
|
||||
deviceName = m_defaultDeviceName;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
@ -212,7 +216,8 @@ void AudioDeviceManager::addAudioSink(AudioFifo* audioFifo, MessageQueue *sample
|
|||
}
|
||||
|
||||
m_audioSinkFifos[audioFifo] = outputDeviceIndex; // register audio FIFO
|
||||
m_sampleSinkMessageQueues[audioFifo] = sampleSinkMessageQueue;
|
||||
m_audioFifoToSinkMessageQueues[audioFifo] = sampleSinkMessageQueue;
|
||||
m_outputDeviceSinkMessageQueues[outputDeviceIndex].append(sampleSinkMessageQueue);
|
||||
}
|
||||
|
||||
void AudioDeviceManager::removeAudioSink(AudioFifo* audioFifo)
|
||||
|
@ -233,7 +238,8 @@ void AudioDeviceManager::removeAudioSink(AudioFifo* audioFifo)
|
|||
}
|
||||
|
||||
m_audioSinkFifos.remove(audioFifo); // unregister audio FIFO
|
||||
m_sampleSinkMessageQueues.remove(audioFifo);
|
||||
m_outputDeviceSinkMessageQueues[audioOutputDeviceIndex].removeOne(m_audioFifoToSinkMessageQueues[audioFifo]);
|
||||
m_audioFifoToSinkMessageQueues.remove(audioFifo);
|
||||
}
|
||||
|
||||
void AudioDeviceManager::addAudioSource(AudioFifo* audioFifo, MessageQueue *sampleSourceMessageQueue, int inputDeviceIndex)
|
||||
|
@ -264,7 +270,8 @@ void AudioDeviceManager::addAudioSource(AudioFifo* audioFifo, MessageQueue *samp
|
|||
}
|
||||
|
||||
m_audioSourceFifos[audioFifo] = inputDeviceIndex; // register audio FIFO
|
||||
m_sampleSourceMessageQueues[audioFifo] = sampleSourceMessageQueue;
|
||||
m_audioFifoToSourceMessageQueues[audioFifo] = sampleSourceMessageQueue;
|
||||
m_outputDeviceSinkMessageQueues[inputDeviceIndex].append(sampleSourceMessageQueue);
|
||||
}
|
||||
|
||||
void AudioDeviceManager::removeAudioSource(AudioFifo* audioFifo)
|
||||
|
@ -285,7 +292,8 @@ void AudioDeviceManager::removeAudioSource(AudioFifo* audioFifo)
|
|||
}
|
||||
|
||||
m_audioSourceFifos.remove(audioFifo); // unregister audio FIFO
|
||||
m_sampleSourceMessageQueues.remove(audioFifo);
|
||||
m_inputDeviceSourceMessageQueues[audioInputDeviceIndex].removeOne(m_audioFifoToSourceMessageQueues[audioFifo]);
|
||||
m_audioFifoToSourceMessageQueues.remove(audioFifo);
|
||||
}
|
||||
|
||||
void AudioDeviceManager::startAudioOutput(int outputDeviceIndex)
|
||||
|
@ -373,6 +381,294 @@ void AudioDeviceManager::stopAudioInput(int inputDeviceIndex)
|
|||
m_audioInputs[inputDeviceIndex]->stop();
|
||||
}
|
||||
|
||||
bool AudioDeviceManager::getInputDeviceInfo(const QString& deviceName, InputDeviceInfo& deviceInfo) const
|
||||
{
|
||||
if (m_audioInputInfos.find(deviceName) == m_audioInputInfos.end())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
deviceInfo = m_audioInputInfos[deviceName];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool AudioDeviceManager::getOutputDeviceInfo(const QString& deviceName, OutputDeviceInfo& deviceInfo) const
|
||||
{
|
||||
if (m_audioOutputInfos.find(deviceName) == m_audioOutputInfos.end())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
deviceInfo = m_audioOutputInfos[deviceName];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
int AudioDeviceManager::getInputSampleRate(int inputDeviceIndex)
|
||||
{
|
||||
QString deviceName;
|
||||
|
||||
if (!getInputDeviceName(inputDeviceIndex, deviceName))
|
||||
{
|
||||
qDebug("AudioDeviceManager::getInputSampleRate: unknown device index %d", inputDeviceIndex);
|
||||
return m_defaultAudioSampleRate;
|
||||
}
|
||||
|
||||
InputDeviceInfo deviceInfo;
|
||||
|
||||
if (!getInputDeviceInfo(deviceName, deviceInfo))
|
||||
{
|
||||
qDebug("AudioDeviceManager::getInputSampleRate: unknown device %s", qPrintable(deviceName));
|
||||
return m_defaultAudioSampleRate;
|
||||
}
|
||||
else
|
||||
{
|
||||
return deviceInfo.sampleRate;
|
||||
}
|
||||
}
|
||||
|
||||
int AudioDeviceManager::getOutputSampleRate(int outputDeviceIndex)
|
||||
{
|
||||
QString deviceName;
|
||||
|
||||
if (!getOutputDeviceName(outputDeviceIndex, deviceName))
|
||||
{
|
||||
qDebug("AudioDeviceManager::getOutputSampleRate: unknown device index %d", outputDeviceIndex);
|
||||
return m_defaultAudioSampleRate;
|
||||
}
|
||||
|
||||
OutputDeviceInfo deviceInfo;
|
||||
|
||||
if (!getOutputDeviceInfo(deviceName, deviceInfo))
|
||||
{
|
||||
qDebug("AudioDeviceManager::getOutputSampleRate: unknown device %s", qPrintable(deviceName));
|
||||
return m_defaultAudioSampleRate;
|
||||
}
|
||||
else
|
||||
{
|
||||
return deviceInfo.sampleRate;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AudioDeviceManager::setInputDeviceInfo(int inputDeviceIndex, const InputDeviceInfo& deviceInfo)
|
||||
{
|
||||
QString deviceName;
|
||||
|
||||
if (!getInputDeviceName(inputDeviceIndex, deviceName))
|
||||
{
|
||||
qWarning("AudioDeviceManager::setInputDeviceInfo: unknown device index %d", inputDeviceIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
InputDeviceInfo oldDeviceInfo;
|
||||
|
||||
if (!getInputDeviceInfo(deviceName, oldDeviceInfo))
|
||||
{
|
||||
qDebug("AudioDeviceManager::setInputDeviceInfo: unknown device %s", qPrintable(deviceName));
|
||||
}
|
||||
|
||||
m_audioInputInfos[deviceName] = deviceInfo;
|
||||
|
||||
if (m_audioInputs.find(inputDeviceIndex) == m_audioInputs.end()) { // no FIFO registered yet hence no audio input has been allocated yet
|
||||
return;
|
||||
}
|
||||
|
||||
AudioInput *audioInput = m_audioInputs[inputDeviceIndex];
|
||||
|
||||
if (oldDeviceInfo.sampleRate != deviceInfo.sampleRate)
|
||||
{
|
||||
audioInput->stop();
|
||||
audioInput->start(inputDeviceIndex, deviceInfo.sampleRate);
|
||||
m_audioInputInfos[deviceName].sampleRate = audioInput->getRate(); // store actual sample rate
|
||||
|
||||
// send message to attached channels
|
||||
QList<MessageQueue *>::const_iterator it = m_inputDeviceSourceMessageQueues[inputDeviceIndex].begin();
|
||||
|
||||
for (; it != m_inputDeviceSourceMessageQueues[inputDeviceIndex].end(); ++it)
|
||||
{
|
||||
DSPConfigureAudio *msg = new DSPConfigureAudio(m_audioInputInfos[deviceName].sampleRate);
|
||||
(*it)->push(msg);
|
||||
}
|
||||
}
|
||||
|
||||
audioInput->setVolume(deviceInfo.volume);
|
||||
}
|
||||
|
||||
void AudioDeviceManager::setOutputDeviceInfo(int outputDeviceIndex, const OutputDeviceInfo& deviceInfo)
|
||||
{
|
||||
QString deviceName;
|
||||
|
||||
if (!getOutputDeviceName(outputDeviceIndex, deviceName))
|
||||
{
|
||||
qWarning("AudioDeviceManager::setOutputDeviceInfo: unknown device index %d", outputDeviceIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
OutputDeviceInfo oldDeviceInfo;
|
||||
|
||||
if (!getOutputDeviceInfo(deviceName, oldDeviceInfo))
|
||||
{
|
||||
qDebug("AudioDeviceManager::setOutputDeviceInfo: unknown device %s", qPrintable(deviceName));
|
||||
}
|
||||
|
||||
m_audioOutputInfos[deviceName] = deviceInfo;
|
||||
|
||||
if (m_audioOutputs.find(outputDeviceIndex) == m_audioOutputs.end()) { // no FIFO registered yet hence no audio output has been allocated yet
|
||||
return;
|
||||
}
|
||||
|
||||
AudioOutput *audioOutput = m_audioOutputs[outputDeviceIndex];
|
||||
|
||||
if (oldDeviceInfo.sampleRate != deviceInfo.sampleRate)
|
||||
{
|
||||
audioOutput->stop();
|
||||
audioOutput->start(outputDeviceIndex, deviceInfo.sampleRate);
|
||||
m_audioOutputInfos[deviceName].sampleRate = audioOutput->getRate(); // store actual sample rate
|
||||
|
||||
// send message to attached channels
|
||||
QList<MessageQueue *>::const_iterator it = m_outputDeviceSinkMessageQueues[outputDeviceIndex].begin();
|
||||
|
||||
for (; it != m_outputDeviceSinkMessageQueues[outputDeviceIndex].end(); ++it)
|
||||
{
|
||||
DSPConfigureAudio *msg = new DSPConfigureAudio(m_audioOutputInfos[deviceName].sampleRate);
|
||||
(*it)->push(msg);
|
||||
}
|
||||
}
|
||||
|
||||
audioOutput->setUdpCopyToUDP(deviceInfo.copyToUDP);
|
||||
audioOutput->setUdpDestination(deviceInfo.udpAddress, deviceInfo.udpPort);
|
||||
audioOutput->setUdpStereo(deviceInfo.udpStereo);
|
||||
audioOutput->setUdpUseRTP(deviceInfo.udpUseRTP);
|
||||
}
|
||||
|
||||
void AudioDeviceManager::unsetOutputDeviceInfo(int outputDeviceIndex)
|
||||
{
|
||||
QString deviceName;
|
||||
|
||||
if (!getOutputDeviceName(outputDeviceIndex, deviceName))
|
||||
{
|
||||
qWarning("AudioDeviceManager::unsetOutputDeviceInfo: unknown device index %d", outputDeviceIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
OutputDeviceInfo oldDeviceInfo;
|
||||
|
||||
if (!getOutputDeviceInfo(deviceName, oldDeviceInfo))
|
||||
{
|
||||
qDebug("AudioDeviceManager::unsetOutputDeviceInfo: unregistered device %s", qPrintable(deviceName));
|
||||
return;
|
||||
}
|
||||
|
||||
m_audioOutputInfos.remove(deviceName);
|
||||
|
||||
if (m_audioOutputs.find(outputDeviceIndex) == m_audioOutputs.end()) { // no FIFO registered yet hence no audio output has been allocated yet
|
||||
return;
|
||||
}
|
||||
|
||||
stopAudioOutput(outputDeviceIndex);
|
||||
startAudioOutput(outputDeviceIndex);
|
||||
|
||||
if (oldDeviceInfo.sampleRate != m_audioOutputInfos[deviceName].sampleRate)
|
||||
{
|
||||
// send message to attached channels
|
||||
QList<MessageQueue *>::const_iterator it = m_outputDeviceSinkMessageQueues[outputDeviceIndex].begin();
|
||||
|
||||
for (; it != m_outputDeviceSinkMessageQueues[outputDeviceIndex].end(); ++it)
|
||||
{
|
||||
DSPConfigureAudio *msg = new DSPConfigureAudio(m_audioOutputInfos[deviceName].sampleRate);
|
||||
(*it)->push(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AudioDeviceManager::unsetInputDeviceInfo(int inputDeviceIndex)
|
||||
{
|
||||
QString deviceName;
|
||||
|
||||
if (!getInputDeviceName(inputDeviceIndex, deviceName))
|
||||
{
|
||||
qWarning("AudioDeviceManager::unsetInputDeviceInfo: unknown device index %d", inputDeviceIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
InputDeviceInfo oldDeviceInfo;
|
||||
|
||||
if (!getInputDeviceInfo(deviceName, oldDeviceInfo))
|
||||
{
|
||||
qDebug("AudioDeviceManager::unsetInputDeviceInfo: unregistered device %s", qPrintable(deviceName));
|
||||
return;
|
||||
}
|
||||
|
||||
m_audioInputInfos.remove(deviceName);
|
||||
|
||||
if (m_audioInputs.find(inputDeviceIndex) == m_audioInputs.end()) { // no FIFO registered yet hence no audio input has been allocated yet
|
||||
return;
|
||||
}
|
||||
|
||||
stopAudioInput(inputDeviceIndex);
|
||||
startAudioInput(inputDeviceIndex);
|
||||
|
||||
if (oldDeviceInfo.sampleRate != m_audioInputInfos[deviceName].sampleRate)
|
||||
{
|
||||
// send message to attached channels
|
||||
QList<MessageQueue *>::const_iterator it = m_inputDeviceSourceMessageQueues[inputDeviceIndex].begin();
|
||||
|
||||
for (; it != m_inputDeviceSourceMessageQueues[inputDeviceIndex].end(); ++it)
|
||||
{
|
||||
DSPConfigureAudio *msg = new DSPConfigureAudio(m_audioInputInfos[deviceName].sampleRate);
|
||||
(*it)->push(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AudioDeviceManager::inputInfosCleanup()
|
||||
{
|
||||
QSet<QString> deviceNames;
|
||||
deviceNames.insert(m_defaultDeviceName);
|
||||
QList<QAudioDeviceInfo>::const_iterator itd = m_inputDevicesInfo.begin();
|
||||
|
||||
for (; itd != m_inputDevicesInfo.end(); ++itd) {
|
||||
deviceNames.insert(itd->deviceName());
|
||||
}
|
||||
|
||||
QMap<QString, InputDeviceInfo>::iterator itm = m_audioInputInfos.begin();
|
||||
|
||||
for (; itm != m_audioInputInfos.end(); ++itm)
|
||||
{
|
||||
if (!deviceNames.contains(itm.key()))
|
||||
{
|
||||
qDebug("AudioDeviceManager::inputInfosCleanup: removing key: %s", qPrintable(itm.key()));
|
||||
m_audioInputInfos.remove(itm.key());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AudioDeviceManager::outputInfosCleanup()
|
||||
{
|
||||
QSet<QString> deviceNames;
|
||||
deviceNames.insert(m_defaultDeviceName);
|
||||
QList<QAudioDeviceInfo>::const_iterator itd = m_outputDevicesInfo.begin();
|
||||
|
||||
for (; itd != m_outputDevicesInfo.end(); ++itd) {
|
||||
deviceNames.insert(itd->deviceName());
|
||||
}
|
||||
|
||||
QMap<QString, OutputDeviceInfo>::iterator itm = m_audioOutputInfos.begin();
|
||||
|
||||
for (; itm != m_audioOutputInfos.end(); ++itm)
|
||||
{
|
||||
if (!deviceNames.contains(itm.key()))
|
||||
{
|
||||
qDebug("AudioDeviceManager::outputInfosCleanup: removing key: %s", qPrintable(itm.key()));
|
||||
m_audioOutputInfos.remove(itm.key());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AudioDeviceManager::debugAudioInputInfos() const
|
||||
{
|
||||
QMap<QString, InputDeviceInfo>::const_iterator it = m_audioInputInfos.begin();
|
||||
|
|
|
@ -40,6 +40,10 @@ public:
|
|||
sampleRate(m_defaultAudioSampleRate),
|
||||
volume(m_defaultAudioInputVolume)
|
||||
{}
|
||||
void resetToDefaults() {
|
||||
sampleRate = m_defaultAudioSampleRate;
|
||||
volume = m_defaultAudioInputVolume;
|
||||
}
|
||||
unsigned int sampleRate;
|
||||
float volume;
|
||||
friend QDataStream& operator<<(QDataStream& ds, const InputDeviceInfo& info);
|
||||
|
@ -57,6 +61,14 @@ public:
|
|||
udpStereo(false),
|
||||
udpUseRTP(false)
|
||||
{}
|
||||
void resetToDefaults() {
|
||||
sampleRate = m_defaultAudioSampleRate;
|
||||
udpAddress = m_defaultUDPAddress;
|
||||
udpPort = m_defaultUDPPort;
|
||||
copyToUDP = false;
|
||||
udpStereo = false;
|
||||
udpUseRTP = false;
|
||||
}
|
||||
unsigned int sampleRate;
|
||||
QString udpAddress;
|
||||
quint16 udpPort;
|
||||
|
@ -70,12 +82,11 @@ public:
|
|||
AudioDeviceManager();
|
||||
~AudioDeviceManager();
|
||||
|
||||
|
||||
const QList<QAudioDeviceInfo>& getInputDevices() const { return m_inputDevicesInfo; }
|
||||
const QList<QAudioDeviceInfo>& getOutputDevices() const { return m_outputDevicesInfo; }
|
||||
|
||||
bool getOutputDeviceName(int outputDeviceIndex, QString &deviceName) const;
|
||||
bool getInputDeviceName(int outputDeviceIndex, QString &deviceName) const;
|
||||
bool getInputDeviceName(int inputDeviceIndex, QString &deviceName) const;
|
||||
|
||||
void addAudioSink(AudioFifo* audioFifo, MessageQueue *sampleSinkMessageQueue, int outputDeviceIndex = -1); //!< Add the audio sink
|
||||
void removeAudioSink(AudioFifo* audioFifo); //!< Remove the audio sink
|
||||
|
@ -83,22 +94,36 @@ public:
|
|||
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
|
||||
|
||||
static const unsigned 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:
|
||||
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*, MessageQueue*> m_sampleSinkMessageQueues; //!< audio sink FIFO to attached sink message queue
|
||||
QMap<AudioFifo*, MessageQueue*> m_audioFifoToSinkMessageQueues; //!< audio sink FIFO to attached sink message queue
|
||||
QMap<int, QList<MessageQueue*> > m_outputDeviceSinkMessageQueues; //!< sink message queues attached to device
|
||||
QMap<int, AudioOutput*> m_audioOutputs; //!< audio device index to audio output map (index -1 is default device)
|
||||
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*, MessageQueue*> m_sampleSourceMessageQueues; //!< audio source FIFO to attached source message queue
|
||||
QMap<AudioFifo*, MessageQueue*> m_audioFifoToSourceMessageQueues; //!< audio source FIFO to attached source message queue
|
||||
QMap<int, QList<MessageQueue*> > m_inputDeviceSourceMessageQueues; //!< sink message queues attached to device
|
||||
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
|
||||
|
||||
|
|
|
@ -46,3 +46,4 @@ MESSAGE_CLASS_DEFINITION(DSPEngineReport, Message)
|
|||
MESSAGE_CLASS_DEFINITION(DSPConfigureScopeVis, Message)
|
||||
MESSAGE_CLASS_DEFINITION(DSPSignalNotification, Message)
|
||||
MESSAGE_CLASS_DEFINITION(DSPConfigureChannelizer, Message)
|
||||
MESSAGE_CLASS_DEFINITION(DSPConfigureAudio, Message)
|
||||
|
|
|
@ -371,4 +371,17 @@ private:
|
|||
int m_centerFrequency;
|
||||
};
|
||||
|
||||
class SDRBASE_API DSPConfigureAudio : public Message {
|
||||
MESSAGE_CLASS_DECLARATION
|
||||
|
||||
public:
|
||||
DSPConfigureAudio(int sampleRate) : m_sampleRate(sampleRate)
|
||||
{ }
|
||||
|
||||
int getSampleRate() const { return m_sampleRate; }
|
||||
|
||||
private:
|
||||
int m_sampleRate;
|
||||
};
|
||||
|
||||
#endif // INCLUDE_DSPCOMMANDS_H
|
||||
|
|
|
@ -18,11 +18,11 @@
|
|||
#ifndef INCLUDE_DSPENGINE_H
|
||||
#define INCLUDE_DSPENGINE_H
|
||||
|
||||
#include <audio/audiodevicemanager.h>
|
||||
#include <QObject>
|
||||
#include <QTimer>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "audio/audiodevicemanager.h"
|
||||
#include "audio/audiooutput.h"
|
||||
#include "audio/audioinput.h"
|
||||
#include "export.h"
|
||||
|
|
|
@ -706,6 +706,9 @@ margin-bottom: 20px;
|
|||
"squelch" : {
|
||||
"type" : "integer",
|
||||
"description" : "squelch status (1 if open else 0)"
|
||||
},
|
||||
"audioSampleRate" : {
|
||||
"type" : "integer"
|
||||
}
|
||||
},
|
||||
"description" : "AMDemod"
|
||||
|
@ -731,9 +734,6 @@ margin-bottom: 20px;
|
|||
"type" : "number",
|
||||
"format" : "float"
|
||||
},
|
||||
"audioSampleRate" : {
|
||||
"type" : "integer"
|
||||
},
|
||||
"audioMute" : {
|
||||
"type" : "integer"
|
||||
},
|
||||
|
@ -18063,7 +18063,7 @@ except ApiException as e:
|
|||
</div>
|
||||
<div id="generator">
|
||||
<div class="content">
|
||||
Generated 2018-03-22T05:08:39.552+01:00
|
||||
Generated 2018-03-26T10:23:40.336+02:00
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -16,8 +16,6 @@ AMDemodSettings:
|
|||
volume:
|
||||
type: number
|
||||
format: float
|
||||
audioSampleRate:
|
||||
type: integer
|
||||
audioMute:
|
||||
type: integer
|
||||
bandpassEnable:
|
||||
|
@ -46,3 +44,6 @@ AMDemodReport:
|
|||
squelch:
|
||||
description: squelch status (1 if open else 0)
|
||||
type: integer
|
||||
audioSampleRate:
|
||||
type: integer
|
||||
|
|
@ -11,66 +11,44 @@ AudioDialogX::AudioDialogX(AudioDeviceManager* audioDeviceManager, QWidget* pare
|
|||
{
|
||||
ui->setupUi(this);
|
||||
QTreeWidgetItem* treeItem;
|
||||
int i;
|
||||
|
||||
// out panel
|
||||
|
||||
QAudioDeviceInfo defaultOutputDeviceInfo = QAudioDeviceInfo::defaultOutputDevice();
|
||||
treeItem = new QTreeWidgetItem(ui->audioOutTree);
|
||||
treeItem->setText(0, tr("System default output device"));
|
||||
treeItem->setText(0, AudioDeviceManager::m_defaultDeviceName);
|
||||
ui->audioOutTree->setCurrentItem(treeItem);
|
||||
|
||||
const QList<QAudioDeviceInfo>& outputDevices = m_audioDeviceManager->getOutputDevices();
|
||||
i = 0;
|
||||
|
||||
for(QList<QAudioDeviceInfo>::const_iterator it = outputDevices.begin(); it != outputDevices.end(); ++it)
|
||||
{
|
||||
bool isDefaultDevice = it->deviceName() == defaultOutputDeviceInfo.deviceName();
|
||||
treeItem = new QTreeWidgetItem(ui->audioOutTree);
|
||||
treeItem->setText(0, it->deviceName() + (isDefaultDevice ? "(*)" : ""));
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
ui->audioOutTree->setCurrentItem(treeItem);
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
// in panel
|
||||
|
||||
QAudioDeviceInfo defaultInputDeviceInfo = QAudioDeviceInfo::defaultInputDevice();
|
||||
treeItem = new QTreeWidgetItem(ui->audioInTree);
|
||||
treeItem->setText(0, tr("System default input device"));
|
||||
treeItem->setText(0, AudioDeviceManager::m_defaultDeviceName);
|
||||
ui->audioInTree->setCurrentItem(treeItem);
|
||||
|
||||
const QList<QAudioDeviceInfo>& inputDevices = m_audioDeviceManager->getInputDevices();
|
||||
i = 0;
|
||||
|
||||
for(QList<QAudioDeviceInfo>::const_iterator it = inputDevices.begin(); it != inputDevices.end(); ++it)
|
||||
{
|
||||
bool isDefaultDevice = it->deviceName() == defaultInputDeviceInfo.deviceName();
|
||||
treeItem = new QTreeWidgetItem(ui->audioInTree);
|
||||
treeItem->setText(0, it->deviceName() + (isDefaultDevice ? "(*)" : ""));
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
ui->audioInTree->setCurrentItem(treeItem);
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
if(ui->audioOutTree->currentItem() == 0) {
|
||||
ui->audioOutTree->setCurrentItem(ui->audioOutTree->topLevelItem(0));
|
||||
}
|
||||
|
||||
if(ui->audioInTree->currentItem() == 0) {
|
||||
ui->audioInTree->setCurrentItem(ui->audioInTree->topLevelItem(0));
|
||||
}
|
||||
m_outputUDPPort = 9998;
|
||||
m_outIndex = -1;
|
||||
m_inIndex = -1;
|
||||
|
||||
ui->tabWidget->setCurrentIndex(0);
|
||||
|
||||
ui->inputVolume->setValue((int) (m_inputVolume * 100.0f));
|
||||
ui->inputVolumeText->setText(QString("%1").arg(m_inputVolume, 0, 'f', 2));
|
||||
}
|
||||
|
||||
AudioDialogX::~AudioDialogX()
|
||||
|
@ -80,11 +58,152 @@ AudioDialogX::~AudioDialogX()
|
|||
|
||||
void AudioDialogX::accept()
|
||||
{
|
||||
QDialog::accept();
|
||||
m_inIndex = ui->audioInTree->indexOfTopLevelItem(ui->audioInTree->currentItem());
|
||||
m_outIndex = ui->audioOutTree->indexOfTopLevelItem(ui->audioOutTree->currentItem());
|
||||
|
||||
if (ui->tabWidget->currentIndex() == 0) // output
|
||||
{
|
||||
updateOutputDeviceInfo();
|
||||
|
||||
if (ui->outputResetKey->isChecked()) {
|
||||
m_audioDeviceManager->unsetOutputDeviceInfo(m_outIndex-1);
|
||||
} else {
|
||||
m_audioDeviceManager->setOutputDeviceInfo(m_outIndex-1, m_outputDeviceInfo);
|
||||
}
|
||||
}
|
||||
else if (ui->tabWidget->currentIndex() == 1) // input
|
||||
{
|
||||
updateInputDeviceInfo();
|
||||
|
||||
if (ui->inputResetKey->isChecked()) {
|
||||
m_audioDeviceManager->unsetInputDeviceInfo(m_inIndex-1);
|
||||
} else {
|
||||
m_audioDeviceManager->setInputDeviceInfo(m_inIndex-1, m_inputDeviceInfo);
|
||||
}
|
||||
}
|
||||
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
void AudioDialogX::reject()
|
||||
{
|
||||
QDialog::reject();
|
||||
}
|
||||
|
||||
void AudioDialogX::on_audioInTree_currentItemChanged(
|
||||
QTreeWidgetItem* currentItem,
|
||||
QTreeWidgetItem* previousItem)
|
||||
{
|
||||
AudioDeviceManager::InputDeviceInfo inDeviceInfo;
|
||||
QString inDeviceName = currentItem->text(0);
|
||||
int newIndex = ui->audioInTree->indexOfTopLevelItem(currentItem);
|
||||
int oldIndex = ui->audioInTree->indexOfTopLevelItem(previousItem);
|
||||
//qDebug("AudioDialogX::on_audioInTree_currentItemChanged: %s", qPrintable(inDeviceName));
|
||||
|
||||
if (newIndex != oldIndex) {
|
||||
ui->inputResetKey->setChecked(false);
|
||||
}
|
||||
|
||||
bool found = m_audioDeviceManager->getInputDeviceInfo(inDeviceName, inDeviceInfo);
|
||||
m_inputDeviceInfo = inDeviceInfo;
|
||||
ui->inputDefaultText->setText(found ? "" : "D");
|
||||
|
||||
updateInputDisplay();
|
||||
}
|
||||
|
||||
void AudioDialogX::on_audioOutTree_currentItemChanged(
|
||||
QTreeWidgetItem* currentItem,
|
||||
QTreeWidgetItem* previousItem)
|
||||
{
|
||||
AudioDeviceManager::OutputDeviceInfo outDeviceInfo;
|
||||
QString outDeviceName = currentItem->text(0);
|
||||
int newIndex = ui->audioOutTree->indexOfTopLevelItem(currentItem);
|
||||
int oldIndex = ui->audioOutTree->indexOfTopLevelItem(previousItem);
|
||||
|
||||
if (newIndex != oldIndex) {
|
||||
ui->outputResetKey->setChecked(false);
|
||||
}
|
||||
|
||||
bool found = m_audioDeviceManager->getOutputDeviceInfo(outDeviceName, outDeviceInfo);
|
||||
m_outputDeviceInfo = outDeviceInfo;
|
||||
ui->outputDefaultText->setText(found ? "" : "D");
|
||||
|
||||
updateOutputDisplay();
|
||||
|
||||
//qDebug("AudioDialogX::on_audioOutTree_currentItemChanged: %d:%s", outIndex, qPrintable(outDeviceName));
|
||||
}
|
||||
|
||||
void AudioDialogX::on_inputVolume_valueChanged(int value)
|
||||
{
|
||||
m_inputVolume = (float) value / 100.0f;
|
||||
ui->inputVolumeText->setText(QString("%1").arg(m_inputVolume, 0, 'f', 2));
|
||||
float volume = value / 100.0f;
|
||||
ui->inputVolumeText->setText(QString("%1").arg(volume, 0, 'f', 2));
|
||||
}
|
||||
|
||||
void AudioDialogX::on_inputReset_clicked(bool checked __attribute__((unused)))
|
||||
{
|
||||
m_inputDeviceInfo.resetToDefaults();
|
||||
updateInputDisplay();
|
||||
}
|
||||
|
||||
void AudioDialogX::on_inputCleanup_clicked(bool checked __attribute__((unused)))
|
||||
{
|
||||
m_audioDeviceManager->inputInfosCleanup();
|
||||
}
|
||||
|
||||
void AudioDialogX::updateInputDisplay()
|
||||
{
|
||||
ui->inputSampleRate->setValue(m_inputDeviceInfo.sampleRate);
|
||||
ui->inputVolume->setValue(roundf(m_inputDeviceInfo.volume * 100.0f));
|
||||
ui->inputVolumeText->setText(QString("%1").arg(m_inputDeviceInfo.volume, 0, 'f', 2));
|
||||
}
|
||||
|
||||
void AudioDialogX::updateInputDeviceInfo()
|
||||
{
|
||||
m_inputDeviceInfo.sampleRate = ui->inputSampleRate->value();
|
||||
m_inputDeviceInfo.volume = ui->inputVolume->value() / 100.0f;
|
||||
}
|
||||
|
||||
void AudioDialogX::on_outputUDPPort_editingFinished()
|
||||
{
|
||||
bool ok;
|
||||
quint16 udpPort = ui->outputUDPPort->text().toInt(&ok);
|
||||
|
||||
if((!ok) || (udpPort < 1024)) {
|
||||
udpPort = 9999;
|
||||
}
|
||||
|
||||
m_outputUDPPort = udpPort;
|
||||
ui->outputUDPPort->setText(tr("%1").arg(m_outputDeviceInfo.udpPort));
|
||||
}
|
||||
|
||||
void AudioDialogX::on_outputReset_clicked(bool checked __attribute__((unused)))
|
||||
{
|
||||
m_outputDeviceInfo.resetToDefaults();
|
||||
updateOutputDisplay();
|
||||
}
|
||||
|
||||
void AudioDialogX::on_outputCleanup_clicked(bool checked __attribute__((unused)))
|
||||
{
|
||||
m_audioDeviceManager->outputInfosCleanup();
|
||||
}
|
||||
|
||||
void AudioDialogX::updateOutputDisplay()
|
||||
{
|
||||
ui->outputSampleRate->setValue(m_outputDeviceInfo.sampleRate);
|
||||
ui->outputUDPAddress->setText(m_outputDeviceInfo.udpAddress);
|
||||
ui->outputUDPPort->setText(tr("%1").arg(m_outputDeviceInfo.udpPort));
|
||||
ui->outputUDPCopy->setChecked(m_outputDeviceInfo.copyToUDP);
|
||||
ui->outputUDPStereo->setChecked(m_outputDeviceInfo.udpStereo);
|
||||
ui->outputUDPUseRTP->setChecked(m_outputDeviceInfo.udpUseRTP);
|
||||
}
|
||||
|
||||
void AudioDialogX::updateOutputDeviceInfo()
|
||||
{
|
||||
m_outputDeviceInfo.sampleRate = ui->outputSampleRate->value();
|
||||
m_outputDeviceInfo.udpAddress = ui->outputUDPAddress->text();
|
||||
m_outputDeviceInfo.udpPort = m_outputUDPPort;
|
||||
m_outputDeviceInfo.copyToUDP = ui->outputUDPCopy->isChecked();
|
||||
m_outputDeviceInfo.udpStereo = ui->outputUDPStereo->isChecked();
|
||||
m_outputDeviceInfo.udpUseRTP = ui->outputUDPUseRTP->isChecked();
|
||||
}
|
||||
|
||||
|
|
|
@ -4,8 +4,9 @@
|
|||
#include <QDialog>
|
||||
|
||||
#include "export.h"
|
||||
#include "audio/audiodevicemanager.h"
|
||||
|
||||
class AudioDeviceManager;
|
||||
class QTreeWidgetItem;
|
||||
|
||||
namespace Ui {
|
||||
class AudioDialog;
|
||||
|
@ -18,15 +19,33 @@ public:
|
|||
explicit AudioDialogX(AudioDeviceManager* audioDeviceManager, QWidget* parent = 0);
|
||||
~AudioDialogX();
|
||||
|
||||
int m_inIndex;
|
||||
int m_outIndex;
|
||||
|
||||
private:
|
||||
void updateInputDisplay();
|
||||
void updateOutputDisplay();
|
||||
void updateInputDeviceInfo();
|
||||
void updateOutputDeviceInfo();
|
||||
|
||||
Ui::AudioDialog* ui;
|
||||
|
||||
AudioDeviceManager* m_audioDeviceManager;
|
||||
float m_inputVolume;
|
||||
AudioDeviceManager::InputDeviceInfo m_inputDeviceInfo;
|
||||
AudioDeviceManager::OutputDeviceInfo m_outputDeviceInfo;
|
||||
quint16 m_outputUDPPort;
|
||||
|
||||
private slots:
|
||||
void accept();
|
||||
void reject();
|
||||
void on_audioInTree_currentItemChanged(QTreeWidgetItem* currentItem, QTreeWidgetItem* previousItem);
|
||||
void on_audioOutTree_currentItemChanged(QTreeWidgetItem* currentItem, QTreeWidgetItem* previousItem);
|
||||
void on_inputVolume_valueChanged(int value);
|
||||
void on_inputReset_clicked(bool checked);
|
||||
void on_inputCleanup_clicked(bool checked);
|
||||
void on_outputUDPPort_editingFinished();
|
||||
void on_outputReset_clicked(bool checked);
|
||||
void on_outputCleanup_clicked(bool checked);
|
||||
};
|
||||
|
||||
#endif // INCLUDE_AUDIODIALOG_H
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
<height>349</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
|
@ -69,7 +69,7 @@
|
|||
<number>192000</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>50</number>
|
||||
<number>1000</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>48000</number>
|
||||
|
@ -89,6 +89,22 @@
|
|||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="outputDefaultText">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>16</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Default values indicator</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>D</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="outputReset">
|
||||
<property name="maximumSize">
|
||||
|
@ -108,16 +124,16 @@
|
|||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="udpLayout">
|
||||
<layout class="QHBoxLayout" name="outputUDPLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="udpAddressLabel">
|
||||
<widget class="QLabel" name="outputUDPAddressLabel">
|
||||
<property name="text">
|
||||
<string>Addr</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="udpAddress">
|
||||
<widget class="QLineEdit" name="outputUDPAddress">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>140</width>
|
||||
|
@ -136,14 +152,14 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="udpPortLabel">
|
||||
<widget class="QLabel" name="outputUDPPortLabel">
|
||||
<property name="text">
|
||||
<string>Port</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="udpPort">
|
||||
<widget class="QLineEdit" name="outputUDPPort">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
|
@ -178,7 +194,7 @@
|
|||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ButtonSwitch" name="udpCopy">
|
||||
<widget class="ButtonSwitch" name="outputUDPCopy">
|
||||
<property name="toolTip">
|
||||
<string>Copy audio to UDP</string>
|
||||
</property>
|
||||
|
@ -188,7 +204,7 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="udpStereo">
|
||||
<widget class="QCheckBox" name="outputUDPStereo">
|
||||
<property name="toolTip">
|
||||
<string>Copy to UDP as stereo (no L+R mix)</string>
|
||||
</property>
|
||||
|
@ -198,7 +214,7 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="udpUseRTP">
|
||||
<widget class="QCheckBox" name="outputUDPUseRTP">
|
||||
<property name="toolTip">
|
||||
<string>Use RTP protocol</string>
|
||||
</property>
|
||||
|
@ -209,6 +225,51 @@
|
|||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="outputGeneralLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="outputCleanup">
|
||||
<property name="toolTip">
|
||||
<string>Remove references to devices not listed</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources/res.qrc">
|
||||
<normaloff>:/recycle.png</normaloff>:/recycle.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ButtonSwitch" name="outputResetKey">
|
||||
<property name="toolTip">
|
||||
<string>Remove settings for this device and return to defaults</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources/res.qrc">
|
||||
<normaloff>:/bin.png</normaloff>:/bin.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tabInput">
|
||||
|
@ -255,7 +316,7 @@
|
|||
<number>192000</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>50</number>
|
||||
<number>1000</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>48000</number>
|
||||
|
@ -326,6 +387,22 @@
|
|||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="inputDefaultText">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>16</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Default values indicator</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>D</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="inputReset">
|
||||
<property name="maximumSize">
|
||||
|
@ -344,6 +421,51 @@
|
|||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="inputGeneralLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="inputCleanup">
|
||||
<property name="toolTip">
|
||||
<string>Remove references to devices not listed</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources/res.qrc">
|
||||
<normaloff>:/recycle.png</normaloff>:/recycle.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ButtonSwitch" name="inputResetKey">
|
||||
<property name="toolTip">
|
||||
<string>Remove settings for this device and return to defaults</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources/res.qrc">
|
||||
<normaloff>:/bin.png</normaloff>:/bin.png</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
|
@ -372,7 +494,9 @@
|
|||
<tabstop>tabWidget</tabstop>
|
||||
<tabstop>audioOutTree</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<resources>
|
||||
<include location="../resources/res.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
|
|
|
@ -16,8 +16,6 @@ AMDemodSettings:
|
|||
volume:
|
||||
type: number
|
||||
format: float
|
||||
audioSampleRate:
|
||||
type: integer
|
||||
audioMute:
|
||||
type: integer
|
||||
bandpassEnable:
|
||||
|
@ -46,3 +44,6 @@ AMDemodReport:
|
|||
squelch:
|
||||
description: squelch status (1 if open else 0)
|
||||
type: integer
|
||||
audioSampleRate:
|
||||
type: integer
|
||||
|
|
@ -706,6 +706,9 @@ margin-bottom: 20px;
|
|||
"squelch" : {
|
||||
"type" : "integer",
|
||||
"description" : "squelch status (1 if open else 0)"
|
||||
},
|
||||
"audioSampleRate" : {
|
||||
"type" : "integer"
|
||||
}
|
||||
},
|
||||
"description" : "AMDemod"
|
||||
|
@ -731,9 +734,6 @@ margin-bottom: 20px;
|
|||
"type" : "number",
|
||||
"format" : "float"
|
||||
},
|
||||
"audioSampleRate" : {
|
||||
"type" : "integer"
|
||||
},
|
||||
"audioMute" : {
|
||||
"type" : "integer"
|
||||
},
|
||||
|
@ -18063,7 +18063,7 @@ except ApiException as e:
|
|||
</div>
|
||||
<div id="generator">
|
||||
<div class="content">
|
||||
Generated 2018-03-22T05:08:39.552+01:00
|
||||
Generated 2018-03-26T10:23:40.336+02:00
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -32,6 +32,8 @@ SWGAMDemodReport::SWGAMDemodReport() {
|
|||
m_channel_power_db_isSet = false;
|
||||
squelch = 0;
|
||||
m_squelch_isSet = false;
|
||||
audio_sample_rate = 0;
|
||||
m_audio_sample_rate_isSet = false;
|
||||
}
|
||||
|
||||
SWGAMDemodReport::~SWGAMDemodReport() {
|
||||
|
@ -44,12 +46,15 @@ SWGAMDemodReport::init() {
|
|||
m_channel_power_db_isSet = false;
|
||||
squelch = 0;
|
||||
m_squelch_isSet = false;
|
||||
audio_sample_rate = 0;
|
||||
m_audio_sample_rate_isSet = false;
|
||||
}
|
||||
|
||||
void
|
||||
SWGAMDemodReport::cleanup() {
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
SWGAMDemodReport*
|
||||
|
@ -67,6 +72,8 @@ SWGAMDemodReport::fromJsonObject(QJsonObject &pJson) {
|
|||
|
||||
::SWGSDRangel::setValue(&squelch, pJson["squelch"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&audio_sample_rate, pJson["audioSampleRate"], "qint32", "");
|
||||
|
||||
}
|
||||
|
||||
QString
|
||||
|
@ -89,6 +96,9 @@ SWGAMDemodReport::asJsonObject() {
|
|||
if(m_squelch_isSet){
|
||||
obj->insert("squelch", QJsonValue(squelch));
|
||||
}
|
||||
if(m_audio_sample_rate_isSet){
|
||||
obj->insert("audioSampleRate", QJsonValue(audio_sample_rate));
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
@ -113,6 +123,16 @@ SWGAMDemodReport::setSquelch(qint32 squelch) {
|
|||
this->m_squelch_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGAMDemodReport::getAudioSampleRate() {
|
||||
return audio_sample_rate;
|
||||
}
|
||||
void
|
||||
SWGAMDemodReport::setAudioSampleRate(qint32 audio_sample_rate) {
|
||||
this->audio_sample_rate = audio_sample_rate;
|
||||
this->m_audio_sample_rate_isSet = true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
SWGAMDemodReport::isSet(){
|
||||
|
@ -120,6 +140,7 @@ SWGAMDemodReport::isSet(){
|
|||
do{
|
||||
if(m_channel_power_db_isSet){ isObjectUpdated = true; break;}
|
||||
if(m_squelch_isSet){ isObjectUpdated = true; break;}
|
||||
if(m_audio_sample_rate_isSet){ isObjectUpdated = true; break;}
|
||||
}while(false);
|
||||
return isObjectUpdated;
|
||||
}
|
||||
|
|
|
@ -47,6 +47,9 @@ public:
|
|||
qint32 getSquelch();
|
||||
void setSquelch(qint32 squelch);
|
||||
|
||||
qint32 getAudioSampleRate();
|
||||
void setAudioSampleRate(qint32 audio_sample_rate);
|
||||
|
||||
|
||||
virtual bool isSet() override;
|
||||
|
||||
|
@ -57,6 +60,9 @@ private:
|
|||
qint32 squelch;
|
||||
bool m_squelch_isSet;
|
||||
|
||||
qint32 audio_sample_rate;
|
||||
bool m_audio_sample_rate_isSet;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -36,8 +36,6 @@ SWGAMDemodSettings::SWGAMDemodSettings() {
|
|||
m_squelch_isSet = false;
|
||||
volume = 0.0f;
|
||||
m_volume_isSet = false;
|
||||
audio_sample_rate = 0;
|
||||
m_audio_sample_rate_isSet = false;
|
||||
audio_mute = 0;
|
||||
m_audio_mute_isSet = false;
|
||||
bandpass_enable = 0;
|
||||
|
@ -70,8 +68,6 @@ SWGAMDemodSettings::init() {
|
|||
m_squelch_isSet = false;
|
||||
volume = 0.0f;
|
||||
m_volume_isSet = false;
|
||||
audio_sample_rate = 0;
|
||||
m_audio_sample_rate_isSet = false;
|
||||
audio_mute = 0;
|
||||
m_audio_mute_isSet = false;
|
||||
bandpass_enable = 0;
|
||||
|
@ -100,7 +96,6 @@ SWGAMDemodSettings::cleanup() {
|
|||
|
||||
|
||||
|
||||
|
||||
if(udp_address != nullptr) {
|
||||
delete udp_address;
|
||||
}
|
||||
|
@ -130,8 +125,6 @@ SWGAMDemodSettings::fromJsonObject(QJsonObject &pJson) {
|
|||
|
||||
::SWGSDRangel::setValue(&volume, pJson["volume"], "float", "");
|
||||
|
||||
::SWGSDRangel::setValue(&audio_sample_rate, pJson["audioSampleRate"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&audio_mute, pJson["audioMute"], "qint32", "");
|
||||
|
||||
::SWGSDRangel::setValue(&bandpass_enable, pJson["bandpassEnable"], "qint32", "");
|
||||
|
@ -176,9 +169,6 @@ SWGAMDemodSettings::asJsonObject() {
|
|||
if(m_volume_isSet){
|
||||
obj->insert("volume", QJsonValue(volume));
|
||||
}
|
||||
if(m_audio_sample_rate_isSet){
|
||||
obj->insert("audioSampleRate", QJsonValue(audio_sample_rate));
|
||||
}
|
||||
if(m_audio_mute_isSet){
|
||||
obj->insert("audioMute", QJsonValue(audio_mute));
|
||||
}
|
||||
|
@ -247,16 +237,6 @@ SWGAMDemodSettings::setVolume(float volume) {
|
|||
this->m_volume_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGAMDemodSettings::getAudioSampleRate() {
|
||||
return audio_sample_rate;
|
||||
}
|
||||
void
|
||||
SWGAMDemodSettings::setAudioSampleRate(qint32 audio_sample_rate) {
|
||||
this->audio_sample_rate = audio_sample_rate;
|
||||
this->m_audio_sample_rate_isSet = true;
|
||||
}
|
||||
|
||||
qint32
|
||||
SWGAMDemodSettings::getAudioMute() {
|
||||
return audio_mute;
|
||||
|
@ -346,7 +326,6 @@ SWGAMDemodSettings::isSet(){
|
|||
if(m_rf_bandwidth_isSet){ isObjectUpdated = true; break;}
|
||||
if(m_squelch_isSet){ isObjectUpdated = true; break;}
|
||||
if(m_volume_isSet){ isObjectUpdated = true; break;}
|
||||
if(m_audio_sample_rate_isSet){ isObjectUpdated = true; break;}
|
||||
if(m_audio_mute_isSet){ isObjectUpdated = true; break;}
|
||||
if(m_bandpass_enable_isSet){ isObjectUpdated = true; break;}
|
||||
if(m_copy_audio_to_udp_isSet){ isObjectUpdated = true; break;}
|
||||
|
|
|
@ -54,9 +54,6 @@ public:
|
|||
float getVolume();
|
||||
void setVolume(float volume);
|
||||
|
||||
qint32 getAudioSampleRate();
|
||||
void setAudioSampleRate(qint32 audio_sample_rate);
|
||||
|
||||
qint32 getAudioMute();
|
||||
void setAudioMute(qint32 audio_mute);
|
||||
|
||||
|
@ -97,9 +94,6 @@ private:
|
|||
float volume;
|
||||
bool m_volume_isSet;
|
||||
|
||||
qint32 audio_sample_rate;
|
||||
bool m_audio_sample_rate_isSet;
|
||||
|
||||
qint32 audio_mute;
|
||||
bool m_audio_mute_isSet;
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue