1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-11-15 12:51:49 -05:00

ATV Modulator: added possibility to adjust baseband modulated signal amplitude to prevent filter saturation

This commit is contained in:
f4exb 2017-03-21 21:59:44 +01:00
parent 5ae92bf1b6
commit 7e70b7f6c6
5 changed files with 89 additions and 15 deletions

View File

@ -112,7 +112,8 @@ void ATVMod::configure(MessageQueue* messageQueue,
bool videoPlay, bool videoPlay,
bool cameraPlay, bool cameraPlay,
bool channelMute, bool channelMute,
bool invertedVideo) bool invertedVideo,
float rfScaling)
{ {
Message* cmd = MsgConfigureATVMod::create( Message* cmd = MsgConfigureATVMod::create(
rfBandwidth, rfBandwidth,
@ -127,7 +128,8 @@ void ATVMod::configure(MessageQueue* messageQueue,
videoPlay, videoPlay,
cameraPlay, cameraPlay,
channelMute, channelMute,
invertedVideo); invertedVideo,
rfScaling);
messageQueue->push(cmd); messageQueue->push(cmd);
} }
@ -206,22 +208,22 @@ void ATVMod::modulateSample()
m_modPhasor += (t - 0.5f) * M_PI; 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
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.real(cos(m_modPhasor) * m_running.m_rfScalingFactor); // -1 dB
m_modSample.imag(sin(m_modPhasor) * 29204.0f); m_modSample.imag(sin(m_modPhasor) * m_running.m_rfScalingFactor);
break; break;
case ATVModulationLSB: case ATVModulationLSB:
case ATVModulationUSB: case ATVModulationUSB:
m_modSample = modulateSSB(t); m_modSample = modulateSSB(t);
m_modSample *= 29204.0f; m_modSample *= m_running.m_rfScalingFactor;
break; break;
case ATVModulationVestigialLSB: case ATVModulationVestigialLSB:
case ATVModulationVestigialUSB: case ATVModulationVestigialUSB:
m_modSample = modulateVestigialSSB(t); m_modSample = modulateVestigialSSB(t);
m_modSample *= 29204.0f; m_modSample *= m_running.m_rfScalingFactor;
break; break;
case ATVModulationAM: // AM 90% case ATVModulationAM: // AM 90%
default: 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) * (m_running.m_rfScalingFactor/2.0f)); // modulate and scale zero frequency carrier
m_modSample.imag(0.0f); m_modSample.imag(0.0f);
} }
} }
@ -535,6 +537,7 @@ bool ATVMod::handleMessage(const Message& cmd)
m_config.m_cameraPlay = cfg.getCameraPlay(); m_config.m_cameraPlay = cfg.getCameraPlay();
m_config.m_channelMute = cfg.getChannelMute(); m_config.m_channelMute = cfg.getChannelMute();
m_config.m_invertedVideo = cfg.getInvertedVideo(); m_config.m_invertedVideo = cfg.getInvertedVideo();
m_config.m_rfScalingFactor = cfg.getRFScaling();
apply(); apply();
@ -551,7 +554,8 @@ bool ATVMod::handleMessage(const Message& cmd)
<< " m_videoPlay: " << m_config.m_videoPlay << " m_videoPlay: " << m_config.m_videoPlay
<< " m_cameraPlay: " << m_config.m_cameraPlay << " m_cameraPlay: " << m_config.m_cameraPlay
<< " m_channelMute: " << m_config.m_channelMute << " m_channelMute: " << m_config.m_channelMute
<< " m_invertedVideo: " << m_config.m_invertedVideo; << " m_invertedVideo: " << m_config.m_invertedVideo
<< " m_rfScalingFactor: " << m_config.m_rfScalingFactor;
return true; return true;
} }
@ -725,6 +729,7 @@ void ATVMod::apply(bool force)
m_running.m_cameraPlay = m_config.m_cameraPlay; m_running.m_cameraPlay = m_config.m_cameraPlay;
m_running.m_channelMute = m_config.m_channelMute; m_running.m_channelMute = m_config.m_channelMute;
m_running.m_invertedVideo = m_config.m_invertedVideo; m_running.m_invertedVideo = m_config.m_invertedVideo;
m_running.m_rfScalingFactor = m_config.m_rfScalingFactor;
} }
void ATVMod::getBaseValues(int linesPerSecond, int& sampleRateUnits, int& nbPointsPerRateUnit) void ATVMod::getBaseValues(int linesPerSecond, int& sampleRateUnits, int& nbPointsPerRateUnit)

