From cc4604f6d8fd6fdf5eb3dd8cd1dbeab8d84d3d28 Mon Sep 17 00:00:00 2001 From: f4exb Date: Sun, 24 Feb 2019 20:59:09 +0100 Subject: [PATCH] FreeDV modulator: implemented audio input with possible resampling --- plugins/channeltx/modfreedv/freedvmod.cpp | 95 ++++++++++++++++--- plugins/channeltx/modfreedv/freedvmod.h | 3 + plugins/channeltx/modfreedv/freedvmodgui.cpp | 7 ++ plugins/channeltx/modfreedv/freedvmodgui.h | 1 + plugins/channeltx/modfreedv/freedvmodgui.ui | 10 ++ .../channeltx/modfreedv/freedvmodsettings.cpp | 3 + .../channeltx/modfreedv/freedvmodsettings.h | 1 + plugins/channeltx/modssb/ssbmod.cpp | 14 +-- sdrbase/CMakeLists.txt | 2 + sdrbase/audio/audioresampler.cpp | 94 ++++++++++++++++++ sdrbase/audio/audioresampler.h | 41 ++++++++ sdrbase/resources/webapi/doc/html2/index.html | 5 +- .../webapi/doc/swagger/include/FreeDVMod.yaml | 2 + sdrbase/sdrbase.pro | 2 + .../api/swagger/include/FreeDVMod.yaml | 2 + swagger/sdrangel/code/html2/index.html | 5 +- .../code/qt5/client/SWGFreeDVModSettings.cpp | 21 ++++ .../code/qt5/client/SWGFreeDVModSettings.h | 6 ++ 18 files changed, 290 insertions(+), 24 deletions(-) create mode 100644 sdrbase/audio/audioresampler.cpp create mode 100644 sdrbase/audio/audioresampler.h diff --git a/plugins/channeltx/modfreedv/freedvmod.cpp b/plugins/channeltx/modfreedv/freedvmod.cpp index 43ae7f473..441109384 100644 --- a/plugins/channeltx/modfreedv/freedvmod.cpp +++ b/plugins/channeltx/modfreedv/freedvmod.cpp @@ -182,7 +182,7 @@ void FreeDVMod::pull(Sample& sample) void FreeDVMod::pullAudio(int nbSamples) { - unsigned int nbSamplesAudio = nbSamples * ((Real) m_audioSampleRate / (Real) m_basebandSampleRate); + unsigned int nbSamplesAudio = nbSamples * ((Real) m_audioSampleRate / (Real) m_modemSampleRate); if (nbSamplesAudio > m_audioBuffer.size()) { @@ -196,7 +196,9 @@ void FreeDVMod::pullAudio(int nbSamples) void FreeDVMod::modulateSample() { pullAF(m_modSample); - calculateLevel(m_modSample); + if (!m_settings.m_gaugeInputElseModem) { + calculateLevel(m_modSample); + } m_audioBufferFill++; } @@ -221,8 +223,12 @@ void FreeDVMod::pullAF(Complex& sample) switch (m_settings.m_modAFInput) { case FreeDVModSettings::FreeDVModInputTone: - for (int i = 0; i < m_nSpeechSamples; i++) { + for (int i = 0; i < m_nSpeechSamples; i++) + { m_speechIn[i] = m_toneNco.next() * 32768.0f * m_settings.m_volumeFactor; + if (m_settings.m_gaugeInputElseModem) { + calculateLevel(m_speechIn[i]); + } } freedv_tx(m_freeDV, m_modOut, m_speechIn); break; @@ -251,10 +257,16 @@ void FreeDVMod::pullAF(Complex& sample) m_ifstream.read(reinterpret_cast(m_speechIn), sizeof(int16_t) * m_nSpeechSamples); - if (m_settings.m_volumeFactor != 1.0) + if ((m_settings.m_volumeFactor != 1.0) || m_settings.m_gaugeInputElseModem) { - for (int i = 0; i < m_nSpeechSamples; i++) { - m_speechIn[i] *= m_settings.m_volumeFactor; + for (int i = 0; i < m_nSpeechSamples; i++) + { + if (m_settings.m_volumeFactor != 1.0) { + m_speechIn[i] *= m_settings.m_volumeFactor; + } + if (m_settings.m_gaugeInputElseModem) { + calculateLevel(m_speechIn[i]); + } } } @@ -268,8 +280,20 @@ void FreeDVMod::pullAF(Complex& sample) } break; case FreeDVModSettings::FreeDVModInputAudio: - for (int i = 0; i < m_nSpeechSamples; i++) { - m_speechIn[i] = (m_audioBuffer[m_audioBufferFill].l + m_audioBuffer[m_audioBufferFill].r) * (m_settings.m_volumeFactor / 2); + for (int i = 0; i < m_nSpeechSamples; i++) + { + qint16 audioSample = (m_audioBuffer[m_audioBufferFill].l + m_audioBuffer[m_audioBufferFill].r) * (m_settings.m_volumeFactor / 2.0f); + m_audioBufferFill++; + + while (!m_audioResampler.downSample(audioSample, m_speechIn[i])) + { + audioSample = (m_audioBuffer[m_audioBufferFill].l + m_audioBuffer[m_audioBufferFill].r) * (m_settings.m_volumeFactor / 2.0f); + m_audioBufferFill++; + } + + if (m_settings.m_gaugeInputElseModem) { + calculateLevel(m_speechIn[i]); + } } freedv_tx(m_freeDV, m_modOut, m_speechIn); break; @@ -295,6 +319,10 @@ void FreeDVMod::pullAF(Complex& sample) m_toneNco.setPhase(0); } } + + if (m_settings.m_gaugeInputElseModem) { + calculateLevel(m_speechIn[i]); + } } freedv_tx(m_freeDV, m_modOut, m_speechIn); break; @@ -367,6 +395,27 @@ void FreeDVMod::calculateLevel(Complex& sample) } } +void FreeDVMod::calculateLevel(qint16& sample) +{ + Real t = sample / SDR_TX_SCALEF; + + if (m_levelCalcCount < m_levelNbSamples) + { + m_peakLevel = std::max(std::fabs(m_peakLevel), t); + m_levelSum += t * t; + m_levelCalcCount++; + } + else + { + qreal rmsLevel = sqrt(m_levelSum / m_levelNbSamples); + //qDebug("FreeDVMod::calculateLevel: %f %f", rmsLevel, m_peakLevel); + emit levelChanged(rmsLevel, m_peakLevel, m_levelNbSamples); + m_peakLevel = 0.0f; + m_levelSum = 0.0f; + m_levelCalcCount = 0; + } +} + void FreeDVMod::start() { qDebug() << "FreeDVMod::start: m_outputSampleRate: " << m_outputSampleRate @@ -522,6 +571,12 @@ void FreeDVMod::applyAudioSampleRate(int sampleRate) { qDebug("FreeDVMod::applyAudioSampleRate: %d", sampleRate); // TODO: put up simple IIR interpolator when sampleRate < m_modemSampleRate + + m_settingsMutex.lock(); + m_audioResampler.setDecimation(sampleRate / m_inputSampleRate); + m_audioResampler.setAudioFilters(sampleRate, m_inputSampleRate, 250, 3300); + m_settingsMutex.unlock(); + m_audioSampleRate = sampleRate; } @@ -686,6 +741,9 @@ void FreeDVMod::applySettings(const FreeDVModSettings& settings, bool force) if ((settings.m_playLoop != m_settings.m_playLoop) || force) { reverseAPIKeys.append("playLoop"); } + if ((settings.m_playLoop != m_settings.m_gaugeInputElseModem) || force) { + reverseAPIKeys.append("gaugeInputElseModem"); + } if ((settings.m_rgbColor != m_settings.m_rgbColor) || force) { reverseAPIKeys.append("rgbColor"); } @@ -801,6 +859,9 @@ int FreeDVMod::webapiSettingsPutPatch( if (channelSettingsKeys.contains("playLoop")) { settings.m_playLoop = response.getFreeDvModSettings()->getPlayLoop() != 0; } + if (channelSettingsKeys.contains("gaugeInputElseModem")) { + settings.m_gaugeInputElseModem = response.getFreeDvModSettings()->getGaugeInputElseModem() != 0; + } if (channelSettingsKeys.contains("rgbColor")) { settings.m_rgbColor = response.getFreeDvModSettings()->getRgbColor(); } @@ -907,6 +968,7 @@ void FreeDVMod::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& res response.getFreeDvModSettings()->setAudioMute(settings.m_audioMute ? 1 : 0); response.getFreeDvModSettings()->setPlayLoop(settings.m_playLoop ? 1 : 0); response.getFreeDvModSettings()->setRgbColor(settings.m_rgbColor); + response.getFreeDvModSettings()->setGaugeInputElseModem(settings.m_gaugeInputElseModem ? 1 : 0); if (response.getFreeDvModSettings()->getTitle()) { *response.getFreeDvModSettings()->getTitle() = settings.m_title; @@ -940,17 +1002,17 @@ void FreeDVMod::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& res apiCwKeyerSettings->setWpm(cwKeyerSettings.m_wpm); - response.getAmModSettings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0); + response.getFreeDvModSettings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0); - if (response.getAmModSettings()->getReverseApiAddress()) { - *response.getAmModSettings()->getReverseApiAddress() = settings.m_reverseAPIAddress; + if (response.getFreeDvModSettings()->getReverseApiAddress()) { + *response.getFreeDvModSettings()->getReverseApiAddress() = settings.m_reverseAPIAddress; } else { - response.getAmModSettings()->setReverseApiAddress(new QString(settings.m_reverseAPIAddress)); + response.getFreeDvModSettings()->setReverseApiAddress(new QString(settings.m_reverseAPIAddress)); } - response.getAmModSettings()->setReverseApiPort(settings.m_reverseAPIPort); - response.getAmModSettings()->setReverseApiDeviceIndex(settings.m_reverseAPIDeviceIndex); - response.getAmModSettings()->setReverseApiChannelIndex(settings.m_reverseAPIChannelIndex); + response.getFreeDvModSettings()->setReverseApiPort(settings.m_reverseAPIPort); + response.getFreeDvModSettings()->setReverseApiDeviceIndex(settings.m_reverseAPIDeviceIndex); + response.getFreeDvModSettings()->setReverseApiChannelIndex(settings.m_reverseAPIChannelIndex); } void FreeDVMod::webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response) @@ -988,6 +1050,9 @@ void FreeDVMod::webapiReverseSendSettings(QList& channelSettingsKeys, c if (channelSettingsKeys.contains("playLoop") || force) { swgFreeDVModSettings->setPlayLoop(settings.m_playLoop ? 1 : 0); } + if (channelSettingsKeys.contains("gaugeInputElseModem") || force) { + swgFreeDVModSettings->setPlayLoop(settings.m_gaugeInputElseModem ? 1 : 0); + } if (channelSettingsKeys.contains("rgbColor") || force) { swgFreeDVModSettings->setRgbColor(settings.m_rgbColor); } diff --git a/plugins/channeltx/modfreedv/freedvmod.h b/plugins/channeltx/modfreedv/freedvmod.h index 2e3272fed..ec2e6934c 100644 --- a/plugins/channeltx/modfreedv/freedvmod.h +++ b/plugins/channeltx/modfreedv/freedvmod.h @@ -34,6 +34,7 @@ #include "dsp/fftfilt.h" #include "dsp/cwkeyer.h" #include "audio/audiofifo.h" +#include "audio/audioresampler.h" #include "util/message.h" #include "freedvmodsettings.h" @@ -325,6 +326,7 @@ private: int16_t *m_speechIn; int16_t *m_modOut; float m_scaleFactor; //!< divide by this amount to scale from int16 to float in [-1.0, 1.0] interval + AudioResampler m_audioResampler; static const int m_levelNbSamples; @@ -334,6 +336,7 @@ private: void applyFreeDVMode(FreeDVModSettings::FreeDVMode mode); void pullAF(Complex& sample); void calculateLevel(Complex& sample); + void calculateLevel(qint16& sample); void modulateSample(); void openFileStream(); void seekFileStream(int seekPercentage); diff --git a/plugins/channeltx/modfreedv/freedvmodgui.cpp b/plugins/channeltx/modfreedv/freedvmodgui.cpp index 67ba97326..d46b78140 100644 --- a/plugins/channeltx/modfreedv/freedvmodgui.cpp +++ b/plugins/channeltx/modfreedv/freedvmodgui.cpp @@ -182,6 +182,12 @@ void FreeDVModGUI::on_spanLog2_valueChanged(int value) applyBandwidths(5 - value); } +void FreeDVModGUI::on_gaugeInput_toggled(bool checked) +{ + m_settings.m_gaugeInputElseModem = checked; + applySettings(); +} + void FreeDVModGUI::on_toneFrequency_valueChanged(int value) { ui->toneFrequencyText->setText(QString("%1k").arg(value / 100.0, 0, 'f', 2)); @@ -463,6 +469,7 @@ void FreeDVModGUI::displaySettings() ui->spanLog2->blockSignals(true); ui->spanLog2->setValue(5 - m_settings.m_spanLog2); + ui->gaugeInput->setChecked(m_settings.m_gaugeInputElseModem); QString s = QString::number(m_freeDVMod->getHiCutoff()/1000.0, 'f', 1); diff --git a/plugins/channeltx/modfreedv/freedvmodgui.h b/plugins/channeltx/modfreedv/freedvmodgui.h index 2cac1f6c5..ce228a71a 100644 --- a/plugins/channeltx/modfreedv/freedvmodgui.h +++ b/plugins/channeltx/modfreedv/freedvmodgui.h @@ -97,6 +97,7 @@ private slots: void handleSourceMessages(); void on_deltaFrequency_changed(qint64 value); void on_spanLog2_valueChanged(int value); + void on_gaugeInput_toggled(bool checked); void on_volume_valueChanged(int value); void on_audioMute_toggled(bool checked); void on_freeDVMode_currentIndexChanged(int index); diff --git a/plugins/channeltx/modfreedv/freedvmodgui.ui b/plugins/channeltx/modfreedv/freedvmodgui.ui index d81098ac3..3e5cb1830 100644 --- a/plugins/channeltx/modfreedv/freedvmodgui.ui +++ b/plugins/channeltx/modfreedv/freedvmodgui.ui @@ -167,6 +167,16 @@ + + + + Check to see input level else shows modem level + + + In + + + diff --git a/plugins/channeltx/modfreedv/freedvmodsettings.cpp b/plugins/channeltx/modfreedv/freedvmodsettings.cpp index 374a9c585..295d3d11d 100644 --- a/plugins/channeltx/modfreedv/freedvmodsettings.cpp +++ b/plugins/channeltx/modfreedv/freedvmodsettings.cpp @@ -42,6 +42,7 @@ void FreeDVModSettings::resetToDefaults() m_modAFInput = FreeDVModInputAF::FreeDVModInputNone; m_audioDeviceName = AudioDeviceManager::m_defaultDeviceName; m_freeDVMode = FreeDVMode::FreeDVMode2400A; + m_gaugeInputElseModem = false; m_useReverseAPI = false; m_reverseAPIAddress = "127.0.0.1"; m_reverseAPIPort = 8888; @@ -66,6 +67,7 @@ QByteArray FreeDVModSettings::serialize() const s.writeBlob(6, m_cwKeyerGUI->serialize()); } + s.writeBool(7, m_gaugeInputElseModem); s.writeS32(8, m_spanLog2); s.writeS32(10, (int) m_freeDVMode); @@ -120,6 +122,7 @@ bool FreeDVModSettings::deserialize(const QByteArray& data) m_cwKeyerGUI->deserialize(bytetmp); } + d.readBool(7, &m_gaugeInputElseModem, false); d.readS32(8, &m_spanLog2, 3); d.readS32(10, &tmp, 0); diff --git a/plugins/channeltx/modfreedv/freedvmodsettings.h b/plugins/channeltx/modfreedv/freedvmodsettings.h index 16d33b5a1..7d0b340b1 100644 --- a/plugins/channeltx/modfreedv/freedvmodsettings.h +++ b/plugins/channeltx/modfreedv/freedvmodsettings.h @@ -54,6 +54,7 @@ struct FreeDVModSettings FreeDVModInputAF m_modAFInput; QString m_audioDeviceName; FreeDVMode m_freeDVMode; + bool m_gaugeInputElseModem; //!< Volume gauge shows speech input level else modem level bool m_useReverseAPI; QString m_reverseAPIAddress; diff --git a/plugins/channeltx/modssb/ssbmod.cpp b/plugins/channeltx/modssb/ssbmod.cpp index 3a962bae6..d2ba1324b 100644 --- a/plugins/channeltx/modssb/ssbmod.cpp +++ b/plugins/channeltx/modssb/ssbmod.cpp @@ -1199,17 +1199,17 @@ void SSBMod::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& respon apiCwKeyerSettings->setWpm(cwKeyerSettings.m_wpm); - response.getAmModSettings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0); + response.getSsbModSettings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0); - if (response.getAmModSettings()->getReverseApiAddress()) { - *response.getAmModSettings()->getReverseApiAddress() = settings.m_reverseAPIAddress; + if (response.getSsbModSettings()->getReverseApiAddress()) { + *response.getSsbModSettings()->getReverseApiAddress() = settings.m_reverseAPIAddress; } else { - response.getAmModSettings()->setReverseApiAddress(new QString(settings.m_reverseAPIAddress)); + response.getSsbModSettings()->setReverseApiAddress(new QString(settings.m_reverseAPIAddress)); } - response.getAmModSettings()->setReverseApiPort(settings.m_reverseAPIPort); - response.getAmModSettings()->setReverseApiDeviceIndex(settings.m_reverseAPIDeviceIndex); - response.getAmModSettings()->setReverseApiChannelIndex(settings.m_reverseAPIChannelIndex); + response.getSsbModSettings()->setReverseApiPort(settings.m_reverseAPIPort); + response.getSsbModSettings()->setReverseApiDeviceIndex(settings.m_reverseAPIDeviceIndex); + response.getSsbModSettings()->setReverseApiChannelIndex(settings.m_reverseAPIChannelIndex); } void SSBMod::webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response) diff --git a/sdrbase/CMakeLists.txt b/sdrbase/CMakeLists.txt index 8d4d2bbb4..f14f3f026 100644 --- a/sdrbase/CMakeLists.txt +++ b/sdrbase/CMakeLists.txt @@ -13,6 +13,7 @@ set(sdrbase_SOURCES audio/audiooutput.cpp audio/audioinput.cpp audio/audionetsink.cpp + audio/audioresampler.cpp channel/channelsinkapi.cpp channel/channelsourceapi.cpp @@ -108,6 +109,7 @@ set(sdrbase_HEADERS audio/audioopus.h audio/audioinput.h audio/audionetsink.h + audio/audioresampler.h channel/channelsinkapi.h channel/channelsourceapi.h diff --git a/sdrbase/audio/audioresampler.cpp b/sdrbase/audio/audioresampler.cpp new file mode 100644 index 000000000..269a0a603 --- /dev/null +++ b/sdrbase/audio/audioresampler.cpp @@ -0,0 +1,94 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2019 F4EXB // +// written by Edouard Griffiths // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation as version 3 of the License, or // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#include "audioresampler.h" + +AudioResampler::AudioResampler() : + m_decimation(1), + m_decimationCount(0) +{} + +AudioResampler::~AudioResampler() +{} + +void AudioResampler::setDecimation(uint32_t decimation) +{ + m_decimation = decimation == 0 ? 1 : decimation; +} + +void AudioResampler::setAudioFilters(int srHigh, int srLow, int fcLow, int fcHigh) +{ + srHigh = (srHigh <= 100 ? 100 : srHigh); + srLow = (srLow <= 0 ? 1 : srLow); + srLow = srLow > srHigh - 50 ? srHigh - 50 : srLow; + + fcLow = fcLow < 0 ? 0 : fcLow; + fcHigh = fcHigh < 100 ? 100 : fcHigh; + fcLow = fcLow > fcHigh - 100 ? fcHigh - 100 : fcLow; + + m_audioFilter.setDecimFilters(srHigh, srLow, fcHigh, fcLow); +} + +bool AudioResampler::downSample(qint16 sampleIn, qint16& sampleOut) +{ + if (m_decimation == 1) + { + sampleOut = sampleIn; + return true; + } + + if (m_decimationCount >= m_decimation - 1) + { + float lpSample = m_audioFilter.run(sampleIn / 32768.0f); + sampleOut = lpSample * 32768.0f; + m_decimationCount = 0; + return true; + } + else + { + m_decimationCount++; + return false; + } +} + +qint16 AudioResampler::upSample(qint16 sampleIn, bool& consumed) +{ + float lpSample; + + if (m_decimation == 1) + { + consumed = true; + return sampleIn; + } + + if (m_decimationCount >= m_decimation - 1) + { + consumed = true; + m_decimationCount = 0; + lpSample = m_audioFilter.run(sampleIn / 32768.0f); + } + else + { + consumed = false; + m_decimationCount++; + lpSample = m_audioFilter.run(0.0f); + } + + return lpSample * 32768.0f; +} + + diff --git a/sdrbase/audio/audioresampler.h b/sdrbase/audio/audioresampler.h new file mode 100644 index 000000000..89613a3f4 --- /dev/null +++ b/sdrbase/audio/audioresampler.h @@ -0,0 +1,41 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2019 F4EXB // +// written by Edouard Griffiths // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation as version 3 of the License, or // +// // +// This program is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY; without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#ifndef SDRBASE_AUDIO_AUDIORESAMPLER_H_ +#define SDRBASE_AUDIO_AUDIORESAMPLER_H_ + +#include "dsp/dsptypes.h" +#include "audiofilter.h" + +class AudioResampler +{ +public: + AudioResampler(); + ~AudioResampler(); + + void setDecimation(uint32_t decimation); + void setAudioFilters(int srHigh, int srLow, int fcLow, int fcHigh); + bool downSample(qint16 sampleIn, qint16& sampleOut); + qint16 upSample(qint16 sampleIn, bool& consumed); + +private: + AudioFilter m_audioFilter; + uint32_t m_decimation; + uint32_t m_decimationCount; +}; + +#endif /* SDRBASE_AUDIO_AUDIORESAMPLER_H_ */ diff --git a/sdrbase/resources/webapi/doc/html2/index.html b/sdrbase/resources/webapi/doc/html2/index.html index a131c3c3a..775a9f299 100644 --- a/sdrbase/resources/webapi/doc/html2/index.html +++ b/sdrbase/resources/webapi/doc/html2/index.html @@ -2608,6 +2608,9 @@ margin-bottom: 20px; "modAFInput" : { "type" : "integer" }, + "gaugeInputElseModem" : { + "type" : "integer" + }, "useReverseAPI" : { "type" : "integer", "description" : "Synchronize with reverse API (1 for yes, 0 for no)" @@ -24471,7 +24474,7 @@ except ApiException as e:
- Generated 2019-02-22T15:22:55.188+01:00 + Generated 2019-02-24T20:42:26.559+01:00
diff --git a/sdrbase/resources/webapi/doc/swagger/include/FreeDVMod.yaml b/sdrbase/resources/webapi/doc/swagger/include/FreeDVMod.yaml index dfdadd622..44511951c 100644 --- a/sdrbase/resources/webapi/doc/swagger/include/FreeDVMod.yaml +++ b/sdrbase/resources/webapi/doc/swagger/include/FreeDVMod.yaml @@ -32,6 +32,8 @@ FreeDVModSettings: type: integer modAFInput: type: integer + gaugeInputElseModem: + type: integer useReverseAPI: description: Synchronize with reverse API (1 for yes, 0 for no) type: integer diff --git a/sdrbase/sdrbase.pro b/sdrbase/sdrbase.pro index 7d49d1af2..491226a81 100644 --- a/sdrbase/sdrbase.pro +++ b/sdrbase/sdrbase.pro @@ -63,6 +63,7 @@ SOURCES += audio/audiodevicemanager.cpp\ audio/audiooutput.cpp\ audio/audioinput.cpp\ audio/audionetsink.cpp\ + audio/audioresampler.cpp\ channel/channelsinkapi.cpp\ channel/channelsourceapi.cpp\ channel/remotedataqueue.cpp\ @@ -144,6 +145,7 @@ HEADERS += audio/audiodevicemanager.h\ audio/audiooutput.h\ audio/audioinput.h\ audio/audionetsink.h\ + audio/audioresampler.h\ channel/channelsinkapi.h\ channel/channelsourceapi.h\ channel/remotedataqueue.h\ diff --git a/swagger/sdrangel/api/swagger/include/FreeDVMod.yaml b/swagger/sdrangel/api/swagger/include/FreeDVMod.yaml index 88d24a6db..ed34a992b 100644 --- a/swagger/sdrangel/api/swagger/include/FreeDVMod.yaml +++ b/swagger/sdrangel/api/swagger/include/FreeDVMod.yaml @@ -32,6 +32,8 @@ FreeDVModSettings: type: integer modAFInput: type: integer + gaugeInputElseModem: + type: integer useReverseAPI: description: Synchronize with reverse API (1 for yes, 0 for no) type: integer diff --git a/swagger/sdrangel/code/html2/index.html b/swagger/sdrangel/code/html2/index.html index a131c3c3a..775a9f299 100644 --- a/swagger/sdrangel/code/html2/index.html +++ b/swagger/sdrangel/code/html2/index.html @@ -2608,6 +2608,9 @@ margin-bottom: 20px; "modAFInput" : { "type" : "integer" }, + "gaugeInputElseModem" : { + "type" : "integer" + }, "useReverseAPI" : { "type" : "integer", "description" : "Synchronize with reverse API (1 for yes, 0 for no)" @@ -24471,7 +24474,7 @@ except ApiException as e:
- Generated 2019-02-22T15:22:55.188+01:00 + Generated 2019-02-24T20:42:26.559+01:00
diff --git a/swagger/sdrangel/code/qt5/client/SWGFreeDVModSettings.cpp b/swagger/sdrangel/code/qt5/client/SWGFreeDVModSettings.cpp index 729b02c6d..7afa07863 100644 --- a/swagger/sdrangel/code/qt5/client/SWGFreeDVModSettings.cpp +++ b/swagger/sdrangel/code/qt5/client/SWGFreeDVModSettings.cpp @@ -54,6 +54,8 @@ SWGFreeDVModSettings::SWGFreeDVModSettings() { m_free_dv_mode_isSet = false; mod_af_input = 0; m_mod_af_input_isSet = false; + gauge_input_else_modem = 0; + m_gauge_input_else_modem_isSet = false; use_reverse_api = 0; m_use_reverse_api_isSet = false; reverse_api_address = nullptr; @@ -100,6 +102,8 @@ SWGFreeDVModSettings::init() { m_free_dv_mode_isSet = false; mod_af_input = 0; m_mod_af_input_isSet = false; + gauge_input_else_modem = 0; + m_gauge_input_else_modem_isSet = false; use_reverse_api = 0; m_use_reverse_api_isSet = false; reverse_api_address = new QString(""); @@ -134,6 +138,7 @@ SWGFreeDVModSettings::cleanup() { + if(reverse_api_address != nullptr) { delete reverse_api_address; } @@ -182,6 +187,8 @@ SWGFreeDVModSettings::fromJsonObject(QJsonObject &pJson) { ::SWGSDRangel::setValue(&mod_af_input, pJson["modAFInput"], "qint32", ""); + ::SWGSDRangel::setValue(&gauge_input_else_modem, pJson["gaugeInputElseModem"], "qint32", ""); + ::SWGSDRangel::setValue(&use_reverse_api, pJson["useReverseAPI"], "qint32", ""); ::SWGSDRangel::setValue(&reverse_api_address, pJson["reverseAPIAddress"], "QString", "QString"); @@ -249,6 +256,9 @@ SWGFreeDVModSettings::asJsonObject() { if(m_mod_af_input_isSet){ obj->insert("modAFInput", QJsonValue(mod_af_input)); } + if(m_gauge_input_else_modem_isSet){ + obj->insert("gaugeInputElseModem", QJsonValue(gauge_input_else_modem)); + } if(m_use_reverse_api_isSet){ obj->insert("useReverseAPI", QJsonValue(use_reverse_api)); } @@ -401,6 +411,16 @@ SWGFreeDVModSettings::setModAfInput(qint32 mod_af_input) { this->m_mod_af_input_isSet = true; } +qint32 +SWGFreeDVModSettings::getGaugeInputElseModem() { + return gauge_input_else_modem; +} +void +SWGFreeDVModSettings::setGaugeInputElseModem(qint32 gauge_input_else_modem) { + this->gauge_input_else_modem = gauge_input_else_modem; + this->m_gauge_input_else_modem_isSet = true; +} + qint32 SWGFreeDVModSettings::getUseReverseApi() { return use_reverse_api; @@ -479,6 +499,7 @@ SWGFreeDVModSettings::isSet(){ if(audio_device_name != nullptr && *audio_device_name != QString("")){ isObjectUpdated = true; break;} if(m_free_dv_mode_isSet){ isObjectUpdated = true; break;} if(m_mod_af_input_isSet){ isObjectUpdated = true; break;} + if(m_gauge_input_else_modem_isSet){ isObjectUpdated = true; break;} if(m_use_reverse_api_isSet){ isObjectUpdated = true; break;} if(reverse_api_address != nullptr && *reverse_api_address != QString("")){ isObjectUpdated = true; break;} if(m_reverse_api_port_isSet){ isObjectUpdated = true; break;} diff --git a/swagger/sdrangel/code/qt5/client/SWGFreeDVModSettings.h b/swagger/sdrangel/code/qt5/client/SWGFreeDVModSettings.h index 01f793d97..500399d07 100644 --- a/swagger/sdrangel/code/qt5/client/SWGFreeDVModSettings.h +++ b/swagger/sdrangel/code/qt5/client/SWGFreeDVModSettings.h @@ -82,6 +82,9 @@ public: qint32 getModAfInput(); void setModAfInput(qint32 mod_af_input); + qint32 getGaugeInputElseModem(); + void setGaugeInputElseModem(qint32 gauge_input_else_modem); + qint32 getUseReverseApi(); void setUseReverseApi(qint32 use_reverse_api); @@ -143,6 +146,9 @@ private: qint32 mod_af_input; bool m_mod_af_input_isSet; + qint32 gauge_input_else_modem; + bool m_gauge_input_else_modem_isSet; + qint32 use_reverse_api; bool m_use_reverse_api_isSet;