mirror of
https://github.com/f4exb/sdrangel.git
synced 2025-05-24 03:02:29 -04:00
NFM, SSB and WFM Mods : use specific method to apply channelizer sample rate and frequency offset changes. Separate this data from settings
This commit is contained in:
parent
6041530353
commit
e5baca1a37
@ -48,7 +48,9 @@ const int NFMMod::m_levelNbSamples = 480; // every 10ms
|
|||||||
NFMMod::NFMMod(DeviceSinkAPI *deviceAPI) :
|
NFMMod::NFMMod(DeviceSinkAPI *deviceAPI) :
|
||||||
ChannelSourceAPI(m_channelIdURI),
|
ChannelSourceAPI(m_channelIdURI),
|
||||||
m_deviceAPI(deviceAPI),
|
m_deviceAPI(deviceAPI),
|
||||||
m_absoluteFrequencyOffset(0),
|
m_basebandSampleRate(48000),
|
||||||
|
m_outputSampleRate(48000),
|
||||||
|
m_inputFrequencyOffset(0),
|
||||||
m_modPhasor(0.0f),
|
m_modPhasor(0.0f),
|
||||||
m_movingAverage(40, 0),
|
m_movingAverage(40, 0),
|
||||||
m_volumeAGC(40, 0),
|
m_volumeAGC(40, 0),
|
||||||
@ -143,7 +145,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_settings.m_basebandSampleRate);
|
unsigned int nbSamplesAudio = nbSamples * ((Real) m_settings.m_audioSampleRate / (Real) m_basebandSampleRate);
|
||||||
|
|
||||||
if (nbSamplesAudio > m_audioBuffer.size())
|
if (nbSamplesAudio > m_audioBuffer.size())
|
||||||
{
|
{
|
||||||
@ -264,8 +266,8 @@ void NFMMod::calculateLevel(Real& sample)
|
|||||||
|
|
||||||
void NFMMod::start()
|
void NFMMod::start()
|
||||||
{
|
{
|
||||||
qDebug() << "NFMMod::start: m_outputSampleRate: " << m_settings.m_outputSampleRate
|
qDebug() << "NFMMod::start: m_outputSampleRate: " << m_outputSampleRate
|
||||||
<< " m_inputFrequencyOffset: " << m_settings.m_inputFrequencyOffset;
|
<< " m_inputFrequencyOffset: " << m_inputFrequencyOffset;
|
||||||
|
|
||||||
m_audioFifo.clear();
|
m_audioFifo.clear();
|
||||||
}
|
}
|
||||||
@ -279,60 +281,31 @@ bool NFMMod::handleMessage(const Message& cmd)
|
|||||||
if (UpChannelizer::MsgChannelizerNotification::match(cmd))
|
if (UpChannelizer::MsgChannelizerNotification::match(cmd))
|
||||||
{
|
{
|
||||||
UpChannelizer::MsgChannelizerNotification& notif = (UpChannelizer::MsgChannelizerNotification&) cmd;
|
UpChannelizer::MsgChannelizerNotification& notif = (UpChannelizer::MsgChannelizerNotification&) cmd;
|
||||||
|
qDebug() << "NFMMod::handleMessage: UpChannelizer::MsgChannelizerNotification";
|
||||||
|
|
||||||
NFMModSettings settings = m_settings;
|
applyChannelSettings(notif.getBasebandSampleRate(), notif.getSampleRate(), notif.getFrequencyOffset());
|
||||||
|
|
||||||
settings.m_basebandSampleRate = notif.getBasebandSampleRate();
|
|
||||||
settings.m_outputSampleRate = notif.getSampleRate();
|
|
||||||
settings.m_inputFrequencyOffset = notif.getFrequencyOffset();
|
|
||||||
|
|
||||||
applySettings(settings);
|
|
||||||
|
|
||||||
qDebug() << "NFMMod::handleMessage: UpChannelizer::MsgChannelizerNotification:"
|
|
||||||
<< " m_basebandSampleRate: " << settings.m_basebandSampleRate
|
|
||||||
<< " m_outputSampleRate: " << settings.m_outputSampleRate
|
|
||||||
<< " m_inputFrequencyOffset: " << settings.m_inputFrequencyOffset;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (MsgConfigureChannelizer::match(cmd))
|
else if (MsgConfigureChannelizer::match(cmd))
|
||||||
{
|
{
|
||||||
MsgConfigureChannelizer& cfg = (MsgConfigureChannelizer&) cmd;
|
MsgConfigureChannelizer& cfg = (MsgConfigureChannelizer&) cmd;
|
||||||
|
qDebug() << "NFMMod::handleMessage: MsgConfigureChannelizer:"
|
||||||
|
<< " getSampleRate: " << cfg.getSampleRate()
|
||||||
|
<< " getCenterFrequency: " << cfg.getCenterFrequency();
|
||||||
|
|
||||||
m_channelizer->configure(m_channelizer->getInputMessageQueue(),
|
m_channelizer->configure(m_channelizer->getInputMessageQueue(),
|
||||||
cfg.getSampleRate(),
|
cfg.getSampleRate(),
|
||||||
cfg.getCenterFrequency());
|
cfg.getCenterFrequency());
|
||||||
|
|
||||||
qDebug() << "NFMMod::handleMessage: MsgConfigureChannelizer:"
|
|
||||||
<< " getSampleRate: " << cfg.getSampleRate()
|
|
||||||
<< " getCenterFrequency: " << cfg.getCenterFrequency();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (MsgConfigureNFMMod::match(cmd))
|
else if (MsgConfigureNFMMod::match(cmd))
|
||||||
{
|
{
|
||||||
MsgConfigureNFMMod& cfg = (MsgConfigureNFMMod&) cmd;
|
MsgConfigureNFMMod& cfg = (MsgConfigureNFMMod&) cmd;
|
||||||
|
qDebug() << "NFMMod::handleMessage: MsgConfigureNFMMod";
|
||||||
|
|
||||||
NFMModSettings settings = cfg.getSettings();
|
applySettings(cfg.getSettings(), cfg.getForce());
|
||||||
|
|
||||||
m_absoluteFrequencyOffset = settings.m_inputFrequencyOffset;
|
|
||||||
settings.m_outputSampleRate = m_settings.m_outputSampleRate;
|
|
||||||
settings.m_inputFrequencyOffset = m_settings.m_inputFrequencyOffset;
|
|
||||||
|
|
||||||
qDebug() << "NFMMod::handleMessage: MsgConfigureNFMMod:"
|
|
||||||
<< " m_rfBandwidth: " << settings.m_rfBandwidth
|
|
||||||
<< " m_afBandwidth: " << settings.m_afBandwidth
|
|
||||||
<< " m_fmDeviation: " << settings.m_fmDeviation
|
|
||||||
<< " m_volumeFactor: " << settings.m_volumeFactor
|
|
||||||
<< " m_toneFrequency: " << settings.m_toneFrequency
|
|
||||||
<< " m_ctcssIndex: " << settings.m_ctcssIndex
|
|
||||||
<< " m_ctcssOn: " << settings.m_ctcssOn
|
|
||||||
<< " m_channelMute: " << settings.m_channelMute
|
|
||||||
<< " m_playLoop: " << settings.m_playLoop
|
|
||||||
<< " m_modAFInout " << settings.m_modAFInput
|
|
||||||
<< " force: " << cfg.getForce();
|
|
||||||
|
|
||||||
applySettings(settings, cfg.getForce());
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -412,24 +385,59 @@ void NFMMod::seekFileStream(int seekPercentage)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NFMMod::applySettings(const NFMModSettings& settings, bool force)
|
void NFMMod::applyChannelSettings(int basebandSampleRate, int outputSampleRate, int inputFrequencyOffset)
|
||||||
{
|
{
|
||||||
if ((settings.m_inputFrequencyOffset != m_settings.m_inputFrequencyOffset) ||
|
qDebug() << "NFMMod::applyChannelSettings:"
|
||||||
(settings.m_outputSampleRate != m_settings.m_outputSampleRate) || force)
|
<< " basebandSampleRate: " << basebandSampleRate
|
||||||
|
<< " outputSampleRate: " << outputSampleRate
|
||||||
|
<< " inputFrequencyOffset: " << inputFrequencyOffset;
|
||||||
|
|
||||||
|
if ((inputFrequencyOffset != m_inputFrequencyOffset) ||
|
||||||
|
(outputSampleRate != m_outputSampleRate))
|
||||||
{
|
{
|
||||||
m_settingsMutex.lock();
|
m_settingsMutex.lock();
|
||||||
m_carrierNco.setFreq(settings.m_inputFrequencyOffset, settings.m_outputSampleRate);
|
m_carrierNco.setFreq(inputFrequencyOffset, m_outputSampleRate);
|
||||||
m_settingsMutex.unlock();
|
m_settingsMutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
if((settings.m_outputSampleRate != m_settings.m_outputSampleRate) ||
|
if (outputSampleRate != m_outputSampleRate)
|
||||||
(settings.m_rfBandwidth != m_settings.m_rfBandwidth) ||
|
{
|
||||||
|
m_settingsMutex.lock();
|
||||||
|
m_interpolatorDistanceRemain = 0;
|
||||||
|
m_interpolatorConsumed = false;
|
||||||
|
m_interpolatorDistance = (Real) m_settings.m_audioSampleRate / (Real) outputSampleRate;
|
||||||
|
m_interpolator.create(48, m_settings.m_audioSampleRate, m_settings.m_rfBandwidth / 2.2, 3.0);
|
||||||
|
m_settingsMutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_basebandSampleRate = basebandSampleRate;
|
||||||
|
m_outputSampleRate = outputSampleRate;
|
||||||
|
m_inputFrequencyOffset = inputFrequencyOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NFMMod::applySettings(const NFMModSettings& settings, bool force)
|
||||||
|
{
|
||||||
|
qDebug() << "NFMMod::applySettings:"
|
||||||
|
<< " m_inputFrequencyOffset: " << settings.m_inputFrequencyOffset
|
||||||
|
<< " m_rfBandwidth: " << settings.m_rfBandwidth
|
||||||
|
<< " m_afBandwidth: " << settings.m_afBandwidth
|
||||||
|
<< " m_fmDeviation: " << settings.m_fmDeviation
|
||||||
|
<< " m_volumeFactor: " << settings.m_volumeFactor
|
||||||
|
<< " m_toneFrequency: " << settings.m_toneFrequency
|
||||||
|
<< " m_ctcssIndex: " << settings.m_ctcssIndex
|
||||||
|
<< " m_ctcssOn: " << settings.m_ctcssOn
|
||||||
|
<< " m_channelMute: " << settings.m_channelMute
|
||||||
|
<< " m_playLoop: " << settings.m_playLoop
|
||||||
|
<< " m_modAFInout " << settings.m_modAFInput
|
||||||
|
<< " force: " << force;
|
||||||
|
|
||||||
|
if((settings.m_rfBandwidth != m_settings.m_rfBandwidth) ||
|
||||||
(settings.m_audioSampleRate != m_settings.m_audioSampleRate) || 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) settings.m_outputSampleRate;
|
m_interpolatorDistance = (Real) settings.m_audioSampleRate / (Real) m_outputSampleRate;
|
||||||
m_interpolator.create(48, settings.m_audioSampleRate, settings.m_rfBandwidth / 2.2, 3.0);
|
m_interpolator.create(48, settings.m_audioSampleRate, settings.m_rfBandwidth / 2.2, 3.0);
|
||||||
m_settingsMutex.unlock();
|
m_settingsMutex.unlock();
|
||||||
}
|
}
|
||||||
@ -499,14 +507,12 @@ int NFMMod::webapiSettingsGet(
|
|||||||
response.setNfmModSettings(new SWGSDRangel::SWGNFMModSettings());
|
response.setNfmModSettings(new SWGSDRangel::SWGNFMModSettings());
|
||||||
response.getNfmModSettings()->setAfBandwidth(m_settings.m_afBandwidth);
|
response.getNfmModSettings()->setAfBandwidth(m_settings.m_afBandwidth);
|
||||||
response.getNfmModSettings()->setAudioSampleRate(m_settings.m_audioSampleRate);
|
response.getNfmModSettings()->setAudioSampleRate(m_settings.m_audioSampleRate);
|
||||||
response.getNfmModSettings()->setBasebandSampleRate(m_settings.m_basebandSampleRate);
|
|
||||||
response.getNfmModSettings()->setChannelMute(m_settings.m_channelMute ? 1 : 0);
|
response.getNfmModSettings()->setChannelMute(m_settings.m_channelMute ? 1 : 0);
|
||||||
response.getNfmModSettings()->setCtcssIndex(m_settings.m_ctcssIndex);
|
response.getNfmModSettings()->setCtcssIndex(m_settings.m_ctcssIndex);
|
||||||
response.getNfmModSettings()->setCtcssOn(m_settings.m_ctcssOn ? 1 : 0);
|
response.getNfmModSettings()->setCtcssOn(m_settings.m_ctcssOn ? 1 : 0);
|
||||||
response.getNfmModSettings()->setFmDeviation(m_settings.m_fmDeviation);
|
response.getNfmModSettings()->setFmDeviation(m_settings.m_fmDeviation);
|
||||||
response.getNfmModSettings()->setInputFrequencyOffset(m_settings.m_inputFrequencyOffset);
|
response.getNfmModSettings()->setInputFrequencyOffset(m_settings.m_inputFrequencyOffset);
|
||||||
response.getNfmModSettings()->setModAfInput((int) m_settings.m_modAFInput);
|
response.getNfmModSettings()->setModAfInput((int) m_settings.m_modAFInput);
|
||||||
response.getNfmModSettings()->setOutputSampleRate(m_settings.m_outputSampleRate);
|
|
||||||
response.getNfmModSettings()->setPlayLoop(m_settings.m_playLoop ? 1 : 0);
|
response.getNfmModSettings()->setPlayLoop(m_settings.m_playLoop ? 1 : 0);
|
||||||
response.getNfmModSettings()->setRfBandwidth(m_settings.m_rfBandwidth);
|
response.getNfmModSettings()->setRfBandwidth(m_settings.m_rfBandwidth);
|
||||||
response.getNfmModSettings()->setRgbColor(m_settings.m_rgbColor);
|
response.getNfmModSettings()->setRgbColor(m_settings.m_rgbColor);
|
||||||
@ -542,9 +548,6 @@ int NFMMod::webapiSettingsPutPatch(
|
|||||||
if (channelSettingsKeys.contains("audioSampleRate")) {
|
if (channelSettingsKeys.contains("audioSampleRate")) {
|
||||||
settings.m_audioSampleRate = response.getNfmModSettings()->getAudioSampleRate();
|
settings.m_audioSampleRate = response.getNfmModSettings()->getAudioSampleRate();
|
||||||
}
|
}
|
||||||
if (channelSettingsKeys.contains("basebandSampleRate")) {
|
|
||||||
settings.m_basebandSampleRate = response.getNfmModSettings()->getBasebandSampleRate();
|
|
||||||
}
|
|
||||||
if (channelSettingsKeys.contains("channelMute")) {
|
if (channelSettingsKeys.contains("channelMute")) {
|
||||||
settings.m_channelMute = response.getNfmModSettings()->getChannelMute() != 0;
|
settings.m_channelMute = response.getNfmModSettings()->getChannelMute() != 0;
|
||||||
}
|
}
|
||||||
@ -565,9 +568,6 @@ int NFMMod::webapiSettingsPutPatch(
|
|||||||
if (channelSettingsKeys.contains("modAFInput")) {
|
if (channelSettingsKeys.contains("modAFInput")) {
|
||||||
settings.m_modAFInput = (NFMModSettings::NFMModInputAF) response.getNfmModSettings()->getModAfInput();
|
settings.m_modAFInput = (NFMModSettings::NFMModInputAF) response.getNfmModSettings()->getModAfInput();
|
||||||
}
|
}
|
||||||
if (channelSettingsKeys.contains("outputSampleRate")) {
|
|
||||||
settings.m_outputSampleRate = response.getNfmModSettings()->getOutputSampleRate();
|
|
||||||
}
|
|
||||||
if (channelSettingsKeys.contains("playLoop")) {
|
if (channelSettingsKeys.contains("playLoop")) {
|
||||||
settings.m_playLoop = response.getNfmModSettings()->getPlayLoop() != 0;
|
settings.m_playLoop = response.getNfmModSettings()->getPlayLoop() != 0;
|
||||||
}
|
}
|
||||||
|
@ -263,8 +263,10 @@ private:
|
|||||||
ThreadedBasebandSampleSource* m_threadedChannelizer;
|
ThreadedBasebandSampleSource* m_threadedChannelizer;
|
||||||
UpChannelizer* m_channelizer;
|
UpChannelizer* m_channelizer;
|
||||||
|
|
||||||
|
int m_basebandSampleRate;
|
||||||
|
int m_outputSampleRate;
|
||||||
|
int m_inputFrequencyOffset;
|
||||||
NFMModSettings m_settings;
|
NFMModSettings m_settings;
|
||||||
int m_absoluteFrequencyOffset;
|
|
||||||
|
|
||||||
NCO m_carrierNco;
|
NCO m_carrierNco;
|
||||||
NCOF m_toneNco;
|
NCOF m_toneNco;
|
||||||
@ -302,7 +304,7 @@ private:
|
|||||||
CWKeyer m_cwKeyer;
|
CWKeyer m_cwKeyer;
|
||||||
static const int m_levelNbSamples;
|
static const int m_levelNbSamples;
|
||||||
|
|
||||||
//void apply();
|
void applyChannelSettings(int basebandSampleRate, int outputSampleRate, int inputFrequencyOffset);
|
||||||
void applySettings(const NFMModSettings& settings, bool force = false);
|
void applySettings(const NFMModSettings& settings, bool force = false);
|
||||||
void pullAF(Real& sample);
|
void pullAF(Real& sample);
|
||||||
void calculateLevel(Real& sample);
|
void calculateLevel(Real& sample);
|
||||||
|
@ -46,8 +46,6 @@ NFMModSettings::NFMModSettings() :
|
|||||||
void NFMModSettings::resetToDefaults()
|
void NFMModSettings::resetToDefaults()
|
||||||
{
|
{
|
||||||
m_afBandwidth = 3000;
|
m_afBandwidth = 3000;
|
||||||
m_basebandSampleRate = 48000;
|
|
||||||
m_outputSampleRate = 48000;
|
|
||||||
m_inputFrequencyOffset = 0;
|
m_inputFrequencyOffset = 0;
|
||||||
m_rfBandwidth = 12500.0f;
|
m_rfBandwidth = 12500.0f;
|
||||||
m_fmDeviation = 5000.0f;
|
m_fmDeviation = 5000.0f;
|
||||||
|
@ -37,8 +37,6 @@ struct NFMModSettings
|
|||||||
static const int m_nbCTCSSFreqs;
|
static const int m_nbCTCSSFreqs;
|
||||||
static const float m_ctcssFreqs[];
|
static const float m_ctcssFreqs[];
|
||||||
|
|
||||||
int m_basebandSampleRate;
|
|
||||||
int m_outputSampleRate;
|
|
||||||
qint64 m_inputFrequencyOffset;
|
qint64 m_inputFrequencyOffset;
|
||||||
Real m_rfBandwidth;
|
Real m_rfBandwidth;
|
||||||
Real m_afBandwidth;
|
Real m_afBandwidth;
|
||||||
|
@ -45,7 +45,9 @@ const int SSBMod::m_ssbFftLen = 1024;
|
|||||||
SSBMod::SSBMod(DeviceSinkAPI *deviceAPI) :
|
SSBMod::SSBMod(DeviceSinkAPI *deviceAPI) :
|
||||||
ChannelSourceAPI(m_channelIdURI),
|
ChannelSourceAPI(m_channelIdURI),
|
||||||
m_deviceAPI(deviceAPI),
|
m_deviceAPI(deviceAPI),
|
||||||
m_absoluteFrequencyOffset(0),
|
m_basebandSampleRate(48000),
|
||||||
|
m_outputSampleRate(48000),
|
||||||
|
m_inputFrequencyOffset(0),
|
||||||
m_SSBFilter(0),
|
m_SSBFilter(0),
|
||||||
m_DSBFilter(0),
|
m_DSBFilter(0),
|
||||||
m_SSBFilterBuffer(0),
|
m_SSBFilterBuffer(0),
|
||||||
@ -172,7 +174,7 @@ void SSBMod::pull(Sample& sample)
|
|||||||
|
|
||||||
void SSBMod::pullAudio(int nbSamples)
|
void SSBMod::pullAudio(int nbSamples)
|
||||||
{
|
{
|
||||||
unsigned int nbSamplesAudio = nbSamples * ((Real) m_settings.m_audioSampleRate / (Real) m_settings.m_basebandSampleRate);
|
unsigned int nbSamplesAudio = nbSamples * ((Real) m_settings.m_audioSampleRate / (Real) m_basebandSampleRate);
|
||||||
|
|
||||||
if (nbSamplesAudio > m_audioBuffer.size())
|
if (nbSamplesAudio > m_audioBuffer.size())
|
||||||
{
|
{
|
||||||
@ -522,7 +524,7 @@ void SSBMod::calculateLevel(Complex& sample)
|
|||||||
|
|
||||||
void SSBMod::start()
|
void SSBMod::start()
|
||||||
{
|
{
|
||||||
qDebug() << "SSBMod::start: m_outputSampleRate: " << m_settings.m_outputSampleRate
|
qDebug() << "SSBMod::start: m_outputSampleRate: " << m_outputSampleRate
|
||||||
<< " m_inputFrequencyOffset: " << m_settings.m_inputFrequencyOffset;
|
<< " m_inputFrequencyOffset: " << m_settings.m_inputFrequencyOffset;
|
||||||
|
|
||||||
m_audioFifo.clear();
|
m_audioFifo.clear();
|
||||||
@ -537,98 +539,30 @@ bool SSBMod::handleMessage(const Message& cmd)
|
|||||||
if (UpChannelizer::MsgChannelizerNotification::match(cmd))
|
if (UpChannelizer::MsgChannelizerNotification::match(cmd))
|
||||||
{
|
{
|
||||||
UpChannelizer::MsgChannelizerNotification& notif = (UpChannelizer::MsgChannelizerNotification&) cmd;
|
UpChannelizer::MsgChannelizerNotification& notif = (UpChannelizer::MsgChannelizerNotification&) cmd;
|
||||||
|
qDebug() << "SSBMod::handleMessage: MsgChannelizerNotification";
|
||||||
|
|
||||||
SSBModSettings settings = m_settings;
|
applyChannelSettings(notif.getBasebandSampleRate(), notif.getSampleRate(), notif.getFrequencyOffset());
|
||||||
|
|
||||||
settings.m_basebandSampleRate = notif.getBasebandSampleRate();
|
|
||||||
settings.m_outputSampleRate = notif.getSampleRate();
|
|
||||||
settings.m_inputFrequencyOffset = notif.getFrequencyOffset();
|
|
||||||
|
|
||||||
applySettings(settings);
|
|
||||||
|
|
||||||
qDebug() << "SSBMod::handleMessage: MsgChannelizerNotification:"
|
|
||||||
<< " m_basebandSampleRate: " << settings.m_basebandSampleRate
|
|
||||||
<< " m_outputSampleRate: " << settings.m_outputSampleRate
|
|
||||||
<< " m_inputFrequencyOffset: " << settings.m_inputFrequencyOffset;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (MsgConfigureChannelizer::match(cmd))
|
else if (MsgConfigureChannelizer::match(cmd))
|
||||||
{
|
{
|
||||||
MsgConfigureChannelizer& cfg = (MsgConfigureChannelizer&) cmd;
|
MsgConfigureChannelizer& cfg = (MsgConfigureChannelizer&) cmd;
|
||||||
|
qDebug() << "SSBMod::handleMessage: MsgConfigureChannelizer: sampleRate: " << cfg.getSampleRate()
|
||||||
|
<< " centerFrequency: " << cfg.getCenterFrequency();
|
||||||
|
|
||||||
m_channelizer->configure(m_channelizer->getInputMessageQueue(),
|
m_channelizer->configure(m_channelizer->getInputMessageQueue(),
|
||||||
cfg.getSampleRate(),
|
cfg.getSampleRate(),
|
||||||
cfg.getCenterFrequency());
|
cfg.getCenterFrequency());
|
||||||
|
|
||||||
qDebug() << "SSBMod::handleMessage: MsgConfigureChannelizer: sampleRate: " << cfg.getSampleRate()
|
|
||||||
<< " centerFrequency: " << cfg.getCenterFrequency();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (MsgConfigureSSBMod::match(cmd))
|
else if (MsgConfigureSSBMod::match(cmd))
|
||||||
{
|
{
|
||||||
float band, lowCutoff;
|
|
||||||
MsgConfigureSSBMod& cfg = (MsgConfigureSSBMod&) cmd;
|
MsgConfigureSSBMod& cfg = (MsgConfigureSSBMod&) cmd;
|
||||||
|
qDebug() << "SSBMod::handleMessage: MsgConfigureSSBMod";
|
||||||
|
|
||||||
SSBModSettings settings = cfg.getSettings();
|
applySettings(cfg.getSettings(), cfg.getForce());
|
||||||
|
|
||||||
// These settings are set with UpChannelizer::MsgChannelizerNotification
|
|
||||||
m_absoluteFrequencyOffset = settings.m_inputFrequencyOffset;
|
|
||||||
settings.m_basebandSampleRate = m_settings.m_basebandSampleRate;
|
|
||||||
settings.m_outputSampleRate = m_settings.m_outputSampleRate;
|
|
||||||
settings.m_inputFrequencyOffset = m_settings.m_inputFrequencyOffset;
|
|
||||||
|
|
||||||
band = settings.m_bandwidth;
|
|
||||||
lowCutoff = settings.m_lowCutoff;
|
|
||||||
|
|
||||||
if (band < 0) // negative means LSB
|
|
||||||
{
|
|
||||||
band = -band; // turn to positive
|
|
||||||
lowCutoff = -lowCutoff;
|
|
||||||
settings.m_usb = false; // and take note of side band
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
settings.m_usb = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (band < 100.0f) // at least 100 Hz
|
|
||||||
{
|
|
||||||
band = 100.0f;
|
|
||||||
lowCutoff = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (band - lowCutoff < 100.0f) {
|
|
||||||
lowCutoff = band - 100.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
settings.m_bandwidth = band;
|
|
||||||
settings.m_lowCutoff = lowCutoff;
|
|
||||||
|
|
||||||
applySettings(settings, cfg.getForce());
|
|
||||||
|
|
||||||
qDebug() << "SSBMod::handleMessage: MsgConfigureSSBMod:"
|
|
||||||
<< " m_bandwidth: " << settings.m_bandwidth
|
|
||||||
<< " m_lowCutoff: " << settings.m_lowCutoff
|
|
||||||
<< " m_toneFrequency: " << settings.m_toneFrequency
|
|
||||||
<< " m_volumeFactor: " << settings.m_volumeFactor
|
|
||||||
<< " m_spanLog2: " << settings.m_spanLog2
|
|
||||||
<< " m_outputSampleRate: " << m_settings.m_outputSampleRate
|
|
||||||
<< " m_audioSampleRate: " << settings.m_audioSampleRate
|
|
||||||
<< " m_audioBinaural: " << settings.m_audioBinaural
|
|
||||||
<< " m_audioFlipChannels: " << settings.m_audioFlipChannels
|
|
||||||
<< " m_dsb: " << settings.m_dsb
|
|
||||||
<< " m_audioMute: " << settings.m_audioMute
|
|
||||||
<< " m_playLoop: " << settings.m_playLoop
|
|
||||||
<< " m_agc: " << settings.m_agc
|
|
||||||
<< " m_agcTime: " << settings.m_agcTime
|
|
||||||
<< " m_agcOrder: " << settings.m_agcOrder
|
|
||||||
<< " m_agcThresholdEnable: " << settings.m_agcThresholdEnable
|
|
||||||
<< " m_agcThreshold: " << settings.m_agcThreshold
|
|
||||||
<< " m_agcThresholdGate: " << settings.m_agcThresholdGate
|
|
||||||
<< " m_agcThresholdDelay: " << settings.m_agcThresholdDelay
|
|
||||||
<< " force: " << cfg.getForce();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -711,35 +645,74 @@ void SSBMod::seekFileStream(int seekPercentage)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSBMod::applySettings(const SSBModSettings& settings, bool force)
|
void SSBMod::applyChannelSettings(int basebandSampleRate, int outputSampleRate, int inputFrequencyOffset)
|
||||||
{
|
{
|
||||||
if ((settings.m_bandwidth != m_settings.m_bandwidth) ||
|
qDebug() << "SSBMod::applyChannelSettings:"
|
||||||
(settings.m_lowCutoff != m_settings.m_lowCutoff) ||
|
<< " basebandSampleRate: " << basebandSampleRate
|
||||||
(settings.m_audioSampleRate != m_settings.m_audioSampleRate) || force)
|
<< " outputSampleRate: " << outputSampleRate
|
||||||
|
<< " inputFrequencyOffset: " << inputFrequencyOffset;
|
||||||
|
|
||||||
|
if ((inputFrequencyOffset != m_inputFrequencyOffset) ||
|
||||||
|
(outputSampleRate != m_outputSampleRate))
|
||||||
{
|
{
|
||||||
m_settingsMutex.lock();
|
m_settingsMutex.lock();
|
||||||
m_SSBFilter->create_filter(settings.m_lowCutoff / settings.m_audioSampleRate, settings.m_bandwidth / settings.m_audioSampleRate);
|
m_carrierNco.setFreq(inputFrequencyOffset, outputSampleRate);
|
||||||
m_DSBFilter->create_dsb_filter((2.0f * settings.m_bandwidth) / settings.m_audioSampleRate);
|
|
||||||
m_settingsMutex.unlock();
|
m_settingsMutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((settings.m_inputFrequencyOffset != m_settings.m_inputFrequencyOffset) ||
|
if (outputSampleRate != m_outputSampleRate)
|
||||||
(settings.m_outputSampleRate != m_settings.m_outputSampleRate) || force)
|
|
||||||
{
|
|
||||||
m_settingsMutex.lock();
|
|
||||||
m_carrierNco.setFreq(settings.m_inputFrequencyOffset, settings.m_outputSampleRate);
|
|
||||||
m_settingsMutex.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
if((settings.m_outputSampleRate != m_settings.m_outputSampleRate) ||
|
|
||||||
(settings.m_bandwidth != m_settings.m_bandwidth) ||
|
|
||||||
(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) settings.m_outputSampleRate;
|
m_interpolatorDistance = (Real) m_settings.m_audioSampleRate / (Real) m_outputSampleRate;
|
||||||
m_interpolator.create(48, settings.m_audioSampleRate, settings.m_bandwidth, 3.0);
|
m_interpolator.create(48, m_settings.m_audioSampleRate, m_settings.m_bandwidth, 3.0);
|
||||||
|
m_settingsMutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_basebandSampleRate = basebandSampleRate;
|
||||||
|
m_outputSampleRate = outputSampleRate;
|
||||||
|
m_inputFrequencyOffset = inputFrequencyOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SSBMod::applySettings(const SSBModSettings& settings, bool force)
|
||||||
|
{
|
||||||
|
float band = settings.m_bandwidth;
|
||||||
|
float lowCutoff = settings.m_lowCutoff;
|
||||||
|
bool usb = settings.m_usb;
|
||||||
|
|
||||||
|
if ((settings.m_bandwidth != m_settings.m_bandwidth) ||
|
||||||
|
(settings.m_lowCutoff != m_settings.m_lowCutoff) ||
|
||||||
|
(settings.m_audioSampleRate != m_settings.m_audioSampleRate) || force)
|
||||||
|
{
|
||||||
|
if (band < 0) // negative means LSB
|
||||||
|
{
|
||||||
|
band = -band; // turn to positive
|
||||||
|
lowCutoff = -lowCutoff;
|
||||||
|
usb = false; // and take note of side band
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
usb = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (band < 100.0f) // at least 100 Hz
|
||||||
|
{
|
||||||
|
band = 100.0f;
|
||||||
|
lowCutoff = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (band - lowCutoff < 100.0f) {
|
||||||
|
lowCutoff = band - 100.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_settingsMutex.lock();
|
||||||
|
m_interpolatorDistanceRemain = 0;
|
||||||
|
m_interpolatorConsumed = false;
|
||||||
|
m_interpolatorDistance = (Real) settings.m_audioSampleRate / (Real) m_outputSampleRate;
|
||||||
|
m_interpolator.create(48, settings.m_audioSampleRate, band, 3.0);
|
||||||
|
m_SSBFilter->create_filter(lowCutoff / settings.m_audioSampleRate, band / settings.m_audioSampleRate);
|
||||||
|
m_DSBFilter->create_dsb_filter((2.0f * band) / settings.m_audioSampleRate);
|
||||||
m_settingsMutex.unlock();
|
m_settingsMutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -799,6 +772,9 @@ void SSBMod::applySettings(const SSBModSettings& settings, bool force)
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_settings = settings;
|
m_settings = settings;
|
||||||
|
m_settings.m_bandwidth = band;
|
||||||
|
m_settings.m_lowCutoff = lowCutoff;
|
||||||
|
m_settings.m_usb = usb;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray SSBMod::serialize() const
|
QByteArray SSBMod::serialize() const
|
||||||
|
@ -275,8 +275,10 @@ private:
|
|||||||
ThreadedBasebandSampleSource* m_threadedChannelizer;
|
ThreadedBasebandSampleSource* m_threadedChannelizer;
|
||||||
UpChannelizer* m_channelizer;
|
UpChannelizer* m_channelizer;
|
||||||
|
|
||||||
|
int m_basebandSampleRate;
|
||||||
|
int m_outputSampleRate;
|
||||||
|
int m_inputFrequencyOffset;
|
||||||
SSBModSettings m_settings;
|
SSBModSettings m_settings;
|
||||||
int m_absoluteFrequencyOffset;
|
|
||||||
|
|
||||||
NCOF m_carrierNco;
|
NCOF m_carrierNco;
|
||||||
NCOF m_toneNco;
|
NCOF m_toneNco;
|
||||||
@ -325,6 +327,7 @@ private:
|
|||||||
|
|
||||||
static const int m_levelNbSamples;
|
static const int m_levelNbSamples;
|
||||||
|
|
||||||
|
void applyChannelSettings(int basebandSampleRate, int outputSampleRate, int inputFrequencyOffset);
|
||||||
void applySettings(const SSBModSettings& settings, bool force = false);
|
void applySettings(const SSBModSettings& settings, bool force = false);
|
||||||
void pullAF(Complex& sample);
|
void pullAF(Complex& sample);
|
||||||
void calculateLevel(Complex& sample);
|
void calculateLevel(Complex& sample);
|
||||||
|
@ -45,8 +45,6 @@ SSBModSettings::SSBModSettings() :
|
|||||||
|
|
||||||
void SSBModSettings::resetToDefaults()
|
void SSBModSettings::resetToDefaults()
|
||||||
{
|
{
|
||||||
m_basebandSampleRate = 48000;
|
|
||||||
m_outputSampleRate = 48000;
|
|
||||||
m_inputFrequencyOffset = 0;
|
m_inputFrequencyOffset = 0;
|
||||||
m_bandwidth = 3000.0;
|
m_bandwidth = 3000.0;
|
||||||
m_lowCutoff = 300.0;
|
m_lowCutoff = 300.0;
|
||||||
|
@ -28,8 +28,6 @@ struct SSBModSettings
|
|||||||
static const int m_nbAGCTimeConstants;
|
static const int m_nbAGCTimeConstants;
|
||||||
static const int m_agcTimeConstant[];
|
static const int m_agcTimeConstant[];
|
||||||
|
|
||||||
int m_basebandSampleRate;
|
|
||||||
int m_outputSampleRate;
|
|
||||||
qint64 m_inputFrequencyOffset;
|
qint64 m_inputFrequencyOffset;
|
||||||
Real m_bandwidth;
|
Real m_bandwidth;
|
||||||
Real m_lowCutoff;
|
Real m_lowCutoff;
|
||||||
|
@ -47,6 +47,9 @@ const int WFMMod::m_rfFilterFFTLength = 1024;
|
|||||||
WFMMod::WFMMod(DeviceSinkAPI *deviceAPI) :
|
WFMMod::WFMMod(DeviceSinkAPI *deviceAPI) :
|
||||||
ChannelSourceAPI(m_channelIdURI),
|
ChannelSourceAPI(m_channelIdURI),
|
||||||
m_deviceAPI(deviceAPI),
|
m_deviceAPI(deviceAPI),
|
||||||
|
m_basebandSampleRate(384000),
|
||||||
|
m_outputSampleRate(384000),
|
||||||
|
m_inputFrequencyOffset(0),
|
||||||
m_modPhasor(0.0f),
|
m_modPhasor(0.0f),
|
||||||
m_movingAverage(40, 0),
|
m_movingAverage(40, 0),
|
||||||
m_volumeAGC(40, 0),
|
m_volumeAGC(40, 0),
|
||||||
@ -75,11 +78,11 @@ WFMMod::WFMMod(DeviceSinkAPI *deviceAPI) :
|
|||||||
m_magsq = 0.0;
|
m_magsq = 0.0;
|
||||||
|
|
||||||
m_toneNco.setFreq(1000.0, m_settings.m_audioSampleRate);
|
m_toneNco.setFreq(1000.0, m_settings.m_audioSampleRate);
|
||||||
m_toneNcoRF.setFreq(1000.0, m_settings.m_outputSampleRate);
|
m_toneNcoRF.setFreq(1000.0, m_outputSampleRate);
|
||||||
DSPEngine::instance()->addAudioSource(&m_audioFifo);
|
DSPEngine::instance()->addAudioSource(&m_audioFifo);
|
||||||
|
|
||||||
// CW keyer
|
// CW keyer
|
||||||
m_cwKeyer.setSampleRate(m_settings.m_outputSampleRate);
|
m_cwKeyer.setSampleRate(m_outputSampleRate);
|
||||||
m_cwKeyer.setWPM(13);
|
m_cwKeyer.setWPM(13);
|
||||||
m_cwKeyer.setMode(CWKeyerSettings::CWNone);
|
m_cwKeyer.setMode(CWKeyerSettings::CWNone);
|
||||||
m_cwKeyer.reset();
|
m_cwKeyer.reset();
|
||||||
@ -134,7 +137,7 @@ void WFMMod::pull(Sample& sample)
|
|||||||
pullAF(ri);
|
pullAF(ri);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_modPhasor += (m_settings.m_fmDeviation / (float) m_settings.m_outputSampleRate) * ri.real() * M_PI * 2.0f;
|
m_modPhasor += (m_settings.m_fmDeviation / (float) m_outputSampleRate) * ri.real() * M_PI * 2.0f;
|
||||||
ci.real(cos(m_modPhasor) * 29204.0f); // -1 dB
|
ci.real(cos(m_modPhasor) * 29204.0f); // -1 dB
|
||||||
ci.imag(sin(m_modPhasor) * 29204.0f);
|
ci.imag(sin(m_modPhasor) * 29204.0f);
|
||||||
|
|
||||||
@ -164,7 +167,7 @@ void WFMMod::pull(Sample& sample)
|
|||||||
|
|
||||||
void WFMMod::pullAudio(int nbSamples)
|
void WFMMod::pullAudio(int nbSamples)
|
||||||
{
|
{
|
||||||
unsigned int nbSamplesAudio = nbSamples * ((Real) m_settings.m_audioSampleRate / (Real) m_settings.m_basebandSampleRate);
|
unsigned int nbSamplesAudio = nbSamples * ((Real) m_settings.m_audioSampleRate / (Real) m_basebandSampleRate);
|
||||||
|
|
||||||
if (nbSamplesAudio > m_audioBuffer.size())
|
if (nbSamplesAudio > m_audioBuffer.size())
|
||||||
{
|
{
|
||||||
@ -275,8 +278,8 @@ void WFMMod::calculateLevel(const Real& sample)
|
|||||||
|
|
||||||
void WFMMod::start()
|
void WFMMod::start()
|
||||||
{
|
{
|
||||||
qDebug() << "WFMMod::start: m_outputSampleRate: " << m_settings.m_outputSampleRate
|
qDebug() << "WFMMod::start: m_outputSampleRate: " << m_outputSampleRate
|
||||||
<< " m_inputFrequencyOffset: " << m_settings.m_inputFrequencyOffset;
|
<< " m_inputFrequencyOffset: " << m_inputFrequencyOffset;
|
||||||
|
|
||||||
m_audioFifo.clear();
|
m_audioFifo.clear();
|
||||||
}
|
}
|
||||||
@ -290,58 +293,33 @@ bool WFMMod::handleMessage(const Message& cmd)
|
|||||||
if (UpChannelizer::MsgChannelizerNotification::match(cmd))
|
if (UpChannelizer::MsgChannelizerNotification::match(cmd))
|
||||||
{
|
{
|
||||||
UpChannelizer::MsgChannelizerNotification& notif = (UpChannelizer::MsgChannelizerNotification&) cmd;
|
UpChannelizer::MsgChannelizerNotification& notif = (UpChannelizer::MsgChannelizerNotification&) cmd;
|
||||||
|
qDebug() << "WFMMod::handleMessage: MsgChannelizerNotification";
|
||||||
|
|
||||||
WFMModSettings settings = m_settings;
|
applyChannelSettings(notif.getBasebandSampleRate(), notif.getSampleRate(), notif.getFrequencyOffset());
|
||||||
|
|
||||||
settings.m_basebandSampleRate = notif.getBasebandSampleRate();
|
|
||||||
settings.m_outputSampleRate = notif.getSampleRate();
|
|
||||||
settings.m_inputFrequencyOffset = notif.getFrequencyOffset();
|
|
||||||
|
|
||||||
applySettings(settings);
|
|
||||||
|
|
||||||
qDebug() << "WFMMod::handleMessage: MsgChannelizerNotification:"
|
|
||||||
<< " m_basebandSampleRate: " << settings.m_basebandSampleRate
|
|
||||||
<< " m_outputSampleRate: " << settings.m_outputSampleRate
|
|
||||||
<< " m_inputFrequencyOffset: " << settings.m_inputFrequencyOffset;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (MsgConfigureChannelizer::match(cmd))
|
else if (MsgConfigureChannelizer::match(cmd))
|
||||||
{
|
{
|
||||||
MsgConfigureChannelizer& cfg = (MsgConfigureChannelizer&) cmd;
|
MsgConfigureChannelizer& cfg = (MsgConfigureChannelizer&) cmd;
|
||||||
|
qDebug() << "WFMMod::handleMessage: MsgConfigureChannelizer:"
|
||||||
|
<< " getSampleRate: " << cfg.getSampleRate()
|
||||||
|
<< " getCenterFrequency: " << cfg.getCenterFrequency();
|
||||||
|
|
||||||
m_channelizer->configure(m_channelizer->getInputMessageQueue(),
|
m_channelizer->configure(m_channelizer->getInputMessageQueue(),
|
||||||
cfg.getSampleRate(),
|
cfg.getSampleRate(),
|
||||||
cfg.getCenterFrequency());
|
cfg.getCenterFrequency());
|
||||||
|
|
||||||
qDebug() << "WFMMod::handleMessage: MsgConfigureChannelizer:"
|
|
||||||
<< " getSampleRate: " << cfg.getSampleRate()
|
|
||||||
<< " getCenterFrequency: " << cfg.getCenterFrequency();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (MsgConfigureWFMMod::match(cmd))
|
else if (MsgConfigureWFMMod::match(cmd))
|
||||||
{
|
{
|
||||||
MsgConfigureWFMMod& cfg = (MsgConfigureWFMMod&) cmd;
|
MsgConfigureWFMMod& cfg = (MsgConfigureWFMMod&) cmd;
|
||||||
|
qDebug() << "NFWFMMod::handleMessage: MsgConfigureWFMMod";
|
||||||
|
|
||||||
WFMModSettings settings = cfg.getSettings();
|
WFMModSettings settings = cfg.getSettings();
|
||||||
|
|
||||||
m_absoluteFrequencyOffset = settings.m_inputFrequencyOffset;
|
applySettings(cfg.getSettings(), cfg.getForce());
|
||||||
settings.m_basebandSampleRate = m_settings.m_basebandSampleRate;
|
|
||||||
settings.m_outputSampleRate = m_settings.m_outputSampleRate;
|
|
||||||
settings.m_inputFrequencyOffset = m_settings.m_inputFrequencyOffset;
|
|
||||||
|
|
||||||
qDebug() << "NFWFMMod::handleMessage: MsgConfigureWFMMod:"
|
|
||||||
<< " m_rfBandwidth: " << settings.m_rfBandwidth
|
|
||||||
<< " m_afBandwidth: " << settings.m_afBandwidth
|
|
||||||
<< " m_fmDeviation: " << settings.m_fmDeviation
|
|
||||||
<< " m_volumeFactor: " << settings.m_volumeFactor
|
|
||||||
<< " m_toneFrequency: " << settings.m_toneFrequency
|
|
||||||
<< " m_channelMute: " << settings.m_channelMute
|
|
||||||
<< " m_playLoop: " << settings.m_playLoop
|
|
||||||
<< " force: " << cfg.getForce();
|
|
||||||
|
|
||||||
applySettings(settings, cfg.getForce());
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -424,34 +402,71 @@ void WFMMod::seekFileStream(int seekPercentage)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WFMMod::applySettings(const WFMModSettings& settings, bool force)
|
void WFMMod::applyChannelSettings(int basebandSampleRate, int outputSampleRate, int inputFrequencyOffset)
|
||||||
{
|
{
|
||||||
if ((settings.m_inputFrequencyOffset != m_settings.m_inputFrequencyOffset) ||
|
qDebug() << "WFMMod::applyChannelSettings:"
|
||||||
(settings.m_outputSampleRate != m_settings.m_outputSampleRate))
|
<< " basebandSampleRate: " << basebandSampleRate
|
||||||
|
<< " outputSampleRate: " << outputSampleRate
|
||||||
|
<< " inputFrequencyOffset: " << inputFrequencyOffset;
|
||||||
|
|
||||||
|
if ((inputFrequencyOffset != m_inputFrequencyOffset) ||
|
||||||
|
(outputSampleRate != m_outputSampleRate))
|
||||||
{
|
{
|
||||||
m_settingsMutex.lock();
|
m_settingsMutex.lock();
|
||||||
m_carrierNco.setFreq(settings.m_inputFrequencyOffset, settings.m_outputSampleRate);
|
m_carrierNco.setFreq(inputFrequencyOffset, outputSampleRate);
|
||||||
m_settingsMutex.unlock();
|
m_settingsMutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
if((settings.m_outputSampleRate != m_settings.m_outputSampleRate) ||
|
if (outputSampleRate != m_outputSampleRate)
|
||||||
(settings.m_audioSampleRate != m_settings.m_audioSampleRate) ||
|
{
|
||||||
|
m_settingsMutex.lock();
|
||||||
|
m_interpolatorDistanceRemain = 0;
|
||||||
|
m_interpolatorConsumed = false;
|
||||||
|
m_interpolatorDistance = (Real) m_settings.m_audioSampleRate / (Real) outputSampleRate;
|
||||||
|
m_interpolator.create(48, m_settings.m_audioSampleRate, m_settings.m_rfBandwidth / 2.2, 3.0);
|
||||||
|
Real lowCut = -(m_settings.m_rfBandwidth / 2.0) / m_outputSampleRate;
|
||||||
|
Real hiCut = (m_settings.m_rfBandwidth / 2.0) / m_outputSampleRate;
|
||||||
|
m_rfFilter->create_filter(lowCut, hiCut);
|
||||||
|
m_toneNcoRF.setFreq(m_settings.m_toneFrequency, m_outputSampleRate);
|
||||||
|
m_cwKeyer.setSampleRate(m_outputSampleRate);
|
||||||
|
m_cwKeyer.reset();
|
||||||
|
m_settingsMutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_basebandSampleRate = basebandSampleRate;
|
||||||
|
m_outputSampleRate = outputSampleRate;
|
||||||
|
m_inputFrequencyOffset = inputFrequencyOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFMMod::applySettings(const WFMModSettings& settings, bool force)
|
||||||
|
{
|
||||||
|
qDebug() << "WFMMod::applySettings:"
|
||||||
|
<< " m_inputFrequencyOffset: " << settings.m_inputFrequencyOffset
|
||||||
|
<< " m_rfBandwidth: " << settings.m_rfBandwidth
|
||||||
|
<< " m_afBandwidth: " << settings.m_afBandwidth
|
||||||
|
<< " m_fmDeviation: " << settings.m_fmDeviation
|
||||||
|
<< " m_volumeFactor: " << settings.m_volumeFactor
|
||||||
|
<< " m_toneFrequency: " << settings.m_toneFrequency
|
||||||
|
<< " m_channelMute: " << settings.m_channelMute
|
||||||
|
<< " m_playLoop: " << settings.m_playLoop
|
||||||
|
<< " force: " << force;
|
||||||
|
|
||||||
|
if((settings.m_audioSampleRate != m_settings.m_audioSampleRate) ||
|
||||||
(settings.m_afBandwidth != m_settings.m_afBandwidth) || force)
|
(settings.m_afBandwidth != m_settings.m_afBandwidth) || 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) settings.m_outputSampleRate;
|
m_interpolatorDistance = (Real) settings.m_audioSampleRate / (Real) m_outputSampleRate;
|
||||||
m_interpolator.create(48, settings.m_audioSampleRate, settings.m_rfBandwidth / 2.2, 3.0);
|
m_interpolator.create(48, settings.m_audioSampleRate, settings.m_rfBandwidth / 2.2, 3.0);
|
||||||
m_settingsMutex.unlock();
|
m_settingsMutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((settings.m_rfBandwidth != m_settings.m_rfBandwidth) ||
|
if ((settings.m_rfBandwidth != m_settings.m_rfBandwidth) || force)
|
||||||
(settings.m_outputSampleRate != m_settings.m_outputSampleRate) || force)
|
|
||||||
{
|
{
|
||||||
m_settingsMutex.lock();
|
m_settingsMutex.lock();
|
||||||
Real lowCut = -(settings.m_rfBandwidth / 2.0) / settings.m_outputSampleRate;
|
Real lowCut = -(settings.m_rfBandwidth / 2.0) / m_outputSampleRate;
|
||||||
Real hiCut = (settings.m_rfBandwidth / 2.0) / settings.m_outputSampleRate;
|
Real hiCut = (settings.m_rfBandwidth / 2.0) / m_outputSampleRate;
|
||||||
m_rfFilter->create_filter(lowCut, hiCut);
|
m_rfFilter->create_filter(lowCut, hiCut);
|
||||||
m_settingsMutex.unlock();
|
m_settingsMutex.unlock();
|
||||||
}
|
}
|
||||||
@ -464,20 +479,13 @@ void WFMMod::applySettings(const WFMModSettings& settings, bool force)
|
|||||||
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_outputSampleRate != m_settings.m_outputSampleRate) || force)
|
|
||||||
{
|
{
|
||||||
m_settingsMutex.lock();
|
m_settingsMutex.lock();
|
||||||
m_toneNcoRF.setFreq(settings.m_toneFrequency, settings.m_outputSampleRate);
|
m_toneNcoRF.setFreq(settings.m_toneFrequency, m_outputSampleRate);
|
||||||
m_settingsMutex.unlock();
|
m_settingsMutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((settings.m_outputSampleRate != m_settings.m_outputSampleRate) || force)
|
|
||||||
{
|
|
||||||
m_cwKeyer.setSampleRate(settings.m_outputSampleRate);
|
|
||||||
m_cwKeyer.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_settings = settings;
|
m_settings = settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -273,8 +273,10 @@ private:
|
|||||||
ThreadedBasebandSampleSource* m_threadedChannelizer;
|
ThreadedBasebandSampleSource* m_threadedChannelizer;
|
||||||
UpChannelizer* m_channelizer;
|
UpChannelizer* m_channelizer;
|
||||||
|
|
||||||
|
int m_basebandSampleRate;
|
||||||
|
int m_outputSampleRate;
|
||||||
|
int m_inputFrequencyOffset;
|
||||||
WFMModSettings m_settings;
|
WFMModSettings m_settings;
|
||||||
int m_absoluteFrequencyOffset;
|
|
||||||
|
|
||||||
NCO m_carrierNco;
|
NCO m_carrierNco;
|
||||||
NCOF m_toneNco;
|
NCOF m_toneNco;
|
||||||
@ -315,6 +317,7 @@ private:
|
|||||||
CWKeyer m_cwKeyer;
|
CWKeyer m_cwKeyer;
|
||||||
static const int m_levelNbSamples;
|
static const int m_levelNbSamples;
|
||||||
|
|
||||||
|
void applyChannelSettings(int basebandSampleRate, int outputSampleRate, int inputFrequencyOffset);
|
||||||
void applySettings(const WFMModSettings& settings, bool force = false);
|
void applySettings(const WFMModSettings& settings, bool force = false);
|
||||||
void pullAF(Complex& sample);
|
void pullAF(Complex& sample);
|
||||||
void calculateLevel(const Real& sample);
|
void calculateLevel(const Real& sample);
|
||||||
|
@ -37,8 +37,6 @@ WFMModSettings::WFMModSettings() :
|
|||||||
|
|
||||||
void WFMModSettings::resetToDefaults()
|
void WFMModSettings::resetToDefaults()
|
||||||
{
|
{
|
||||||
m_basebandSampleRate = 384000;
|
|
||||||
m_outputSampleRate = 384000;
|
|
||||||
m_inputFrequencyOffset = 0;
|
m_inputFrequencyOffset = 0;
|
||||||
m_rfBandwidth = 125000.0f;
|
m_rfBandwidth = 125000.0f;
|
||||||
m_afBandwidth = 15000.0f;
|
m_afBandwidth = 15000.0f;
|
||||||
|
@ -26,8 +26,6 @@ struct WFMModSettings
|
|||||||
static const int m_nbRfBW;
|
static const int m_nbRfBW;
|
||||||
static const int m_rfBW[];
|
static const int m_rfBW[];
|
||||||
|
|
||||||
int m_basebandSampleRate;
|
|
||||||
int m_outputSampleRate;
|
|
||||||
qint64 m_inputFrequencyOffset;
|
qint64 m_inputFrequencyOffset;
|
||||||
Real m_rfBandwidth;
|
Real m_rfBandwidth;
|
||||||
Real m_afBandwidth;
|
Real m_afBandwidth;
|
||||||
|
@ -1360,12 +1360,6 @@ margin-bottom: 20px;
|
|||||||
};
|
};
|
||||||
defs.NFMModSettings = {
|
defs.NFMModSettings = {
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"basebandSampleRate" : {
|
|
||||||
"type" : "integer"
|
|
||||||
},
|
|
||||||
"outputSampleRate" : {
|
|
||||||
"type" : "integer"
|
|
||||||
},
|
|
||||||
"inputFrequencyOffset" : {
|
"inputFrequencyOffset" : {
|
||||||
"type" : "integer",
|
"type" : "integer",
|
||||||
"format" : "int64"
|
"format" : "int64"
|
||||||
@ -16388,7 +16382,7 @@ except ApiException as e:
|
|||||||
</div>
|
</div>
|
||||||
<div id="generator">
|
<div id="generator">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
Generated 2017-12-29T05:27:24.640+01:00
|
Generated 2017-12-29T23:23:36.890+01:00
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,10 +1,6 @@
|
|||||||
NFMModSettings:
|
NFMModSettings:
|
||||||
description: NFMMod
|
description: NFMMod
|
||||||
properties:
|
properties:
|
||||||
basebandSampleRate:
|
|
||||||
type: integer
|
|
||||||
outputSampleRate:
|
|
||||||
type: integer
|
|
||||||
inputFrequencyOffset:
|
inputFrequencyOffset:
|
||||||
type: integer
|
type: integer
|
||||||
format: int64
|
format: int64
|
||||||
|
@ -1360,12 +1360,6 @@ margin-bottom: 20px;
|
|||||||
};
|
};
|
||||||
defs.NFMModSettings = {
|
defs.NFMModSettings = {
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"basebandSampleRate" : {
|
|
||||||
"type" : "integer"
|
|
||||||
},
|
|
||||||
"outputSampleRate" : {
|
|
||||||
"type" : "integer"
|
|
||||||
},
|
|
||||||
"inputFrequencyOffset" : {
|
"inputFrequencyOffset" : {
|
||||||
"type" : "integer",
|
"type" : "integer",
|
||||||
"format" : "int64"
|
"format" : "int64"
|
||||||
@ -16388,7 +16382,7 @@ except ApiException as e:
|
|||||||
</div>
|
</div>
|
||||||
<div id="generator">
|
<div id="generator">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
Generated 2017-12-29T05:27:24.640+01:00
|
Generated 2017-12-29T23:23:36.890+01:00
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -37,8 +37,6 @@ SWGNFMModSettings::~SWGNFMModSettings() {
|
|||||||
|
|
||||||
void
|
void
|
||||||
SWGNFMModSettings::init() {
|
SWGNFMModSettings::init() {
|
||||||
baseband_sample_rate = 0;
|
|
||||||
output_sample_rate = 0;
|
|
||||||
input_frequency_offset = 0L;
|
input_frequency_offset = 0L;
|
||||||
rf_bandwidth = 0.0f;
|
rf_bandwidth = 0.0f;
|
||||||
af_bandwidth = 0.0f;
|
af_bandwidth = 0.0f;
|
||||||
@ -71,8 +69,6 @@ SWGNFMModSettings::cleanup() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(title != nullptr) {
|
if(title != nullptr) {
|
||||||
delete title;
|
delete title;
|
||||||
}
|
}
|
||||||
@ -94,8 +90,6 @@ SWGNFMModSettings::fromJson(QString &json) {
|
|||||||
|
|
||||||
void
|
void
|
||||||
SWGNFMModSettings::fromJsonObject(QJsonObject &pJson) {
|
SWGNFMModSettings::fromJsonObject(QJsonObject &pJson) {
|
||||||
::SWGSDRangel::setValue(&baseband_sample_rate, pJson["basebandSampleRate"], "qint32", "");
|
|
||||||
::SWGSDRangel::setValue(&output_sample_rate, pJson["outputSampleRate"], "qint32", "");
|
|
||||||
::SWGSDRangel::setValue(&input_frequency_offset, pJson["inputFrequencyOffset"], "qint64", "");
|
::SWGSDRangel::setValue(&input_frequency_offset, pJson["inputFrequencyOffset"], "qint64", "");
|
||||||
::SWGSDRangel::setValue(&rf_bandwidth, pJson["rfBandwidth"], "float", "");
|
::SWGSDRangel::setValue(&rf_bandwidth, pJson["rfBandwidth"], "float", "");
|
||||||
::SWGSDRangel::setValue(&af_bandwidth, pJson["afBandwidth"], "float", "");
|
::SWGSDRangel::setValue(&af_bandwidth, pJson["afBandwidth"], "float", "");
|
||||||
@ -127,10 +121,6 @@ QJsonObject*
|
|||||||
SWGNFMModSettings::asJsonObject() {
|
SWGNFMModSettings::asJsonObject() {
|
||||||
QJsonObject* obj = new QJsonObject();
|
QJsonObject* obj = new QJsonObject();
|
||||||
|
|
||||||
obj->insert("basebandSampleRate", QJsonValue(baseband_sample_rate));
|
|
||||||
|
|
||||||
obj->insert("outputSampleRate", QJsonValue(output_sample_rate));
|
|
||||||
|
|
||||||
obj->insert("inputFrequencyOffset", QJsonValue(input_frequency_offset));
|
obj->insert("inputFrequencyOffset", QJsonValue(input_frequency_offset));
|
||||||
|
|
||||||
obj->insert("rfBandwidth", QJsonValue(rf_bandwidth));
|
obj->insert("rfBandwidth", QJsonValue(rf_bandwidth));
|
||||||
@ -164,24 +154,6 @@ SWGNFMModSettings::asJsonObject() {
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
qint32
|
|
||||||
SWGNFMModSettings::getBasebandSampleRate() {
|
|
||||||
return baseband_sample_rate;
|
|
||||||
}
|
|
||||||
void
|
|
||||||
SWGNFMModSettings::setBasebandSampleRate(qint32 baseband_sample_rate) {
|
|
||||||
this->baseband_sample_rate = baseband_sample_rate;
|
|
||||||
}
|
|
||||||
|
|
||||||
qint32
|
|
||||||
SWGNFMModSettings::getOutputSampleRate() {
|
|
||||||
return output_sample_rate;
|
|
||||||
}
|
|
||||||
void
|
|
||||||
SWGNFMModSettings::setOutputSampleRate(qint32 output_sample_rate) {
|
|
||||||
this->output_sample_rate = output_sample_rate;
|
|
||||||
}
|
|
||||||
|
|
||||||
qint64
|
qint64
|
||||||
SWGNFMModSettings::getInputFrequencyOffset() {
|
SWGNFMModSettings::getInputFrequencyOffset() {
|
||||||
return input_frequency_offset;
|
return input_frequency_offset;
|
||||||
|
@ -43,12 +43,6 @@ public:
|
|||||||
void fromJsonObject(QJsonObject &json);
|
void fromJsonObject(QJsonObject &json);
|
||||||
SWGNFMModSettings* fromJson(QString &jsonString);
|
SWGNFMModSettings* fromJson(QString &jsonString);
|
||||||
|
|
||||||
qint32 getBasebandSampleRate();
|
|
||||||
void setBasebandSampleRate(qint32 baseband_sample_rate);
|
|
||||||
|
|
||||||
qint32 getOutputSampleRate();
|
|
||||||
void setOutputSampleRate(qint32 output_sample_rate);
|
|
||||||
|
|
||||||
qint64 getInputFrequencyOffset();
|
qint64 getInputFrequencyOffset();
|
||||||
void setInputFrequencyOffset(qint64 input_frequency_offset);
|
void setInputFrequencyOffset(qint64 input_frequency_offset);
|
||||||
|
|
||||||
@ -96,8 +90,6 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
qint32 baseband_sample_rate;
|
|
||||||
qint32 output_sample_rate;
|
|
||||||
qint64 input_frequency_offset;
|
qint64 input_frequency_offset;
|
||||||
float rf_bandwidth;
|
float rf_bandwidth;
|
||||||
float af_bandwidth;
|
float af_bandwidth;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user