1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2025-07-14 23:05:20 -04:00

Multiple audio support: New audio preferences dialog (3). Application to AM demod

This commit is contained in:
f4exb 2018-03-26 11:55:45 +02:00
parent 677c598347
commit 095ab14a14
21 changed files with 742 additions and 112 deletions

View File

@ -64,6 +64,7 @@ AMDemod::AMDemod(DeviceSourceAPI *deviceAPI) :
m_magsq = 0.0; m_magsq = 0.0;
DSPEngine::instance()->getAudioDeviceManager()->addAudioSink(&m_audioFifo, getInputMessageQueue()); DSPEngine::instance()->getAudioDeviceManager()->addAudioSink(&m_audioFifo, getInputMessageQueue());
m_audioSampleRate = DSPEngine::instance()->getAudioDeviceManager()->getOutputSampleRate();
m_audioNetSink = new AudioNetSink(0); // parent thread allocated dynamically m_audioNetSink = new AudioNetSink(0); // parent thread allocated dynamically
m_audioNetSink->setDestination(m_settings.m_udpAddress, m_settings.m_udpPort); m_audioNetSink->setDestination(m_settings.m_udpAddress, m_settings.m_udpPort);
@ -205,12 +206,45 @@ bool AMDemod::handleMessage(const Message& cmd)
{ {
return true; 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 else
{ {
return false; 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) void AMDemod::applyChannelSettings(int inputSampleRate, int inputFrequencyOffset, bool force)
{ {
qDebug() << "AMDemod::applyChannelSettings:" qDebug() << "AMDemod::applyChannelSettings:"
@ -228,7 +262,7 @@ void AMDemod::applyChannelSettings(int inputSampleRate, int inputFrequencyOffset
m_settingsMutex.lock(); m_settingsMutex.lock();
m_interpolator.create(16, inputSampleRate, m_settings.m_rfBandwidth / 2.2f); m_interpolator.create(16, inputSampleRate, m_settings.m_rfBandwidth / 2.2f);
m_interpolatorDistanceRemain = 0; m_interpolatorDistanceRemain = 0;
m_interpolatorDistance = (Real) inputSampleRate / (Real) m_settings.m_audioSampleRate; m_interpolatorDistance = (Real) inputSampleRate / (Real) m_audioSampleRate;
m_settingsMutex.unlock(); m_settingsMutex.unlock();
} }
@ -252,14 +286,13 @@ void AMDemod::applySettings(const AMDemodSettings& settings, bool force)
<< " force: " << force; << " force: " << force;
if((m_settings.m_rfBandwidth != settings.m_rfBandwidth) || if((m_settings.m_rfBandwidth != settings.m_rfBandwidth) ||
(m_settings.m_audioSampleRate != settings.m_audioSampleRate) ||
(m_settings.m_bandpassEnable != settings.m_bandpassEnable) || force) (m_settings.m_bandpassEnable != settings.m_bandpassEnable) || force)
{ {
m_settingsMutex.lock(); m_settingsMutex.lock();
m_interpolator.create(16, m_inputSampleRate, settings.m_rfBandwidth / 2.2f); m_interpolator.create(16, m_inputSampleRate, settings.m_rfBandwidth / 2.2f);
m_interpolatorDistanceRemain = 0; m_interpolatorDistanceRemain = 0;
m_interpolatorDistance = (Real) m_inputSampleRate / (Real) settings.m_audioSampleRate; m_interpolatorDistance = (Real) m_inputSampleRate / (Real) m_audioSampleRate;
m_bandpass.create(301, settings.m_audioSampleRate, 300.0, settings.m_rfBandwidth / 2.0f); m_bandpass.create(301, m_audioSampleRate, 300.0, settings.m_rfBandwidth / 2.0f);
m_settingsMutex.unlock(); m_settingsMutex.unlock();
} }
@ -341,9 +374,6 @@ int AMDemod::webapiSettingsPutPatch(
if (channelSettingsKeys.contains("audioMute")) { if (channelSettingsKeys.contains("audioMute")) {
settings.m_audioMute = response.getAmDemodSettings()->getAudioMute() != 0; settings.m_audioMute = response.getAmDemodSettings()->getAudioMute() != 0;
} }
if (channelSettingsKeys.contains("audioSampleRate")) {
settings.m_audioSampleRate = response.getAmDemodSettings()->getAudioSampleRate();
}
if (channelSettingsKeys.contains("copyAudioToUDP")) { if (channelSettingsKeys.contains("copyAudioToUDP")) {
settings.m_copyAudioToUDP = response.getAmDemodSettings()->getCopyAudioToUdp() != 0; settings.m_copyAudioToUDP = response.getAmDemodSettings()->getCopyAudioToUdp() != 0;
} }
@ -383,7 +413,7 @@ int AMDemod::webapiSettingsPutPatch(
if (frequencyOffsetChanged) if (frequencyOffsetChanged)
{ {
MsgConfigureChannelizer* channelConfigMsg = MsgConfigureChannelizer::create( MsgConfigureChannelizer* channelConfigMsg = MsgConfigureChannelizer::create(
48000, settings.m_inputFrequencyOffset); m_audioSampleRate, settings.m_inputFrequencyOffset);
m_inputMessageQueue.push(channelConfigMsg); m_inputMessageQueue.push(channelConfigMsg);
} }
@ -415,7 +445,6 @@ int AMDemod::webapiReportGet(
void AMDemod::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& response, const AMDemodSettings& settings) void AMDemod::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& response, const AMDemodSettings& settings)
{ {
response.getAmDemodSettings()->setAudioMute(settings.m_audioMute ? 1 : 0); response.getAmDemodSettings()->setAudioMute(settings.m_audioMute ? 1 : 0);
response.getAmDemodSettings()->setAudioSampleRate(settings.m_audioSampleRate);
response.getAmDemodSettings()->setCopyAudioToUdp(settings.m_copyAudioToUDP ? 1 : 0); response.getAmDemodSettings()->setCopyAudioToUdp(settings.m_copyAudioToUDP ? 1 : 0);
response.getAmDemodSettings()->setCopyAudioUseRtp(settings.m_copyAudioUseRTP ? 1 : 0); response.getAmDemodSettings()->setCopyAudioUseRtp(settings.m_copyAudioUseRTP ? 1 : 0);
response.getAmDemodSettings()->setInputFrequencyOffset(settings.m_inputFrequencyOffset); response.getAmDemodSettings()->setInputFrequencyOffset(settings.m_inputFrequencyOffset);
@ -447,5 +476,6 @@ void AMDemod::webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response)
response.getAmDemodReport()->setChannelPowerDb(CalcDb::dbPower(magsqAvg)); response.getAmDemodReport()->setChannelPowerDb(CalcDb::dbPower(magsqAvg));
response.getAmDemodReport()->setSquelch(m_squelchOpen ? 1 : 0); response.getAmDemodReport()->setSquelch(m_squelchOpen ? 1 : 0);
response.getAmDemodReport()->setAudioSampleRate(m_audioSampleRate);
} }

View File

@ -115,6 +115,7 @@ public:
SWGSDRangel::SWGChannelReport& response, SWGSDRangel::SWGChannelReport& response,
QString& errorMessage); QString& errorMessage);
uint32_t getAudioSampleRate() const { return m_audioSampleRate; }
double getMagSq() const { return m_magsq; } double getMagSq() const { return m_magsq; }
bool getSquelchOpen() const { return m_squelchOpen; } bool getSquelchOpen() const { return m_squelchOpen; }
@ -146,6 +147,7 @@ private:
int m_inputSampleRate; int m_inputSampleRate;
int m_inputFrequencyOffset; int m_inputFrequencyOffset;
AMDemodSettings m_settings; AMDemodSettings m_settings;
uint32_t m_audioSampleRate;
bool m_running; bool m_running;
NCO m_nco; NCO m_nco;
@ -176,6 +178,7 @@ private:
void applyChannelSettings(int inputSampleRate, int inputFrequencyOffset, bool force = false); void applyChannelSettings(int inputSampleRate, int inputFrequencyOffset, bool force = false);
void applySettings(const AMDemodSettings& settings, bool force = false); void applySettings(const AMDemodSettings& settings, bool force = false);
void applyAudioSampleRate(int sampleRate);
void webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& response, const AMDemodSettings& settings); void webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& response, const AMDemodSettings& settings);
void webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response); void webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response);
@ -197,7 +200,7 @@ private:
if (m_magsq >= m_squelchLevel) if (m_magsq >= m_squelchLevel)
{ {
if (m_squelchCount <= m_settings.m_audioSampleRate / 10) if (m_squelchCount <= m_audioSampleRate / 10)
{ {
m_squelchCount++; m_squelchCount++;
} }
@ -212,7 +215,7 @@ private:
qint16 sample; 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); Real demod = sqrt(magsq);
m_volumeAGC.feed(demod); m_volumeAGC.feed(demod);
@ -224,7 +227,7 @@ private:
demod /= 301.0f; 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; sample = demod * attack * 2048 * m_settings.m_volume;
if (m_settings.m_copyAudioToUDP) { if (m_settings.m_copyAudioToUDP) {
m_audioNetSink->write(demod * attack * 32768.0f); m_audioNetSink->write(demod * attack * 32768.0f);

View File

@ -281,7 +281,7 @@ void AMDemodGUI::applySettings(bool force)
if (m_doApplySettings) if (m_doApplySettings)
{ {
AMDemod::MsgConfigureChannelizer* channelConfigMsg = AMDemod::MsgConfigureChannelizer::create( AMDemod::MsgConfigureChannelizer* channelConfigMsg = AMDemod::MsgConfigureChannelizer::create(
48000, m_channelMarker.getCenterFrequency()); m_amDemod->getAudioSampleRate(), m_channelMarker.getCenterFrequency());
m_amDemod->getInputMessageQueue()->push(channelConfigMsg); m_amDemod->getInputMessageQueue()->push(channelConfigMsg);

View File

@ -33,7 +33,6 @@ void AMDemodSettings::resetToDefaults()
m_rfBandwidth = 5000; m_rfBandwidth = 5000;
m_squelch = -40.0; m_squelch = -40.0;
m_volume = 2.0; m_volume = 2.0;
m_audioSampleRate = DSPEngine::instance()->getDefaultAudioSampleRate();
m_audioMute = false; m_audioMute = false;
m_bandpassEnable = false; m_bandpassEnable = false;
m_copyAudioToUDP = false; m_copyAudioToUDP = false;

View File

@ -27,7 +27,6 @@ struct AMDemodSettings
Real m_rfBandwidth; Real m_rfBandwidth;
Real m_squelch; Real m_squelch;
Real m_volume; Real m_volume;
quint32 m_audioSampleRate;
bool m_audioMute; bool m_audioMute;
bool m_bandpassEnable; bool m_bandpassEnable;
bool m_copyAudioToUDP; bool m_copyAudioToUDP;

View File

@ -17,12 +17,16 @@
#include "audio/audiodevicemanager.h" #include "audio/audiodevicemanager.h"
#include "util/simpleserializer.h" #include "util/simpleserializer.h"
#include "util/messagequeue.h"
#include "dsp/dspcommands.h"
#include <QDataStream> #include <QDataStream>
#include <QSet>
#include <QDebug> #include <QDebug>
const float AudioDeviceManager::m_defaultAudioInputVolume = 0.15f; const float AudioDeviceManager::m_defaultAudioInputVolume = 0.15f;
const QString AudioDeviceManager::m_defaultUDPAddress = "127.0.0.1"; 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) QDataStream& operator<<(QDataStream& ds, const AudioDeviceManager::InputDeviceInfo& info)
{ {
@ -67,7 +71,7 @@ bool AudioDeviceManager::getOutputDeviceName(int outputDeviceIndex, QString &dev
{ {
if (outputDeviceIndex < 0) if (outputDeviceIndex < 0)
{ {
deviceName = "System default device"; deviceName = m_defaultDeviceName;
return true; return true;
} }
else else
@ -88,7 +92,7 @@ bool AudioDeviceManager::getInputDeviceName(int inputDeviceIndex, QString &devic
{ {
if (inputDeviceIndex < 0) if (inputDeviceIndex < 0)
{ {
deviceName = "System default device"; deviceName = m_defaultDeviceName;
return true; return true;
} }
else else
@ -212,7 +216,8 @@ void AudioDeviceManager::addAudioSink(AudioFifo* audioFifo, MessageQueue *sample
} }
m_audioSinkFifos[audioFifo] = outputDeviceIndex; // register audio FIFO 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) void AudioDeviceManager::removeAudioSink(AudioFifo* audioFifo)
@ -233,7 +238,8 @@ void AudioDeviceManager::removeAudioSink(AudioFifo* audioFifo)
} }
m_audioSinkFifos.remove(audioFifo); // unregister audio FIFO 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) 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_audioSourceFifos[audioFifo] = inputDeviceIndex; // register audio FIFO
m_sampleSourceMessageQueues[audioFifo] = sampleSourceMessageQueue; m_audioFifoToSourceMessageQueues[audioFifo] = sampleSourceMessageQueue;
m_outputDeviceSinkMessageQueues[inputDeviceIndex].append(sampleSourceMessageQueue);
} }
void AudioDeviceManager::removeAudioSource(AudioFifo* audioFifo) void AudioDeviceManager::removeAudioSource(AudioFifo* audioFifo)
@ -285,7 +292,8 @@ void AudioDeviceManager::removeAudioSource(AudioFifo* audioFifo)
} }
m_audioSourceFifos.remove(audioFifo); // unregister audio FIFO 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) void AudioDeviceManager::startAudioOutput(int outputDeviceIndex)
@ -373,6 +381,294 @@ void AudioDeviceManager::stopAudioInput(int inputDeviceIndex)
m_audioInputs[inputDeviceIndex]->stop(); 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 void AudioDeviceManager::debugAudioInputInfos() const
{ {
QMap<QString, InputDeviceInfo>::const_iterator it = m_audioInputInfos.begin(); QMap<QString, InputDeviceInfo>::const_iterator it = m_audioInputInfos.begin();

View File

@ -40,6 +40,10 @@ public:
sampleRate(m_defaultAudioSampleRate), sampleRate(m_defaultAudioSampleRate),
volume(m_defaultAudioInputVolume) volume(m_defaultAudioInputVolume)
{} {}
void resetToDefaults() {
sampleRate = m_defaultAudioSampleRate;
volume = m_defaultAudioInputVolume;
}
unsigned int sampleRate; unsigned int sampleRate;
float volume; float volume;
friend QDataStream& operator<<(QDataStream& ds, const InputDeviceInfo& info); friend QDataStream& operator<<(QDataStream& ds, const InputDeviceInfo& info);
@ -57,6 +61,14 @@ public:
udpStereo(false), udpStereo(false),
udpUseRTP(false) udpUseRTP(false)
{} {}
void resetToDefaults() {
sampleRate = m_defaultAudioSampleRate;
udpAddress = m_defaultUDPAddress;
udpPort = m_defaultUDPPort;
copyToUDP = false;
udpStereo = false;
udpUseRTP = false;
}
unsigned int sampleRate; unsigned int sampleRate;
QString udpAddress; QString udpAddress;
quint16 udpPort; quint16 udpPort;
@ -70,12 +82,11 @@ public:
AudioDeviceManager(); AudioDeviceManager();
~AudioDeviceManager(); ~AudioDeviceManager();
const QList<QAudioDeviceInfo>& getInputDevices() const { return m_inputDevicesInfo; } const QList<QAudioDeviceInfo>& getInputDevices() const { return m_inputDevicesInfo; }
const QList<QAudioDeviceInfo>& getOutputDevices() const { return m_outputDevicesInfo; } const QList<QAudioDeviceInfo>& getOutputDevices() const { return m_outputDevicesInfo; }
bool getOutputDeviceName(int outputDeviceIndex, QString &deviceName) const; 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 addAudioSink(AudioFifo* audioFifo, MessageQueue *sampleSinkMessageQueue, int outputDeviceIndex = -1); //!< Add the audio sink
void removeAudioSink(AudioFifo* audioFifo); //!< Remove 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 addAudioSource(AudioFifo* audioFifo, MessageQueue *sampleSourceMessageQueue, int inputDeviceIndex = -1); //!< Add an audio source
void removeAudioSource(AudioFifo* audioFifo); //!< Remove 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 unsigned int m_defaultAudioSampleRate = 48000;
static const float m_defaultAudioInputVolume; static const float m_defaultAudioInputVolume;
static const QString m_defaultUDPAddress; static const QString m_defaultUDPAddress;
static const quint16 m_defaultUDPPort = 9998; static const quint16 m_defaultUDPPort = 9998;
static const QString m_defaultDeviceName;
private: private:
QList<QAudioDeviceInfo> m_inputDevicesInfo; QList<QAudioDeviceInfo> m_inputDevicesInfo;
QList<QAudioDeviceInfo> m_outputDevicesInfo; 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<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<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<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<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<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 QMap<QString, InputDeviceInfo> m_audioInputInfos; //!< audio device name to audio input device info

View File

@ -46,3 +46,4 @@ MESSAGE_CLASS_DEFINITION(DSPEngineReport, Message)
MESSAGE_CLASS_DEFINITION(DSPConfigureScopeVis, Message) MESSAGE_CLASS_DEFINITION(DSPConfigureScopeVis, Message)
MESSAGE_CLASS_DEFINITION(DSPSignalNotification, Message) MESSAGE_CLASS_DEFINITION(DSPSignalNotification, Message)
MESSAGE_CLASS_DEFINITION(DSPConfigureChannelizer, Message) MESSAGE_CLASS_DEFINITION(DSPConfigureChannelizer, Message)
MESSAGE_CLASS_DEFINITION(DSPConfigureAudio, Message)

View File

@ -371,4 +371,17 @@ private:
int m_centerFrequency; 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 #endif // INCLUDE_DSPCOMMANDS_H

View File

@ -18,11 +18,11 @@
#ifndef INCLUDE_DSPENGINE_H #ifndef INCLUDE_DSPENGINE_H
#define INCLUDE_DSPENGINE_H #define INCLUDE_DSPENGINE_H
#include <audio/audiodevicemanager.h>
#include <QObject> #include <QObject>
#include <QTimer> #include <QTimer>
#include <vector> #include <vector>
#include "audio/audiodevicemanager.h"
#include "audio/audiooutput.h" #include "audio/audiooutput.h"
#include "audio/audioinput.h" #include "audio/audioinput.h"
#include "export.h" #include "export.h"

View File

@ -706,6 +706,9 @@ margin-bottom: 20px;
"squelch" : { "squelch" : {
"type" : "integer", "type" : "integer",
"description" : "squelch status (1 if open else 0)" "description" : "squelch status (1 if open else 0)"
},
"audioSampleRate" : {
"type" : "integer"
} }
}, },
"description" : "AMDemod" "description" : "AMDemod"
@ -731,9 +734,6 @@ margin-bottom: 20px;
"type" : "number", "type" : "number",
"format" : "float" "format" : "float"
}, },
"audioSampleRate" : {
"type" : "integer"
},
"audioMute" : { "audioMute" : {
"type" : "integer" "type" : "integer"
}, },
@ -18063,7 +18063,7 @@ except ApiException as e:
</div> </div>
<div id="generator"> <div id="generator">
<div class="content"> <div class="content">
Generated 2018-03-22T05:08:39.552+01:00 Generated 2018-03-26T10:23:40.336+02:00
</div> </div>
</div> </div>
</div> </div>

View File

@ -16,8 +16,6 @@ AMDemodSettings:
volume: volume:
type: number type: number
format: float format: float
audioSampleRate:
type: integer
audioMute: audioMute:
type: integer type: integer
bandpassEnable: bandpassEnable:
@ -46,3 +44,6 @@ AMDemodReport:
squelch: squelch:
description: squelch status (1 if open else 0) description: squelch status (1 if open else 0)
type: integer type: integer
audioSampleRate:
type: integer

View File

@ -11,66 +11,44 @@ AudioDialogX::AudioDialogX(AudioDeviceManager* audioDeviceManager, QWidget* pare
{ {
ui->setupUi(this); ui->setupUi(this);
QTreeWidgetItem* treeItem; QTreeWidgetItem* treeItem;
int i;
// out panel // out panel
QAudioDeviceInfo defaultOutputDeviceInfo = QAudioDeviceInfo::defaultOutputDevice(); QAudioDeviceInfo defaultOutputDeviceInfo = QAudioDeviceInfo::defaultOutputDevice();
treeItem = new QTreeWidgetItem(ui->audioOutTree); 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(); const QList<QAudioDeviceInfo>& outputDevices = m_audioDeviceManager->getOutputDevices();
i = 0;
for(QList<QAudioDeviceInfo>::const_iterator it = outputDevices.begin(); it != outputDevices.end(); ++it) for(QList<QAudioDeviceInfo>::const_iterator it = outputDevices.begin(); it != outputDevices.end(); ++it)
{ {
bool isDefaultDevice = it->deviceName() == defaultOutputDeviceInfo.deviceName(); bool isDefaultDevice = it->deviceName() == defaultOutputDeviceInfo.deviceName();
treeItem = new QTreeWidgetItem(ui->audioOutTree); treeItem = new QTreeWidgetItem(ui->audioOutTree);
treeItem->setText(0, it->deviceName() + (isDefaultDevice ? "(*)" : "")); treeItem->setText(0, it->deviceName() + (isDefaultDevice ? "(*)" : ""));
if (i == 0)
{
ui->audioOutTree->setCurrentItem(treeItem);
}
i++;
} }
// in panel // in panel
QAudioDeviceInfo defaultInputDeviceInfo = QAudioDeviceInfo::defaultInputDevice(); QAudioDeviceInfo defaultInputDeviceInfo = QAudioDeviceInfo::defaultInputDevice();
treeItem = new QTreeWidgetItem(ui->audioInTree); 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(); const QList<QAudioDeviceInfo>& inputDevices = m_audioDeviceManager->getInputDevices();
i = 0;
for(QList<QAudioDeviceInfo>::const_iterator it = inputDevices.begin(); it != inputDevices.end(); ++it) for(QList<QAudioDeviceInfo>::const_iterator it = inputDevices.begin(); it != inputDevices.end(); ++it)
{ {
bool isDefaultDevice = it->deviceName() == defaultInputDeviceInfo.deviceName(); bool isDefaultDevice = it->deviceName() == defaultInputDeviceInfo.deviceName();
treeItem = new QTreeWidgetItem(ui->audioInTree); treeItem = new QTreeWidgetItem(ui->audioInTree);
treeItem->setText(0, it->deviceName() + (isDefaultDevice ? "(*)" : "")); treeItem->setText(0, it->deviceName() + (isDefaultDevice ? "(*)" : ""));
if (i == 0)
{
ui->audioInTree->setCurrentItem(treeItem);
} }
i++; m_outputUDPPort = 9998;
} m_outIndex = -1;
m_inIndex = -1;
if(ui->audioOutTree->currentItem() == 0) {
ui->audioOutTree->setCurrentItem(ui->audioOutTree->topLevelItem(0));
}
if(ui->audioInTree->currentItem() == 0) {
ui->audioInTree->setCurrentItem(ui->audioInTree->topLevelItem(0));
}
ui->tabWidget->setCurrentIndex(0); 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() AudioDialogX::~AudioDialogX()
@ -80,11 +58,152 @@ AudioDialogX::~AudioDialogX()
void AudioDialogX::accept() void AudioDialogX::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(); 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) void AudioDialogX::on_inputVolume_valueChanged(int value)
{ {
m_inputVolume = (float) value / 100.0f; float volume = value / 100.0f;
ui->inputVolumeText->setText(QString("%1").arg(m_inputVolume, 0, 'f', 2)); 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();
}

View File

@ -4,8 +4,9 @@
#include <QDialog> #include <QDialog>
#include "export.h" #include "export.h"
#include "audio/audiodevicemanager.h"
class AudioDeviceManager; class QTreeWidgetItem;
namespace Ui { namespace Ui {
class AudioDialog; class AudioDialog;
@ -18,15 +19,33 @@ public:
explicit AudioDialogX(AudioDeviceManager* audioDeviceManager, QWidget* parent = 0); explicit AudioDialogX(AudioDeviceManager* audioDeviceManager, QWidget* parent = 0);
~AudioDialogX(); ~AudioDialogX();
int m_inIndex;
int m_outIndex;
private: private:
void updateInputDisplay();
void updateOutputDisplay();
void updateInputDeviceInfo();
void updateOutputDeviceInfo();
Ui::AudioDialog* ui; Ui::AudioDialog* ui;
AudioDeviceManager* m_audioDeviceManager; AudioDeviceManager* m_audioDeviceManager;
float m_inputVolume; AudioDeviceManager::InputDeviceInfo m_inputDeviceInfo;
AudioDeviceManager::OutputDeviceInfo m_outputDeviceInfo;
quint16 m_outputUDPPort;
private slots: private slots:
void accept(); 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_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 #endif // INCLUDE_AUDIODIALOG_H

View File

@ -7,7 +7,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>400</width> <width>400</width>
<height>300</height> <height>349</height>
</rect> </rect>
</property> </property>
<property name="font"> <property name="font">
@ -69,7 +69,7 @@
<number>192000</number> <number>192000</number>
</property> </property>
<property name="singleStep"> <property name="singleStep">
<number>50</number> <number>1000</number>
</property> </property>
<property name="value"> <property name="value">
<number>48000</number> <number>48000</number>
@ -89,6 +89,22 @@
</property> </property>
</spacer> </spacer>
</item> </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> <item>
<widget class="QPushButton" name="outputReset"> <widget class="QPushButton" name="outputReset">
<property name="maximumSize"> <property name="maximumSize">
@ -108,16 +124,16 @@
</layout> </layout>
</item> </item>
<item> <item>
<layout class="QHBoxLayout" name="udpLayout"> <layout class="QHBoxLayout" name="outputUDPLayout">
<item> <item>
<widget class="QLabel" name="udpAddressLabel"> <widget class="QLabel" name="outputUDPAddressLabel">
<property name="text"> <property name="text">
<string>Addr</string> <string>Addr</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QLineEdit" name="udpAddress"> <widget class="QLineEdit" name="outputUDPAddress">
<property name="maximumSize"> <property name="maximumSize">
<size> <size>
<width>140</width> <width>140</width>
@ -136,14 +152,14 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QLabel" name="udpPortLabel"> <widget class="QLabel" name="outputUDPPortLabel">
<property name="text"> <property name="text">
<string>Port</string> <string>Port</string>
</property> </property>
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QLineEdit" name="udpPort"> <widget class="QLineEdit" name="outputUDPPort">
<property name="maximumSize"> <property name="maximumSize">
<size> <size>
<width>60</width> <width>60</width>
@ -178,7 +194,7 @@
</spacer> </spacer>
</item> </item>
<item> <item>
<widget class="ButtonSwitch" name="udpCopy"> <widget class="ButtonSwitch" name="outputUDPCopy">
<property name="toolTip"> <property name="toolTip">
<string>Copy audio to UDP</string> <string>Copy audio to UDP</string>
</property> </property>
@ -188,7 +204,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QCheckBox" name="udpStereo"> <widget class="QCheckBox" name="outputUDPStereo">
<property name="toolTip"> <property name="toolTip">
<string>Copy to UDP as stereo (no L+R mix)</string> <string>Copy to UDP as stereo (no L+R mix)</string>
</property> </property>
@ -198,7 +214,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QCheckBox" name="udpUseRTP"> <widget class="QCheckBox" name="outputUDPUseRTP">
<property name="toolTip"> <property name="toolTip">
<string>Use RTP protocol</string> <string>Use RTP protocol</string>
</property> </property>
@ -209,6 +225,51 @@
</item> </item>
</layout> </layout>
</item> </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> </layout>
</widget> </widget>
<widget class="QWidget" name="tabInput"> <widget class="QWidget" name="tabInput">
@ -255,7 +316,7 @@
<number>192000</number> <number>192000</number>
</property> </property>
<property name="singleStep"> <property name="singleStep">
<number>50</number> <number>1000</number>
</property> </property>
<property name="value"> <property name="value">
<number>48000</number> <number>48000</number>
@ -326,6 +387,22 @@
</property> </property>
</spacer> </spacer>
</item> </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> <item>
<widget class="QPushButton" name="inputReset"> <widget class="QPushButton" name="inputReset">
<property name="maximumSize"> <property name="maximumSize">
@ -344,6 +421,51 @@
</item> </item>
</layout> </layout>
</item> </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> </layout>
</widget> </widget>
</widget> </widget>
@ -372,7 +494,9 @@
<tabstop>tabWidget</tabstop> <tabstop>tabWidget</tabstop>
<tabstop>audioOutTree</tabstop> <tabstop>audioOutTree</tabstop>
</tabstops> </tabstops>
<resources/> <resources>
<include location="../resources/res.qrc"/>
</resources>
<connections> <connections>
<connection> <connection>
<sender>buttonBox</sender> <sender>buttonBox</sender>

View File

@ -16,8 +16,6 @@ AMDemodSettings:
volume: volume:
type: number type: number
format: float format: float
audioSampleRate:
type: integer
audioMute: audioMute:
type: integer type: integer
bandpassEnable: bandpassEnable:
@ -46,3 +44,6 @@ AMDemodReport:
squelch: squelch:
description: squelch status (1 if open else 0) description: squelch status (1 if open else 0)
type: integer type: integer
audioSampleRate:
type: integer

View File

@ -706,6 +706,9 @@ margin-bottom: 20px;
"squelch" : { "squelch" : {
"type" : "integer", "type" : "integer",
"description" : "squelch status (1 if open else 0)" "description" : "squelch status (1 if open else 0)"
},
"audioSampleRate" : {
"type" : "integer"
} }
}, },
"description" : "AMDemod" "description" : "AMDemod"
@ -731,9 +734,6 @@ margin-bottom: 20px;
"type" : "number", "type" : "number",
"format" : "float" "format" : "float"
}, },
"audioSampleRate" : {
"type" : "integer"
},
"audioMute" : { "audioMute" : {
"type" : "integer" "type" : "integer"
}, },
@ -18063,7 +18063,7 @@ except ApiException as e:
</div> </div>
<div id="generator"> <div id="generator">
<div class="content"> <div class="content">
Generated 2018-03-22T05:08:39.552+01:00 Generated 2018-03-26T10:23:40.336+02:00
</div> </div>
</div> </div>
</div> </div>

View File

@ -32,6 +32,8 @@ SWGAMDemodReport::SWGAMDemodReport() {
m_channel_power_db_isSet = false; m_channel_power_db_isSet = false;
squelch = 0; squelch = 0;
m_squelch_isSet = false; m_squelch_isSet = false;
audio_sample_rate = 0;
m_audio_sample_rate_isSet = false;
} }
SWGAMDemodReport::~SWGAMDemodReport() { SWGAMDemodReport::~SWGAMDemodReport() {
@ -44,12 +46,15 @@ SWGAMDemodReport::init() {
m_channel_power_db_isSet = false; m_channel_power_db_isSet = false;
squelch = 0; squelch = 0;
m_squelch_isSet = false; m_squelch_isSet = false;
audio_sample_rate = 0;
m_audio_sample_rate_isSet = false;
} }
void void
SWGAMDemodReport::cleanup() { SWGAMDemodReport::cleanup() {
} }
SWGAMDemodReport* SWGAMDemodReport*
@ -67,6 +72,8 @@ SWGAMDemodReport::fromJsonObject(QJsonObject &pJson) {
::SWGSDRangel::setValue(&squelch, pJson["squelch"], "qint32", ""); ::SWGSDRangel::setValue(&squelch, pJson["squelch"], "qint32", "");
::SWGSDRangel::setValue(&audio_sample_rate, pJson["audioSampleRate"], "qint32", "");
} }
QString QString
@ -89,6 +96,9 @@ SWGAMDemodReport::asJsonObject() {
if(m_squelch_isSet){ if(m_squelch_isSet){
obj->insert("squelch", QJsonValue(squelch)); obj->insert("squelch", QJsonValue(squelch));
} }
if(m_audio_sample_rate_isSet){
obj->insert("audioSampleRate", QJsonValue(audio_sample_rate));
}
return obj; return obj;
} }
@ -113,6 +123,16 @@ SWGAMDemodReport::setSquelch(qint32 squelch) {
this->m_squelch_isSet = true; 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 bool
SWGAMDemodReport::isSet(){ SWGAMDemodReport::isSet(){
@ -120,6 +140,7 @@ SWGAMDemodReport::isSet(){
do{ do{
if(m_channel_power_db_isSet){ isObjectUpdated = true; break;} if(m_channel_power_db_isSet){ isObjectUpdated = true; break;}
if(m_squelch_isSet){ isObjectUpdated = true; break;} if(m_squelch_isSet){ isObjectUpdated = true; break;}
if(m_audio_sample_rate_isSet){ isObjectUpdated = true; break;}
}while(false); }while(false);
return isObjectUpdated; return isObjectUpdated;
} }

View File

@ -47,6 +47,9 @@ public:
qint32 getSquelch(); qint32 getSquelch();
void setSquelch(qint32 squelch); void setSquelch(qint32 squelch);
qint32 getAudioSampleRate();
void setAudioSampleRate(qint32 audio_sample_rate);
virtual bool isSet() override; virtual bool isSet() override;
@ -57,6 +60,9 @@ private:
qint32 squelch; qint32 squelch;
bool m_squelch_isSet; bool m_squelch_isSet;
qint32 audio_sample_rate;
bool m_audio_sample_rate_isSet;
}; };
} }

