1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2026-06-03 14:34:57 -04:00

FCD: added decimation and center frequency shift

This commit is contained in:
f4exb
2019-01-05 00:31:16 +01:00
parent 050ae9d2e8
commit 65e7519cd1
19 changed files with 424 additions and 125 deletions
@@ -245,6 +245,20 @@ void FCDProPlusGui::on_decim_currentIndexChanged(int index)
sendSettings();
}
void FCDProPlusGui::on_fcPos_currentIndexChanged(int index)
{
if (index == 0) {
m_settings.m_fcPos = FCDProPlusSettings::FC_POS_INFRA;
sendSettings();
} else if (index == 1) {
m_settings.m_fcPos = FCDProPlusSettings::FC_POS_SUPRA;
sendSettings();
} else if (index == 2) {
m_settings.m_fcPos = FCDProPlusSettings::FC_POS_CENTER;
sendSettings();
}
}
void FCDProPlusGui::on_dcOffset_toggled(bool checked)
{
m_settings.m_dcBlock = checked;
@@ -76,6 +76,7 @@ private slots:
void handleInputMessages();
void on_centerFrequency_changed(quint64 value);
void on_decim_currentIndexChanged(int index);
void on_fcPos_currentIndexChanged(int index);
void on_dcOffset_toggled(bool checked);
void on_iqImbalance_toggled(bool checked);
void on_checkBoxG_stateChanged(int state);
@@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>260</width>
<width>320</width>
<height>180</height>
</rect>
</property>
@@ -18,7 +18,7 @@
</property>
<property name="minimumSize">
<size>
<width>260</width>
<width>320</width>
<height>180</height>
</size>
</property>
@@ -251,6 +251,44 @@
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="fcPosLabel">
<property name="text">
<string>Fp</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="fcPos">
<property name="maximumSize">
<size>
<width>50</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Relative position of device center frequency</string>
</property>
<property name="currentIndex">
<number>2</number>
</property>
<item>
<property name="text">
<string>Inf</string>
</property>
</item>
<item>
<property name="text">
<string>Sup</string>
</property>
</item>
<item>
<property name="text">
<string>Cen</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QLabel" name="labelDecim">
<property name="text">
@@ -334,14 +334,24 @@ void FCDProPlusInput::applySettings(const FCDProPlusSettings& settings, bool for
if (force || (m_settings.m_transverterDeltaFrequency != settings.m_transverterDeltaFrequency)) {
reverseAPIKeys.append("transverterDeltaFrequency");
}
if ((m_settings.m_LOppmTenths != settings.m_LOppmTenths) || force) {
reverseAPIKeys.append("LOppmTenths");
}
if (force || (m_settings.m_centerFrequency != settings.m_centerFrequency)
|| (m_settings.m_transverterMode != settings.m_transverterMode)
|| (m_settings.m_transverterDeltaFrequency != settings.m_transverterDeltaFrequency))
|| (m_settings.m_LOppmTenths != settings.m_LOppmTenths)
|| (m_settings.m_fcPos != settings.m_fcPos)
|| (m_settings.m_log2Decim != settings.m_log2Decim)
|| (m_settings.m_transverterMode != settings.m_transverterMode)
|| (m_settings.m_transverterDeltaFrequency != settings.m_transverterDeltaFrequency))
{
qint64 deviceCenterFrequency = settings.m_centerFrequency;
deviceCenterFrequency -= settings.m_transverterMode ? settings.m_transverterDeltaFrequency : 0;
deviceCenterFrequency = deviceCenterFrequency < 0 ? 0 : deviceCenterFrequency;
qint64 deviceCenterFrequency = DeviceSampleSource::calculateDeviceCenterFrequency(
settings.m_centerFrequency,
settings.m_transverterDeltaFrequency,
settings.m_log2Decim,
(DeviceSampleSource::fcPos_t) settings.m_fcPos,
fcd_traits<ProPlus>::sampleRate,
settings.m_transverterMode);
if (m_dev != 0) {
set_center_freq((double) deviceCenterFrequency);
@@ -367,6 +377,17 @@ void FCDProPlusInput::applySettings(const FCDProPlusSettings& settings, bool for
}
}
if ((m_settings.m_fcPos != settings.m_fcPos) || force)
{
reverseAPIKeys.append("fcPos");
if (m_FCDThread != 0) {
m_FCDThread->setFcPos((int) settings.m_fcPos);
}
qDebug() << "FCDProPlusInput::applySettings: set fc pos (enum) to " << (int) settings.m_fcPos;
}
if ((m_settings.m_lnaGain != settings.m_lnaGain) || force)
{
reverseAPIKeys.append("lnaGain");
@@ -421,16 +442,6 @@ void FCDProPlusInput::applySettings(const FCDProPlusSettings& settings, bool for
}
}
if ((m_settings.m_LOppmTenths != settings.m_LOppmTenths) || force)
{
reverseAPIKeys.append("LOppmTenths");
m_settings.m_LOppmTenths = settings.m_LOppmTenths;
if (m_dev != 0) {
set_lo_ppm();
}
}
if ((m_settings.m_dcBlock != settings.m_dcBlock) || force)
{
reverseAPIKeys.append("dcBlock");
@@ -539,11 +550,6 @@ void FCDProPlusInput::set_rf_filter(int filterIndex)
}
}
void FCDProPlusInput::set_lo_ppm()
{
set_center_freq((double) m_settings.m_centerFrequency);
}
int FCDProPlusInput::webapiRunGet(
SWGSDRangel::SWGDeviceState& response,
QString& errorMessage)
@@ -150,7 +150,6 @@ public:
void set_if_gain(int gain);
void set_rf_filter(int filterIndex);
void set_if_filter(int filterIndex);
void set_lo_ppm();
private:
DeviceSourceAPI *m_deviceAPI;
@@ -35,6 +35,7 @@ void FCDProPlusSettings::resetToDefaults()
m_ifFilterIndex = 0;
m_LOppmTenths = 0;
m_log2Decim = 0;
m_fcPos = FC_POS_CENTER;
m_dcBlock = false;
m_iqImbalance = false;
m_transverterMode = false;
@@ -56,16 +57,17 @@ QByteArray FCDProPlusSettings::serialize() const
s.writeS32(4, m_ifFilterIndex);
s.writeS32(5, m_rfFilterIndex);
s.writeU32(6, m_log2Decim);
s.writeBool(7, m_dcBlock);
s.writeBool(8, m_iqImbalance);
s.writeS32(9, m_LOppmTenths);
s.writeU32(10, m_ifGain);
s.writeBool(11, m_transverterMode);
s.writeS64(12, m_transverterDeltaFrequency);
s.writeBool(13, m_useReverseAPI);
s.writeString(14, m_reverseAPIAddress);
s.writeU32(15, m_reverseAPIPort);
s.writeU32(16, m_reverseAPIDeviceIndex);
s.writeS32(7, (int) m_fcPos);
s.writeBool(8, m_dcBlock);
s.writeBool(9, m_iqImbalance);
s.writeS32(10, m_LOppmTenths);
s.writeU32(11, m_ifGain);
s.writeBool(12, m_transverterMode);
s.writeS64(13, m_transverterDeltaFrequency);
s.writeBool(14, m_useReverseAPI);
s.writeString(15, m_reverseAPIAddress);
s.writeU32(16, m_reverseAPIPort);
s.writeU32(17, m_reverseAPIDeviceIndex);
return s.final();
}
@@ -82,6 +84,7 @@ bool FCDProPlusSettings::deserialize(const QByteArray& data)
if (d.getVersion() == 1)
{
int intval;
uint32_t uintval;
d.readBool(1, &m_biasT, false);
@@ -90,15 +93,17 @@ bool FCDProPlusSettings::deserialize(const QByteArray& data)
d.readS32(4, &m_ifFilterIndex, 0);
d.readS32(5, &m_rfFilterIndex, 0);
d.readU32(6, &m_log2Decim, 0);
d.readBool(7, &m_dcBlock, false);
d.readBool(8, &m_iqImbalance, false);
d.readS32(9, &m_LOppmTenths, 0);
d.readU32(10, &m_ifGain, 0);
d.readBool(11, &m_transverterMode, false);
d.readS64(12, &m_transverterDeltaFrequency, 0);
d.readBool(13, &m_useReverseAPI, false);
d.readString(14, &m_reverseAPIAddress, "127.0.0.1");
d.readU32(15, &uintval, 0);
d.readS32(7, &intval, 2);
m_fcPos = (fcPos_t) intval;
d.readBool(8, &m_dcBlock, false);
d.readBool(9, &m_iqImbalance, false);
d.readS32(10, &m_LOppmTenths, 0);
d.readU32(11, &m_ifGain, 0);
d.readBool(12, &m_transverterMode, false);
d.readS64(13, &m_transverterDeltaFrequency, 0);
d.readBool(14, &m_useReverseAPI, false);
d.readString(15, &m_reverseAPIAddress, "127.0.0.1");
d.readU32(16, &uintval, 0);
if ((uintval > 1023) && (uintval < 65535)) {
m_reverseAPIPort = uintval;
@@ -106,7 +111,7 @@ bool FCDProPlusSettings::deserialize(const QByteArray& data)
m_reverseAPIPort = 8888;
}
d.readU32(16, &uintval, 0);
d.readU32(17, &uintval, 0);
m_reverseAPIDeviceIndex = uintval > 99 ? 99 : uintval;
return true;
}
@@ -20,6 +20,12 @@
#include <QString>
struct FCDProPlusSettings {
typedef enum {
FC_POS_INFRA = 0,
FC_POS_SUPRA,
FC_POS_CENTER
} fcPos_t;
quint64 m_centerFrequency;
bool m_rangeLow;
bool m_lnaGain;
@@ -30,6 +36,7 @@ struct FCDProPlusSettings {
qint32 m_rfFilterIndex;
qint32 m_LOppmTenths;
quint32 m_log2Decim;
fcPos_t m_fcPos;
bool m_dcBlock;
bool m_iqImbalance;
bool m_transverterMode;
@@ -29,6 +29,8 @@ FCDProPlusThread::FCDProPlusThread(SampleSinkFifo* sampleFifo, AudioFifo *fcdFIF
QThread(parent),
m_fcdFIFO(fcdFIFO),
m_running(false),
m_log2Decim(0),
m_fcPos(2),
m_convertBuffer(fcd_traits<ProPlus>::convBufSize), // nb samples
m_sampleFifo(sampleFifo)
{
@@ -64,6 +66,11 @@ void FCDProPlusThread::setLog2Decimation(unsigned int log2_decim)
m_log2Decim = log2_decim;
}
void FCDProPlusThread::setFcPos(int fcPos)
{
m_fcPos = fcPos;
}
void FCDProPlusThread::run()
{
m_running = true;
@@ -84,25 +91,90 @@ void FCDProPlusThread::work(unsigned int n_items)
uint32_t nbRead = m_fcdFIFO->read((unsigned char *) m_buf, n_items); // number of samples
SampleVector::iterator it = m_convertBuffer.begin();
switch (m_log2Decim)
if (m_log2Decim == 0)
{
case 0:
m_decimators.decimate1(&it, m_buf, 2*nbRead);
break;
case 1:
m_decimators.decimate2_cen(&it, m_buf, 2*nbRead);
break;
case 2:
m_decimators.decimate4_cen(&it, m_buf, 2*nbRead);
break;
case 3:
m_decimators.decimate8_cen(&it, m_buf, 2*nbRead);
break;
case 4:
m_decimators.decimate16_cen(&it, m_buf, 2*nbRead);
break;
default:
break;
m_decimators.decimate1(&it, m_buf, 2*nbRead);
}
else
{
if (m_fcPos == 0) // Infradyne
{
switch (m_log2Decim)
{
case 1:
m_decimators.decimate2_inf(&it, m_buf, 2*nbRead);
break;
case 2:
m_decimators.decimate4_inf(&it, m_buf, 2*nbRead);
break;
case 3:
m_decimators.decimate8_inf(&it, m_buf, 2*nbRead);
break;
case 4:
m_decimators.decimate16_inf(&it, m_buf, 2*nbRead);
break;
case 5:
m_decimators.decimate32_inf(&it, m_buf, 2*nbRead);
break;
case 6:
m_decimators.decimate64_inf(&it, m_buf, 2*nbRead);
break;
default:
break;
}
}
else if (m_fcPos == 1) // Supradyne
{
switch (m_log2Decim)
{
case 1:
m_decimators.decimate2_sup(&it, m_buf, 2*nbRead);
break;
case 2:
m_decimators.decimate4_sup(&it, m_buf, 2*nbRead);
break;
case 3:
m_decimators.decimate8_sup(&it, m_buf, 2*nbRead);
break;
case 4:
m_decimators.decimate16_sup(&it, m_buf, 2*nbRead);
break;
case 5:
m_decimators.decimate32_sup(&it, m_buf, 2*nbRead);
break;
case 6:
m_decimators.decimate64_sup(&it, m_buf, 2*nbRead);
break;
default:
break;
}
}
else // Centered
{
switch (m_log2Decim)
{
case 1:
m_decimators.decimate2_cen(&it, m_buf, 2*nbRead);
break;
case 2:
m_decimators.decimate4_cen(&it, m_buf, 2*nbRead);
break;
case 3:
m_decimators.decimate8_cen(&it, m_buf, 2*nbRead);
break;
case 4:
m_decimators.decimate16_cen(&it, m_buf, 2*nbRead);
break;
case 5:
m_decimators.decimate32_cen(&it, m_buf, 2*nbRead);
break;
case 6:
m_decimators.decimate64_cen(&it, m_buf, 2*nbRead);
break;
default:
break;
}
}
}
m_sampleFifo->write(m_convertBuffer.begin(), it);
@@ -38,6 +38,7 @@ public:
void startWork();
void stopWork();
void setLog2Decimation(unsigned int log2_decim);
void setFcPos(int fcPos);
private:
AudioFifo* m_fcdFIFO;
@@ -46,6 +47,7 @@ private:
QWaitCondition m_startWaiter;
bool m_running;
unsigned int m_log2Decim;
int m_fcPos;
qint16 m_buf[fcd_traits<ProPlus>::convBufSize*2]; // stereo (I, Q)
SampleVector m_convertBuffer;