Change down and up channelizers filter chain strategy. Fixes #1846

This commit is contained in:
f4exb 2023-10-17 02:52:45 +02:00
parent 2f2c387276
commit 9abd62f40e
4 changed files with 82 additions and 66 deletions

View File

@ -218,46 +218,55 @@ DownChannelizer::FilterStage::~FilterStage()
delete m_filter;
}
bool DownChannelizer::signalContainsChannel(Real sigStart, Real sigEnd, Real chanStart, Real chanEnd) const
Real DownChannelizer::channelMinSpace(Real sigStart, Real sigEnd, Real chanStart, Real chanEnd)
{
//qDebug(" testing signal [%f, %f], channel [%f, %f]", sigStart, sigEnd, chanStart, chanEnd);
if(sigEnd <= sigStart)
return false;
if(chanEnd <= chanStart)
return false;
return (sigStart <= chanStart) && (sigEnd >= chanEnd);
Real leftSpace = chanStart - sigStart;
Real rightSpace = sigEnd - chanEnd;
return std::min(leftSpace, rightSpace);
}
Real DownChannelizer::createFilterChain(Real sigStart, Real sigEnd, Real chanStart, Real chanEnd)
{
Real sigBw = sigEnd - sigStart;
Real chanBw = chanEnd - chanStart;
Real rot = sigBw / 4;
qDebug("DownChannelizer::createFilterChain: Signal [%.1f, %.1f] (BW %.1f), Channel [%.1f, %.1f], Rot %.1f", sigStart, sigEnd, sigBw, chanStart, chanEnd, rot);
// check if it fits into the center
if(signalContainsChannel(sigStart + rot, sigEnd - rot, chanStart, chanEnd))
{
qDebug("DownChannelizer::createFilterChain: -> take center half (decimate by 2)");
m_filterStages.push_back(new FilterStage(FilterStage::ModeCenter));
return createFilterChain(sigStart + rot, sigEnd - rot, chanStart, chanEnd);
}
std::array<Real, 3> filterMinSpaces; // Array of left, center and right filter min spaces respectively
filterMinSpaces[0] = channelMinSpace(sigStart, sigStart + sigBw / 2.0, chanStart, chanEnd);
filterMinSpaces[1] = channelMinSpace(sigStart + rot, sigEnd - rot, chanStart, chanEnd);
filterMinSpaces[2] = channelMinSpace(sigEnd - sigBw / 2.0f, sigEnd, chanStart, chanEnd);
auto maxIt = std::max_element(filterMinSpaces.begin(), filterMinSpaces.end());
int maxIndex = maxIt - filterMinSpaces.begin();
Real maxValue = *maxIt;
// check if it fits into the left half
if(signalContainsChannel(sigStart, sigStart + sigBw / 2.0, chanStart, chanEnd))
{
qDebug("DownChannelizer::createFilterChain: -> take left half (rotate by +1/4 and decimate by 2)");
m_filterStages.push_back(new FilterStage(FilterStage::ModeLowerHalf));
return createFilterChain(sigStart, sigStart + sigBw / 2.0, chanStart, chanEnd);
}
qDebug("DownChannelizer::createFilterChain: best index: %d best value: %.1f sigBW: %.1f chanBW: %.1f",
maxIndex, maxValue, sigBw, chanBw);
// check if it fits into the right half
if(signalContainsChannel(sigEnd - sigBw / 2.0f, sigEnd, chanStart, chanEnd))
if ((sigStart < sigEnd) && (chanStart < chanEnd) && (maxValue >= chanBw/10.0))
{
qDebug("DownChannelizer::createFilterChain: -> take right half (rotate by -1/4 and decimate by 2)");
m_filterStages.push_back(new FilterStage(FilterStage::ModeUpperHalf));
return createFilterChain(sigEnd - sigBw / 2.0f, sigEnd, chanStart, chanEnd);
}
if (maxIndex == 0)
{
qDebug("DownChannelizer::createFilterChain: -> take left half (rotate by +1/4 and decimate by 2)");
m_filterStages.push_back(new FilterStage(FilterStage::ModeLowerHalf));
return createFilterChain(sigStart, sigStart + sigBw / 2.0, chanStart, chanEnd);
}
if (maxIndex == 1)
{
qDebug("DownChannelizer::createFilterChain: -> take center half (decimate by 2)");
m_filterStages.push_back(new FilterStage(FilterStage::ModeCenter));
return createFilterChain(sigStart + rot, sigEnd - rot, chanStart, chanEnd);
}
if (maxIndex == 2)
{
qDebug("DownChannelizer::createFilterChain: -> take right half (rotate by -1/4 and decimate by 2)");
m_filterStages.push_back(new FilterStage(FilterStage::ModeUpperHalf));
return createFilterChain(sigEnd - sigBw / 2.0f, sigEnd, chanStart, chanEnd);
}
}
Real ofs = ((chanEnd - chanStart) / 2.0 + chanStart) - ((sigEnd - sigStart) / 2.0 + sigStart);
qDebug("DownChannelizer::createFilterChain: -> complete (final BW %.1f, frequency offset %.1f)", sigBw, ofs);

