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

View File

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

View File

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

View File

@ -92,7 +92,7 @@ protected:
void applyChannelization(); void applyChannelization();
void applyInterpolation(); 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); 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 double setFilterChain(const std::vector<unsigned int>& stageIndexes); //!< returns offset in ratio of sample rate
void freeFilterChain(); void freeFilterChain();