Improve impulse response interpolation
This commit is contained in:
parent
7ca93af620
commit
329f4487ee
@ -214,7 +214,7 @@ void EyeDiagramDialog::updateThread(unsigned int width, unsigned int height)
|
|||||||
updating = false;
|
updating = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(datarate <= trace->getSample(0).x) {
|
if(datarate <= 0) {
|
||||||
emit calculationStatus("Data rate too low");
|
emit calculationStatus("Data rate too low");
|
||||||
updating = false;
|
updating = false;
|
||||||
return;
|
return;
|
||||||
@ -347,16 +347,27 @@ void EyeDiagramDialog::updateThread(unsigned int width, unsigned int height)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto scale = timestep / (length / (samples - 1));
|
|
||||||
unsigned long convolutedSize = length / timestep;
|
unsigned long convolutedSize = length / timestep;
|
||||||
if(convolutedSize > inVec.size()) {
|
if(convolutedSize > inVec.size()) {
|
||||||
// impulse response is longer than what we display, truncate
|
// impulse response is longer than what we display, truncate
|
||||||
convolutedSize = inVec.size();
|
convolutedSize = inVec.size();
|
||||||
}
|
}
|
||||||
impulseVec.resize(convolutedSize);
|
impulseVec.resize(convolutedSize);
|
||||||
|
/*
|
||||||
|
* we can't use the impulse response directly because we most likely need samples inbetween
|
||||||
|
* the calculated values. Interpolation is available but if our sample spacing here is much
|
||||||
|
* wider than the impulse response data, we might miss peaks (or severely miscalculate their
|
||||||
|
* amplitude.
|
||||||
|
* Instead, the step response is interpolated and the impulse response determined by deriving
|
||||||
|
* it from the interpolated step response data. As the step response is the integrated imulse
|
||||||
|
* response data, we can't miss narrow peaks that way.
|
||||||
|
*/
|
||||||
|
double lastStepResponse = 0.0;
|
||||||
for(unsigned long i=0;i<convolutedSize;i++) {
|
for(unsigned long i=0;i<convolutedSize;i++) {
|
||||||
auto x = i*timestep;
|
auto x = i*timestep;
|
||||||
impulseVec[i] = tdr->getInterpolatedSample(x).y.real() * scale;
|
auto step = tdr->getInterpolatedStepResponse(x);
|
||||||
|
impulseVec[i] = step - lastStepResponse;
|
||||||
|
lastStepResponse = step;
|
||||||
}
|
}
|
||||||
|
|
||||||
eyeTimeShift += (risetime + falltime) * 1.25 / 4;
|
eyeTimeShift += (risetime + falltime) * 1.25 / 4;
|
||||||
|
@ -106,6 +106,37 @@ double TraceMath::getStepResponse(unsigned int index)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double TraceMath::getInterpolatedStepResponse(double x)
|
||||||
|
{
|
||||||
|
if(stepResponse.size() != data.size()) {
|
||||||
|
// make sure all the step response data is available
|
||||||
|
return std::numeric_limits<double>::quiet_NaN();
|
||||||
|
}
|
||||||
|
|
||||||
|
double ret = std::numeric_limits<double>::quiet_NaN();
|
||||||
|
|
||||||
|
if(data.size() == 0 || x < data.front().x || x > data.back().x) {
|
||||||
|
ret = std::numeric_limits<double>::quiet_NaN();
|
||||||
|
} else {
|
||||||
|
auto it = lower_bound(data.begin(), data.end(), x, [](const Data &lhs, const double x) -> bool {
|
||||||
|
return lhs.x < x;
|
||||||
|
});
|
||||||
|
if(it->x == x) {
|
||||||
|
ret = stepResponse[it - data.begin()];
|
||||||
|
} else {
|
||||||
|
// no exact match, needs to interpolate
|
||||||
|
unsigned int highIndex = it - data.begin();
|
||||||
|
unsigned int lowIndex = highIndex - 1;
|
||||||
|
auto high = *it;
|
||||||
|
it--;
|
||||||
|
auto low = *it;
|
||||||
|
double alpha = (x - low.x) / (high.x - low.x);
|
||||||
|
ret = stepResponse[lowIndex] * (1 - alpha) + stepResponse[highIndex] * alpha;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
TraceMath::Data TraceMath::getInterpolatedSample(double x)
|
TraceMath::Data TraceMath::getInterpolatedSample(double x)
|
||||||
{
|
{
|
||||||
Data ret;
|
Data ret;
|
||||||
|
@ -91,8 +91,9 @@ public:
|
|||||||
static TypeInfo getInfo(Type type);
|
static TypeInfo getInfo(Type type);
|
||||||
|
|
||||||
Data getSample(unsigned int index);
|
Data getSample(unsigned int index);
|
||||||
double getStepResponse(unsigned int index);
|
|
||||||
Data getInterpolatedSample(double x);
|
Data getInterpolatedSample(double x);
|
||||||
|
double getStepResponse(unsigned int index);
|
||||||
|
double getInterpolatedStepResponse(double x);
|
||||||
unsigned int numSamples();
|
unsigned int numSamples();
|
||||||
|
|
||||||
static QString dataTypeToString(DataType type);
|
static QString dataTypeToString(DataType type);
|
||||||
|
Loading…
Reference in New Issue
Block a user