mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-12-22 09:31:10 -05:00
Added infradyne or supradyne option when decimating
This commit is contained in:
parent
f2af402087
commit
637c6e74f7
@ -130,6 +130,8 @@ void BladerfGui::displaySettings()
|
||||
ui->decimText->setText(tr("%1").arg(1<<m_settings.m_log2Decim));
|
||||
ui->decim->setValue(m_settings.m_log2Decim);
|
||||
|
||||
ui->fcPos->setCurrentIndex((int) m_settings.m_fcPos);
|
||||
|
||||
ui->lnaGainText->setText(tr("%1").arg(m_settings.m_lnaGain));
|
||||
ui->lna->setValue(m_settings.m_lnaGain);
|
||||
|
||||
@ -179,6 +181,17 @@ void BladerfGui::on_decim_valueChanged(int value)
|
||||
sendSettings();
|
||||
}
|
||||
|
||||
void BladerfGui::on_fcPos_currentIndexChanged(int index)
|
||||
{
|
||||
if (index == 0) {
|
||||
m_settings.m_fcPos = BladerfInput::FC_POS_INFRA;
|
||||
sendSettings();
|
||||
} else if (index == 1) {
|
||||
m_settings.m_fcPos = BladerfInput::FC_POS_SUPRA;
|
||||
sendSettings();
|
||||
}
|
||||
}
|
||||
|
||||
void BladerfGui::on_lna_valueChanged(int value)
|
||||
{
|
||||
std::cerr << "BladerfGui: LNA gain = " << value << std::endl;
|
||||
|
@ -71,6 +71,7 @@ private slots:
|
||||
void on_vga1_valueChanged(int value);
|
||||
void on_vga2_valueChanged(int value);
|
||||
void on_xb200_currentIndexChanged(int index);
|
||||
void on_fcPos_currentIndexChanged(int index);
|
||||
void updateHardware();
|
||||
};
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>198</width>
|
||||
<height>255</height>
|
||||
<height>274</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
@ -364,6 +364,54 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_fcPos" columnstretch="0,0,0,0">
|
||||
<property name="spacing">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_fcPos">
|
||||
<property name="text">
|
||||
<string>Fc pos</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<spacer name="fcPosRightSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="fcPos">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Inf</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Sup</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line_fcPos">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_lna">
|
||||
<property name="spacing">
|
||||
|
@ -34,6 +34,7 @@ BladerfInput::Settings::Settings() :
|
||||
m_samplerate(3072000),
|
||||
m_bandwidth(1500000),
|
||||
m_log2Decim(0),
|
||||
m_fcPos(FC_POS_INFRA),
|
||||
m_xb200(false),
|
||||
m_xb200Path(BLADERF_XB200_MIX),
|
||||
m_xb200Filter(BLADERF_XB200_AUTO_1DB)
|
||||
@ -48,6 +49,7 @@ void BladerfInput::Settings::resetToDefaults()
|
||||
m_samplerate = 3072000;
|
||||
m_bandwidth = 1500000;
|
||||
m_log2Decim = 0;
|
||||
m_fcPos = FC_POS_INFRA;
|
||||
m_xb200 = false;
|
||||
m_xb200Path = BLADERF_XB200_MIX;
|
||||
m_xb200Filter = BLADERF_XB200_AUTO_1DB;
|
||||
@ -65,6 +67,7 @@ QByteArray BladerfInput::Settings::serialize() const
|
||||
s.writeS32(7, (int) m_xb200Path);
|
||||
s.writeS32(8, (int) m_xb200Filter);
|
||||
s.writeS32(9, m_bandwidth);
|
||||
s.writeS32(10, (int) m_fcPos);
|
||||
return s.final();
|
||||
}
|
||||
|
||||
@ -90,6 +93,8 @@ bool BladerfInput::Settings::deserialize(const QByteArray& data)
|
||||
d.readS32(8, &intval);
|
||||
m_xb200Filter = (bladerf_xb200_filter) intval;
|
||||
d.readS32(9, &m_bandwidth, 0);
|
||||
d.readS32(10, &intval, 0);
|
||||
m_fcPos = (fcPos_t) intval;
|
||||
return true;
|
||||
} else {
|
||||
resetToDefaults();
|
||||
@ -332,19 +337,50 @@ bool BladerfInput::applySettings(const GeneralSettings& generalSettings, const S
|
||||
}
|
||||
}
|
||||
|
||||
if((m_settings.m_fcPos != settings.m_fcPos) || force) {
|
||||
if(m_dev != NULL) {
|
||||
m_settings.m_fcPos = settings.m_fcPos;
|
||||
m_bladerfThread->setFcPos((int) settings.m_fcPos);
|
||||
std::cerr << "BladerfInput: set fc pos (enum) to " << (int) m_settings.m_fcPos << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
m_generalSettings.m_centerFrequency = generalSettings.m_centerFrequency;
|
||||
if(m_dev != NULL) {
|
||||
qint64 centerFrequency = m_generalSettings.m_centerFrequency + (m_settings.m_samplerate / 4);
|
||||
qint64 centerFrequency = m_generalSettings.m_centerFrequency;
|
||||
qint64 f_img = centerFrequency;
|
||||
qint64 f_cut = centerFrequency + m_settings.m_bandwidth/2;
|
||||
|
||||
if (m_settings.m_log2Decim == 0) { // Little wooby-doop if no decimation
|
||||
if (m_settings.m_log2Decim == 0)
|
||||
{ // Little wooby-doop if no decimation
|
||||
centerFrequency = m_generalSettings.m_centerFrequency;
|
||||
} else {
|
||||
centerFrequency = m_generalSettings.m_centerFrequency + (m_settings.m_samplerate / 4);
|
||||
f_img = centerFrequency;
|
||||
f_cut = centerFrequency + m_settings.m_bandwidth/2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_settings.m_fcPos == FC_POS_INFRA) {
|
||||
centerFrequency = m_generalSettings.m_centerFrequency + (m_settings.m_samplerate / 4);
|
||||
f_img = centerFrequency + m_settings.m_samplerate/2;
|
||||
f_cut = centerFrequency + m_settings.m_bandwidth/2;
|
||||
} else if (m_settings.m_fcPos == FC_POS_SUPRA) {
|
||||
centerFrequency = m_generalSettings.m_centerFrequency - (m_settings.m_samplerate / 4);
|
||||
f_img = centerFrequency - m_settings.m_samplerate/2;
|
||||
f_cut = centerFrequency - m_settings.m_bandwidth/2;
|
||||
}
|
||||
}
|
||||
|
||||
if(bladerf_set_frequency( m_dev, BLADERF_MODULE_RX, centerFrequency ) != 0) {
|
||||
qDebug("bladerf_set_frequency(%lld) failed", m_generalSettings.m_centerFrequency);
|
||||
}
|
||||
|
||||
std::cerr << "BladerfInput: center freq: " << m_generalSettings.m_centerFrequency << " Hz"
|
||||
<< " RF center freq: " << centerFrequency << " Hz"
|
||||
<< " sample rate / 2 : " << m_settings.m_samplerate/2 << "Hz"
|
||||
<< " BW: " << m_settings.m_bandwidth << "Hz"
|
||||
<< " img: " << f_img << "Hz"
|
||||
<< " cut: " << f_cut << "Hz"
|
||||
<< " img - cut: " << f_img - f_cut << std::endl;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -25,6 +25,11 @@ class BladerfThread;
|
||||
|
||||
class BladerfInput : public SampleSource {
|
||||
public:
|
||||
typedef enum {
|
||||
FC_POS_INFRA = 0,
|
||||
FC_POS_SUPRA
|
||||
} fcPos_t;
|
||||
|
||||
struct Settings {
|
||||
qint32 m_lnaGain;
|
||||
qint32 m_vga1;
|
||||
@ -32,6 +37,7 @@ public:
|
||||
qint32 m_samplerate;
|
||||
qint32 m_bandwidth;
|
||||
quint32 m_log2Decim;
|
||||
fcPos_t m_fcPos;
|
||||
bool m_xb200;
|
||||
bladerf_xb200_path m_xb200Path;
|
||||
bladerf_xb200_filter m_xb200Filter;
|
||||
|
@ -28,7 +28,8 @@ BladerfThread::BladerfThread(struct bladerf* dev, SampleFifo* sampleFifo, QObjec
|
||||
m_convertBuffer(BLADERF_BLOCKSIZE),
|
||||
m_sampleFifo(sampleFifo),
|
||||
m_samplerate(3072000),
|
||||
m_log2Decim(0)
|
||||
m_log2Decim(0),
|
||||
m_fcPos(0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -62,6 +63,11 @@ void BladerfThread::setLog2Decimation(unsigned int log2_decim)
|
||||
m_log2Decim = log2_decim;
|
||||
}
|
||||
|
||||
void BladerfThread::setFcPos(int fcPos)
|
||||
{
|
||||
m_fcPos = fcPos;
|
||||
}
|
||||
|
||||
void BladerfThread::run()
|
||||
{
|
||||
int res;
|
||||
@ -128,6 +134,23 @@ void BladerfThread::decimate2(SampleVector::iterator* it, const qint16* buf, qin
|
||||
}
|
||||
}
|
||||
|
||||
void BladerfThread::decimate2_sup(SampleVector::iterator* it, const qint16* buf, qint32 len)
|
||||
{
|
||||
qint16 xreal, yimag;
|
||||
for (int pos = 0; pos < len - 7; pos += 8) {
|
||||
xreal = buf[pos+1] - buf[pos+2];
|
||||
yimag = - buf[pos+0] - buf[pos+3];
|
||||
Sample s( xreal << 3, yimag << 3 );
|
||||
**it = s;
|
||||
(*it)++;
|
||||
xreal = buf[pos+6] - buf[pos+5];
|
||||
yimag = buf[pos+4] + buf[pos+7];
|
||||
Sample t( xreal << 3, yimag << 3 );
|
||||
**it = t;
|
||||
(*it)++;
|
||||
}
|
||||
}
|
||||
|
||||
void BladerfThread::decimate4(SampleVector::iterator* it, const qint16* buf, qint32 len)
|
||||
{
|
||||
qint16 xreal, yimag;
|
||||
@ -140,6 +163,26 @@ void BladerfThread::decimate4(SampleVector::iterator* it, const qint16* buf, qin
|
||||
}
|
||||
}
|
||||
|
||||
void BladerfThread::decimate4_sup(SampleVector::iterator* it, const qint16* buf, qint32 len)
|
||||
{
|
||||
// Sup (USB):
|
||||
// x y x y x y x y / x -> 1,-2,-5,6 / y -> -0,-3,4,7
|
||||
// [ rotate: 1, 0, -2, 3, -5, -4, 6, -7]
|
||||
// Inf (LSB):
|
||||
// x y x y x y x y / x -> 0,-3,-4,7 / y -> 1,2,-5,-6
|
||||
// [ rotate: 0, 1, -3, 2, -4, -5, 7, -6]
|
||||
qint16 xreal, yimag;
|
||||
for (int pos = 0; pos < len - 7; pos += 8) {
|
||||
xreal = buf[pos+1] - buf[pos+2] - buf[pos+5] + buf[pos+6];
|
||||
yimag = - buf[pos+0] - buf[pos+3] + buf[pos+4] + buf[pos+7];
|
||||
//xreal = buf[pos+0] - buf[pos+3] - buf[pos+4] + buf[pos+7];
|
||||
//yimag = buf[pos+1] + buf[pos+2] - buf[pos+5] - buf[pos+6];
|
||||
Sample s( xreal << 2, yimag << 2 ); // was shift 3
|
||||
**it = s;
|
||||
(*it)++;
|
||||
}
|
||||
}
|
||||
|
||||
void BladerfThread::decimate8(SampleVector::iterator* it, const qint16* buf, qint32 len)
|
||||
{
|
||||
qint16 xreal, yimag;
|
||||
@ -158,6 +201,24 @@ void BladerfThread::decimate8(SampleVector::iterator* it, const qint16* buf, qin
|
||||
}
|
||||
}
|
||||
|
||||
void BladerfThread::decimate8_sup(SampleVector::iterator* it, const qint16* buf, qint32 len)
|
||||
{
|
||||
qint16 xreal, yimag;
|
||||
for (int pos = 0; pos < len - 15; pos += 8) {
|
||||
xreal = buf[pos+1] - buf[pos+2] - buf[pos+5] + buf[pos+6];
|
||||
yimag = - buf[pos+0] - buf[pos+3] + buf[pos+4] + buf[pos+7];
|
||||
Sample s1( xreal << 2, yimag << 2 ); // was shift 3
|
||||
pos += 8;
|
||||
xreal = buf[pos+1] - buf[pos+2] - buf[pos+5] + buf[pos+6];
|
||||
yimag = - buf[pos+0] - buf[pos+3] + buf[pos+4] + buf[pos+7];
|
||||
Sample s2( xreal << 2, yimag << 2 ); // was shift 3
|
||||
|
||||
m_decimator2.myDecimate(&s1, &s2);
|
||||
**it = s2;
|
||||
(*it)++;
|
||||
}
|
||||
}
|
||||
|
||||
void BladerfThread::decimate16(SampleVector::iterator* it, const qint16* buf, qint32 len)
|
||||
{
|
||||
// Offset tuning: 4x downsample and rotate, then
|
||||
@ -186,6 +247,34 @@ void BladerfThread::decimate16(SampleVector::iterator* it, const qint16* buf, qi
|
||||
}
|
||||
}
|
||||
|
||||
void BladerfThread::decimate16_sup(SampleVector::iterator* it, const qint16* buf, qint32 len)
|
||||
{
|
||||
// Offset tuning: 4x downsample and rotate, then
|
||||
// downsample 4x more. [ rotate: 1, 0, -2, 3, -5, -4, 6, -7]
|
||||
qint16 xreal[4], yimag[4];
|
||||
|
||||
for (int pos = 0; pos < len - 31; ) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
xreal[i] = (buf[pos+1] - buf[pos+2] - buf[pos+5] + buf[pos+6]) << 2; // was shift 4
|
||||
yimag[i] = (buf[pos+4] + buf[pos+7] - buf[pos+0] - buf[pos+3]) << 2; // was shift 4
|
||||
pos += 8;
|
||||
}
|
||||
|
||||
Sample s1( xreal[0], yimag[0] );
|
||||
Sample s2( xreal[1], yimag[1] );
|
||||
Sample s3( xreal[2], yimag[2] );
|
||||
Sample s4( xreal[3], yimag[3] );
|
||||
|
||||
m_decimator2.myDecimate(&s1, &s2);
|
||||
m_decimator2.myDecimate(&s3, &s4);
|
||||
|
||||
m_decimator4.myDecimate(&s2, &s4);
|
||||
|
||||
**it = s4;
|
||||
(*it)++;
|
||||
}
|
||||
}
|
||||
|
||||
void BladerfThread::decimate32(SampleVector::iterator* it, const qint16* buf, qint32 len)
|
||||
{
|
||||
qint16 xreal[8], yimag[8];
|
||||
@ -221,34 +310,100 @@ void BladerfThread::decimate32(SampleVector::iterator* it, const qint16* buf, qi
|
||||
}
|
||||
}
|
||||
|
||||
void BladerfThread::decimate32_sup(SampleVector::iterator* it, const qint16* buf, qint32 len)
|
||||
{
|
||||
qint16 xreal[8], yimag[8];
|
||||
|
||||
for (int pos = 0; pos < len - 63; ) {
|
||||
for (int i = 0; i < 8; i++) {
|
||||
xreal[i] = (buf[pos+1] - buf[pos+2] - buf[pos+5] + buf[pos+6]) << 2;
|
||||
yimag[i] = (buf[pos+4] + buf[pos+7] - buf[pos+0] - buf[pos+3]) << 2;
|
||||
pos += 8;
|
||||
}
|
||||
|
||||
Sample s1( xreal[0], yimag[0] );
|
||||
Sample s2( xreal[1], yimag[1] );
|
||||
Sample s3( xreal[2], yimag[2] );
|
||||
Sample s4( xreal[3], yimag[3] );
|
||||
Sample s5( xreal[4], yimag[4] );
|
||||
Sample s6( xreal[5], yimag[5] );
|
||||
Sample s7( xreal[6], yimag[6] );
|
||||
Sample s8( xreal[7], yimag[7] );
|
||||
|
||||
m_decimator2.myDecimate(&s1, &s2);
|
||||
m_decimator2.myDecimate(&s3, &s4);
|
||||
m_decimator2.myDecimate(&s5, &s6);
|
||||
m_decimator2.myDecimate(&s7, &s8);
|
||||
|
||||
m_decimator4.myDecimate(&s2, &s4);
|
||||
m_decimator4.myDecimate(&s6, &s8);
|
||||
|
||||
m_decimator8.myDecimate(&s4, &s8);
|
||||
|
||||
**it = s8;
|
||||
(*it)++;
|
||||
}
|
||||
}
|
||||
|
||||
// Decimate according to specified log2 (ex: log2=4 => decim=16)
|
||||
void BladerfThread::callback(const qint16* buf, qint32 len)
|
||||
{
|
||||
SampleVector::iterator it = m_convertBuffer.begin();
|
||||
|
||||
switch (m_log2Decim)
|
||||
if (m_log2Decim == 0)
|
||||
{
|
||||
case 0:
|
||||
decimate1(&it, buf, len);
|
||||
break;
|
||||
case 1:
|
||||
decimate2(&it, buf, len);
|
||||
break;
|
||||
case 2:
|
||||
decimate4(&it, buf, len);
|
||||
break;
|
||||
case 3:
|
||||
decimate8(&it, buf, len);
|
||||
break;
|
||||
case 4:
|
||||
decimate16(&it, buf, len);
|
||||
break;
|
||||
case 5:
|
||||
decimate32(&it, buf, len);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_fcPos == 0) // Infra
|
||||
{
|
||||
switch (m_log2Decim)
|
||||
{
|
||||
case 1:
|
||||
decimate2(&it, buf, len);
|
||||
break;
|
||||
case 2:
|
||||
decimate4(&it, buf, len);
|
||||
break;
|
||||
case 3:
|
||||
decimate8(&it, buf, len);
|
||||
break;
|
||||
case 4:
|
||||
decimate16(&it, buf, len);
|
||||
break;
|
||||
case 5:
|
||||
decimate32(&it, buf, len);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (m_fcPos == 1) // Supra
|
||||
{
|
||||
switch (m_log2Decim)
|
||||
{
|
||||
case 1:
|
||||
decimate2_sup(&it, buf, len);
|
||||
break;
|
||||
case 2:
|
||||
decimate4_sup(&it, buf, len);
|
||||
break;
|
||||
case 3:
|
||||
decimate8_sup(&it, buf, len);
|
||||
break;
|
||||
case 4:
|
||||
decimate16_sup(&it, buf, len);
|
||||
break;
|
||||
case 5:
|
||||
decimate32_sup(&it, buf, len);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
m_sampleFifo->write(m_convertBuffer.begin(), it);
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ public:
|
||||
void stopWork();
|
||||
void setSamplerate(int samplerate);
|
||||
void setLog2Decimation(unsigned int log2_decim);
|
||||
void setFcPos(int fcPos);
|
||||
|
||||
private:
|
||||
QMutex m_startWaitMutex;
|
||||
@ -50,6 +51,7 @@ private:
|
||||
|
||||
int m_samplerate;
|
||||
unsigned int m_log2Decim;
|
||||
int m_fcPos;
|
||||
|
||||
IntHalfbandFilter m_decimator2; // 1st stages
|
||||
IntHalfbandFilter m_decimator4; // 2nd stages
|
||||
@ -59,10 +61,15 @@ private:
|
||||
void decimate1(SampleVector::iterator* it, const qint16* buf, qint32 len);
|
||||
void decimate2_u(SampleVector::iterator* it, const quint16* buf, qint32 len);
|
||||
void decimate2(SampleVector::iterator* it, const qint16* buf, qint32 len);
|
||||
void decimate2_sup(SampleVector::iterator* it, const qint16* buf, qint32 len);
|
||||
void decimate4(SampleVector::iterator* it, const qint16* buf, qint32 len);
|
||||
void decimate4_sup(SampleVector::iterator* it, const qint16* buf, qint32 len);
|
||||
void decimate8(SampleVector::iterator* it, const qint16* buf, qint32 len);
|
||||
void decimate8_sup(SampleVector::iterator* it, const qint16* buf, qint32 len);
|
||||
void decimate16(SampleVector::iterator* it, const qint16* buf, qint32 len);
|
||||
void decimate16_sup(SampleVector::iterator* it, const qint16* buf, qint32 len);
|
||||
void decimate32(SampleVector::iterator* it, const qint16* buf, qint32 len);
|
||||
void decimate32_sup(SampleVector::iterator* it, const qint16* buf, qint32 len);
|
||||
void callback(const qint16* buf, qint32 len);
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user