1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2025-05-23 18:52:28 -04: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/dsptypes.h"
#include "dsp/inthalfbandfilter.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 class Decimators
{ {
public: public:
void decimate1(SampleVector::iterator* it, const T* buf, qint32 len); void decimate1(SampleVector::iterator* it, const T* buf, qint32 len);
void decimate2_u(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_sup(SampleVector::iterator* it, const T* buf, qint32 len);
void decimate2_cen(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_sup(SampleVector::iterator* it, const T* buf, qint32 len);
void decimate4_cen(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_sup(SampleVector::iterator* it, const T* buf, qint32 len);
void decimate8_cen(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_sup(SampleVector::iterator* it, const T* buf, qint32 len);
void decimate16_cen(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_sup(SampleVector::iterator* it, const T* buf, qint32 len);
void decimate32_cen(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 IntHalfbandFilter m_decimator32; // 5th stages
}; };
template<typename T> template<typename T, uint SdrBits, uint InputBits>
void Decimators<T>::decimate1(SampleVector::iterator* it, const T* buf, qint32 len) void Decimators<T, SdrBits, InputBits>::decimate1(SampleVector::iterator* it, const T* buf, qint32 len)
{ {
qint16 xreal, yimag; qint16 xreal, yimag;
for (int pos = 0; pos < len; pos += 2) { for (int pos = 0; pos < len; pos += 2)
{
xreal = buf[pos+0]; xreal = buf[pos+0];
yimag = buf[pos+1]; yimag = buf[pos+1];
(**it).setReal(xreal * 16); // Valgrind optim (2 - comment not repeated) (**it).setReal(xreal << decimation_shifts<SdrBits, InputBits>::pre1); // Valgrind optim (2 - comment not repeated)
(**it).setImag(yimag * 16); (**it).setImag(yimag << decimation_shifts<SdrBits, InputBits>::pre1);
//Sample s( xreal * 16, yimag * 16 ); // shift by 4 bit positions (signed)
//**it = s;
++(*it); // Valgrind optim (comment not repeated) ++(*it); // Valgrind optim (comment not repeated)
} }
} }
template<typename T> template<typename T, uint SdrBits, uint InputBits>
void Decimators<T>::decimate2_u(SampleVector::iterator* it, const T* buf, qint32 len) void Decimators<T, SdrBits, InputBits>::decimate2_u(SampleVector::iterator* it, const T* buf, qint32 len)
{ {
qint16 xreal, yimag; qint16 xreal, yimag;
for (int pos = 0; pos < len - 7; pos += 8) for (int pos = 0; pos < len - 7; pos += 8)
{ {
xreal = buf[pos+0] - buf[pos+3]; xreal = (buf[pos+0] - buf[pos+3]) << decimation_shifts<SdrBits, InputBits>::pre2;
yimag = buf[pos+1] + buf[pos+2] - 255; yimag = (buf[pos+1] + buf[pos+2] - 255) << decimation_shifts<SdrBits, InputBits>::pre2;
//Sample s( xreal << 3, yimag << 3 ); (**it).setReal(xreal >> decimation_shifts<SdrBits, InputBits>::post2);
//**it = s; (**it).setImag(yimag >> decimation_shifts<SdrBits, InputBits>::post2);
(**it).setReal(xreal << 3);
(**it).setImag(yimag << 3);
++(*it); ++(*it);
xreal = buf[pos+7] - buf[pos+4];
yimag = 255 - buf[pos+5] - buf[pos+6]; xreal = (buf[pos+7] - buf[pos+4]) << decimation_shifts<SdrBits, InputBits>::pre2;
//Sample t( xreal << 3, yimag << 3 ); yimag = (255 - buf[pos+5] - buf[pos+6]) << decimation_shifts<SdrBits, InputBits>::pre2;
//**it = t; (**it).setReal(xreal >> decimation_shifts<SdrBits, InputBits>::post2);
(**it).setReal(xreal << 3); (**it).setImag(yimag >> decimation_shifts<SdrBits, InputBits>::post2);
(**it).setImag(yimag << 3);
++(*it); ++(*it);
} }
} }
template<typename T> template<typename T, uint SdrBits, uint InputBits>
void Decimators<T>::decimate2(SampleVector::iterator* it, const T* buf, qint32 len) void Decimators<T, SdrBits, InputBits>::decimate2_inf(SampleVector::iterator* it, const T* buf, qint32 len)
{ {
qint16 xreal, yimag; qint16 xreal, yimag;
for (int pos = 0; pos < len - 7; pos += 8) for (int pos = 0; pos < len - 7; pos += 8)
{ {
xreal = buf[pos+0] - buf[pos+3]; xreal = (buf[pos+0] - buf[pos+3]) << decimation_shifts<SdrBits, InputBits>::pre2;
yimag = buf[pos+1] + buf[pos+2]; yimag = (buf[pos+1] + buf[pos+2]) << decimation_shifts<SdrBits, InputBits>::pre2;
//Sample s( xreal << 3, yimag << 3 ); (**it).setReal(xreal >> decimation_shifts<SdrBits, InputBits>::post2);
//**it = s; (**it).setImag(yimag >> decimation_shifts<SdrBits, InputBits>::post2);
(**it).setReal(xreal << 3);
(**it).setImag(yimag << 3);
++(*it); ++(*it);
xreal = buf[pos+7] - buf[pos+4];
yimag = - buf[pos+5] - buf[pos+6]; xreal = (buf[pos+7] - buf[pos+4]) << decimation_shifts<SdrBits, InputBits>::pre2;
//Sample t( xreal << 3, yimag << 3 ); yimag = (- buf[pos+5] - buf[pos+6]) << decimation_shifts<SdrBits, InputBits>::pre2;
//**it = t; (**it).setReal(xreal >> decimation_shifts<SdrBits, InputBits>::post2);
(**it).setReal(xreal << 3); (**it).setImag(yimag >> decimation_shifts<SdrBits, InputBits>::post2);
(**it).setImag(yimag << 3);
++(*it); ++(*it);
} }
} }
template<typename T> template<typename T, uint SdrBits, uint InputBits>
void Decimators<T>::decimate2_sup(SampleVector::iterator* it, const T* buf, qint32 len) void Decimators<T, SdrBits, InputBits>::decimate2_sup(SampleVector::iterator* it, const T* buf, qint32 len)
{ {
qint16 xreal, yimag; qint16 xreal, yimag;
for (int pos = 0; pos < len - 7; pos += 8) for (int pos = 0; pos < len - 7; pos += 8)
{ {
xreal = buf[pos+1] - buf[pos+2]; xreal = (buf[pos+1] - buf[pos+2]) << decimation_shifts<SdrBits, InputBits>::pre2;
yimag = - buf[pos+0] - buf[pos+3]; yimag = (- buf[pos+0] - buf[pos+3]) << decimation_shifts<SdrBits, InputBits>::pre2;
//Sample s( xreal << 3, yimag << 3 ); (**it).setReal(xreal >> decimation_shifts<SdrBits, InputBits>::post2);
//**it = s; (**it).setImag(yimag >> decimation_shifts<SdrBits, InputBits>::post2);
(**it).setReal(xreal << 3);
(**it).setImag(yimag << 3);
++(*it); ++(*it);
xreal = buf[pos+6] - buf[pos+5];
yimag = buf[pos+4] + buf[pos+7]; xreal = (buf[pos+6] - buf[pos+5]) << decimation_shifts<SdrBits, InputBits>::pre2;
//Sample t( xreal << 3, yimag << 3 ); yimag = (buf[pos+4] + buf[pos+7]) << decimation_shifts<SdrBits, InputBits>::pre2;
//**it = t; (**it).setReal(xreal >> decimation_shifts<SdrBits, InputBits>::post2);
(**it).setReal(xreal << 3); (**it).setImag(yimag >> decimation_shifts<SdrBits, InputBits>::post2);
(**it).setImag(yimag << 3);
++(*it); ++(*it);
} }
} }
/* template<typename T, uint SdrBits, uint InputBits>
template<typename T> void Decimators<T, SdrBits, InputBits>::decimate2_cen(SampleVector::iterator* it, const T* buf, qint32 len)
void Decimators<T>::decimate2_cen(SampleVector::iterator* it, const T* buf, qint32 len)
{ {
int pos = 0; int pos = 0;
while (pos < len - 3) while (pos < len - 3)
{ {
Sample s0(buf[pos+0] << 3, buf[pos+1] << 3); qint16 x0 = buf[pos+0] << decimation_shifts<SdrBits, InputBits>::pre2;
pos += 2; qint16 y0 = buf[pos+1] << decimation_shifts<SdrBits, InputBits>::pre2;
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;
pos += 2; pos += 2;
if (m_decimator2.workDecimateCenter(&x0, &y0)) if (m_decimator2.workDecimateCenter(&x0, &y0))
{ {
(**it).setReal(x0); (**it).setReal(x0 >> decimation_shifts<SdrBits, InputBits>::post2);
(**it).setImag(y0); (**it).setImag(y0 >> decimation_shifts<SdrBits, InputBits>::post2);
++(*it); ++(*it);
} }
} }
} }
/* template<typename T, uint SdrBits, uint InputBits>
template<typename T> void Decimators<T, SdrBits, InputBits>::decimate4_cen(SampleVector::iterator* it, const T* buf, qint32 len)
void Decimators<T>::decimate4_cen(SampleVector::iterator* it, const T* buf, qint32 len)
{ {
int pos = 0; int pos = 0;
while (pos < len) while (pos < len)
{ {
Sample s0(buf[pos+0] << 4, buf[pos+1] << 4); qint16 x0 = buf[pos+0] << decimation_shifts<SdrBits, InputBits>::pre4;
pos += 2; qint16 y0 = buf[pos+1] << decimation_shifts<SdrBits, InputBits>::pre4;
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;
pos += 2; pos += 2;
if (m_decimator2.workDecimateCenter(&x0, &y0)) 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)) if (m_decimator4.workDecimateCenter(&x1, &y1))
{ {
(**it).setReal(x0); (**it).setReal(x0 >> decimation_shifts<SdrBits, InputBits>::post4);
(**it).setImag(y0); (**it).setImag(y0 >> decimation_shifts<SdrBits, InputBits>::post4);
++(*it); ++(*it);
} }
} }
} }
} }
template<typename T> template<typename T, uint SdrBits, uint InputBits>
void Decimators<T>::decimate8_cen(SampleVector::iterator* it, const T* buf, qint32 len) void Decimators<T, SdrBits, InputBits>::decimate8_cen(SampleVector::iterator* it, const T* buf, qint32 len)
{ {
int pos = 0; int pos = 0;
while (pos < len) while (pos < len)
{ {
qint16 x0 = buf[pos+0] << 4; qint16 x0 = buf[pos+0] << decimation_shifts<SdrBits, InputBits>::pre8;
qint16 y0 = buf[pos+1] << 4; qint16 y0 = buf[pos+1] << decimation_shifts<SdrBits, InputBits>::pre8;
pos += 2; pos += 2;
if (m_decimator2.workDecimateCenter(&x0, &y0)) 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)) if (m_decimator8.workDecimateCenter(&x2, &y2))
{ {
(**it).setReal(x2); (**it).setReal(x2 >> decimation_shifts<SdrBits, InputBits>::post8);
(**it).setImag(y2); (**it).setImag(y2 >> decimation_shifts<SdrBits, InputBits>::post8);
++(*it); ++(*it);
} }
} }
@ -259,44 +254,15 @@ void Decimators<T>::decimate8_cen(SampleVector::iterator* it, const T* buf, qint
} }
} }
/* template<typename T, uint SdrBits, uint InputBits>
template<typename T> void Decimators<T, SdrBits, InputBits>::decimate16_cen(SampleVector::iterator* it, const T* buf, qint32 len)
void Decimators<T>::decimate8_cen(SampleVector::iterator* it, const T* buf, qint32 len)
{ {
int pos = 0; int pos = 0;
while (pos < len) while (pos < len)
{ {
Sample s0(buf[pos+0] << 4, buf[pos+1] << 4); qint16 x0 = buf[pos+0] << decimation_shifts<SdrBits, InputBits>::pre16;
pos += 2; qint16 y0 = buf[pos+1] << decimation_shifts<SdrBits, InputBits>::pre16;
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;
pos += 2; pos += 2;
if (m_decimator2.workDecimateCenter(&x0, &y0)) 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)) if (m_decimator16.workDecimateCenter(&x3, &y3))
{ {
(**it).setReal(x3); (**it).setReal(x3 >> decimation_shifts<SdrBits, InputBits>::post16);
(**it).setImag(y3); (**it).setImag(y3 >> decimation_shifts<SdrBits, InputBits>::post16);
++(*it); ++(*it);
} }
} }
@ -326,15 +292,15 @@ void Decimators<T>::decimate16_cen(SampleVector::iterator* it, const T* buf, qin
} }
} }
template<typename T> template<typename T, uint SdrBits, uint InputBits>
void Decimators<T>::decimate32_cen(SampleVector::iterator* it, const T* buf, qint32 len) void Decimators<T, SdrBits, InputBits>::decimate32_cen(SampleVector::iterator* it, const T* buf, qint32 len)
{ {
int pos = 0; int pos = 0;
while (pos < len) while (pos < len)
{ {
qint16 x0 = buf[pos+0] << 4; qint16 x0 = buf[pos+0] << decimation_shifts<SdrBits, InputBits>::pre32;
qint16 y0 = buf[pos+1] << 4; qint16 y0 = buf[pos+1] << decimation_shifts<SdrBits, InputBits>::pre32;
pos += 2; pos += 2;
if (m_decimator2.workDecimateCenter(&x0, &y0)) 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)) if (m_decimator32.workDecimateCenter(&x4, &y4))
{ {
(**it).setReal(x4); (**it).setReal(x4 >> decimation_shifts<SdrBits, InputBits>::post32);
(**it).setImag(y4); (**it).setImag(y4 >> decimation_shifts<SdrBits, InputBits>::post32);
++(*it); ++(*it);
} }
} }
@ -370,27 +336,25 @@ void Decimators<T>::decimate32_cen(SampleVector::iterator* it, const T* buf, qin
} }
} }
template<typename T> template<typename T, uint SdrBits, uint InputBits>
void Decimators<T>::decimate4(SampleVector::iterator* it, const T* buf, qint32 len) void Decimators<T, SdrBits, InputBits>::decimate4_inf(SampleVector::iterator* it, const T* buf, qint32 len)
{ {
qint16 xreal, yimag; qint16 xreal, yimag;
for (int pos = 0; pos < len - 7; pos += 8) for (int pos = 0; pos < len - 7; pos += 8)
{ {
xreal = buf[pos+0] - buf[pos+3] + buf[pos+7] - buf[pos+4]; 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]; 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); ++(*it);
} }
} }
template<typename T> template<typename T, uint SdrBits, uint InputBits>
void Decimators<T>::decimate4_sup(SampleVector::iterator* it, const T* buf, qint32 len) void Decimators<T, SdrBits, InputBits>::decimate4_sup(SampleVector::iterator* it, const T* buf, qint32 len)
{ {
// Sup (USB): // Sup (USB):
// x y x y x y x y / x -> 1,-2,-5,6 / y -> -0,-3,4,7 // 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) for (int pos = 0; pos < len - 7; pos += 8)
{ {
xreal = 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]; yimag = (- buf[pos+0] - buf[pos+3] + buf[pos+4] + buf[pos+7]) << decimation_shifts<SdrBits, InputBits>::pre4;
//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]; (**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); ++(*it);
} }
} }
template<typename T> template<typename T, uint SdrBits, uint InputBits>
void Decimators<T>::decimate8(SampleVector::iterator* it, const T* buf, qint32 len) void Decimators<T, SdrBits, InputBits>::decimate8_inf(SampleVector::iterator* it, const T* buf, qint32 len)
{ {
qint16 xreal[2], yimag[2]; qint16 xreal[2], yimag[2];
for (int pos = 0; pos < len - 15; pos += 8) for (int pos = 0; pos < len - 15; pos += 8)
{ {
xreal[0] = (buf[pos+0] - buf[pos+3] + buf[pos+7] - buf[pos+4]) << 2; 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]) << 2; yimag[0] = (buf[pos+1] - buf[pos+5] + buf[pos+2] - buf[pos+6]) << decimation_shifts<SdrBits, InputBits>::pre8;
//Sample s1( xreal << 2, yimag << 2 ); // was shift 3
pos += 8; 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; xreal[1] = (buf[pos+0] - buf[pos+3] + buf[pos+7] - buf[pos+4]) << decimation_shifts<SdrBits, InputBits>::pre8;
//Sample s2( xreal << 2, yimag << 2 ); // was shift 3 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]); m_decimator2.myDecimate(xreal[0], yimag[0], &xreal[1], &yimag[1]);
(**it).setReal(xreal[1]); (**it).setReal(xreal[1] >> decimation_shifts<SdrBits, InputBits>::post8);
(**it).setImag(yimag[1]); (**it).setImag(yimag[1] >> decimation_shifts<SdrBits, InputBits>::post8);
/*
m_decimator2.myDecimate(&s1, &s2);
**it = s2;*/
++(*it); ++(*it);
} }
} }
template<typename T> template<typename T, uint SdrBits, uint InputBits>
void Decimators<T>::decimate8_sup(SampleVector::iterator* it, const T* buf, qint32 len) void Decimators<T, SdrBits, InputBits>::decimate8_sup(SampleVector::iterator* it, const T* buf, qint32 len)
{ {
qint16 xreal[2], yimag[2]; qint16 xreal[2], yimag[2];
for (int pos = 0; pos < len - 15; pos += 8) for (int pos = 0; pos < len - 15; pos += 8)
{ {
xreal[0] = (buf[pos+1] - buf[pos+2] - buf[pos+5] + buf[pos+6]) << 2; 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]) << 2; yimag[0] = (- buf[pos+0] - buf[pos+3] + buf[pos+4] + buf[pos+7]) << decimation_shifts<SdrBits, InputBits>::pre8;
//Sample s1( xreal << 2, yimag << 2 ); // was shift 3
pos += 8; 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; xreal[1] = (buf[pos+1] - buf[pos+2] - buf[pos+5] + buf[pos+6]) << decimation_shifts<SdrBits, InputBits>::pre8;
//Sample s2( xreal << 2, yimag << 2 ); // was shift 3 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]); m_decimator2.myDecimate(xreal[0], yimag[0], &xreal[1], &yimag[1]);
(**it).setReal(xreal[1]); (**it).setReal(xreal[1] >> decimation_shifts<SdrBits, InputBits>::post8);
(**it).setImag(yimag[1]); (**it).setImag(yimag[1] >> decimation_shifts<SdrBits, InputBits>::post8);
/*
m_decimator2.myDecimate(&s1, &s2);
**it = s2;*/
++(*it); ++(*it);
} }
} }
template<typename T> template<typename T, uint SdrBits, uint InputBits>
void Decimators<T>::decimate16(SampleVector::iterator* it, const T* buf, qint32 len) void Decimators<T, SdrBits, InputBits>::decimate16_inf(SampleVector::iterator* it, const T* buf, qint32 len)
{ {
// Offset tuning: 4x downsample and rotate, then // Offset tuning: 4x downsample and rotate, then
// downsample 4x more. [ rotate: 0, 1, -3, 2, -4, -5, 7, -6] // 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++) 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 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]) << 2; // was shift 4 yimag[i] = (buf[pos+1] - buf[pos+5] + buf[pos+2] - buf[pos+6]) << decimation_shifts<SdrBits, InputBits>::pre16;
pos += 8; pos += 8;
} }
m_decimator2.myDecimate(xreal[0], yimag[0], &xreal[1], &yimag[1]); m_decimator2.myDecimate(xreal[0], yimag[0], &xreal[1], &yimag[1]);
m_decimator2.myDecimate(xreal[2], yimag[2], &xreal[3], &yimag[3]); m_decimator2.myDecimate(xreal[2], yimag[2], &xreal[3], &yimag[3]);
m_decimator4.myDecimate(xreal[1], yimag[1], &xreal[3], &yimag[3]); m_decimator4.myDecimate(xreal[1], yimag[1], &xreal[3], &yimag[3]);
(**it).setReal(xreal[3]); (**it).setReal(xreal[3] >> decimation_shifts<SdrBits, InputBits>::post16);
(**it).setImag(yimag[3]); (**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); ++(*it);
} }
} }
template<typename T> template<typename T, uint SdrBits, uint InputBits>
void Decimators<T>::decimate16_sup(SampleVector::iterator* it, const T* buf, qint32 len) void Decimators<T, SdrBits, InputBits>::decimate16_sup(SampleVector::iterator* it, const T* buf, qint32 len)
{ {
// Offset tuning: 4x downsample and rotate, then // Offset tuning: 4x downsample and rotate, then
// downsample 4x more. [ rotate: 1, 0, -2, 3, -5, -4, 6, -7] // 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++) 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 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]) << 2; // was shift 4 yimag[i] = (buf[pos+4] + buf[pos+7] - buf[pos+0] - buf[pos+3]) << decimation_shifts<SdrBits, InputBits>::pre16;
pos += 8; 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]); m_decimator4.myDecimate(xreal[1], yimag[1], &xreal[3], &yimag[3]);
(**it).setReal(xreal[3]); (**it).setReal(xreal[3] >> decimation_shifts<SdrBits, InputBits>::post16);
(**it).setImag(yimag[3]); (**it).setImag(yimag[3] >> decimation_shifts<SdrBits, InputBits>::post16);
/*
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); ++(*it);
} }
} }
template<typename T> template<typename T, uint SdrBits, uint InputBits>
void Decimators<T>::decimate32(SampleVector::iterator* it, const T* buf, qint32 len) void Decimators<T, SdrBits, InputBits>::decimate32_inf(SampleVector::iterator* it, const T* buf, qint32 len)
{ {
qint16 xreal[8], yimag[8]; 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++) for (int i = 0; i < 8; i++)
{ {
xreal[i] = (buf[pos+0] - buf[pos+3] + buf[pos+7] - buf[pos+4]) << 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]) << 2; yimag[i] = (buf[pos+1] - buf[pos+5] + buf[pos+2] - buf[pos+6]) << decimation_shifts<SdrBits, InputBits>::pre32;
pos += 8; 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]); m_decimator8.myDecimate(xreal[3], yimag[3], &xreal[7], &yimag[7]);
(**it).setReal(xreal[7]); (**it).setReal(xreal[7] >> decimation_shifts<SdrBits, InputBits>::post32);
(**it).setImag(yimag[7]); (**it).setImag(yimag[7] >> decimation_shifts<SdrBits, InputBits>::post32);
/*
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); ++(*it);
} }
} }
template<typename T> template<typename T, uint SdrBits, uint InputBits>
void Decimators<T>::decimate32_sup(SampleVector::iterator* it, const T* buf, qint32 len) void Decimators<T, SdrBits, InputBits>::decimate32_sup(SampleVector::iterator* it, const T* buf, qint32 len)
{ {
qint16 xreal[8], yimag[8]; 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++) for (int i = 0; i < 8; i++)
{ {
xreal[i] = (buf[pos+1] - buf[pos+2] - buf[pos+5] + buf[pos+6]) << 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]) << 2; yimag[i] = (buf[pos+4] + buf[pos+7] - buf[pos+0] - buf[pos+3]) << decimation_shifts<SdrBits, InputBits>::pre32;
pos += 8; 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]); m_decimator8.myDecimate(xreal[3], yimag[3], &xreal[7], &yimag[7]);
(**it).setReal(xreal[7]); (**it).setReal(xreal[7] >> decimation_shifts<SdrBits, InputBits>::post32);
(**it).setImag(yimag[7]); (**it).setImag(yimag[7] >> decimation_shifts<SdrBits, InputBits>::post32);
/*
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); ++(*it);
} }
} }

View File

@ -424,7 +424,7 @@ protected:
0.317491986549921390015072120149852707982 * (1 << HB_SHIFT) 0.317491986549921390015072120149852707982 * (1 << HB_SHIFT)
}; };
#elif HB_FILTERORDER == 32 #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} ; 20,21,22,23,24,25,26,27,28,29,30,31,32,0,1,2} ;
static const qint32 COEFF[8] = { static const qint32 COEFF[8] = {
(qint32)(-0.015956912844043127236437484839370881673 * (1 << HB_SHIFT)), (qint32)(-0.015956912844043127236437484839370881673 * (1 << HB_SHIFT)),
@ -467,8 +467,8 @@ protected:
iAcc += ((qint32)m_samples[a][0] + 1) << (HB_SHIFT - 1); iAcc += ((qint32)m_samples[a][0] + 1) << (HB_SHIFT - 1);
qAcc += ((qint32)m_samples[a][1] + 1) << (HB_SHIFT - 1); qAcc += ((qint32)m_samples[a][1] + 1) << (HB_SHIFT - 1);
*x = iAcc >> HB_SHIFT; *x = iAcc >> (HB_SHIFT -1); // HB_SHIFT incorrect do not loose the gained bit
*y = qAcc >> HB_SHIFT; *y = qAcc >> (HB_SHIFT -1);
} }
}; };

View File

@ -22,6 +22,8 @@
#include <vector> #include <vector>
#include <QtGlobal> #include <QtGlobal>
#define SDR_SAMP_SZ 16 // internal fixed arithmetic sample size
typedef float Real; typedef float Real;
typedef std::complex<Real> Complex; 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)) if (m_interpolator.interpolate(&m_interpolatorDistanceRemain, c, &ci))
{ {
m_sampleBuffer.push_back(Sample(ci.real() * 32767.0, ci.imag() * 32767.0));
qint16 sample; qint16 sample;
@ -269,8 +268,6 @@ void NFMDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto
m_audioBufferFill = 0; m_audioBufferFill = 0;
} }
m_sampleBuffer.clear();
m_settingsMutex.unlock(); m_settingsMutex.unlock();
} }

View File

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

View File

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

View File

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

View File

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

View File

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