View File

@ -36,8 +36,6 @@ SWGAMDemodSettings::SWGAMDemodSettings() {
m_squelch_isSet = false; m_squelch_isSet = false;
volume = 0.0f; volume = 0.0f;
m_volume_isSet = false; m_volume_isSet = false;
audio_sample_rate = 0;
m_audio_sample_rate_isSet = false;
audio_mute = 0; audio_mute = 0;
m_audio_mute_isSet = false; m_audio_mute_isSet = false;
bandpass_enable = 0; bandpass_enable = 0;
@ -70,8 +68,6 @@ SWGAMDemodSettings::init() {
m_squelch_isSet = false; m_squelch_isSet = false;
volume = 0.0f; volume = 0.0f;
m_volume_isSet = false; m_volume_isSet = false;
audio_sample_rate = 0;
m_audio_sample_rate_isSet = false;
audio_mute = 0; audio_mute = 0;
m_audio_mute_isSet = false; m_audio_mute_isSet = false;
bandpass_enable = 0; bandpass_enable = 0;
@ -100,7 +96,6 @@ SWGAMDemodSettings::cleanup() {
if(udp_address != nullptr) { if(udp_address != nullptr) {
delete udp_address; delete udp_address;
} }
@ -130,8 +125,6 @@ SWGAMDemodSettings::fromJsonObject(QJsonObject &pJson) {
::SWGSDRangel::setValue(&volume, pJson["volume"], "float", ""); ::SWGSDRangel::setValue(&volume, pJson["volume"], "float", "");
::SWGSDRangel::setValue(&audio_sample_rate, pJson["audioSampleRate"], "qint32", "");
::SWGSDRangel::setValue(&audio_mute, pJson["audioMute"], "qint32", ""); ::SWGSDRangel::setValue(&audio_mute, pJson["audioMute"], "qint32", "");
::SWGSDRangel::setValue(&bandpass_enable, pJson["bandpassEnable"], "qint32", ""); ::SWGSDRangel::setValue(&bandpass_enable, pJson["bandpassEnable"], "qint32", "");
@ -176,9 +169,6 @@ SWGAMDemodSettings::asJsonObject() {
if(m_volume_isSet){ if(m_volume_isSet){
obj->insert("volume", QJsonValue(volume)); obj->insert("volume", QJsonValue(volume));
} }
if(m_audio_sample_rate_isSet){
obj->insert("audioSampleRate", QJsonValue(audio_sample_rate));
}
if(m_audio_mute_isSet){ if(m_audio_mute_isSet){
obj->insert("audioMute", QJsonValue(audio_mute)); obj->insert("audioMute", QJsonValue(audio_mute));
} }
@ -247,16 +237,6 @@ SWGAMDemodSettings::setVolume(float volume) {
this->m_volume_isSet = true; 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 qint32
SWGAMDemodSettings::getAudioMute() { SWGAMDemodSettings::getAudioMute() {
return audio_mute; return audio_mute;
@ -346,7 +326,6 @@ SWGAMDemodSettings::isSet(){
if(m_rf_bandwidth_isSet){ isObjectUpdated = true; break;} if(m_rf_bandwidth_isSet){ isObjectUpdated = true; break;}
if(m_squelch_isSet){ isObjectUpdated = true; break;} if(m_squelch_isSet){ isObjectUpdated = true; break;}
if(m_volume_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_audio_mute_isSet){ isObjectUpdated = true; break;}
if(m_bandpass_enable_isSet){ isObjectUpdated = true; break;} if(m_bandpass_enable_isSet){ isObjectUpdated = true; break;}
if(m_copy_audio_to_udp_isSet){ isObjectUpdated = true; break;} if(m_copy_audio_to_udp_isSet){ isObjectUpdated = true; break;}

View File

@ -54,9 +54,6 @@ public:
float getVolume(); float getVolume();
void setVolume(float volume); void setVolume(float volume);
qint32 getAudioSampleRate();
void setAudioSampleRate(qint32 audio_sample_rate);
qint32 getAudioMute(); qint32 getAudioMute();
void setAudioMute(qint32 audio_mute); void setAudioMute(qint32 audio_mute);
@ -97,9 +94,6 @@ private:
float volume; float volume;
bool m_volume_isSet; bool m_volume_isSet;
qint32 audio_sample_rate;
bool m_audio_sample_rate_isSet;
qint32 audio_mute; qint32 audio_mute;
bool m_audio_mute_isSet; bool m_audio_mute_isSet;