mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-11-13 20:01:46 -05:00
Tx ph.1: new AM modulator plugin (3). Implemented actual modulation code.
This commit is contained in:
parent
c28751124c
commit
9fff2b8477
@ -18,6 +18,7 @@
|
||||
|
||||
#include <QTime>
|
||||
#include <QDebug>
|
||||
#include <QMutexLocker>
|
||||
#include <stdio.h>
|
||||
#include <complex.h>
|
||||
#include <dsp/upchannelizer.h>
|
||||
@ -35,7 +36,7 @@ AMMod::AMMod() :
|
||||
m_config.m_inputFrequencyOffset = 0;
|
||||
m_config.m_rfBandwidth = 12500;
|
||||
m_config.m_afBandwidth = 3000;
|
||||
m_config.m_modPercent = 20;
|
||||
m_config.m_modFactor = 20;
|
||||
m_config.m_audioSampleRate = DSPEngine::instance()->getAudioSampleRate();
|
||||
|
||||
apply();
|
||||
@ -46,6 +47,8 @@ AMMod::AMMod() :
|
||||
m_movingAverage.resize(16, 0);
|
||||
m_volumeAGC.resize(4096, 0.003, 0);
|
||||
m_magsq = 0.0;
|
||||
|
||||
m_toneNco.setFreq(1000.0, m_config.m_audioSampleRate);
|
||||
}
|
||||
|
||||
AMMod::~AMMod()
|
||||
@ -60,7 +63,30 @@ void AMMod::configure(MessageQueue* messageQueue, Real rfBandwidth, Real afBandw
|
||||
|
||||
void AMMod::pull(Sample& sample)
|
||||
{
|
||||
// TODO
|
||||
Complex ci;
|
||||
|
||||
if (m_interpolator.interpolate(&m_interpolatorDistanceRemain, m_modSample, &ci))
|
||||
{
|
||||
m_settingsMutex.lock();
|
||||
m_carrierNco.nextPhase();
|
||||
m_toneNco.nextPhase();
|
||||
m_settingsMutex.unlock();
|
||||
|
||||
m_carrierNco.getIQ(m_modSample);
|
||||
Real t = m_toneNco.get();
|
||||
|
||||
m_modSample *= (t+1.0f) * m_running.m_modFactor * 16384.0f; // modulate carrier
|
||||
|
||||
m_interpolatorDistanceRemain += m_interpolatorDistance;
|
||||
}
|
||||
|
||||
Real magsq = ci.real() * ci.real() + ci.imag() * ci.imag();
|
||||
magsq /= (1<<30);
|
||||
m_movingAverage.feed(magsq);
|
||||
m_magsq = m_movingAverage.average();
|
||||
|
||||
sample.m_real = (FixReal) ci.real();
|
||||
sample.m_imag = (FixReal) ci.imag();
|
||||
}
|
||||
|
||||
void AMMod::start()
|
||||
@ -100,7 +126,7 @@ bool AMMod::handleMessage(const Message& cmd)
|
||||
|
||||
m_config.m_rfBandwidth = cfg.getRFBandwidth();
|
||||
m_config.m_afBandwidth = cfg.getAFBandwidth();
|
||||
m_config.m_modPercent = cfg.getModPercent();
|
||||
m_config.m_modFactor = cfg.getModFactor();
|
||||
m_config.m_audioMute = cfg.getAudioMute();
|
||||
|
||||
apply();
|
||||
@ -108,7 +134,7 @@ bool AMMod::handleMessage(const Message& cmd)
|
||||
qDebug() << "AMMod::handleMessage: MsgConfigureAMMod:"
|
||||
<< " m_rfBandwidth: " << m_config.m_rfBandwidth
|
||||
<< " m_afBandwidth: " << m_config.m_afBandwidth
|
||||
<< " m_modPercent: " << m_config.m_modPercent
|
||||
<< " m_modFactor: " << m_config.m_modFactor
|
||||
<< " m_audioMute: " << m_config.m_audioMute;
|
||||
|
||||
return true;
|
||||
@ -122,10 +148,9 @@ bool AMMod::handleMessage(const Message& cmd)
|
||||
void AMMod::apply()
|
||||
{
|
||||
|
||||
if((m_config.m_inputFrequencyOffset != m_running.m_inputFrequencyOffset) ||
|
||||
(m_config.m_outputSampleRate != m_running.m_outputSampleRate))
|
||||
if(m_config.m_inputFrequencyOffset != m_running.m_inputFrequencyOffset)
|
||||
{
|
||||
m_carrierNco.setFreq(-m_config.m_inputFrequencyOffset, m_config.m_outputSampleRate);
|
||||
m_carrierNco.setFreq(-m_config.m_inputFrequencyOffset, m_config.m_audioSampleRate);
|
||||
}
|
||||
|
||||
if((m_config.m_outputSampleRate != m_running.m_outputSampleRate) ||
|
||||
@ -150,7 +175,7 @@ void AMMod::apply()
|
||||
m_running.m_inputFrequencyOffset = m_config.m_inputFrequencyOffset;
|
||||
m_running.m_rfBandwidth = m_config.m_rfBandwidth;
|
||||
m_running.m_afBandwidth = m_config.m_afBandwidth;
|
||||
m_running.m_modPercent = m_config.m_modPercent;
|
||||
m_running.m_modFactor = m_config.m_modFactor;
|
||||
m_running.m_audioSampleRate = m_config.m_audioSampleRate;
|
||||
m_running.m_audioMute = m_config.m_audioMute;
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ private:
|
||||
public:
|
||||
Real getRFBandwidth() const { return m_rfBandwidth; }
|
||||
Real getAFBandwidth() const { return m_afBandwidth; }
|
||||
Real getModPercent() const { return m_modPercent; }
|
||||
float getModFactor() const { return m_modFactor; }
|
||||
bool getAudioMute() const { return m_audioMute; }
|
||||
|
||||
static MsgConfigureAMMod* create(Real rfBandwidth, Real afBandwidth, int modPercent, bool audioMute)
|
||||
@ -62,14 +62,14 @@ private:
|
||||
private:
|
||||
Real m_rfBandwidth;
|
||||
Real m_afBandwidth;
|
||||
Real m_modPercent;
|
||||
float m_modFactor;
|
||||
bool m_audioMute;
|
||||
|
||||
MsgConfigureAMMod(Real rfBandwidth, Real afBandwidth, int modPercent, bool audioMute) :
|
||||
MsgConfigureAMMod(Real rfBandwidth, Real afBandwidth, float modFactor, bool audioMute) :
|
||||
Message(),
|
||||
m_rfBandwidth(rfBandwidth),
|
||||
m_afBandwidth(afBandwidth),
|
||||
m_modPercent(modPercent),
|
||||
m_modFactor(modFactor),
|
||||
m_audioMute(audioMute)
|
||||
{ }
|
||||
};
|
||||
@ -90,7 +90,7 @@ private:
|
||||
qint64 m_inputFrequencyOffset;
|
||||
Real m_rfBandwidth;
|
||||
Real m_afBandwidth;
|
||||
int m_modPercent;
|
||||
float m_modFactor;
|
||||
quint32 m_audioSampleRate;
|
||||
bool m_audioMute;
|
||||
|
||||
@ -99,7 +99,7 @@ private:
|
||||
m_inputFrequencyOffset(0),
|
||||
m_rfBandwidth(-1),
|
||||
m_afBandwidth(-1),
|
||||
m_modPercent(20),
|
||||
m_modFactor(0.2f),
|
||||
m_audioSampleRate(0),
|
||||
m_audioMute(false)
|
||||
{ }
|
||||
@ -110,6 +110,7 @@ private:
|
||||
|
||||
NCO m_carrierNco;
|
||||
NCO m_toneNco;
|
||||
Complex m_modSample;
|
||||
Interpolator m_interpolator;
|
||||
Real m_interpolatorDistance;
|
||||
Real m_interpolatorDistanceRemain;
|
||||
|
@ -278,7 +278,7 @@ void AMModGUI::applySettings()
|
||||
m_amMod->configure(m_amMod->getInputMessageQueue(),
|
||||
m_rfBW[ui->rfBW->value()],
|
||||
ui->afBW->value() * 1000.0,
|
||||
ui->modPercent->value(),
|
||||
ui->modPercent->value() / 100.0f,
|
||||
ui->audioMute->isChecked());
|
||||
}
|
||||
}
|
||||
|
@ -49,22 +49,28 @@ void NCO::setFreq(Real freq, Real sampleRate)
|
||||
|
||||
float NCO::next()
|
||||
{
|
||||
m_phase += m_phaseIncrement;
|
||||
while(m_phase >= TableSize)
|
||||
m_phase -= TableSize;
|
||||
while(m_phase < 0)
|
||||
m_phase += TableSize;
|
||||
|
||||
nextPhase();
|
||||
return m_table[m_phase];
|
||||
}
|
||||
|
||||
Complex NCO::nextIQ()
|
||||
{
|
||||
m_phase += m_phaseIncrement;
|
||||
while(m_phase >= TableSize)
|
||||
m_phase -= TableSize;
|
||||
while(m_phase < 0)
|
||||
m_phase += TableSize;
|
||||
|
||||
nextPhase();
|
||||
return Complex(m_table[m_phase], -m_table[(m_phase + TableSize / 4) % TableSize]);
|
||||
}
|
||||
|
||||
float NCO::get()
|
||||
{
|
||||
return m_table[m_phase];
|
||||
}
|
||||
|
||||
Complex NCO::getIQ()
|
||||
{
|
||||
return Complex(m_table[m_phase], -m_table[(m_phase + TableSize / 4) % TableSize]);
|
||||
}
|
||||
|
||||
void NCO::getIQ(Complex& c)
|
||||
{
|
||||
c.real(m_table[m_phase]);
|
||||
c.imag(-m_table[(m_phase + TableSize / 4) % TableSize]);
|
||||
}
|
||||
|
@ -38,8 +38,21 @@ public:
|
||||
NCO();
|
||||
|
||||
void setFreq(Real freq, Real sampleRate);
|
||||
Real next();
|
||||
Complex nextIQ();
|
||||
|
||||
void nextPhase() //!< Increment phase
|
||||
{
|
||||
m_phase += m_phaseIncrement;
|
||||
while(m_phase >= TableSize)
|
||||
m_phase -= TableSize;
|
||||
while(m_phase < 0)
|
||||
m_phase += TableSize;
|
||||
}
|
||||
|
||||
Real next(); //!< Return next real sample
|
||||
Complex nextIQ(); //!< Return next complex sample
|
||||
Real get(); //!< Return current real sample (no phase increment)
|
||||
Complex getIQ(); //!< Return current complex sample (no phase increment)
|
||||
void getIQ(Complex& c); //!< Sets to the current complex sample (no phase increment)
|
||||
};
|
||||
|
||||
#endif // INCLUDE_NCO_H
|
||||
|
Loading…
Reference in New Issue
Block a user