mirror of https://github.com/f4exb/sdrangel.git
WFM modulator: fixed RF bandwidth issue
This commit is contained in:
parent
b626cf67e6
commit
f91b0382e5
|
@ -59,9 +59,13 @@ WFMMod::WFMMod() :
|
||||||
m_config.m_audioSampleRate = DSPEngine::instance()->getAudioSampleRate();
|
m_config.m_audioSampleRate = DSPEngine::instance()->getAudioSampleRate();
|
||||||
|
|
||||||
m_rfFilter = new fftfilt(-62500.0 / 384000.0, 62500.0 / 384000.0, m_rfFilterFFTLength);
|
m_rfFilter = new fftfilt(-62500.0 / 384000.0, 62500.0 / 384000.0, m_rfFilterFFTLength);
|
||||||
|
m_rfFilterBuffer = new Complex[m_rfFilterFFTLength];
|
||||||
|
memset(m_rfFilterBuffer, 0, sizeof(Complex)*(m_rfFilterFFTLength));
|
||||||
|
m_rfFilterBufferIndex = 0;
|
||||||
|
|
||||||
apply();
|
apply();
|
||||||
|
|
||||||
|
|
||||||
m_audioBuffer.resize(1<<14);
|
m_audioBuffer.resize(1<<14);
|
||||||
m_audioBufferFill = 0;
|
m_audioBufferFill = 0;
|
||||||
|
|
||||||
|
@ -70,6 +74,7 @@ WFMMod::WFMMod() :
|
||||||
m_magsq = 0.0;
|
m_magsq = 0.0;
|
||||||
|
|
||||||
m_toneNco.setFreq(1000.0, m_config.m_audioSampleRate);
|
m_toneNco.setFreq(1000.0, m_config.m_audioSampleRate);
|
||||||
|
m_toneNcoRF.setFreq(1000.0, m_config.m_outputSampleRate);
|
||||||
DSPEngine::instance()->addAudioSource(&m_audioFifo);
|
DSPEngine::instance()->addAudioSource(&m_audioFifo);
|
||||||
|
|
||||||
// CW keyer
|
// CW keyer
|
||||||
|
@ -82,6 +87,7 @@ WFMMod::WFMMod() :
|
||||||
WFMMod::~WFMMod()
|
WFMMod::~WFMMod()
|
||||||
{
|
{
|
||||||
delete m_rfFilter;
|
delete m_rfFilter;
|
||||||
|
delete[] m_rfFilterBuffer;
|
||||||
DSPEngine::instance()->removeAudioSource(&m_audioFifo);
|
DSPEngine::instance()->removeAudioSource(&m_audioFifo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,25 +115,43 @@ void WFMMod::pull(Sample& sample)
|
||||||
|
|
||||||
Complex ci, ri;
|
Complex ci, ri;
|
||||||
Real t;
|
Real t;
|
||||||
|
fftfilt::cmplx *rf;
|
||||||
|
int rf_out;
|
||||||
|
|
||||||
m_settingsMutex.lock();
|
m_settingsMutex.lock();
|
||||||
|
|
||||||
if (m_interpolator.interpolate(&m_interpolatorDistanceRemain, m_modSample, &ri))
|
if ((m_afInput == WFMModInputFile) || (m_afInput == WFMModInputAudio) || (m_afInput == WFMModInputCWTone))
|
||||||
{
|
{
|
||||||
pullAF(m_modSample);
|
if (m_interpolator.interpolate(&m_interpolatorDistanceRemain, m_modSample, &ri))
|
||||||
calculateLevel(m_modSample.real());
|
{
|
||||||
m_audioBufferFill++;
|
pullAF(m_modSample);
|
||||||
}
|
calculateLevel(m_modSample.real());
|
||||||
|
m_audioBufferFill++;
|
||||||
|
}
|
||||||
|
|
||||||
m_interpolatorDistanceRemain += m_interpolatorDistance;
|
m_interpolatorDistanceRemain += m_interpolatorDistance;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pullAF(ri);
|
||||||
|
}
|
||||||
|
|
||||||
m_modPhasor += (m_running.m_fmDeviation / (float) m_running.m_outputSampleRate) * ri.real() * M_PI;
|
m_modPhasor += (m_running.m_fmDeviation / (float) m_running.m_outputSampleRate) * ri.real() * M_PI;
|
||||||
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);
|
||||||
|
|
||||||
// RF filtering is unnecessary
|
// RF filtering
|
||||||
|
rf_out = m_rfFilter->runFilt(ci, &rf);
|
||||||
|
|
||||||
ci *= m_carrierNco.nextIQ(); // shift to carrier frequency
|
if (rf_out > 0)
|
||||||
|
{
|
||||||
|
memcpy((void *) m_rfFilterBuffer, (const void *) rf, rf_out*sizeof(Complex));
|
||||||
|
m_rfFilterBufferIndex = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ci = m_rfFilterBuffer[m_rfFilterBufferIndex] * m_carrierNco.nextIQ(); // shift to carrier frequency
|
||||||
|
m_rfFilterBufferIndex++;
|
||||||
|
|
||||||
m_settingsMutex.unlock();
|
m_settingsMutex.unlock();
|
||||||
|
|
||||||
|
@ -158,7 +182,7 @@ void WFMMod::pullAF(Complex& sample)
|
||||||
switch (m_afInput)
|
switch (m_afInput)
|
||||||
{
|
{
|
||||||
case WFMModInputTone:
|
case WFMModInputTone:
|
||||||
sample.real(m_toneNco.next() * m_running.m_volumeFactor);
|
sample.real(m_toneNcoRF.next() * m_running.m_volumeFactor);
|
||||||
sample.imag(0.0f);
|
sample.imag(0.0f);
|
||||||
break;
|
break;
|
||||||
case WFMModInputFile:
|
case WFMModInputFile:
|
||||||
|
@ -390,6 +414,14 @@ void WFMMod::apply()
|
||||||
m_settingsMutex.unlock();
|
m_settingsMutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((m_config.m_toneFrequency != m_running.m_toneFrequency) ||
|
||||||
|
(m_config.m_outputSampleRate != m_running.m_outputSampleRate))
|
||||||
|
{
|
||||||
|
m_settingsMutex.lock();
|
||||||
|
m_toneNcoRF.setFreq(m_config.m_toneFrequency, m_config.m_outputSampleRate);
|
||||||
|
m_settingsMutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
if (m_config.m_audioSampleRate != m_running.m_audioSampleRate)
|
if (m_config.m_audioSampleRate != m_running.m_audioSampleRate)
|
||||||
{
|
{
|
||||||
m_cwKeyer.setSampleRate(m_config.m_audioSampleRate);
|
m_cwKeyer.setSampleRate(m_config.m_audioSampleRate);
|
||||||
|
|
|
@ -310,14 +310,18 @@ private:
|
||||||
|
|
||||||
NCO m_carrierNco;
|
NCO m_carrierNco;
|
||||||
NCOF m_toneNco;
|
NCOF m_toneNco;
|
||||||
|
NCOF m_toneNcoRF;
|
||||||
float m_modPhasor; //!< baseband modulator phasor
|
float m_modPhasor; //!< baseband modulator phasor
|
||||||
Complex m_modSample;
|
Complex m_modSample;
|
||||||
Interpolator m_interpolator;
|
Interpolator m_interpolator;
|
||||||
Real m_interpolatorDistance;
|
Real m_interpolatorDistance;
|
||||||
Real m_interpolatorDistanceRemain;
|
Real m_interpolatorDistanceRemain;
|
||||||
bool m_interpolatorConsumed;
|
bool m_interpolatorConsumed;
|
||||||
|
|
||||||
fftfilt* m_rfFilter;
|
fftfilt* m_rfFilter;
|
||||||
static const int m_rfFilterFFTLength;
|
static const int m_rfFilterFFTLength;
|
||||||
|
fftfilt::cmplx *m_rfFilterBuffer;
|
||||||
|
int m_rfFilterBufferIndex;
|
||||||
|
|
||||||
Real m_magsq;
|
Real m_magsq;
|
||||||
MovingAverage<Real> m_movingAverage;
|
MovingAverage<Real> m_movingAverage;
|
||||||
|
|
|
@ -40,6 +40,16 @@ const int WFMModGUI::m_rfBW[] = {
|
||||||
};
|
};
|
||||||
const int WFMModGUI::m_nbRfBW = 14;
|
const int WFMModGUI::m_nbRfBW = 14;
|
||||||
|
|
||||||
|
int WFMModGUI::requiredBW(int rfBW)
|
||||||
|
{
|
||||||
|
if (rfBW <= 48000)
|
||||||
|
return 48000;
|
||||||
|
else if (rfBW < 100000)
|
||||||
|
return 96000;
|
||||||
|
else
|
||||||
|
return 384000;
|
||||||
|
}
|
||||||
|
|
||||||
WFMModGUI* WFMModGUI::create(PluginAPI* pluginAPI, DeviceSinkAPI *deviceAPI)
|
WFMModGUI* WFMModGUI::create(PluginAPI* pluginAPI, DeviceSinkAPI *deviceAPI)
|
||||||
{
|
{
|
||||||
WFMModGUI* gui = new WFMModGUI(pluginAPI, deviceAPI);
|
WFMModGUI* gui = new WFMModGUI(pluginAPI, deviceAPI);
|
||||||
|
@ -430,7 +440,7 @@ void WFMModGUI::applySettings()
|
||||||
setTitleColor(m_channelMarker.getColor());
|
setTitleColor(m_channelMarker.getColor());
|
||||||
|
|
||||||
m_channelizer->configure(m_channelizer->getInputMessageQueue(),
|
m_channelizer->configure(m_channelizer->getInputMessageQueue(),
|
||||||
48000,
|
requiredBW(m_rfBW[ui->rfBW->currentIndex()]),
|
||||||
m_channelMarker.getCenterFrequency());
|
m_channelMarker.getCenterFrequency());
|
||||||
|
|
||||||
ui->deltaFrequency->setValue(abs(m_channelMarker.getCenterFrequency()));
|
ui->deltaFrequency->setValue(abs(m_channelMarker.getCenterFrequency()));
|
||||||
|
|
|
@ -109,6 +109,7 @@ private:
|
||||||
explicit WFMModGUI(PluginAPI* pluginAPI, DeviceSinkAPI *deviceAPI, QWidget* parent = NULL);
|
explicit WFMModGUI(PluginAPI* pluginAPI, DeviceSinkAPI *deviceAPI, QWidget* parent = NULL);
|
||||||
virtual ~WFMModGUI();
|
virtual ~WFMModGUI();
|
||||||
|
|
||||||
|
int requiredBW(int rfBW);
|
||||||
void blockApplySettings(bool block);
|
void blockApplySettings(bool block);
|
||||||
void applySettings();
|
void applySettings();
|
||||||
void updateWithStreamData();
|
void updateWithStreamData();
|
||||||
|
|
|
@ -56,16 +56,7 @@
|
||||||
<property name="spacing">
|
<property name="spacing">
|
||||||
<number>3</number>
|
<number>3</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="leftMargin">
|
<property name="margin">
|
||||||
<number>2</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>2</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>2</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>2</number>
|
<number>2</number>
|
||||||
</property>
|
</property>
|
||||||
<item>
|
<item>
|
||||||
|
@ -455,7 +446,7 @@
|
||||||
<number>10</number>
|
<number>10</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="maximum">
|
<property name="maximum">
|
||||||
<number>250</number>
|
<number>1000</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="pageStep">
|
<property name="pageStep">
|
||||||
<number>1</number>
|
<number>1</number>
|
||||||
|
|
Loading…
Reference in New Issue