View File

@ -87,7 +87,7 @@ protected:
void applyChannelization();
void applyDecimation();
bool signalContainsChannel(Real sigStart, Real sigEnd, Real chanStart, Real chanEnd) const;
static Real channelMinSpace(Real sigStart, Real sigEnd, Real chanStart, Real chanEnd);
Real createFilterChain(Real sigStart, Real sigEnd, Real chanStart, Real chanEnd);
double setFilterChain(const std::vector<unsigned int>& stageIndexes);
void freeFilterChain();

View File

@ -237,19 +237,17 @@ UpChannelizer::FilterStage::~FilterStage()
delete m_filter;
}
bool UpChannelizer::signalContainsChannel(Real sigStart, Real sigEnd, Real chanStart, Real chanEnd) const
Real UpChannelizer::channelMinSpace(Real sigStart, Real sigEnd, Real chanStart, Real chanEnd)
{
//qDebug(" testing signal [%f, %f], channel [%f, %f]", sigStart, sigEnd, chanStart, chanEnd);
if(sigEnd <= sigStart)
return false;
if(chanEnd <= chanStart)
return false;
return (sigStart <= chanStart) && (sigEnd >= chanEnd);
Real leftSpace = chanStart - sigStart;
Real rightSpace = sigEnd - chanEnd;
return std::min(leftSpace, rightSpace);
}
Real UpChannelizer::createFilterChain(Real sigStart, Real sigEnd, Real chanStart, Real chanEnd)
{
Real sigBw = sigEnd - sigStart;
Real chanBw = chanEnd - chanStart;
Real rot = sigBw / 4;
Sample s;
@ -259,39 +257,48 @@ Real UpChannelizer::createFilterChain(Real sigStart, Real sigEnd, Real chanStart
<< " chan: [" << chanStart << ":" << chanEnd << "]"
<< " rot: " << rot;
// check if it fits into the center
// Was: if(signalContainsChannel(sigStart + rot + safetyMargin, sigStart + rot + sigBw / 2.0f - safetyMargin, chanStart, chanEnd)) {
if(signalContainsChannel(sigStart + rot, sigEnd - rot, chanStart, chanEnd))
{
qDebug() << "UpChannelizer::createFilterChain: take center half (decimate by 2):"
<< " [" << m_filterStages.size() << "]"
<< " sig: [" << sigStart + rot << ":" << sigEnd - rot << "]";
m_filterStages.push_back(new FilterStage(FilterStage::ModeCenter));
m_stageSamples.push_back(s);
// Was: return createFilterChain(sigStart + rot, sigStart + sigBw / 2.0f + rot, chanStart, chanEnd);
return createFilterChain(sigStart + rot, sigEnd - rot, chanStart, chanEnd);
}
std::array<Real, 3> filterMinSpaces; // Array of left, center and right filter min spaces respectively
filterMinSpaces[0] = channelMinSpace(sigStart, sigStart + sigBw / 2.0, chanStart, chanEnd);
filterMinSpaces[1] = channelMinSpace(sigStart + rot, sigEnd - rot, chanStart, chanEnd);
filterMinSpaces[2] = channelMinSpace(sigEnd - sigBw / 2.0f, sigEnd, chanStart, chanEnd);
auto maxIt = std::max_element(filterMinSpaces.begin(), filterMinSpaces.end());
int maxIndex = maxIt - filterMinSpaces.begin();
Real maxValue = *maxIt;
// check if it fits into the left half
if(signalContainsChannel(sigStart, sigStart + sigBw / 2.0, chanStart, chanEnd))
{
qDebug() << "UpChannelizer::createFilterChain: take left half (rotate by +1/4 and decimate by 2):"
<< " [" << m_filterStages.size() << "]"
<< " sig: [" << sigStart << ":" << sigStart + sigBw / 2.0 << "]";
m_filterStages.push_back(new FilterStage(FilterStage::ModeLowerHalf));
m_stageSamples.push_back(s);
return createFilterChain(sigStart, sigStart + sigBw / 2.0, chanStart, chanEnd);
}
qDebug("UpChannelizer::createFilterChain: best index: %d best value: %.1f sigBW: %.1f chanBW: %.1f",
maxIndex, maxValue, sigBw, chanBw);
// check if it fits into the right half
if(signalContainsChannel(sigEnd - sigBw / 2.0f, sigEnd, chanStart, chanEnd))
if ((sigStart < sigEnd) && (chanStart < chanEnd) && (maxValue >= chanBw/10.0))
{
qDebug() << "UpChannelizer::createFilterChain: take right half (rotate by -1/4 and decimate by 2):"
<< " [" << m_filterStages.size() << "]"
<< " sig: [" << sigEnd - sigBw / 2.0f << ":" << sigEnd << "]";
m_filterStages.push_back(new FilterStage(FilterStage::ModeUpperHalf));
m_stageSamples.push_back(s);
return createFilterChain(sigEnd - sigBw / 2.0f, sigEnd, chanStart, chanEnd);
if (maxIndex == 0)
{
qDebug() << "UpChannelizer::createFilterChain: take left half (rotate by +1/4 and decimate by 2):"
<< " [" << m_filterStages.size() << "]"
<< " sig: [" << sigStart << ":" << sigStart + sigBw / 2.0 << "]";
m_filterStages.push_back(new FilterStage(FilterStage::ModeLowerHalf));
m_stageSamples.push_back(s);
return createFilterChain(sigStart, sigStart + sigBw / 2.0, chanStart, chanEnd);
}
if (maxIndex == 1)
{
qDebug() << "UpChannelizer::createFilterChain: take center half (decimate by 2):"
<< " [" << m_filterStages.size() << "]"
<< " sig: [" << sigStart + rot << ":" << sigEnd - rot << "]";
m_filterStages.push_back(new FilterStage(FilterStage::ModeCenter));
m_stageSamples.push_back(s);
return createFilterChain(sigStart + rot, sigEnd - rot, chanStart, chanEnd);
}
if (maxIndex == 2)
{
qDebug() << "UpChannelizer::createFilterChain: take right half (rotate by -1/4 and decimate by 2):"
<< " [" << m_filterStages.size() << "]"
<< " sig: [" << sigEnd - sigBw / 2.0f << ":" << sigEnd << "]";
m_filterStages.push_back(new FilterStage(FilterStage::ModeUpperHalf));
m_stageSamples.push_back(s);
return createFilterChain(sigEnd - sigBw / 2.0f, sigEnd, chanStart, chanEnd);
}
}
Real ofs = ((chanEnd - chanStart) / 2.0 + chanStart) - ((sigEnd - sigStart) / 2.0 + sigStart);

View File

@ -92,7 +92,7 @@ protected:
void applyChannelization();
void applyInterpolation();
bool signalContainsChannel(Real sigStart, Real sigEnd, Real chanStart, Real chanEnd) const;
static Real channelMinSpace(Real sigStart, Real sigEnd, Real chanStart, Real chanEnd);
Real createFilterChain(Real sigStart, Real sigEnd, Real chanStart, Real chanEnd);
double setFilterChain(const std::vector<unsigned int>& stageIndexes); //!< returns offset in ratio of sample rate
void freeFilterChain();