mirror of
https://github.com/f4exb/sdrangel.git
synced 2025-09-10 10:47:48 -04:00
Multiple audio support: NFM modulator
This commit is contained in:
parent
2380211533
commit
eb57c1aca6
@ -71,12 +71,14 @@ NFMMod::NFMMod(DeviceSinkAPI *deviceAPI) :
|
|||||||
|
|
||||||
m_magsq = 0.0;
|
m_magsq = 0.0;
|
||||||
|
|
||||||
m_toneNco.setFreq(1000.0, m_settings.m_audioSampleRate);
|
|
||||||
m_ctcssNco.setFreq(88.5, m_settings.m_audioSampleRate);
|
|
||||||
DSPEngine::instance()->getAudioDeviceManager()->addAudioSource(&m_audioFifo, getInputMessageQueue());
|
DSPEngine::instance()->getAudioDeviceManager()->addAudioSource(&m_audioFifo, getInputMessageQueue());
|
||||||
|
m_audioSampleRate = DSPEngine::instance()->getAudioDeviceManager()->getInputSampleRate();
|
||||||
|
|
||||||
|
m_toneNco.setFreq(1000.0, m_audioSampleRate);
|
||||||
|
m_ctcssNco.setFreq(88.5, m_audioSampleRate);
|
||||||
|
|
||||||
// CW keyer
|
// CW keyer
|
||||||
m_cwKeyer.setSampleRate(m_settings.m_audioSampleRate);
|
m_cwKeyer.setSampleRate(m_audioSampleRate);
|
||||||
m_cwKeyer.setWPM(13);
|
m_cwKeyer.setWPM(13);
|
||||||
m_cwKeyer.setMode(CWKeyerSettings::CWNone);
|
m_cwKeyer.setMode(CWKeyerSettings::CWNone);
|
||||||
|
|
||||||
@ -145,7 +147,7 @@ void NFMMod::pull(Sample& sample)
|
|||||||
|
|
||||||
void NFMMod::pullAudio(int nbSamples)
|
void NFMMod::pullAudio(int nbSamples)
|
||||||
{
|
{
|
||||||
unsigned int nbSamplesAudio = nbSamples * ((Real) m_settings.m_audioSampleRate / (Real) m_basebandSampleRate);
|
unsigned int nbSamplesAudio = nbSamples * ((Real) m_audioSampleRate / (Real) m_basebandSampleRate);
|
||||||
|
|
||||||
if (nbSamplesAudio > m_audioBuffer.size())
|
if (nbSamplesAudio > m_audioBuffer.size())
|
||||||
{
|
{
|
||||||
@ -166,12 +168,12 @@ void NFMMod::modulateSample()
|
|||||||
|
|
||||||
if (m_settings.m_ctcssOn)
|
if (m_settings.m_ctcssOn)
|
||||||
{
|
{
|
||||||
m_modPhasor += (m_settings.m_fmDeviation / (float) m_settings.m_audioSampleRate) * (0.85f * m_bandpass.filter(t) + 0.15f * 378.0f * m_ctcssNco.next()) * (M_PI / 378.0f);
|
m_modPhasor += (m_settings.m_fmDeviation / (float) m_audioSampleRate) * (0.85f * m_bandpass.filter(t) + 0.15f * 378.0f * m_ctcssNco.next()) * (M_PI / 378.0f);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// 378 = 302 * 1.25; 302 = number of filter taps (established experimentally)
|
// 378 = 302 * 1.25; 302 = number of filter taps (established experimentally)
|
||||||
m_modPhasor += (m_settings.m_fmDeviation / (float) m_settings.m_audioSampleRate) * m_bandpass.filter(t) * (M_PI / 378.0f);
|
m_modPhasor += (m_settings.m_fmDeviation / (float) m_audioSampleRate) * m_bandpass.filter(t) * (M_PI / 378.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_modSample.real(cos(m_modPhasor) * 0.891235351562f * SDR_TX_SCALEF); // -1 dB
|
m_modSample.real(cos(m_modPhasor) * 0.891235351562f * SDR_TX_SCALEF); // -1 dB
|
||||||
@ -345,6 +347,20 @@ bool NFMMod::handleMessage(const Message& cmd)
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
else if (DSPConfigureAudio::match(cmd))
|
||||||
|
{
|
||||||
|
DSPConfigureAudio& cfg = (DSPConfigureAudio&) cmd;
|
||||||
|
uint32_t sampleRate = cfg.getSampleRate();
|
||||||
|
|
||||||
|
qDebug() << "NFMMod::handleMessage: DSPConfigureAudio:"
|
||||||
|
<< " sampleRate: " << sampleRate;
|
||||||
|
|
||||||
|
if (sampleRate != m_audioSampleRate) {
|
||||||
|
applyAudioSampleRate(sampleRate);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
else if (DSPSignalNotification::match(cmd))
|
else if (DSPSignalNotification::match(cmd))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
@ -390,6 +406,31 @@ void NFMMod::seekFileStream(int seekPercentage)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NFMMod::applyAudioSampleRate(int sampleRate)
|
||||||
|
{
|
||||||
|
qDebug("NFMMod::applyAudioSampleRate: %d", sampleRate);
|
||||||
|
|
||||||
|
MsgConfigureChannelizer* channelConfigMsg = MsgConfigureChannelizer::create(
|
||||||
|
sampleRate, m_settings.m_inputFrequencyOffset);
|
||||||
|
m_inputMessageQueue.push(channelConfigMsg);
|
||||||
|
|
||||||
|
m_settingsMutex.lock();
|
||||||
|
|
||||||
|
m_interpolatorDistanceRemain = 0;
|
||||||
|
m_interpolatorConsumed = false;
|
||||||
|
m_interpolatorDistance = (Real) sampleRate / (Real) m_outputSampleRate;
|
||||||
|
m_interpolator.create(48, sampleRate, m_settings.m_rfBandwidth / 2.2, 3.0);
|
||||||
|
m_lowpass.create(301, sampleRate, 250.0);
|
||||||
|
m_bandpass.create(301, sampleRate, 300.0, m_settings.m_afBandwidth);
|
||||||
|
m_toneNco.setFreq(m_settings.m_toneFrequency, sampleRate);
|
||||||
|
m_ctcssNco.setFreq(NFMModSettings::getCTCSSFreq(m_settings.m_ctcssIndex), sampleRate);
|
||||||
|
m_cwKeyer.setSampleRate(sampleRate);
|
||||||
|
|
||||||
|
m_settingsMutex.unlock();
|
||||||
|
|
||||||
|
m_audioSampleRate = sampleRate;
|
||||||
|
}
|
||||||
|
|
||||||
void NFMMod::applyChannelSettings(int basebandSampleRate, int outputSampleRate, int inputFrequencyOffset, bool force)
|
void NFMMod::applyChannelSettings(int basebandSampleRate, int outputSampleRate, int inputFrequencyOffset, bool force)
|
||||||
{
|
{
|
||||||
qDebug() << "NFMMod::applyChannelSettings:"
|
qDebug() << "NFMMod::applyChannelSettings:"
|
||||||
@ -410,8 +451,8 @@ void NFMMod::applyChannelSettings(int basebandSampleRate, int outputSampleRate,
|
|||||||
m_settingsMutex.lock();
|
m_settingsMutex.lock();
|
||||||
m_interpolatorDistanceRemain = 0;
|
m_interpolatorDistanceRemain = 0;
|
||||||
m_interpolatorConsumed = false;
|
m_interpolatorConsumed = false;
|
||||||
m_interpolatorDistance = (Real) m_settings.m_audioSampleRate / (Real) outputSampleRate;
|
m_interpolatorDistance = (Real) m_audioSampleRate / (Real) outputSampleRate;
|
||||||
m_interpolator.create(48, m_settings.m_audioSampleRate, m_settings.m_rfBandwidth / 2.2, 3.0);
|
m_interpolator.create(48, m_audioSampleRate, m_settings.m_rfBandwidth / 2.2, 3.0);
|
||||||
m_settingsMutex.unlock();
|
m_settingsMutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -434,49 +475,53 @@ void NFMMod::applySettings(const NFMModSettings& settings, bool force)
|
|||||||
<< " m_channelMute: " << settings.m_channelMute
|
<< " m_channelMute: " << settings.m_channelMute
|
||||||
<< " m_playLoop: " << settings.m_playLoop
|
<< " m_playLoop: " << settings.m_playLoop
|
||||||
<< " m_modAFInout " << settings.m_modAFInput
|
<< " m_modAFInout " << settings.m_modAFInput
|
||||||
|
<< " m_audioDeviceName: " << settings.m_audioDeviceName
|
||||||
<< " force: " << force;
|
<< " force: " << force;
|
||||||
|
|
||||||
if((settings.m_rfBandwidth != m_settings.m_rfBandwidth) ||
|
if((settings.m_rfBandwidth != m_settings.m_rfBandwidth) || force)
|
||||||
(settings.m_audioSampleRate != m_settings.m_audioSampleRate) || force)
|
|
||||||
{
|
{
|
||||||
m_settingsMutex.lock();
|
m_settingsMutex.lock();
|
||||||
m_interpolatorDistanceRemain = 0;
|
m_interpolatorDistanceRemain = 0;
|
||||||
m_interpolatorConsumed = false;
|
m_interpolatorConsumed = false;
|
||||||
m_interpolatorDistance = (Real) settings.m_audioSampleRate / (Real) m_outputSampleRate;
|
m_interpolatorDistance = (Real) m_audioSampleRate / (Real) m_outputSampleRate;
|
||||||
m_interpolator.create(48, settings.m_audioSampleRate, settings.m_rfBandwidth / 2.2, 3.0);
|
m_interpolator.create(48, m_audioSampleRate, settings.m_rfBandwidth / 2.2, 3.0);
|
||||||
m_settingsMutex.unlock();
|
m_settingsMutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((settings.m_afBandwidth != m_settings.m_afBandwidth) ||
|
if ((settings.m_afBandwidth != m_settings.m_afBandwidth) || force)
|
||||||
(settings.m_audioSampleRate != m_settings.m_audioSampleRate) || force)
|
|
||||||
{
|
{
|
||||||
m_settingsMutex.lock();
|
m_settingsMutex.lock();
|
||||||
m_lowpass.create(301, settings.m_audioSampleRate, 250.0);
|
m_lowpass.create(301, m_audioSampleRate, 250.0);
|
||||||
m_bandpass.create(301, settings.m_audioSampleRate, 300.0, settings.m_afBandwidth);
|
m_bandpass.create(301, m_audioSampleRate, 300.0, settings.m_afBandwidth);
|
||||||
m_settingsMutex.unlock();
|
m_settingsMutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((settings.m_toneFrequency != m_settings.m_toneFrequency) ||
|
if ((settings.m_toneFrequency != m_settings.m_toneFrequency) || force)
|
||||||
(settings.m_audioSampleRate != m_settings.m_audioSampleRate) || force)
|
|
||||||
{
|
{
|
||||||
m_settingsMutex.lock();
|
m_settingsMutex.lock();
|
||||||
m_toneNco.setFreq(settings.m_toneFrequency, settings.m_audioSampleRate);
|
m_toneNco.setFreq(settings.m_toneFrequency, m_audioSampleRate);
|
||||||
m_settingsMutex.unlock();
|
m_settingsMutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((settings.m_audioSampleRate != m_settings.m_audioSampleRate) || force)
|
if ((settings.m_ctcssIndex != m_settings.m_ctcssIndex) || force)
|
||||||
{
|
|
||||||
m_cwKeyer.setSampleRate(settings.m_audioSampleRate);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((settings.m_ctcssIndex != m_settings.m_ctcssIndex) ||
|
|
||||||
(settings.m_audioSampleRate != m_settings.m_audioSampleRate) || force)
|
|
||||||
{
|
{
|
||||||
m_settingsMutex.lock();
|
m_settingsMutex.lock();
|
||||||
m_ctcssNco.setFreq(NFMModSettings::getCTCSSFreq(settings.m_ctcssIndex), settings.m_audioSampleRate);
|
m_ctcssNco.setFreq(NFMModSettings::getCTCSSFreq(settings.m_ctcssIndex), m_audioSampleRate);
|
||||||
m_settingsMutex.unlock();
|
m_settingsMutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((settings.m_audioDeviceName != m_settings.m_audioDeviceName) || force)
|
||||||
|
{
|
||||||
|
AudioDeviceManager *audioDeviceManager = DSPEngine::instance()->getAudioDeviceManager();
|
||||||
|
int audioDeviceIndex = audioDeviceManager->getInputDeviceIndex(settings.m_audioDeviceName);
|
||||||
|
audioDeviceManager->addAudioSource(&m_audioFifo, getInputMessageQueue(), audioDeviceIndex);
|
||||||
|
uint32_t audioSampleRate = audioDeviceManager->getInputSampleRate(audioDeviceIndex);
|
||||||
|
|
||||||
|
if (m_audioSampleRate != audioSampleRate) {
|
||||||
|
applyAudioSampleRate(audioSampleRate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_settings = settings;
|
m_settings = settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -531,9 +576,6 @@ int NFMMod::webapiSettingsPutPatch(
|
|||||||
if (channelSettingsKeys.contains("afBandwidth")) {
|
if (channelSettingsKeys.contains("afBandwidth")) {
|
||||||
settings.m_afBandwidth = response.getNfmModSettings()->getAfBandwidth();
|
settings.m_afBandwidth = response.getNfmModSettings()->getAfBandwidth();
|
||||||
}
|
}
|
||||||
if (channelSettingsKeys.contains("audioSampleRate")) {
|
|
||||||
settings.m_audioSampleRate = response.getNfmModSettings()->getAudioSampleRate();
|
|
||||||
}
|
|
||||||
if (channelSettingsKeys.contains("channelMute")) {
|
if (channelSettingsKeys.contains("channelMute")) {
|
||||||
settings.m_channelMute = response.getNfmModSettings()->getChannelMute() != 0;
|
settings.m_channelMute = response.getNfmModSettings()->getChannelMute() != 0;
|
||||||
}
|
}
|
||||||
@ -641,7 +683,6 @@ int NFMMod::webapiReportGet(
|
|||||||
void NFMMod::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& response, const NFMModSettings& settings)
|
void NFMMod::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& response, const NFMModSettings& settings)
|
||||||
{
|
{
|
||||||
response.getNfmModSettings()->setAfBandwidth(settings.m_afBandwidth);
|
response.getNfmModSettings()->setAfBandwidth(settings.m_afBandwidth);
|
||||||
response.getNfmModSettings()->setAudioSampleRate(settings.m_audioSampleRate);
|
|
||||||
response.getNfmModSettings()->setChannelMute(settings.m_channelMute ? 1 : 0);
|
response.getNfmModSettings()->setChannelMute(settings.m_channelMute ? 1 : 0);
|
||||||
response.getNfmModSettings()->setCtcssIndex(settings.m_ctcssIndex);
|
response.getNfmModSettings()->setCtcssIndex(settings.m_ctcssIndex);
|
||||||
response.getNfmModSettings()->setCtcssOn(settings.m_ctcssOn ? 1 : 0);
|
response.getNfmModSettings()->setCtcssOn(settings.m_ctcssOn ? 1 : 0);
|
||||||
@ -677,10 +718,18 @@ void NFMMod::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& respon
|
|||||||
apiCwKeyerSettings->setText(new QString(cwKeyerSettings.m_text));
|
apiCwKeyerSettings->setText(new QString(cwKeyerSettings.m_text));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (response.getNfmDemodSettings()->getAudioDeviceName()) {
|
||||||
|
*response.getNfmDemodSettings()->getAudioDeviceName() = settings.m_audioDeviceName;
|
||||||
|
} else {
|
||||||
|
response.getNfmDemodSettings()->setAudioDeviceName(new QString(settings.m_audioDeviceName));
|
||||||
|
}
|
||||||
|
|
||||||
apiCwKeyerSettings->setWpm(cwKeyerSettings.m_wpm);
|
apiCwKeyerSettings->setWpm(cwKeyerSettings.m_wpm);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NFMMod::webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response)
|
void NFMMod::webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response)
|
||||||
{
|
{
|
||||||
response.getNfmModReport()->setChannelPowerDb(CalcDb::dbPower(getMagSq()));
|
response.getNfmModReport()->setChannelPowerDb(CalcDb::dbPower(getMagSq()));
|
||||||
|
response.getNfmModReport()->setAudioSampleRate(m_audioSampleRate);
|
||||||
|
response.getNfmModReport()->setChannelSampleRate(m_outputSampleRate);
|
||||||
}
|
}
|
||||||
|
@ -262,6 +262,7 @@ private:
|
|||||||
int m_outputSampleRate;
|
int m_outputSampleRate;
|
||||||
int m_inputFrequencyOffset;
|
int m_inputFrequencyOffset;
|
||||||
NFMModSettings m_settings;
|
NFMModSettings m_settings;
|
||||||
|
quint32 m_audioSampleRate;
|
||||||
|
|
||||||
NCO m_carrierNco;
|
NCO m_carrierNco;
|
||||||
NCOF m_toneNco;
|
NCOF m_toneNco;
|
||||||
@ -298,6 +299,7 @@ private:
|
|||||||
CWKeyer m_cwKeyer;
|
CWKeyer m_cwKeyer;
|
||||||
static const int m_levelNbSamples;
|
static const int m_levelNbSamples;
|
||||||
|
|
||||||
|
void applyAudioSampleRate(int sampleRate);
|
||||||
void applyChannelSettings(int basebandSampleRate, int outputSampleRate, int inputFrequencyOffset, bool force = false);
|
void applyChannelSettings(int basebandSampleRate, int outputSampleRate, int inputFrequencyOffset, bool force = false);
|
||||||
void applySettings(const NFMModSettings& settings, bool force = false);
|
void applySettings(const NFMModSettings& settings, bool force = false);
|
||||||
void pullAF(Real& sample);
|
void pullAF(Real& sample);
|
||||||
|
@ -26,6 +26,8 @@
|
|||||||
#include "util/simpleserializer.h"
|
#include "util/simpleserializer.h"
|
||||||
#include "util/db.h"
|
#include "util/db.h"
|
||||||
#include "dsp/dspengine.h"
|
#include "dsp/dspengine.h"
|
||||||
|
#include "gui/crightclickenabler.h"
|
||||||
|
#include "gui/audioselectdialog.h"
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
|
|
||||||
#include "ui_nfmmodgui.h"
|
#include "ui_nfmmodgui.h"
|
||||||
@ -320,6 +322,9 @@ NFMModGUI::NFMModGUI(PluginAPI* pluginAPI, DeviceUISet *deviceUISet, BasebandSam
|
|||||||
|
|
||||||
connect(&MainWindow::getInstance()->getMasterTimer(), SIGNAL(timeout()), this, SLOT(tick()));
|
connect(&MainWindow::getInstance()->getMasterTimer(), SIGNAL(timeout()), this, SLOT(tick()));
|
||||||
|
|
||||||
|
CRightClickEnabler *audioMuteRightClickEnabler = new CRightClickEnabler(ui->mic);
|
||||||
|
connect(audioMuteRightClickEnabler, SIGNAL(rightClick()), this, SLOT(audioSelect()));
|
||||||
|
|
||||||
ui->deltaFrequencyLabel->setText(QString("%1f").arg(QChar(0x94, 0x03)));
|
ui->deltaFrequencyLabel->setText(QString("%1f").arg(QChar(0x94, 0x03)));
|
||||||
ui->deltaFrequency->setColorMapper(ColorMapper(ColorMapper::GrayGold));
|
ui->deltaFrequency->setColorMapper(ColorMapper(ColorMapper::GrayGold));
|
||||||
ui->deltaFrequency->setValueRange(false, 7, -9999999, 9999999);
|
ui->deltaFrequency->setValueRange(false, 7, -9999999, 9999999);
|
||||||
@ -446,6 +451,19 @@ void NFMModGUI::enterEvent(QEvent*)
|
|||||||
m_channelMarker.setHighlighted(true);
|
m_channelMarker.setHighlighted(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NFMModGUI::audioSelect()
|
||||||
|
{
|
||||||
|
qDebug("NFMModGUI::audioSelect");
|
||||||
|
AudioSelectDialog audioSelect(DSPEngine::instance()->getAudioDeviceManager(), m_settings.m_audioDeviceName, true); // true for input
|
||||||
|
audioSelect.exec();
|
||||||
|
|
||||||
|
if (audioSelect.m_selected)
|
||||||
|
{
|
||||||
|
m_settings.m_audioDeviceName = audioSelect.m_audioDeviceName;
|
||||||
|
applySettings();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void NFMModGUI::tick()
|
void NFMModGUI::tick()
|
||||||
{
|
{
|
||||||
double powDb = CalcDb::dbPower(m_nfmMod->getMagSq());
|
double powDb = CalcDb::dbPower(m_nfmMod->getMagSq());
|
||||||
|
@ -112,6 +112,7 @@ private slots:
|
|||||||
void onWidgetRolled(QWidget* widget, bool rollDown);
|
void onWidgetRolled(QWidget* widget, bool rollDown);
|
||||||
|
|
||||||
void configureFileName();
|
void configureFileName();
|
||||||
|
void audioSelect();
|
||||||
void tick();
|
void tick();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -50,7 +50,6 @@ void NFMModSettings::resetToDefaults()
|
|||||||
m_rfBandwidth = 12500.0f;
|
m_rfBandwidth = 12500.0f;
|
||||||
m_fmDeviation = 5000.0f;
|
m_fmDeviation = 5000.0f;
|
||||||
m_toneFrequency = 1000.0f;
|
m_toneFrequency = 1000.0f;
|
||||||
m_audioSampleRate = DSPEngine::instance()->getDefaultAudioSampleRate();
|
|
||||||
m_volumeFactor = 1.0f;
|
m_volumeFactor = 1.0f;
|
||||||
m_channelMute = false;
|
m_channelMute = false;
|
||||||
m_playLoop = false;
|
m_playLoop = false;
|
||||||
@ -59,6 +58,7 @@ void NFMModSettings::resetToDefaults()
|
|||||||
m_rgbColor = QColor(255, 0, 0).rgb();
|
m_rgbColor = QColor(255, 0, 0).rgb();
|
||||||
m_title = "NFM Modulator";
|
m_title = "NFM Modulator";
|
||||||
m_modAFInput = NFMModInputAF::NFMModInputNone;
|
m_modAFInput = NFMModInputAF::NFMModInputNone;
|
||||||
|
m_audioDeviceName = AudioDeviceManager::m_defaultDeviceName;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray NFMModSettings::serialize() const
|
QByteArray NFMModSettings::serialize() const
|
||||||
@ -85,6 +85,7 @@ QByteArray NFMModSettings::serialize() const
|
|||||||
s.writeS32(10, m_ctcssIndex);
|
s.writeS32(10, m_ctcssIndex);
|
||||||
s.writeString(12, m_title);
|
s.writeString(12, m_title);
|
||||||
s.writeS32(13, (int) m_modAFInput);
|
s.writeS32(13, (int) m_modAFInput);
|
||||||
|
s.writeString(14, m_audioDeviceName);
|
||||||
|
|
||||||
return s.final();
|
return s.final();
|
||||||
}
|
}
|
||||||
@ -135,6 +136,8 @@ bool NFMModSettings::deserialize(const QByteArray& data)
|
|||||||
m_modAFInput = (NFMModInputAF) tmp;
|
m_modAFInput = (NFMModInputAF) tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
d.readString(14, &m_audioDeviceName, AudioDeviceManager::m_defaultDeviceName);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -43,7 +43,6 @@ struct NFMModSettings
|
|||||||
float m_fmDeviation;
|
float m_fmDeviation;
|
||||||
float m_toneFrequency;
|
float m_toneFrequency;
|
||||||
float m_volumeFactor;
|
float m_volumeFactor;
|
||||||
quint32 m_audioSampleRate;
|
|
||||||
bool m_channelMute;
|
bool m_channelMute;
|
||||||
bool m_playLoop;
|
bool m_playLoop;
|
||||||
bool m_ctcssOn;
|
bool m_ctcssOn;
|
||||||
@ -51,6 +50,7 @@ struct NFMModSettings
|
|||||||
quint32 m_rgbColor;
|
quint32 m_rgbColor;
|
||||||
QString m_title;
|
QString m_title;
|
||||||
NFMModInputAF m_modAFInput;
|
NFMModInputAF m_modAFInput;
|
||||||
|
QString m_audioDeviceName;
|
||||||
|
|
||||||
Serializable *m_channelMarker;
|
Serializable *m_channelMarker;
|
||||||
Serializable *m_cwKeyerGUI;
|
Serializable *m_cwKeyerGUI;
|
||||||
|
@ -60,9 +60,11 @@ Switches to the Morse keyer input. You must switch it off to make other inputs a
|
|||||||
|
|
||||||
Adjusts the tone frequency from 0.1 to 2.5 kHz in 0.01 kHz steps
|
Adjusts the tone frequency from 0.1 to 2.5 kHz in 0.01 kHz steps
|
||||||
|
|
||||||
<h4>10.4: Audio input select</h4>
|
<h4>10.4: Audio input select and select audio input device</h4>
|
||||||
|
|
||||||
Switches to the audio input. You must switch it off to make other inputs available.
|
Left click to switch to the audio input. You must switch it off to make other inputs available.
|
||||||
|
|
||||||
|
Right click to select audio input device.
|
||||||
|
|
||||||
<h3>11: CTCSS switch</h3>
|
<h3>11: CTCSS switch</h3>
|
||||||
|
|
||||||
|
@ -1585,6 +1585,12 @@ margin-bottom: 20px;
|
|||||||
"type" : "number",
|
"type" : "number",
|
||||||
"format" : "float",
|
"format" : "float",
|
||||||
"description" : "power transmitted in channel (dB)"
|
"description" : "power transmitted in channel (dB)"
|
||||||
|
},
|
||||||
|
"audioSampleRate" : {
|
||||||
|
"type" : "integer"
|
||||||
|
},
|
||||||
|
"channelSampleRate" : {
|
||||||
|
"type" : "integer"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"description" : "NFMMod"
|
"description" : "NFMMod"
|
||||||
@ -1615,9 +1621,6 @@ margin-bottom: 20px;
|
|||||||
"type" : "number",
|
"type" : "number",
|
||||||
"format" : "float"
|
"format" : "float"
|
||||||
},
|
},
|
||||||
"audioSampleRate" : {
|
|
||||||
"type" : "integer"
|
|
||||||
},
|
|
||||||
"channelMute" : {
|
"channelMute" : {
|
||||||
"type" : "integer"
|
"type" : "integer"
|
||||||
},
|
},
|
||||||
@ -20103,7 +20106,7 @@ except ApiException as e:
|
|||||||
</div>
|
</div>
|
||||||
<div id="generator">
|
<div id="generator">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
Generated 2018-03-29T07:44:35.585+02:00
|
Generated 2018-03-29T15:31:47.724+02:00
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -19,8 +19,6 @@ NFMModSettings:
|
|||||||
volumeFactor:
|
volumeFactor:
|
||||||
type: number
|
type: number
|
||||||
format: float
|
format: float
|
||||||
audioSampleRate:
|
|
||||||
type: integer
|
|
||||||
channelMute:
|
channelMute:
|
||||||
type: integer
|
type: integer
|
||||||
playLoop:
|
playLoop:
|
||||||
@ -45,4 +43,8 @@ NFMModReport:
|
|||||||
description: power transmitted in channel (dB)
|
description: power transmitted in channel (dB)
|
||||||
type: number
|
type: number
|
||||||
format: float
|
format: float
|
||||||
|
audioSampleRate:
|
||||||
|
type: integer
|
||||||
|
channelSampleRate:
|
||||||
|
type: integer
|
||||||
|
|
@ -19,8 +19,6 @@ NFMModSettings:
|
|||||||
volumeFactor:
|
volumeFactor:
|
||||||
type: number
|
type: number
|
||||||
format: float
|
format: float
|
||||||
audioSampleRate:
|
|
||||||
type: integer
|
|
||||||
channelMute:
|
channelMute:
|
||||||
type: integer
|
type: integer
|
||||||
playLoop:
|
playLoop:
|
||||||
@ -45,4 +43,8 @@ NFMModReport:
|
|||||||
description: power transmitted in channel (dB)
|
description: power transmitted in channel (dB)
|
||||||
type: number
|
type: number
|
||||||
format: float
|
format: float
|
||||||
|
audioSampleRate:
|
||||||
|
type: integer
|
||||||
|
channelSampleRate:
|
||||||
|
type: integer
|
||||||
|
|
@ -1585,6 +1585,12 @@ margin-bottom: 20px;
|
|||||||
"type" : "number",
|
"type" : "number",
|
||||||
"format" : "float",
|
"format" : "float",
|
||||||
"description" : "power transmitted in channel (dB)"
|
"description" : "power transmitted in channel (dB)"
|
||||||
|
},
|
||||||
|
"audioSampleRate" : {
|
||||||
|
"type" : "integer"
|
||||||
|
},
|
||||||
|
"channelSampleRate" : {
|
||||||
|
"type" : "integer"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"description" : "NFMMod"
|
"description" : "NFMMod"
|
||||||
@ -1615,9 +1621,6 @@ margin-bottom: 20px;
|
|||||||
"type" : "number",
|
"type" : "number",
|
||||||
"format" : "float"
|
"format" : "float"
|
||||||
},
|
},
|
||||||
"audioSampleRate" : {
|
|
||||||
"type" : "integer"
|
|
||||||
},
|
|
||||||
"channelMute" : {
|
"channelMute" : {
|
||||||
"type" : "integer"
|
"type" : "integer"
|
||||||
},
|
},
|
||||||
@ -20103,7 +20106,7 @@ except ApiException as e:
|
|||||||
</div>
|
</div>
|
||||||
<div id="generator">
|
<div id="generator">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
Generated 2018-03-29T07:44:35.585+02:00
|
Generated 2018-03-29T15:31:47.724+02:00
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -30,6 +30,10 @@ SWGNFMModReport::SWGNFMModReport(QString* json) {
|
|||||||
SWGNFMModReport::SWGNFMModReport() {
|
SWGNFMModReport::SWGNFMModReport() {
|
||||||
channel_power_db = 0.0f;
|
channel_power_db = 0.0f;
|
||||||
m_channel_power_db_isSet = false;
|
m_channel_power_db_isSet = false;
|
||||||
|
audio_sample_rate = 0;
|
||||||
|
m_audio_sample_rate_isSet = false;
|
||||||
|
channel_sample_rate = 0;
|
||||||
|
m_channel_sample_rate_isSet = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SWGNFMModReport::~SWGNFMModReport() {
|
SWGNFMModReport::~SWGNFMModReport() {
|
||||||
@ -40,11 +44,17 @@ void
|
|||||||
SWGNFMModReport::init() {
|
SWGNFMModReport::init() {
|
||||||
channel_power_db = 0.0f;
|
channel_power_db = 0.0f;
|
||||||
m_channel_power_db_isSet = false;
|
m_channel_power_db_isSet = false;
|
||||||
|
audio_sample_rate = 0;
|
||||||
|
m_audio_sample_rate_isSet = false;
|
||||||
|
channel_sample_rate = 0;
|
||||||
|
m_channel_sample_rate_isSet = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SWGNFMModReport::cleanup() {
|
SWGNFMModReport::cleanup() {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SWGNFMModReport*
|
SWGNFMModReport*
|
||||||
@ -60,6 +70,10 @@ void
|
|||||||
SWGNFMModReport::fromJsonObject(QJsonObject &pJson) {
|
SWGNFMModReport::fromJsonObject(QJsonObject &pJson) {
|
||||||
::SWGSDRangel::setValue(&channel_power_db, pJson["channelPowerDB"], "float", "");
|
::SWGSDRangel::setValue(&channel_power_db, pJson["channelPowerDB"], "float", "");
|
||||||
|
|
||||||
|
::SWGSDRangel::setValue(&audio_sample_rate, pJson["audioSampleRate"], "qint32", "");
|
||||||
|
|
||||||
|
::SWGSDRangel::setValue(&channel_sample_rate, pJson["channelSampleRate"], "qint32", "");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString
|
QString
|
||||||
@ -79,6 +93,12 @@ SWGNFMModReport::asJsonObject() {
|
|||||||
if(m_channel_power_db_isSet){
|
if(m_channel_power_db_isSet){
|
||||||
obj->insert("channelPowerDB", QJsonValue(channel_power_db));
|
obj->insert("channelPowerDB", QJsonValue(channel_power_db));
|
||||||
}
|
}
|
||||||
|
if(m_audio_sample_rate_isSet){
|
||||||
|
obj->insert("audioSampleRate", QJsonValue(audio_sample_rate));
|
||||||
|
}
|
||||||
|
if(m_channel_sample_rate_isSet){
|
||||||
|
obj->insert("channelSampleRate", QJsonValue(channel_sample_rate));
|
||||||
|
}
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
@ -93,12 +113,34 @@ SWGNFMModReport::setChannelPowerDb(float channel_power_db) {
|
|||||||
this->m_channel_power_db_isSet = true;
|
this->m_channel_power_db_isSet = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qint32
|
||||||
|
SWGNFMModReport::getAudioSampleRate() {
|
||||||
|
return audio_sample_rate;
|
||||||
|
}
|
||||||
|
void
|
||||||
|
SWGNFMModReport::setAudioSampleRate(qint32 audio_sample_rate) {
|
||||||
|
this->audio_sample_rate = audio_sample_rate;
|
||||||
|
this->m_audio_sample_rate_isSet = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
qint32
|
||||||
|
SWGNFMModReport::getChannelSampleRate() {
|
||||||
|
return channel_sample_rate;
|
||||||
|
}
|
||||||
|
void
|
||||||
|
SWGNFMModReport::setChannelSampleRate(qint32 channel_sample_rate) {
|
||||||
|
this->channel_sample_rate = channel_sample_rate;
|
||||||
|
this->m_channel_sample_rate_isSet = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
SWGNFMModReport::isSet(){
|
SWGNFMModReport::isSet(){
|
||||||
bool isObjectUpdated = false;
|
bool isObjectUpdated = false;
|
||||||
do{
|
do{
|
||||||
if(m_channel_power_db_isSet){ isObjectUpdated = true; break;}
|
if(m_channel_power_db_isSet){ isObjectUpdated = true; break;}
|
||||||
|
if(m_audio_sample_rate_isSet){ isObjectUpdated = true; break;}
|
||||||
|
if(m_channel_sample_rate_isSet){ isObjectUpdated = true; break;}
|
||||||
}while(false);
|
}while(false);
|
||||||
return isObjectUpdated;
|
return isObjectUpdated;
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,12 @@ public:
|
|||||||
float getChannelPowerDb();
|
float getChannelPowerDb();
|
||||||
void setChannelPowerDb(float channel_power_db);
|
void setChannelPowerDb(float channel_power_db);
|
||||||
|
|
||||||
|
qint32 getAudioSampleRate();
|
||||||
|
void setAudioSampleRate(qint32 audio_sample_rate);
|
||||||
|
|
||||||
|
qint32 getChannelSampleRate();
|
||||||
|
void setChannelSampleRate(qint32 channel_sample_rate);
|
||||||
|
|
||||||
|
|
||||||
virtual bool isSet() override;
|
virtual bool isSet() override;
|
||||||
|
|
||||||
@ -51,6 +57,12 @@ private:
|
|||||||
float channel_power_db;
|
float channel_power_db;
|
||||||
bool m_channel_power_db_isSet;
|
bool m_channel_power_db_isSet;
|
||||||
|
|
||||||
|
qint32 audio_sample_rate;
|
||||||
|
bool m_audio_sample_rate_isSet;
|
||||||
|
|
||||||
|
qint32 channel_sample_rate;
|
||||||
|
bool m_channel_sample_rate_isSet;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -40,8 +40,6 @@ SWGNFMModSettings::SWGNFMModSettings() {
|
|||||||
m_tone_frequency_isSet = false;
|
m_tone_frequency_isSet = false;
|
||||||
volume_factor = 0.0f;
|
volume_factor = 0.0f;
|
||||||
m_volume_factor_isSet = false;
|
m_volume_factor_isSet = false;
|
||||||
audio_sample_rate = 0;
|
|
||||||
m_audio_sample_rate_isSet = false;
|
|
||||||
channel_mute = 0;
|
channel_mute = 0;
|
||||||
m_channel_mute_isSet = false;
|
m_channel_mute_isSet = false;
|
||||||
play_loop = 0;
|
play_loop = 0;
|
||||||
@ -78,8 +76,6 @@ SWGNFMModSettings::init() {
|
|||||||
m_tone_frequency_isSet = false;
|
m_tone_frequency_isSet = false;
|
||||||
volume_factor = 0.0f;
|
volume_factor = 0.0f;
|
||||||
m_volume_factor_isSet = false;
|
m_volume_factor_isSet = false;
|
||||||
audio_sample_rate = 0;
|
|
||||||
m_audio_sample_rate_isSet = false;
|
|
||||||
channel_mute = 0;
|
channel_mute = 0;
|
||||||
m_channel_mute_isSet = false;
|
m_channel_mute_isSet = false;
|
||||||
play_loop = 0;
|
play_loop = 0;
|
||||||
@ -111,7 +107,6 @@ SWGNFMModSettings::cleanup() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(title != nullptr) {
|
if(title != nullptr) {
|
||||||
delete title;
|
delete title;
|
||||||
}
|
}
|
||||||
@ -144,8 +139,6 @@ SWGNFMModSettings::fromJsonObject(QJsonObject &pJson) {
|
|||||||
|
|
||||||
::SWGSDRangel::setValue(&volume_factor, pJson["volumeFactor"], "float", "");
|
::SWGSDRangel::setValue(&volume_factor, pJson["volumeFactor"], "float", "");
|
||||||
|
|
||||||
::SWGSDRangel::setValue(&audio_sample_rate, pJson["audioSampleRate"], "qint32", "");
|
|
||||||
|
|
||||||
::SWGSDRangel::setValue(&channel_mute, pJson["channelMute"], "qint32", "");
|
::SWGSDRangel::setValue(&channel_mute, pJson["channelMute"], "qint32", "");
|
||||||
|
|
||||||
::SWGSDRangel::setValue(&play_loop, pJson["playLoop"], "qint32", "");
|
::SWGSDRangel::setValue(&play_loop, pJson["playLoop"], "qint32", "");
|
||||||
@ -196,9 +189,6 @@ SWGNFMModSettings::asJsonObject() {
|
|||||||
if(m_volume_factor_isSet){
|
if(m_volume_factor_isSet){
|
||||||
obj->insert("volumeFactor", QJsonValue(volume_factor));
|
obj->insert("volumeFactor", QJsonValue(volume_factor));
|
||||||
}
|
}
|
||||||
if(m_audio_sample_rate_isSet){
|
|
||||||
obj->insert("audioSampleRate", QJsonValue(audio_sample_rate));
|
|
||||||
}
|
|
||||||
if(m_channel_mute_isSet){
|
if(m_channel_mute_isSet){
|
||||||
obj->insert("channelMute", QJsonValue(channel_mute));
|
obj->insert("channelMute", QJsonValue(channel_mute));
|
||||||
}
|
}
|
||||||
@ -287,16 +277,6 @@ SWGNFMModSettings::setVolumeFactor(float volume_factor) {
|
|||||||
this->m_volume_factor_isSet = true;
|
this->m_volume_factor_isSet = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
qint32
|
|
||||||
SWGNFMModSettings::getAudioSampleRate() {
|
|
||||||
return audio_sample_rate;
|
|
||||||
}
|
|
||||||
void
|
|
||||||
SWGNFMModSettings::setAudioSampleRate(qint32 audio_sample_rate) {
|
|
||||||
this->audio_sample_rate = audio_sample_rate;
|
|
||||||
this->m_audio_sample_rate_isSet = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
qint32
|
qint32
|
||||||
SWGNFMModSettings::getChannelMute() {
|
SWGNFMModSettings::getChannelMute() {
|
||||||
return channel_mute;
|
return channel_mute;
|
||||||
@ -388,7 +368,6 @@ SWGNFMModSettings::isSet(){
|
|||||||
if(m_fm_deviation_isSet){ isObjectUpdated = true; break;}
|
if(m_fm_deviation_isSet){ isObjectUpdated = true; break;}
|
||||||
if(m_tone_frequency_isSet){ isObjectUpdated = true; break;}
|
if(m_tone_frequency_isSet){ isObjectUpdated = true; break;}
|
||||||
if(m_volume_factor_isSet){ isObjectUpdated = true; break;}
|
if(m_volume_factor_isSet){ isObjectUpdated = true; break;}
|
||||||
if(m_audio_sample_rate_isSet){ isObjectUpdated = true; break;}
|
|
||||||
if(m_channel_mute_isSet){ isObjectUpdated = true; break;}
|
if(m_channel_mute_isSet){ isObjectUpdated = true; break;}
|
||||||
if(m_play_loop_isSet){ isObjectUpdated = true; break;}
|
if(m_play_loop_isSet){ isObjectUpdated = true; break;}
|
||||||
if(m_ctcss_on_isSet){ isObjectUpdated = true; break;}
|
if(m_ctcss_on_isSet){ isObjectUpdated = true; break;}
|
||||||
|
@ -61,9 +61,6 @@ public:
|
|||||||
float getVolumeFactor();
|
float getVolumeFactor();
|
||||||
void setVolumeFactor(float volume_factor);
|
void setVolumeFactor(float volume_factor);
|
||||||
|
|
||||||
qint32 getAudioSampleRate();
|
|
||||||
void setAudioSampleRate(qint32 audio_sample_rate);
|
|
||||||
|
|
||||||
qint32 getChannelMute();
|
qint32 getChannelMute();
|
||||||
void setChannelMute(qint32 channel_mute);
|
void setChannelMute(qint32 channel_mute);
|
||||||
|
|
||||||
@ -110,9 +107,6 @@ private:
|
|||||||
float volume_factor;
|
float volume_factor;
|
||||||
bool m_volume_factor_isSet;
|
bool m_volume_factor_isSet;
|
||||||
|
|
||||||
qint32 audio_sample_rate;
|
|
||||||
bool m_audio_sample_rate_isSet;
|
|
||||||
|
|
||||||
qint32 channel_mute;
|
qint32 channel_mute;
|
||||||
bool m_channel_mute_isSet;
|
bool m_channel_mute_isSet;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user