View File

@ -342,7 +342,8 @@ public:
bool videoPlay, bool videoPlay,
bool cameraPLay, bool cameraPLay,
bool channelMute, bool channelMute,
bool invertedVideo); bool invertedVideo,
float rfScaling);
virtual void pull(Sample& sample); virtual void pull(Sample& sample);
virtual void pullAudio(int nbSamples); // this is used for video signal actually virtual void pullAudio(int nbSamples); // this is used for video signal actually
@ -385,6 +386,7 @@ private:
bool getCameraPlay() const { return m_cameraPlay; } bool getCameraPlay() const { return m_cameraPlay; }
bool getChannelMute() const { return m_channelMute; } bool getChannelMute() const { return m_channelMute; }
bool getInvertedVideo() const { return m_invertedVideo; } bool getInvertedVideo() const { return m_invertedVideo; }
float getRFScaling() const { return m_rfScaling; }
static MsgConfigureATVMod* create( static MsgConfigureATVMod* create(
Real rfBandwidth, Real rfBandwidth,
@ -399,7 +401,8 @@ private:
bool videoPlay, bool videoPlay,
bool cameraPlay, bool cameraPlay,
bool channelMute, bool channelMute,
bool invertedVideo) bool invertedVideo,
float rfScaling)
{ {
return new MsgConfigureATVMod( return new MsgConfigureATVMod(
rfBandwidth, rfBandwidth,
@ -414,7 +417,8 @@ private:
videoPlay, videoPlay,
cameraPlay, cameraPlay,
channelMute, channelMute,
invertedVideo); invertedVideo,
rfScaling);
} }
private: private:
@ -431,6 +435,7 @@ private:
bool m_cameraPlay; bool m_cameraPlay;
bool m_channelMute; bool m_channelMute;
bool m_invertedVideo; bool m_invertedVideo;
float m_rfScaling;
MsgConfigureATVMod( MsgConfigureATVMod(
Real rfBandwidth, Real rfBandwidth,
@ -445,7 +450,8 @@ private:
bool videoPlay, bool videoPlay,
bool cameraPlay, bool cameraPlay,
bool channelMute, bool channelMute,
bool invertedVideo) : bool invertedVideo,
float rfScaling) :
Message(), Message(),
m_rfBandwidth(rfBandwidth), m_rfBandwidth(rfBandwidth),
m_rfOppBandwidth(rfOppBandwidth), m_rfOppBandwidth(rfOppBandwidth),
@ -459,7 +465,8 @@ private:
m_videoPlay(videoPlay), m_videoPlay(videoPlay),
m_cameraPlay(cameraPlay), m_cameraPlay(cameraPlay),
m_channelMute(channelMute), m_channelMute(channelMute),
m_invertedVideo(invertedVideo) m_invertedVideo(invertedVideo),
m_rfScaling(rfScaling)
{ } { }
}; };
@ -508,6 +515,7 @@ private:
bool m_cameraPlay; //!< True to play camera video and false to pause bool m_cameraPlay; //!< True to play camera video and false to pause
bool m_channelMute; //!< Mute channel baseband output bool m_channelMute; //!< Mute channel baseband output
bool m_invertedVideo; //!< True if video signal is inverted before modulation bool m_invertedVideo; //!< True if video signal is inverted before modulation
float m_rfScalingFactor; //!< Scaling factor from +/-1 to +/-2^15
Config() : Config() :
m_outputSampleRate(-1), m_outputSampleRate(-1),
@ -524,7 +532,8 @@ private:
m_videoPlay(false), m_videoPlay(false),
m_cameraPlay(false), m_cameraPlay(false),
m_channelMute(false), m_channelMute(false),
m_invertedVideo(false) m_invertedVideo(false),
m_rfScalingFactor(29204.0f) // -1dB
{ } { }
}; };

