mirror of https://github.com/f4exb/sdrangel.git
ATV Modulator: implemented FM
This commit is contained in:
parent
b832ea2173
commit
71d4776a93
|
@ -26,6 +26,7 @@ const float ATVMod::m_spanLevel = 0.7f;
|
||||||
const int ATVMod::m_levelNbSamples = 10000; // every 10ms
|
const int ATVMod::m_levelNbSamples = 10000; // every 10ms
|
||||||
|
|
||||||
ATVMod::ATVMod() :
|
ATVMod::ATVMod() :
|
||||||
|
m_modPhasor(0.0f),
|
||||||
m_evenImage(true),
|
m_evenImage(true),
|
||||||
m_tvSampleRate(1000000),
|
m_tvSampleRate(1000000),
|
||||||
m_settingsMutex(QMutex::Recursive),
|
m_settingsMutex(QMutex::Recursive),
|
||||||
|
@ -59,9 +60,10 @@ void ATVMod::configure(MessageQueue* messageQueue,
|
||||||
ATVStd atvStd,
|
ATVStd atvStd,
|
||||||
ATVModInput atvModInput,
|
ATVModInput atvModInput,
|
||||||
Real uniformLevel,
|
Real uniformLevel,
|
||||||
|
ATVModulation atvModulation,
|
||||||
bool channelMute)
|
bool channelMute)
|
||||||
{
|
{
|
||||||
Message* cmd = MsgConfigureATVMod::create(rfBandwidth, atvStd, atvModInput, uniformLevel);
|
Message* cmd = MsgConfigureATVMod::create(rfBandwidth, atvStd, atvModInput, uniformLevel, atvModulation);
|
||||||
messageQueue->push(cmd);
|
messageQueue->push(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,10 +127,21 @@ void ATVMod::modulateSample()
|
||||||
pullVideo(t);
|
pullVideo(t);
|
||||||
calculateLevel(t);
|
calculateLevel(t);
|
||||||
|
|
||||||
// TODO For now do AM 90%
|
switch (m_running.m_atvModulation)
|
||||||
|
{
|
||||||
|
case ATVModulationFM: // FM half bandwidth deviation
|
||||||
|
m_modPhasor += (t - 0.5f) * M_PI;
|
||||||
|
if (m_modPhasor > 2.0f * M_PI) m_modPhasor -= 2.0f * M_PI; // limit growth
|
||||||
|
if (m_modPhasor < 2.0f * M_PI) m_modPhasor += 2.0f * M_PI; // limit growth
|
||||||
|
m_modSample.real(cos(m_modPhasor) * 29204.0f); // -1 dB
|
||||||
|
m_modSample.imag(sin(m_modPhasor) * 29204.0f);
|
||||||
|
break;
|
||||||
|
case ATVModulationAM: // AM 90%
|
||||||
|
default:
|
||||||
m_modSample.real((t*1.8f + 0.1f) * 16384.0f); // modulate and scale zero frequency carrier
|
m_modSample.real((t*1.8f + 0.1f) * 16384.0f); // modulate and scale zero frequency carrier
|
||||||
m_modSample.imag(0.0f);
|
m_modSample.imag(0.0f);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ATVMod::pullVideo(Real& sample)
|
void ATVMod::pullVideo(Real& sample)
|
||||||
{
|
{
|
||||||
|
@ -216,6 +229,7 @@ bool ATVMod::handleMessage(const Message& cmd)
|
||||||
m_config.m_atvModInput = cfg.getATVModInput();
|
m_config.m_atvModInput = cfg.getATVModInput();
|
||||||
m_config.m_atvStd = cfg.getATVStd();
|
m_config.m_atvStd = cfg.getATVStd();
|
||||||
m_config.m_uniformLevel = cfg.getUniformLevel();
|
m_config.m_uniformLevel = cfg.getUniformLevel();
|
||||||
|
m_config.m_atvModulation = cfg.getModulation();
|
||||||
|
|
||||||
apply();
|
apply();
|
||||||
|
|
||||||
|
@ -223,7 +237,8 @@ bool ATVMod::handleMessage(const Message& cmd)
|
||||||
<< " m_rfBandwidth: " << m_config.m_rfBandwidth
|
<< " m_rfBandwidth: " << m_config.m_rfBandwidth
|
||||||
<< " m_atvStd: " << (int) m_config.m_atvStd
|
<< " m_atvStd: " << (int) m_config.m_atvStd
|
||||||
<< " m_atvModInput: " << (int) m_config.m_atvModInput
|
<< " m_atvModInput: " << (int) m_config.m_atvModInput
|
||||||
<< " m_uniformLevel: " << m_config.m_uniformLevel;
|
<< " m_uniformLevel: " << m_config.m_uniformLevel
|
||||||
|
<< " m_atvModulation: " << (int) m_config.m_atvModulation;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -273,6 +288,7 @@ void ATVMod::apply(bool force)
|
||||||
m_running.m_atvModInput = m_config.m_atvModInput;
|
m_running.m_atvModInput = m_config.m_atvModInput;
|
||||||
m_running.m_atvStd = m_config.m_atvStd;
|
m_running.m_atvStd = m_config.m_atvStd;
|
||||||
m_running.m_uniformLevel = m_config.m_uniformLevel;
|
m_running.m_uniformLevel = m_config.m_uniformLevel;
|
||||||
|
m_running.m_atvModulation = m_config.m_atvModulation;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ATVMod::getSampleRateUnits(ATVStd std)
|
int ATVMod::getSampleRateUnits(ATVStd std)
|
||||||
|
|
|
@ -47,6 +47,12 @@ public:
|
||||||
ATVModInputVGradient
|
ATVModInputVGradient
|
||||||
} ATVModInput;
|
} ATVModInput;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
ATVModulationAM,
|
||||||
|
ATVModulationFM
|
||||||
|
} ATVModulation;
|
||||||
|
|
||||||
ATVMod();
|
ATVMod();
|
||||||
~ATVMod();
|
~ATVMod();
|
||||||
|
|
||||||
|
@ -55,6 +61,7 @@ public:
|
||||||
ATVStd atvStd,
|
ATVStd atvStd,
|
||||||
ATVModInput atvModInput,
|
ATVModInput atvModInput,
|
||||||
Real uniformLevel,
|
Real uniformLevel,
|
||||||
|
ATVModulation atvModulation,
|
||||||
bool channelMute);
|
bool channelMute);
|
||||||
|
|
||||||
virtual void pull(Sample& sample);
|
virtual void pull(Sample& sample);
|
||||||
|
@ -86,14 +93,16 @@ private:
|
||||||
ATVStd getATVStd() const { return m_atvStd; }
|
ATVStd getATVStd() const { return m_atvStd; }
|
||||||
ATVModInput getATVModInput() const { return m_atvModInput; }
|
ATVModInput getATVModInput() const { return m_atvModInput; }
|
||||||
Real getUniformLevel() const { return m_uniformLevel; }
|
Real getUniformLevel() const { return m_uniformLevel; }
|
||||||
|
ATVModulation getModulation() const { return m_atvModulation; }
|
||||||
|
|
||||||
static MsgConfigureATVMod* create(
|
static MsgConfigureATVMod* create(
|
||||||
Real rfBandwidth,
|
Real rfBandwidth,
|
||||||
ATVStd atvStd,
|
ATVStd atvStd,
|
||||||
ATVModInput atvModInput,
|
ATVModInput atvModInput,
|
||||||
Real uniformLevel)
|
Real uniformLevel,
|
||||||
|
ATVModulation atvModulation)
|
||||||
{
|
{
|
||||||
return new MsgConfigureATVMod(rfBandwidth, atvStd, atvModInput, uniformLevel);
|
return new MsgConfigureATVMod(rfBandwidth, atvStd, atvModInput, uniformLevel, atvModulation);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -101,17 +110,20 @@ private:
|
||||||
ATVStd m_atvStd;
|
ATVStd m_atvStd;
|
||||||
ATVModInput m_atvModInput;
|
ATVModInput m_atvModInput;
|
||||||
Real m_uniformLevel;
|
Real m_uniformLevel;
|
||||||
|
ATVModulation m_atvModulation;
|
||||||
|
|
||||||
MsgConfigureATVMod(
|
MsgConfigureATVMod(
|
||||||
Real rfBandwidth,
|
Real rfBandwidth,
|
||||||
ATVStd atvStd,
|
ATVStd atvStd,
|
||||||
ATVModInput atvModInput,
|
ATVModInput atvModInput,
|
||||||
Real uniformLevel) :
|
Real uniformLevel,
|
||||||
|
ATVModulation atvModulation) :
|
||||||
Message(),
|
Message(),
|
||||||
m_rfBandwidth(rfBandwidth),
|
m_rfBandwidth(rfBandwidth),
|
||||||
m_atvStd(atvStd),
|
m_atvStd(atvStd),
|
||||||
m_atvModInput(atvModInput),
|
m_atvModInput(atvModInput),
|
||||||
m_uniformLevel(uniformLevel)
|
m_uniformLevel(uniformLevel),
|
||||||
|
m_atvModulation(atvModulation)
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -123,6 +135,7 @@ private:
|
||||||
ATVStd m_atvStd; //!< Standard
|
ATVStd m_atvStd; //!< Standard
|
||||||
ATVModInput m_atvModInput; //!< Input source type
|
ATVModInput m_atvModInput; //!< Input source type
|
||||||
Real m_uniformLevel; //!< Percentage between black and white for uniform screen display
|
Real m_uniformLevel; //!< Percentage between black and white for uniform screen display
|
||||||
|
ATVModulation m_atvModulation; //!< RF modulation type
|
||||||
|
|
||||||
Config() :
|
Config() :
|
||||||
m_outputSampleRate(-1),
|
m_outputSampleRate(-1),
|
||||||
|
@ -130,7 +143,8 @@ private:
|
||||||
m_rfBandwidth(0),
|
m_rfBandwidth(0),
|
||||||
m_atvStd(ATVStdPAL625),
|
m_atvStd(ATVStdPAL625),
|
||||||
m_atvModInput(ATVModInputHBars),
|
m_atvModInput(ATVModInputHBars),
|
||||||
m_uniformLevel(0.5f)
|
m_uniformLevel(0.5f),
|
||||||
|
m_atvModulation(ATVModulationAM)
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -139,6 +153,7 @@ private:
|
||||||
|
|
||||||
NCO m_carrierNco;
|
NCO m_carrierNco;
|
||||||
Complex m_modSample;
|
Complex m_modSample;
|
||||||
|
float m_modPhasor; //!< For FM modulation
|
||||||
Interpolator m_interpolator;
|
Interpolator m_interpolator;
|
||||||
Real m_interpolatorDistance;
|
Real m_interpolatorDistance;
|
||||||
Real m_interpolatorDistanceRemain;
|
Real m_interpolatorDistanceRemain;
|
||||||
|
|
|
@ -75,6 +75,7 @@ void ATVModGUI::resetToDefaults()
|
||||||
ui->standard->setCurrentIndex(0);
|
ui->standard->setCurrentIndex(0);
|
||||||
ui->inputSelect->setCurrentIndex(0);
|
ui->inputSelect->setCurrentIndex(0);
|
||||||
ui->deltaFrequency->setValue(0);
|
ui->deltaFrequency->setValue(0);
|
||||||
|
ui->modulation->setCurrentIndex(0);
|
||||||
|
|
||||||
blockApplySettings(false);
|
blockApplySettings(false);
|
||||||
applySettings();
|
applySettings();
|
||||||
|
@ -91,6 +92,7 @@ QByteArray ATVModGUI::serialize() const
|
||||||
s.writeS32(5, ui->inputSelect->currentIndex());
|
s.writeS32(5, ui->inputSelect->currentIndex());
|
||||||
s.writeU32(6, m_channelMarker.getColor().rgb());
|
s.writeU32(6, m_channelMarker.getColor().rgb());
|
||||||
s.writeS32(7, ui->volume->value());
|
s.writeS32(7, ui->volume->value());
|
||||||
|
s.writeS32(8, ui->modulation->currentIndex());
|
||||||
|
|
||||||
return s.final();
|
return s.final();
|
||||||
}
|
}
|
||||||
|
@ -132,6 +134,8 @@ bool ATVModGUI::deserialize(const QByteArray& data)
|
||||||
|
|
||||||
d.readS32(7, &tmp, 10);
|
d.readS32(7, &tmp, 10);
|
||||||
ui->volume->setValue(tmp);
|
ui->volume->setValue(tmp);
|
||||||
|
d.readS32(8, &tmp, 0);
|
||||||
|
ui->modulation->setCurrentIndex(tmp);
|
||||||
|
|
||||||
blockApplySettings(false);
|
blockApplySettings(false);
|
||||||
m_channelMarker.blockSignals(false);
|
m_channelMarker.blockSignals(false);
|
||||||
|
@ -189,6 +193,11 @@ void ATVModGUI::on_deltaFrequency_changed(quint64 value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ATVModGUI::on_modulation_currentIndexChanged(int index)
|
||||||
|
{
|
||||||
|
applySettings();
|
||||||
|
}
|
||||||
|
|
||||||
void ATVModGUI::on_rfBW_valueChanged(int value)
|
void ATVModGUI::on_rfBW_valueChanged(int value)
|
||||||
{
|
{
|
||||||
ui->rfBWText->setText(QString("%1 MHz").arg(value / 10.0, 0, 'f', 1));
|
ui->rfBWText->setText(QString("%1 MHz").arg(value / 10.0, 0, 'f', 1));
|
||||||
|
@ -313,6 +322,7 @@ void ATVModGUI::applySettings()
|
||||||
(ATVMod::ATVStd) ui->standard->currentIndex(),
|
(ATVMod::ATVStd) ui->standard->currentIndex(),
|
||||||
(ATVMod::ATVModInput) ui->inputSelect->currentIndex(),
|
(ATVMod::ATVModInput) ui->inputSelect->currentIndex(),
|
||||||
ui->uniformLevel->value() / 100.0f,
|
ui->uniformLevel->value() / 100.0f,
|
||||||
|
(ATVMod::ATVModulation) ui->modulation->currentIndex(),
|
||||||
ui->channelMute->isChecked());
|
ui->channelMute->isChecked());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,6 +60,7 @@ private slots:
|
||||||
|
|
||||||
void on_deltaFrequency_changed(quint64 value);
|
void on_deltaFrequency_changed(quint64 value);
|
||||||
void on_deltaMinus_toggled(bool minus);
|
void on_deltaMinus_toggled(bool minus);
|
||||||
|
void on_modulation_currentIndexChanged(int index);
|
||||||
void on_rfBW_valueChanged(int value);
|
void on_rfBW_valueChanged(int value);
|
||||||
void on_uniformLevel_valueChanged(int value);
|
void on_uniformLevel_valueChanged(int value);
|
||||||
void on_inputSelect_currentIndexChanged(int index);
|
void on_inputSelect_currentIndexChanged(int index);
|
||||||
|
|
|
@ -191,16 +191,30 @@
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="rfBandwidthLayout">
|
<layout class="QHBoxLayout" name="rfBandwidthLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QComboBox" name="standard">
|
<widget class="QComboBox" name="modulation">
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>50</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Modulation type</string>
|
||||||
|
</property>
|
||||||
<item>
|
<item>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>PAL625L</string>
|
<string>AM</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>FM</string>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
</item>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label">
|
<widget class="QLabel" name="rfBWLabel">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>RFBW</string>
|
<string>RFBW</string>
|
||||||
</property>
|
</property>
|
||||||
|
@ -321,8 +335,24 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="Line" name="line_3">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="recordFileSelectLayout">
|
<layout class="QHBoxLayout" name="recordFileSelectLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="standard">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>PAL625L</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QComboBox" name="inputSelect">
|
<widget class="QComboBox" name="inputSelect">
|
||||||
<item>
|
<item>
|
||||||
|
@ -361,7 +391,7 @@
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Tone frequency</string>
|
<string>Uniform level luminance (%)</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="minimum">
|
<property name="minimum">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
|
@ -419,7 +449,7 @@
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="Line" name="line_3">
|
<widget class="Line" name="line">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
|
@ -640,6 +670,11 @@
|
||||||
<include location="../../../sdrbase/resources/res.qrc"/>
|
<include location="../../../sdrbase/resources/res.qrc"/>
|
||||||
<include location="../../../sdrbase/resources/res.qrc"/>
|
<include location="../../../sdrbase/resources/res.qrc"/>
|
||||||
<include location="../../../sdrbase/resources/res.qrc"/>
|
<include location="../../../sdrbase/resources/res.qrc"/>
|
||||||
|
<include location="../../../sdrbase/resources/res.qrc"/>
|
||||||
|
<include location="../../../sdrbase/resources/res.qrc"/>
|
||||||
|
<include location="../../../sdrbase/resources/res.qrc"/>
|
||||||
|
<include location="../../../sdrbase/resources/res.qrc"/>
|
||||||
|
<include location="../../../sdrbase/resources/res.qrc"/>
|
||||||
</resources>
|
</resources>
|
||||||
<connections/>
|
<connections/>
|
||||||
</ui>
|
</ui>
|
||||||
|
|
Loading…
Reference in New Issue