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

IntHalfbandFilters: set workInterpolateLowerHalf and UpperHalf optimized methods as defaults

This commit is contained in:
f4exb 2017-04-26 02:20:07 +02:00
parent 172de27047
commit 137647e2ca
3 changed files with 408 additions and 6 deletions

View File

@ -287,7 +287,7 @@ public:
} }
// upsample by 2, from lower half of original spectrum // upsample by 2, from lower half of original spectrum
bool workInterpolateLowerHalf(Sample* sampleIn, Sample *sampleOut) bool workInterpolateLowerHalfZeroStuffing(Sample* sampleIn, Sample *sampleOut)
{ {
Sample s; Sample s;
@ -371,6 +371,73 @@ public:
} }
} }
/** Optimized upsampler by 2 not calculating FIR with inserted null samples */
bool workInterpolateLowerHalf(Sample* sampleIn, Sample *sampleOut)
{
Sample s;
switch(m_state)
{
case 0:
// return the middle peak
sampleOut->setReal(m_samples[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][1]); // imag
sampleOut->setImag(-m_samples[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][0]); // - real
m_state = 1; // next state
return false; // tell caller we didn't consume the sample
case 1:
// calculate with non null samples
doInterpolateFIR(&s);
sampleOut->setReal(-s.real());
sampleOut->setImag(-s.imag());
// insert sample into ring double buffer
m_samples[m_ptr][0] = sampleIn->real();
m_samples[m_ptr][1] = sampleIn->imag();
m_samples[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][0] = sampleIn->real();
m_samples[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][1] = sampleIn->imag();
// advance pointer
if (m_ptr < (HBFIRFilterTraits<HBFilterOrder>::hbOrder/2) - 1) {
m_ptr++;
} else {
m_ptr = 0;
}
m_state = 2; // next state
return true; // tell caller we consumed the sample
case 2:
// return the middle peak
sampleOut->setReal(-m_samples[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][1]); // - imag
sampleOut->setImag(m_samples[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][0]); // real
m_state = 3; // next state
return false; // tell caller we didn't consume the sample
default:
// calculate with non null samples
doInterpolateFIR(&s);
sampleOut->setReal(s.real());
sampleOut->setImag(s.imag());
// insert sample into ring double buffer
m_samples[m_ptr][0] = sampleIn->real();
m_samples[m_ptr][1] = sampleIn->imag();
m_samples[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][0] = sampleIn->real();
m_samples[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][1] = sampleIn->imag();
// advance pointer
if (m_ptr < (HBFIRFilterTraits<HBFilterOrder>::hbOrder/2) - 1) {
m_ptr++;
} else {
m_ptr = 0;
}
m_state = 0; // next state
return true; // tell caller we consumed the sample
}
}
// downsample by 2, return upper half of original spectrum // downsample by 2, return upper half of original spectrum
bool workDecimateUpperHalf(Sample* sample) bool workDecimateUpperHalf(Sample* sample)
{ {
@ -441,7 +508,7 @@ public:
} }
// upsample by 2, move original spectrum to upper half // upsample by 2, move original spectrum to upper half
bool workInterpolateUpperHalf(Sample* sampleIn, Sample *sampleOut) bool workInterpolateUpperHalfZeroStuffing(Sample* sampleIn, Sample *sampleOut)
{ {
Sample s; Sample s;
@ -525,6 +592,73 @@ public:
} }
} }
/** Optimized upsampler by 2 not calculating FIR with inserted null samples */
bool workInterpolateUpperHalf(Sample* sampleIn, Sample *sampleOut)
{
Sample s;
switch(m_state)
{
case 0:
// return the middle peak
sampleOut->setReal(-m_samples[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][1]); // - imag
sampleOut->setImag(m_samples[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][0]); // + real
m_state = 1; // next state
return false; // tell caller we didn't consume the sample
case 1:
// calculate with non null samples
doInterpolateFIR(&s);
sampleOut->setReal(-s.real());
sampleOut->setImag(-s.imag());
// insert sample into ring double buffer
m_samples[m_ptr][0] = sampleIn->real();
m_samples[m_ptr][1] = sampleIn->imag();
m_samples[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][0] = sampleIn->real();
m_samples[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][1] = sampleIn->imag();
// advance pointer
if (m_ptr < (HBFIRFilterTraits<HBFilterOrder>::hbOrder/2) - 1) {
m_ptr++;
} else {
m_ptr = 0;
}
m_state = 2; // next state
return true; // tell caller we consumed the sample
case 2:
// return the middle peak
sampleOut->setReal(m_samples[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][1]); // + imag
sampleOut->setImag(-m_samples[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][0]); // - real
m_state = 3; // next state
return false; // tell caller we didn't consume the sample
default:
// calculate with non null samples
doInterpolateFIR(&s);
sampleOut->setReal(s.real());
sampleOut->setImag(s.imag());
// insert sample into ring double buffer
m_samples[m_ptr][0] = sampleIn->real();
m_samples[m_ptr][1] = sampleIn->imag();
m_samples[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][0] = sampleIn->real();
m_samples[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][1] = sampleIn->imag();
// advance pointer
if (m_ptr < (HBFIRFilterTraits<HBFilterOrder>::hbOrder/2) - 1) {
m_ptr++;
} else {
m_ptr = 0;
}
m_state = 0; // next state
return true; // tell caller we consumed the sample
}
}
void myDecimate(const Sample* sample1, Sample* sample2) void myDecimate(const Sample* sample1, Sample* sample2)
{ {
m_samples[m_ptr][0] = sample1->real(); m_samples[m_ptr][0] = sample1->real();

View File

@ -203,11 +203,78 @@ public:
} }
} }
// upsample by 2, from lower half of original spectrum - double buffer variant /** Optimized upsampler by 2 not calculating FIR with inserted null samples */
bool workInterpolateLowerHalf(Sample* sampleIn, Sample *sampleOut) bool workInterpolateLowerHalf(Sample* sampleIn, Sample *sampleOut)
{ {
Sample s; Sample s;
switch(m_state)
{
case 0:
// return the middle peak
sampleOut->setReal(m_samplesDB[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][1]); // imag
sampleOut->setImag(-m_samplesDB[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][0]); // - real
m_state = 1; // next state
return false; // tell caller we didn't consume the sample
case 1:
// calculate with non null samples
doInterpolateFIR(&s);
sampleOut->setReal(-s.real());
sampleOut->setImag(-s.imag());
// insert sample into ring double buffer
m_samplesDB[m_ptr][0] = sampleIn->real();
m_samplesDB[m_ptr][1] = sampleIn->imag();
m_samplesDB[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][0] = sampleIn->real();
m_samplesDB[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][1] = sampleIn->imag();
// advance pointer
if (m_ptr < (HBFIRFilterTraits<HBFilterOrder>::hbOrder/2) - 1) {
m_ptr++;
} else {
m_ptr = 0;
}
m_state = 2; // next state
return true; // tell caller we consumed the sample
case 2:
// return the middle peak
sampleOut->setReal(-m_samplesDB[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][1]); // - imag
sampleOut->setImag(m_samplesDB[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][0]); // real
m_state = 3; // next state
return false; // tell caller we didn't consume the sample
default:
// calculate with non null samples
doInterpolateFIR(&s);
sampleOut->setReal(s.real());
sampleOut->setImag(s.imag());
// insert sample into ring double buffer
m_samplesDB[m_ptr][0] = sampleIn->real();
m_samplesDB[m_ptr][1] = sampleIn->imag();
m_samplesDB[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][0] = sampleIn->real();
m_samplesDB[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][1] = sampleIn->imag();
// advance pointer
if (m_ptr < (HBFIRFilterTraits<HBFilterOrder>::hbOrder/2) - 1) {
m_ptr++;
} else {
m_ptr = 0;
}
m_state = 0; // next state
return true; // tell caller we consumed the sample
}
}
// upsample by 2, from lower half of original spectrum - double buffer variant
bool workInterpolateLowerHalfZeroStuffing(Sample* sampleIn, Sample *sampleOut)
{
Sample s;
switch(m_state) switch(m_state)
{ {
case 0: case 0:
@ -335,11 +402,78 @@ public:
} }
} }
// upsample by 2, move original spectrum to upper half - double buffer variant /** Optimized upsampler by 2 not calculating FIR with inserted null samples */
bool workInterpolateUpperHalf(Sample* sampleIn, Sample *sampleOut) bool workInterpolateUpperHalf(Sample* sampleIn, Sample *sampleOut)
{ {
Sample s; Sample s;
switch(m_state)
{
case 0:
// return the middle peak
sampleOut->setReal(-m_samplesDB[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][1]); // - imag
sampleOut->setImag(m_samplesDB[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][0]); // + real
m_state = 1; // next state
return false; // tell caller we didn't consume the sample
case 1:
// calculate with non null samples
doInterpolateFIR(&s);
sampleOut->setReal(-s.real());
sampleOut->setImag(-s.imag());
// insert sample into ring double buffer
m_samplesDB[m_ptr][0] = sampleIn->real();
m_samplesDB[m_ptr][1] = sampleIn->imag();
m_samplesDB[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][0] = sampleIn->real();
m_samplesDB[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][1] = sampleIn->imag();
// advance pointer
if (m_ptr < (HBFIRFilterTraits<HBFilterOrder>::hbOrder/2) - 1) {
m_ptr++;
} else {
m_ptr = 0;
}
m_state = 2; // next state
return true; // tell caller we consumed the sample
case 2:
// return the middle peak
sampleOut->setReal(m_samplesDB[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][1]); // + imag
sampleOut->setImag(-m_samplesDB[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][0]); // - real
m_state = 3; // next state
return false; // tell caller we didn't consume the sample
default:
// calculate with non null samples
doInterpolateFIR(&s);
sampleOut->setReal(s.real());
sampleOut->setImag(s.imag());
// insert sample into ring double buffer
m_samplesDB[m_ptr][0] = sampleIn->real();
m_samplesDB[m_ptr][1] = sampleIn->imag();
m_samplesDB[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][0] = sampleIn->real();
m_samplesDB[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][1] = sampleIn->imag();
// advance pointer
if (m_ptr < (HBFIRFilterTraits<HBFilterOrder>::hbOrder/2) - 1) {
m_ptr++;
} else {
m_ptr = 0;
}
m_state = 0; // next state
return true; // tell caller we consumed the sample
}
}
// upsample by 2, move original spectrum to upper half - double buffer variant
bool workInterpolateUpperHalfZeroStuffing(Sample* sampleIn, Sample *sampleOut)
{
Sample s;
switch(m_state) switch(m_state)
{ {
case 0: case 0:

View File

@ -207,7 +207,7 @@ public:
} }
// upsample by 2, from lower half of original spectrum - double buffer variant // upsample by 2, from lower half of original spectrum - double buffer variant
bool workInterpolateLowerHalf(Sample* sampleIn, Sample *sampleOut) bool workInterpolateLowerHalfZeroStuffing(Sample* sampleIn, Sample *sampleOut)
{ {
Sample s; Sample s;
@ -287,6 +287,73 @@ public:
} }
} }
/** Optimized upsampler by 2 not calculating FIR with inserted null samples */
bool workInterpolateLowerHalf(Sample* sampleIn, Sample *sampleOut)
{
Sample s;
switch(m_state)
{
case 0:
// return the middle peak
sampleOut->setReal(m_samples[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][1]); // imag
sampleOut->setImag(-m_samples[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][0]); // - real
m_state = 1; // next state
return false; // tell caller we didn't consume the sample
case 1:
// calculate with non null samples
doInterpolateFIR(&s);
sampleOut->setReal(-s.real());
sampleOut->setImag(-s.imag());
// insert sample into ring double buffer
m_samples[m_ptr][0] = sampleIn->real();
m_samples[m_ptr][1] = sampleIn->imag();
m_samples[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][0] = sampleIn->real();
m_samples[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][1] = sampleIn->imag();
// advance pointer
if (m_ptr < (HBFIRFilterTraits<HBFilterOrder>::hbOrder/2) - 1) {
m_ptr++;
} else {
m_ptr = 0;
}
m_state = 2; // next state
return true; // tell caller we consumed the sample
case 2:
// return the middle peak
sampleOut->setReal(-m_samples[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][1]); // - imag
sampleOut->setImag(m_samples[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][0]); // real
m_state = 3; // next state
return false; // tell caller we didn't consume the sample
default:
// calculate with non null samples
doInterpolateFIR(&s);
sampleOut->setReal(s.real());
sampleOut->setImag(s.imag());
// insert sample into ring double buffer
m_samples[m_ptr][0] = sampleIn->real();
m_samples[m_ptr][1] = sampleIn->imag();
m_samples[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][0] = sampleIn->real();
m_samples[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][1] = sampleIn->imag();
// advance pointer
if (m_ptr < (HBFIRFilterTraits<HBFilterOrder>::hbOrder/2) - 1) {
m_ptr++;
} else {
m_ptr = 0;
}
m_state = 0; // next state
return true; // tell caller we consumed the sample
}
}
// downsample by 2, return upper half of original spectrum // downsample by 2, return upper half of original spectrum
bool workDecimateUpperHalf(Sample* sample) bool workDecimateUpperHalf(Sample* sample)
{ {
@ -339,7 +406,7 @@ public:
} }
// upsample by 2, move original spectrum to upper half - double buffer variant // upsample by 2, move original spectrum to upper half - double buffer variant
bool workInterpolateUpperHalf(Sample* sampleIn, Sample *sampleOut) bool workInterpolateUpperHalfZeroStuffing(Sample* sampleIn, Sample *sampleOut)
{ {
Sample s; Sample s;
@ -419,6 +486,73 @@ public:
} }
} }
/** Optimized upsampler by 2 not calculating FIR with inserted null samples */
bool workInterpolateUpperHalf(Sample* sampleIn, Sample *sampleOut)
{
Sample s;
switch(m_state)
{
case 0:
// return the middle peak
sampleOut->setReal(-m_samples[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][1]); // - imag
sampleOut->setImag(m_samples[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][0]); // + real
m_state = 1; // next state
return false; // tell caller we didn't consume the sample
case 1:
// calculate with non null samples
doInterpolateFIR(&s);
sampleOut->setReal(-s.real());
sampleOut->setImag(-s.imag());
// insert sample into ring double buffer
m_samples[m_ptr][0] = sampleIn->real();
m_samples[m_ptr][1] = sampleIn->imag();
m_samples[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][0] = sampleIn->real();
m_samples[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][1] = sampleIn->imag();
// advance pointer
if (m_ptr < (HBFIRFilterTraits<HBFilterOrder>::hbOrder/2) - 1) {
m_ptr++;
} else {
m_ptr = 0;
}
m_state = 2; // next state
return true; // tell caller we consumed the sample
case 2:
// return the middle peak
sampleOut->setReal(m_samples[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][1]); // + imag
sampleOut->setImag(-m_samples[m_ptr + (HBFIRFilterTraits<HBFilterOrder>::hbOrder/4) - 1][0]); // - real
m_state = 3; // next state
return false; // tell caller we didn't consume the sample
default:
// calculate with non null samples
doInterpolateFIR(&s);
sampleOut->setReal(s.real());
sampleOut->setImag(s.imag());
// insert sample into ring double buffer
m_samples[m_ptr][0] = sampleIn->real();
m_samples[m_ptr][1] = sampleIn->imag();
m_samples[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][0] = sampleIn->real();
m_samples[m_ptr + HBFIRFilterTraits<HBFilterOrder>::hbOrder/2][1] = sampleIn->imag();
// advance pointer
if (m_ptr < (HBFIRFilterTraits<HBFilterOrder>::hbOrder/2) - 1) {
m_ptr++;
} else {
m_ptr = 0;
}
m_state = 0; // next state
return true; // tell caller we consumed the sample
}
}
void myDecimate(const Sample* sample1, Sample* sample2) void myDecimate(const Sample* sample1, Sample* sample2)
{ {
storeSample((FixReal) sample1->real(), (FixReal) sample1->imag()); storeSample((FixReal) sample1->real(), (FixReal) sample1->imag());