View File

@ -100,6 +100,7 @@ QByteArray ATVModGUI::serialize() const
s.writeBool(9, ui->invertVideo->isChecked()); s.writeBool(9, ui->invertVideo->isChecked());
s.writeS32(10, ui->nbLines->currentIndex()); s.writeS32(10, ui->nbLines->currentIndex());
s.writeS32(11, ui->fps->currentIndex()); s.writeS32(11, ui->fps->currentIndex());
s.writeS32(12, ui->rfScaling->value());
return s.final(); return s.final();
} }
@ -150,6 +151,8 @@ bool ATVModGUI::deserialize(const QByteArray& data)
ui->nbLines->setCurrentIndex(tmp); ui->nbLines->setCurrentIndex(tmp);
d.readS32(11, &tmp, 0); d.readS32(11, &tmp, 0);
ui->fps->setCurrentIndex(tmp); ui->fps->setCurrentIndex(tmp);
d.readS32(12, &tmp, 80);
ui->rfScaling->setValue(tmp);
blockApplySettings(false); blockApplySettings(false);
m_channelMarker.blockSignals(false); m_channelMarker.blockSignals(false);
@ -333,6 +336,12 @@ void ATVModGUI::on_modulation_currentIndexChanged(int index)
applySettings(); applySettings();
} }
void ATVModGUI::on_rfScaling_valueChanged(int value)
{
ui->rfScalingText->setText(tr("%1").arg(value));
applySettings();
}
void ATVModGUI::on_rfBW_valueChanged(int value) void ATVModGUI::on_rfBW_valueChanged(int value)
{ {
ui->rfBWText->setText(QString("%1k").arg((value*m_rfSliderDivisor) / 1000.0, 0, 'f', 0)); ui->rfBWText->setText(QString("%1k").arg((value*m_rfSliderDivisor) / 1000.0, 0, 'f', 0));
@ -613,7 +622,8 @@ void ATVModGUI::applySettings()
ui->playVideo->isChecked(), ui->playVideo->isChecked(),
ui->playCamera->isChecked(), ui->playCamera->isChecked(),
ui->channelMute->isChecked(), ui->channelMute->isChecked(),
ui->invertVideo->isChecked()); ui->invertVideo->isChecked(),
ui->rfScaling->value() * 327.68f);
} }
} }

View File

@ -64,6 +64,7 @@ private slots:
void on_deltaMinus_toggled(bool minus); void on_deltaMinus_toggled(bool minus);
void on_channelMute_toggled(bool checked); void on_channelMute_toggled(bool checked);
void on_modulation_currentIndexChanged(int index); void on_modulation_currentIndexChanged(int index);
void on_rfScaling_valueChanged(int value);
void on_rfBW_valueChanged(int value); void on_rfBW_valueChanged(int value);
void on_rfOppBW_valueChanged(int value); void on_rfOppBW_valueChanged(int value);
void on_nbLines_currentIndexChanged(int index); void on_nbLines_currentIndexChanged(int index);

View File

@ -347,6 +347,55 @@
</item> </item>
<item> <item>
<layout class="QHBoxLayout" name="volumeLayout"> <layout class="QHBoxLayout" name="volumeLayout">
<item>
<widget class="QLabel" name="rfScalingLabel">
<property name="text">
<string>RF</string>
</property>
</widget>
</item>
<item>
<widget class="QDial" name="rfScaling">
<property name="maximumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="value">
<number>80</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="rfScalingText">
<property name="minimumSize">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>80</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="Line" name="line_9">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item> <item>
<widget class="QLabel" name="volLabel"> <widget class="QLabel" name="volLabel">
<property name="text"> <property name="text">