1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-11-26 01:39:05 -05:00

Deep redesign: fixed decimation bit shifts and halfband filter decimation bit loss

This commit is contained in:
f4exb 2015-09-02 00:12:00 +02:00
parent b3fd6bad15
commit a559035e22
9 changed files with 198 additions and 308 deletions

View File

@ -20,25 +20,73 @@
#include "dsp/dsptypes.h"
#include "dsp/inthalfbandfilter.h"
template<typename T>
template<uint SdrBits, uint InputBits>
struct decimation_shifts
{
static const uint pre1 = 0;
static const uint pre2 = 0;
static const uint post2 = 0;
static const uint pre4 = 0;
static const uint post4 = 0;
static const uint pre8 = 0;
static const uint post8 = 0;
static const uint pre16 = 0;
static const uint post16 = 0;
static const uint pre32 = 0;
static const uint post32 = 0;
};
template<>
struct decimation_shifts<16, 12>
{
static const uint pre1 = 4;
static const uint pre2 = 3;
static const uint post2 = 0;
static const uint pre4 = 2;
static const uint post4 = 0;
static const uint pre8 = 1;
static const uint post8 = 0;
static const uint pre16 = 0;
static const uint post16 = 0;
static const uint pre32 = 0;
static const uint post32 = 1;
};
template<>
struct decimation_shifts<16, 8>
{
static const uint pre1 = 8;
static const uint pre2 = 7;
static const uint post2 = 0;
static const uint pre4 = 6;
static const uint post4 = 0;
static const uint pre8 = 5;
static const uint post8 = 0;
static const uint pre16 = 4;
static const uint post16 = 0;
static const uint pre32 = 3;
static const uint post32 = 0;
};
template<typename T, uint SdrBits, uint InputBits>
class Decimators
{
public:
void decimate1(SampleVector::iterator* it, const T* buf, qint32 len);
void decimate2_u(SampleVector::iterator* it, const T* buf, qint32 len);
void decimate2(SampleVector::iterator* it, const T* buf, qint32 len);
void decimate2_inf(SampleVector::iterator* it, const T* buf, qint32 len);
void decimate2_sup(SampleVector::iterator* it, const T* buf, qint32 len);
void decimate2_cen(SampleVector::iterator* it, const T* buf, qint32 len);
void decimate4(SampleVector::iterator* it, const T* buf, qint32 len);
void decimate4_inf(SampleVector::iterator* it, const T* buf, qint32 len);
void decimate4_sup(SampleVector::iterator* it, const T* buf, qint32 len);
void decimate4_cen(SampleVector::iterator* it, const T* buf, qint32 len);
void decimate8(SampleVector::iterator* it, const T* buf, qint32 len);
void decimate8_inf(SampleVector::iterator* it, const T* buf, qint32 len);
void decimate8_sup(SampleVector::iterator* it, const T* buf, qint32 len);
void decimate8_cen(SampleVector::iterator* it, const T* buf, qint32 len);
void decimate16(SampleVector::iterator* it, const T* buf, qint32 len);
void decimate16_inf(SampleVector::iterator* it, const T* buf, qint32 len);
void decimate16_sup(SampleVector::iterator* it, const T* buf, qint32 len);
void decimate16_cen(SampleVector::iterator* it, const T* buf, qint32 len);
void decimate32(SampleVector::iterator* it, const T* buf, qint32 len);
void decimate32_inf(SampleVector::iterator* it, const T* buf, qint32 len);
void decimate32_sup(SampleVector::iterator* it, const T* buf, qint32 len);
void decimate32_cen(SampleVector::iterator* it, const T* buf, qint32 len);
@ -50,166 +98,113 @@ private:
IntHalfbandFilter m_decimator32; // 5th stages
};
template<typename T>
void Decimators<T>::decimate1(SampleVector::iterator* it, const T* buf, qint32 len)
template<typename T, uint SdrBits, uint InputBits>
void Decimators<T, SdrBits, InputBits>::decimate1(SampleVector::iterator* it, const T* buf, qint32 len)
{
qint16 xreal, yimag;
for (int pos = 0; pos < len; pos += 2) {
for (int pos = 0; pos < len; pos += 2)
{
xreal = buf[pos+0];
yimag = buf[pos+1];
(**it).setReal(xreal * 16); // Valgrind optim (2 - comment not repeated)
(**it).setImag(yimag * 16);
//Sample s( xreal * 16, yimag * 16 ); // shift by 4 bit positions (signed)
//**it = s;
(**it).setReal(xreal << decimation_shifts<SdrBits, InputBits>::pre1); // Valgrind optim (2 - comment not repeated)
(**it).setImag(yimag << decimation_shifts<SdrBits, InputBits>::pre1);
++(*it); // Valgrind optim (comment not repeated)
}
}
template<typename T>
void Decimators<T>::decimate2_u(SampleVector::iterator* it, const T* buf, qint32 len)
template<typename T, uint SdrBits, uint InputBits>
void Decimators<T, SdrBits, InputBits>::decimate2_u(SampleVector::iterator* it, const T* buf, qint32 len)
{
qint16 xreal, yimag;
for (int pos = 0; pos < len - 7; pos += 8)
{
xreal = buf[pos+0] - buf[pos+3];
yimag = buf[pos+1] + buf[pos+2] - 255;
//Sample s( xreal << 3, yimag << 3 );
//**it = s;
(**it).setReal(xreal << 3);
(**it).setImag(yimag << 3);
xreal = (buf[pos+0] - buf[pos+3]) << decimation_shifts<SdrBits, InputBits>::pre2;
yimag = (buf[pos+1] + buf[pos+2] - 255) << decimation_shifts<SdrBits, InputBits>::pre2;
(**it).setReal(xreal >> decimation_shifts<SdrBits, InputBits>::post2);
(**it).setImag(yimag >> decimation_shifts<SdrBits, InputBits>::post2);
++(*it);
xreal = buf[pos+7] - buf[pos+4];
yimag = 255 - buf[pos+5] - buf[pos+6];
//Sample t( xreal << 3, yimag << 3 );
//**it = t;
(**it).setReal(xreal << 3);
(**it).setImag(yimag << 3);
xreal = (buf[pos+7] - buf[pos+4]) << decimation_shifts<SdrBits, InputBits>::pre2;
yimag = (255 - buf[pos+5] - buf[pos+6]) << decimation_shifts<SdrBits, InputBits>::pre2;
(**it).setReal(xreal >> decimation_shifts<SdrBits, InputBits>::post2);
(**it).setImag(yimag >> decimation_shifts<SdrBits, InputBits>::post2);
++(*it);
}
}
template<typename T>
void Decimators<T>::decimate2(SampleVector::iterator* it, const T* buf, qint32 len)
template<typename T, uint SdrBits, uint InputBits>
void Decimators<T, SdrBits, InputBits>::decimate2_inf(SampleVector::iterator* it, const T* buf, qint32 len)
{
qint16 xreal, yimag;
for (int pos = 0; pos < len - 7; pos += 8)
{
xreal = buf[pos+0] - buf[pos+3];
yimag = buf[pos+1] + buf[pos+2];
//Sample s( xreal << 3, yimag << 3 );
//**it = s;
(**it).setReal(xreal << 3);
(**it).setImag(yimag << 3);
xreal = (buf[pos+0] - buf[pos+3]) << decimation_shifts<SdrBits, InputBits>::pre2;
yimag = (buf[pos+1] + buf[pos+2]) << decimation_shifts<SdrBits, InputBits>::pre2;
(**it).setReal(xreal >> decimation_shifts<SdrBits, InputBits>::post2);
(**it).setImag(yimag >> decimation_shifts<SdrBits, InputBits>::post2);
++(*it);
xreal = buf[pos+7] - buf[pos+4];
yimag = - buf[pos+5] - buf[pos+6];
//Sample t( xreal << 3, yimag << 3 );
//**it = t;
(**it).setReal(xreal << 3);
(**it).setImag(yimag << 3);
xreal = (buf[pos+7] - buf[pos+4]) << decimation_shifts<SdrBits, InputBits>::pre2;
yimag = (- buf[pos+5] - buf[pos+6]) << decimation_shifts<SdrBits, InputBits>::pre2;
(**it).setReal(xreal >> decimation_shifts<SdrBits, InputBits>::post2);
(**it).setImag(yimag >> decimation_shifts<SdrBits, InputBits>::post2);
++(*it);
}
}
template<typename T>
void Decimators<T>::decimate2_sup(SampleVector::iterator* it, const T* buf, qint32 len)
template<typename T, uint SdrBits, uint InputBits>
void Decimators<T, SdrBits, InputBits>::decimate2_sup(SampleVector::iterator* it, const T* 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).setReal(xreal << 3);
(**it).setImag(yimag << 3);
xreal = (buf[pos+1] - buf[pos+2]) << decimation_shifts<SdrBits, InputBits>::pre2;
yimag = (- buf[pos+0] - buf[pos+3]) << decimation_shifts<SdrBits, InputBits>::pre2;
(**it).setReal(xreal >> decimation_shifts<SdrBits, InputBits>::post2);
(**it).setImag(yimag >> decimation_shifts<SdrBits, InputBits>::post2);
++(*it);
xreal = buf[pos+6] - buf[pos+5];
yimag = buf[pos+4] + buf[pos+7];
//Sample t( xreal << 3, yimag << 3 );
//**it = t;
(**it).setReal(xreal << 3);
(**it).setImag(yimag << 3);
xreal = (buf[pos+6] - buf[pos+5]) << decimation_shifts<SdrBits, InputBits>::pre2;
yimag = (buf[pos+4] + buf[pos+7]) << decimation_shifts<SdrBits, InputBits>::pre2;
(**it).setReal(xreal >> decimation_shifts<SdrBits, InputBits>::post2);
(**it).setImag(yimag >> decimation_shifts<SdrBits, InputBits>::post2);
++(*it);
}
}
/*
template<typename T>
void Decimators<T>::decimate2_cen(SampleVector::iterator* it, const T* buf, qint32 len)
template<typename T, uint SdrBits, uint InputBits>
void Decimators<T, SdrBits, InputBits>::decimate2_cen(SampleVector::iterator* it, const T* buf, qint32 len)
{
int pos = 0;
while (pos < len - 3)
{
Sample s0(buf[pos+0] << 3, buf[pos+1] << 3);
pos += 2;
if (m_decimator2.workDecimateCenter(&s0))
{
**it = s0;
++(*it);
}
}
}*/
template<typename T>
void Decimators<T>::decimate2_cen(SampleVector::iterator* it, const T* buf, qint32 len)
{
int pos = 0;
while (pos < len - 3)
{
qint16 x0 = buf[pos+0] << 3;
qint16 y0 = buf[pos+1] << 3;
qint16 x0 = buf[pos+0] << decimation_shifts<SdrBits, InputBits>::pre2;
qint16 y0 = buf[pos+1] << decimation_shifts<SdrBits, InputBits>::pre2;
pos += 2;
if (m_decimator2.workDecimateCenter(&x0, &y0))
{
(**it).setReal(x0);
(**it).setImag(y0);
(**it).setReal(x0 >> decimation_shifts<SdrBits, InputBits>::post2);
(**it).setImag(y0 >> decimation_shifts<SdrBits, InputBits>::post2);
++(*it);
}
}
}
/*
template<typename T>
void Decimators<T>::decimate4_cen(SampleVector::iterator* it, const T* buf, qint32 len)
template<typename T, uint SdrBits, uint InputBits>
void Decimators<T, SdrBits, InputBits>::decimate4_cen(SampleVector::iterator* it, const T* buf, qint32 len)
{
int pos = 0;
while (pos < len)
{
Sample s0(buf[pos+0] << 4, buf[pos+1] << 4);
pos += 2;
if (m_decimator2.workDecimateCenter(&s0))
{
Sample s1 = s0;
if (m_decimator4.workDecimateCenter(&s1))
{
(**it) = s1;
++(*it);
}
}
}
}*/
template<typename T>
void Decimators<T>::decimate4_cen(SampleVector::iterator* it, const T* buf, qint32 len)
{
int pos = 0;
while (pos < len)
{
qint16 x0 = buf[pos+0] << 3;
qint16 y0 = buf[pos+1] << 3;
qint16 x0 = buf[pos+0] << decimation_shifts<SdrBits, InputBits>::pre4;
qint16 y0 = buf[pos+1] << decimation_shifts<SdrBits, InputBits>::pre4;
pos += 2;
if (m_decimator2.workDecimateCenter(&x0, &y0))
@ -219,23 +214,23 @@ void Decimators<T>::decimate4_cen(SampleVector::iterator* it, const T* buf, qint
if (m_decimator4.workDecimateCenter(&x1, &y1))
{
(**it).setReal(x0);
(**it).setImag(y0);
(**it).setReal(x0 >> decimation_shifts<SdrBits, InputBits>::post4);
(**it).setImag(y0 >> decimation_shifts<SdrBits, InputBits>::post4);
++(*it);
}
}
}
}
template<typename T>
void Decimators<T>::decimate8_cen(SampleVector::iterator* it, const T* buf, qint32 len)
template<typename T, uint SdrBits, uint InputBits>
void Decimators<T, SdrBits, InputBits>::decimate8_cen(SampleVector::iterator* it, const T* buf, qint32 len)
{
int pos = 0;
while (pos < len)
{
qint16 x0 = buf[pos+0] << 4;
qint16 y0 = buf[pos+1] << 4;
qint16 x0 = buf[pos+0] << decimation_shifts<SdrBits, InputBits>::pre8;
qint16 y0 = buf[pos+1] << decimation_shifts<SdrBits, InputBits>::pre8;
pos += 2;
if (m_decimator2.workDecimateCenter(&x0, &y0))
@ -250,8 +245,8 @@ void Decimators<T>::decimate8_cen(SampleVector::iterator* it, const T* buf, qint
if (m_decimator8.workDecimateCenter(&x2, &y2))
{
(**it).setReal(x2);
(**it).setImag(y2);
(**it).setReal(x2 >> decimation_shifts<SdrBits, InputBits>::post8);
(**it).setImag(y2 >> decimation_shifts<SdrBits, InputBits>::post8);
++(*it);
}
}
@ -259,44 +254,15 @@ void Decimators<T>::decimate8_cen(SampleVector::iterator* it, const T* buf, qint
}
}
/*
template<typename T>
void Decimators<T>::decimate8_cen(SampleVector::iterator* it, const T* buf, qint32 len)
template<typename T, uint SdrBits, uint InputBits>
void Decimators<T, SdrBits, InputBits>::decimate16_cen(SampleVector::iterator* it, const T* buf, qint32 len)
{
int pos = 0;
while (pos < len)
{
Sample s0(buf[pos+0] << 4, buf[pos+1] << 4);
pos += 2;
if (m_decimator2.workDecimateCenter(&s0))
{
Sample s1 = s0;
if (m_decimator4.workDecimateCenter(&s1))
{
Sample s2 = s1;
if (m_decimator8.workDecimateCenter(&s2))
{
(**it) = s2;
++(*it);
}
}
}
}
}*/
template<typename T>
void Decimators<T>::decimate16_cen(SampleVector::iterator* it, const T* buf, qint32 len)
{
int pos = 0;
while (pos < len)
{
qint16 x0 = buf[pos+0] << 4;
qint16 y0 = buf[pos+1] << 4;
qint16 x0 = buf[pos+0] << decimation_shifts<SdrBits, InputBits>::pre16;
qint16 y0 = buf[pos+1] << decimation_shifts<SdrBits, InputBits>::pre16;
pos += 2;
if (m_decimator2.workDecimateCenter(&x0, &y0))
@ -316,8 +282,8 @@ void Decimators<T>::decimate16_cen(SampleVector::iterator* it, const T* buf, qin
if (m_decimator16.workDecimateCenter(&x3, &y3))
{
(**it).setReal(x3);
(**it).setImag(y3);
(**it).setReal(x3 >> decimation_shifts<SdrBits, InputBits>::post16);
(**it).setImag(y3 >> decimation_shifts<SdrBits, InputBits>::post16);
++(*it);
}
}
@ -326,15 +292,15 @@ void Decimators<T>::decimate16_cen(SampleVector::iterator* it, const T* buf, qin
}
}
template<typename T>
void Decimators<T>::decimate32_cen(SampleVector::iterator* it, const T* buf, qint32 len)
template<typename T, uint SdrBits, uint InputBits>
void Decimators<T, SdrBits, InputBits>::decimate32_cen(SampleVector::iterator* it, const T* buf, qint32 len)
{
int pos = 0;
while (pos < len)
{
qint16 x0 = buf[pos+0] << 4;
qint16 y0 = buf[pos+1] << 4;
qint16 x0 = buf[pos+0] << decimation_shifts<SdrBits, InputBits>::pre32;
qint16 y0 = buf[pos+1] << decimation_shifts<SdrBits, InputBits>::pre32;
pos += 2;
if (m_decimator2.workDecimateCenter(&x0, &y0))
@ -359,8 +325,8 @@ void Decimators<T>::decimate32_cen(SampleVector::iterator* it, const T* buf, qin
if (m_decimator32.workDecimateCenter(&x4, &y4))
{
(**it).setReal(x4);
(**it).setImag(y4);
(**it).setReal(x4 >> decimation_shifts<SdrBits, InputBits>::post32);
(**it).setImag(y4 >> decimation_shifts<SdrBits, InputBits>::post32);
++(*it);
}
}
@ -370,27 +336,25 @@ void Decimators<T>::decimate32_cen(SampleVector::iterator* it, const T* buf, qin
}
}
template<typename T>
void Decimators<T>::decimate4(SampleVector::iterator* it, const T* buf, qint32 len)
template<typename T, uint SdrBits, uint InputBits>
void Decimators<T, SdrBits, InputBits>::decimate4_inf(SampleVector::iterator* it, const T* buf, qint32 len)
{
qint16 xreal, yimag;
for (int pos = 0; pos < len - 7; pos += 8)
{
xreal = buf[pos+0] - buf[pos+3] + buf[pos+7] - buf[pos+4];
yimag = buf[pos+1] - buf[pos+5] + buf[pos+2] - buf[pos+6];
xreal = (buf[pos+0] - buf[pos+3] + buf[pos+7] - buf[pos+4]) << decimation_shifts<SdrBits, InputBits>::pre4;
yimag = (buf[pos+1] - buf[pos+5] + buf[pos+2] - buf[pos+6]) << decimation_shifts<SdrBits, InputBits>::pre4;
(**it).setReal(xreal >> decimation_shifts<SdrBits, InputBits>::post4);
(**it).setImag(yimag >> decimation_shifts<SdrBits, InputBits>::post4);
(**it).setReal(xreal << 2);
(**it).setImag(yimag << 2);
/*
Sample s( xreal << 2, yimag << 2 ); // was shift 3
**it = s;*/
++(*it);
}
}
template<typename T>
void Decimators<T>::decimate4_sup(SampleVector::iterator* it, const T* buf, qint32 len)
template<typename T, uint SdrBits, uint InputBits>
void Decimators<T, SdrBits, InputBits>::decimate4_sup(SampleVector::iterator* it, const T* buf, qint32 len)
{
// Sup (USB):
// x y x y x y x y / x -> 1,-2,-5,6 / y -> -0,-3,4,7
@ -402,74 +366,64 @@ void Decimators<T>::decimate4_sup(SampleVector::iterator* it, const T* buf, qint
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];
xreal = (buf[pos+1] - buf[pos+2] - buf[pos+5] + buf[pos+6]) << decimation_shifts<SdrBits, InputBits>::pre4;
yimag = (- buf[pos+0] - buf[pos+3] + buf[pos+4] + buf[pos+7]) << decimation_shifts<SdrBits, InputBits>::pre4;
(**it).setReal(xreal >> decimation_shifts<SdrBits, InputBits>::post4);
(**it).setImag(yimag >> decimation_shifts<SdrBits, InputBits>::post4);
(**it).setReal(xreal << 2);
(**it).setImag(yimag << 2);
/*
Sample s( xreal << 2, yimag << 2 ); // was shift 3
**it = s;*/
++(*it);
}
}
template<typename T>
void Decimators<T>::decimate8(SampleVector::iterator* it, const T* buf, qint32 len)
template<typename T, uint SdrBits, uint InputBits>
void Decimators<T, SdrBits, InputBits>::decimate8_inf(SampleVector::iterator* it, const T* buf, qint32 len)
{
qint16 xreal[2], yimag[2];
for (int pos = 0; pos < len - 15; pos += 8)
{
xreal[0] = (buf[pos+0] - buf[pos+3] + buf[pos+7] - buf[pos+4]) << 2;
yimag[0] = (buf[pos+1] - buf[pos+5] + buf[pos+2] - buf[pos+6]) << 2;
//Sample s1( xreal << 2, yimag << 2 ); // was shift 3
xreal[0] = (buf[pos+0] - buf[pos+3] + buf[pos+7] - buf[pos+4]) << decimation_shifts<SdrBits, InputBits>::pre8;
yimag[0] = (buf[pos+1] - buf[pos+5] + buf[pos+2] - buf[pos+6]) << decimation_shifts<SdrBits, InputBits>::pre8;
pos += 8;
xreal[1] = (buf[pos+0] - buf[pos+3] + buf[pos+7] - buf[pos+4]) << 2;
yimag[1] = (buf[pos+1] - buf[pos+5] + buf[pos+2] - buf[pos+6]) << 2;
//Sample s2( xreal << 2, yimag << 2 ); // was shift 3
xreal[1] = (buf[pos+0] - buf[pos+3] + buf[pos+7] - buf[pos+4]) << decimation_shifts<SdrBits, InputBits>::pre8;
yimag[1] = (buf[pos+1] - buf[pos+5] + buf[pos+2] - buf[pos+6]) << decimation_shifts<SdrBits, InputBits>::pre8;
m_decimator2.myDecimate(xreal[0], yimag[0], &xreal[1], &yimag[1]);
(**it).setReal(xreal[1]);
(**it).setImag(yimag[1]);
/*
m_decimator2.myDecimate(&s1, &s2);
**it = s2;*/
(**it).setReal(xreal[1] >> decimation_shifts<SdrBits, InputBits>::post8);
(**it).setImag(yimag[1] >> decimation_shifts<SdrBits, InputBits>::post8);
++(*it);
}
}
template<typename T>
void Decimators<T>::decimate8_sup(SampleVector::iterator* it, const T* buf, qint32 len)
template<typename T, uint SdrBits, uint InputBits>
void Decimators<T, SdrBits, InputBits>::decimate8_sup(SampleVector::iterator* it, const T* buf, qint32 len)
{
qint16 xreal[2], yimag[2];
for (int pos = 0; pos < len - 15; pos += 8)
{
xreal[0] = (buf[pos+1] - buf[pos+2] - buf[pos+5] + buf[pos+6]) << 2;
yimag[0] = (- buf[pos+0] - buf[pos+3] + buf[pos+4] + buf[pos+7]) << 2;
//Sample s1( xreal << 2, yimag << 2 ); // was shift 3
xreal[0] = (buf[pos+1] - buf[pos+2] - buf[pos+5] + buf[pos+6]) << decimation_shifts<SdrBits, InputBits>::pre8;
yimag[0] = (- buf[pos+0] - buf[pos+3] + buf[pos+4] + buf[pos+7]) << decimation_shifts<SdrBits, InputBits>::pre8;
pos += 8;
xreal[1] = (buf[pos+1] - buf[pos+2] - buf[pos+5] + buf[pos+6]) << 2;
yimag[1] = (- buf[pos+0] - buf[pos+3] + buf[pos+4] + buf[pos+7]) << 2;
//Sample s2( xreal << 2, yimag << 2 ); // was shift 3
xreal[1] = (buf[pos+1] - buf[pos+2] - buf[pos+5] + buf[pos+6]) << decimation_shifts<SdrBits, InputBits>::pre8;
yimag[1] = (- buf[pos+0] - buf[pos+3] + buf[pos+4] + buf[pos+7]) << decimation_shifts<SdrBits, InputBits>::pre8;
m_decimator2.myDecimate(xreal[0], yimag[0], &xreal[1], &yimag[1]);
(**it).setReal(xreal[1]);
(**it).setImag(yimag[1]);
/*
m_decimator2.myDecimate(&s1, &s2);
**it = s2;*/
(**it).setReal(xreal[1] >> decimation_shifts<SdrBits, InputBits>::post8);
(**it).setImag(yimag[1] >> decimation_shifts<SdrBits, InputBits>::post8);
++(*it);
}
}
template<typename T>
void Decimators<T>::decimate16(SampleVector::iterator* it, const T* buf, qint32 len)
template<typename T, uint SdrBits, uint InputBits>
void Decimators<T, SdrBits, InputBits>::decimate16_inf(SampleVector::iterator* it, const T* buf, qint32 len)
{
// Offset tuning: 4x downsample and rotate, then
// downsample 4x more. [ rotate: 0, 1, -3, 2, -4, -5, 7, -6]
@ -479,36 +433,25 @@ void Decimators<T>::decimate16(SampleVector::iterator* it, const T* buf, qint32
{
for (int i = 0; i < 4; i++)
{
xreal[i] = (buf[pos+0] - buf[pos+3] + buf[pos+7] - buf[pos+4]) << 2; // was shift 4
yimag[i] = (buf[pos+1] - buf[pos+5] + buf[pos+2] - buf[pos+6]) << 2; // was shift 4
xreal[i] = (buf[pos+0] - buf[pos+3] + buf[pos+7] - buf[pos+4]) << decimation_shifts<SdrBits, InputBits>::pre16;
yimag[i] = (buf[pos+1] - buf[pos+5] + buf[pos+2] - buf[pos+6]) << decimation_shifts<SdrBits, InputBits>::pre16;
pos += 8;
}
m_decimator2.myDecimate(xreal[0], yimag[0], &xreal[1], &yimag[1]);
m_decimator2.myDecimate(xreal[2], yimag[2], &xreal[3], &yimag[3]);
m_decimator4.myDecimate(xreal[1], yimag[1], &xreal[3], &yimag[3]);
(**it).setReal(xreal[3]);
(**it).setImag(yimag[3]);
(**it).setReal(xreal[3] >> decimation_shifts<SdrBits, InputBits>::post16);
(**it).setImag(yimag[3] >> decimation_shifts<SdrBits, InputBits>::post16);
/* Valgrind optim
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);
}
}
template<typename T>
void Decimators<T>::decimate16_sup(SampleVector::iterator* it, const T* buf, qint32 len)
template<typename T, uint SdrBits, uint InputBits>
void Decimators<T, SdrBits, InputBits>::decimate16_sup(SampleVector::iterator* it, const T* buf, qint32 len)
{
// Offset tuning: 4x downsample and rotate, then
// downsample 4x more. [ rotate: 1, 0, -2, 3, -5, -4, 6, -7]
@ -518,8 +461,8 @@ void Decimators<T>::decimate16_sup(SampleVector::iterator* it, const T* buf, qin
{
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
xreal[i] = (buf[pos+1] - buf[pos+2] - buf[pos+5] + buf[pos+6]) << decimation_shifts<SdrBits, InputBits>::pre16;
yimag[i] = (buf[pos+4] + buf[pos+7] - buf[pos+0] - buf[pos+3]) << decimation_shifts<SdrBits, InputBits>::pre16;
pos += 8;
}
@ -528,26 +471,15 @@ void Decimators<T>::decimate16_sup(SampleVector::iterator* it, const T* buf, qin
m_decimator4.myDecimate(xreal[1], yimag[1], &xreal[3], &yimag[3]);
(**it).setReal(xreal[3]);
(**it).setImag(yimag[3]);
/*
Sample s1( xreal[0], yimag[0] );
Sample s2( xreal[1], yimag[1] );
Sample s3( xreal[2], yimag[2] );
Sample s4( xreal[3], yimag[3] );
(**it).setReal(xreal[3] >> decimation_shifts<SdrBits, InputBits>::post16);
(**it).setImag(yimag[3] >> decimation_shifts<SdrBits, InputBits>::post16);
m_decimator2.myDecimate(&s1, &s2);
m_decimator2.myDecimate(&s3, &s4);
m_decimator4.myDecimate(&s2, &s4);
**it = s4;*/
++(*it);
}
}
template<typename T>
void Decimators<T>::decimate32(SampleVector::iterator* it, const T* buf, qint32 len)
template<typename T, uint SdrBits, uint InputBits>
void Decimators<T, SdrBits, InputBits>::decimate32_inf(SampleVector::iterator* it, const T* buf, qint32 len)
{
qint16 xreal[8], yimag[8];
@ -555,8 +487,8 @@ void Decimators<T>::decimate32(SampleVector::iterator* it, const T* buf, qint32
{
for (int i = 0; i < 8; i++)
{
xreal[i] = (buf[pos+0] - buf[pos+3] + buf[pos+7] - buf[pos+4]) << 2;
yimag[i] = (buf[pos+1] - buf[pos+5] + buf[pos+2] - buf[pos+6]) << 2;
xreal[i] = (buf[pos+0] - buf[pos+3] + buf[pos+7] - buf[pos+4]) << decimation_shifts<SdrBits, InputBits>::pre32;
yimag[i] = (buf[pos+1] - buf[pos+5] + buf[pos+2] - buf[pos+6]) << decimation_shifts<SdrBits, InputBits>::pre32;
pos += 8;
}
@ -570,35 +502,15 @@ void Decimators<T>::decimate32(SampleVector::iterator* it, const T* buf, qint32
m_decimator8.myDecimate(xreal[3], yimag[3], &xreal[7], &yimag[7]);
(**it).setReal(xreal[7]);
(**it).setImag(yimag[7]);
/*
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] );
(**it).setReal(xreal[7] >> decimation_shifts<SdrBits, InputBits>::post32);
(**it).setImag(yimag[7] >> decimation_shifts<SdrBits, InputBits>::post32);
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);
}
}
template<typename T>
void Decimators<T>::decimate32_sup(SampleVector::iterator* it, const T* buf, qint32 len)
template<typename T, uint SdrBits, uint InputBits>
void Decimators<T, SdrBits, InputBits>::decimate32_sup(SampleVector::iterator* it, const T* buf, qint32 len)
{
qint16 xreal[8], yimag[8];
@ -606,8 +518,8 @@ void Decimators<T>::decimate32_sup(SampleVector::iterator* it, const T* buf, qin
{
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;
xreal[i] = (buf[pos+1] - buf[pos+2] - buf[pos+5] + buf[pos+6]) << decimation_shifts<SdrBits, InputBits>::pre32;
yimag[i] = (buf[pos+4] + buf[pos+7] - buf[pos+0] - buf[pos+3]) << decimation_shifts<SdrBits, InputBits>::pre32;
pos += 8;
}
@ -621,29 +533,9 @@ void Decimators<T>::decimate32_sup(SampleVector::iterator* it, const T* buf, qin
m_decimator8.myDecimate(xreal[3], yimag[3], &xreal[7], &yimag[7]);
(**it).setReal(xreal[7]);
(**it).setImag(yimag[7]);
/*
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] );
(**it).setReal(xreal[7] >> decimation_shifts<SdrBits, InputBits>::post32);
(**it).setImag(yimag[7] >> decimation_shifts<SdrBits, InputBits>::post32);
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);
}
}

View File

@ -424,7 +424,7 @@ protected:
0.317491986549921390015072120149852707982 * (1 << HB_SHIFT)
};
#elif HB_FILTERORDER == 32
static const qint16 mod33[38] = { 31,32,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,
static const int mod33[38] = { 31,32,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,
20,21,22,23,24,25,26,27,28,29,30,31,32,0,1,2} ;
static const qint32 COEFF[8] = {
(qint32)(-0.015956912844043127236437484839370881673 * (1 << HB_SHIFT)),
@ -467,8 +467,8 @@ protected:
iAcc += ((qint32)m_samples[a][0] + 1) << (HB_SHIFT - 1);
qAcc += ((qint32)m_samples[a][1] + 1) << (HB_SHIFT - 1);
*x = iAcc >> HB_SHIFT;
*y = qAcc >> HB_SHIFT;
*x = iAcc >> (HB_SHIFT -1); // HB_SHIFT incorrect do not loose the gained bit
*y = qAcc >> (HB_SHIFT -1);
}
};

View File

@ -22,6 +22,8 @@
#include <vector>
#include <QtGlobal>
#define SDR_SAMP_SZ 16 // internal fixed arithmetic sample size
typedef float Real;
typedef std::complex<Real> Complex;

View File

@ -130,7 +130,6 @@ void NFMDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto
{
if (m_interpolator.interpolate(&m_interpolatorDistanceRemain, c, &ci))
{
m_sampleBuffer.push_back(Sample(ci.real() * 32767.0, ci.imag() * 32767.0));
qint16 sample;
@ -269,8 +268,6 @@ void NFMDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto
m_audioBufferFill = 0;
}
m_sampleBuffer.clear();
m_settingsMutex.unlock();
}

View File

@ -171,7 +171,6 @@ private:
uint m_audioBufferFill;
AudioFifo m_audioFifo;
SampleVector m_sampleBuffer;
NFMDemodGUI *m_nfmDemodGUI;
QMutex m_settingsMutex;

View File

@ -610,19 +610,19 @@ void BladerfThread::callback(const qint16* buf, qint32 len)
switch (m_log2Decim)
{
case 1:
m_decimators.decimate2(&it, buf, len);
m_decimators.decimate2_inf(&it, buf, len);
break;
case 2:
m_decimators.decimate4(&it, buf, len);
m_decimators.decimate4_inf(&it, buf, len);
break;
case 3:
m_decimators.decimate8(&it, buf, len);
m_decimators.decimate8_inf(&it, buf, len);
break;
case 4:
m_decimators.decimate16(&it, buf, len);
m_decimators.decimate16_inf(&it, buf, len);
break;
case 5:
m_decimators.decimate32(&it, buf, len);
m_decimators.decimate32_inf(&it, buf, len);
break;
default:
break;

View File

@ -62,7 +62,7 @@ private:
IntHalfbandFilter m_decimator32; // 5th stages
*/
Decimators<qint16> m_decimators;
Decimators<qint16, SDR_SAMP_SZ, 12> m_decimators;
void run();
/*

View File

@ -91,16 +91,16 @@ void RTLSDRThread::callback(const quint8* buf, qint32 len)
m_decimators.decimate1(&it, buf, len);
break;
case 1:
m_decimators.decimate2(&it, buf, len);
m_decimators.decimate2_inf(&it, buf, len);
break;
case 2:
m_decimators.decimate4(&it, buf, len);
m_decimators.decimate4_inf(&it, buf, len);
break;
case 3:
m_decimators.decimate8(&it, buf, len);
m_decimators.decimate8_inf(&it, buf, len);
break;
case 4:
m_decimators.decimate16(&it, buf, len);
m_decimators.decimate16_inf(&it, buf, len);
break;
default:
break;

View File

@ -50,7 +50,7 @@ private:
int m_samplerate;
unsigned int m_log2Decim;
Decimators<quint8> m_decimators;
Decimators<quint8, SDR_SAMP_SZ, 8> m_decimators;
void run();
void callback(const quint8* buf, qint32 len);