📄 drmplot.cpp
字号:
setAxisTitle(QwtPlot::yLeft, tr("IR [dB]"));
canvas()->setBackgroundMode(QWidget::PaletteBackground);
/* Insert curves */
clear();
curve1 = insertCurve(tr("Guard-interval beginning"));
curve2 = insertCurve(tr("Guard-interval end"));
curve3 = insertCurve(tr("Estimated begin of impulse response"));
curve4 = insertCurve(tr("Estimated end of impulse response"));
setCurvePen(curve1, QPen(SpecLine1ColorPlot, 1, DotLine));
setCurvePen(curve2, QPen(SpecLine1ColorPlot, 1, DotLine));
setCurvePen(curve3, QPen(SpecLine2ColorPlot, 1, DotLine));
setCurvePen(curve4, QPen(SpecLine2ColorPlot, 1, DotLine));
curve5 = insertCurve(tr("Higher Bound"));
#ifdef _DEBUG_
curve6 = insertCurve(tr("Lower bound"));
setCurvePen(curve5, QPen(SpecLine1ColorPlot));
setCurvePen(curve6, QPen(SpecLine2ColorPlot));
#else
setCurvePen(curve5, QPen(SpecLine1ColorPlot, 1, DotLine));
#endif
/* Add main curve */
main1curve = insertCurve(tr("Channel Impulse Response"));
/* Curve color */
setCurvePen(main1curve, QPen(MainPenColorPlot, 2, SolidLine, RoundCap,
RoundJoin));
}
void CDRMPlot::SetAvIR(CVector<_REAL>& vecrData, CVector<_REAL>& vecrScale,
_REAL rLowerB, _REAL rHigherB,
const _REAL rStartGuard, const _REAL rEndGuard,
const _REAL rBeginIR, const _REAL rEndIR)
{
/* First check if plot must be set up */
if (InitCharType != AVERAGED_IR)
{
InitCharType = AVERAGED_IR;
SetupAvIR();
}
if (vecrScale.Size() != 0)
{
/* Fixed scale */
const double cdAxMinLeft = (double) -20.0;
const double cdAxMaxLeft = (double) 40.0;
setAxisScale(QwtPlot::yLeft, cdAxMinLeft, cdAxMaxLeft);
/* Vertical bounds -------------------------------------------------- */
double dX[2], dY[2];
/* These bounds show the beginning and end of the guard-interval */
dY[0] = cdAxMinLeft;
dY[1] = cdAxMaxLeft;
/* Left bound */
dX[0] = dX[1] = rStartGuard;
setCurveData(curve1, dX, dY, 2);
/* Right bound */
dX[0] = dX[1] = rEndGuard;
setCurveData(curve2, dX, dY, 2);
/* Estimated begin of impulse response */
dX[0] = dX[1] = rBeginIR;
setCurveData(curve3, dX, dY, 2);
/* Estimated end of impulse response */
dX[0] = dX[1] = rEndIR;
setCurveData(curve4, dX, dY, 2);
/* Data for the actual impulse response curve */
SetData(vecrData, vecrScale);
/* Horizontal bounds ------------------------------------------------ */
/* These bounds show the peak detection bound from timing tracking */
dX[0] = vecrScale[0];
dX[1] = vecrScale[vecrScale.Size() - 1];
#ifdef _DEBUG_
/* Lower bound */
dY[0] = dY[1] = rLowerB;
setCurveData(curve6, dX, dY, 2);
/* Higher bound */
dY[0] = dY[1] = rHigherB;
#else
/* Only include highest bound */
dY[0] = dY[1] = Max(rHigherB, rLowerB);
#endif
setCurveData(curve5, dX, dY, 2);
/* Adjust scale for x-axis */
setAxisScale(QwtPlot::xBottom, (double) vecrScale[0],
(double) vecrScale[vecrScale.Size() - 1]);
replot();
}
else
{
/* No input data, clear plot (by resetting it) */
SetupAvIR();
}
}
void CDRMPlot::SetupTranFct()
{
/* Init chart for transfer function */
setTitle(tr("Channel Transfer Function / Group Delay"));
enableAxis(QwtPlot::yRight);
enableGridX(TRUE);
enableGridY(TRUE);
setAxisTitle(QwtPlot::xBottom, tr("Carrier Index"));
enableAxis(QwtPlot::yLeft, TRUE);
setAxisTitle(QwtPlot::yLeft, tr("TF [dB]"));
canvas()->setBackgroundMode(QWidget::PaletteBackground);
setAxisTitle(QwtPlot::yRight, tr("Group Delay [ms]"));
setAxisScale(QwtPlot::yRight, (double) -50.0, (double) 50.0);
/* Fixed scale */
setAxisScale(QwtPlot::yLeft, (double) -85.0, (double) -35.0);
/* Add main curves */
clear();
main1curve = insertCurve(tr("Transf. Fct."));
main2curve = insertCurve(tr("Group Del."),
QwtPlot::xBottom, QwtPlot::yRight);
/* Curve colors */
setCurvePen(main1curve, QPen(MainPenColorPlot, 2, SolidLine, RoundCap,
RoundJoin));
setCurvePen(main2curve, QPen(SpecLine2ColorPlot, 1, SolidLine, RoundCap,
RoundJoin));
/* Legend */
enableLegend(TRUE, main1curve);
enableLegend(TRUE, main2curve);
}
void CDRMPlot::SetTranFct(CVector<_REAL>& vecrData, CVector<_REAL>& vecrData2,
CVector<_REAL>& vecrScale)
{
/* First check if plot must be set up */
if (InitCharType != TRANSFERFUNCTION)
{
InitCharType = TRANSFERFUNCTION;
SetupTranFct();
}
/* Fixed scale */
setAxisScale(QwtPlot::xBottom, (double) 0.0, (double) vecrScale.Size());
SetData(vecrData, vecrData2, vecrScale);
replot();
}
void CDRMPlot::SetupAudioSpec()
{
/* Init chart for audio spectrum */
setTitle(tr("Audio Spectrum"));
enableAxis(QwtPlot::yRight, FALSE);
enableGridX(TRUE);
enableGridY(TRUE);
setAxisTitle(QwtPlot::xBottom, tr("Frequency [kHz]"));
enableAxis(QwtPlot::yLeft, TRUE);
setAxisTitle(QwtPlot::yLeft, "AS [dB]");
canvas()->setBackgroundMode(QWidget::PaletteBackground);
/* Fixed scale */
setAxisScale(QwtPlot::yLeft, (double) -90.0, (double) -20.0);
double dBandwidth = (double) SOUNDCRD_SAMPLE_RATE / 2000;
if (SOUNDCRD_SAMPLE_RATE == 48000)
dBandwidth = (double) 20.0; /* Special value in case of 48 kHz */
setAxisScale(QwtPlot::xBottom, (double) 0.0, dBandwidth);
/* Add main curve */
clear();
main1curve = insertCurve(tr("Audio Spectrum"));
/* Curve color */
setCurvePen(main1curve, QPen(MainPenColorPlot, 2, SolidLine, RoundCap,
RoundJoin));
}
void CDRMPlot::SetAudioSpec(CVector<_REAL>& vecrData, CVector<_REAL>& vecrScale)
{
/* First check if plot must be set up */
if (InitCharType != AUDIO_SPECTRUM)
{
InitCharType = AUDIO_SPECTRUM;
SetupAudioSpec();
}
SetData(vecrData, vecrScale);
replot();
}
void CDRMPlot::SetupFreqSamOffsHist()
{
/* Init chart for transfer function. Enable right axis, too */
setTitle(tr("Rel. Frequency Offset / Sample Rate Offset History"));
enableAxis(QwtPlot::yRight);
enableGridX(TRUE);
enableGridY(TRUE);
setAxisTitle(QwtPlot::xBottom, tr("Time [s]"));
enableAxis(QwtPlot::yLeft, TRUE);
setAxisTitle(QwtPlot::yRight, tr("Sample Rate Offset [Hz]"));
canvas()->setBackgroundMode(QWidget::PaletteBackground);
/* Add main curves */
clear();
main1curve = insertCurve(tr("Freq."));
main2curve = insertCurve(tr("Samp."), QwtPlot::xBottom, QwtPlot::yRight);
/* Curve colors */
setCurvePen(main1curve, QPen(MainPenColorPlot, 2, SolidLine, RoundCap,
RoundJoin));
setCurvePen(main2curve, QPen(SpecLine2ColorPlot, 1, SolidLine, RoundCap,
RoundJoin));
/* Legend */
enableLegend(TRUE, main1curve);
enableLegend(TRUE, main2curve);
}
void CDRMPlot::SetFreqSamOffsHist(CVector<_REAL>& vecrData,
CVector<_REAL>& vecrData2,
CVector<_REAL>& vecrScale,
const _REAL rFreqOffAcquVal)
{
/* First check if plot must be set up */
if (InitCharType != FREQ_SAM_OFFS_HIST)
{
InitCharType = FREQ_SAM_OFFS_HIST;
SetupFreqSamOffsHist();
}
QString strYLeftLabel = tr("Freq. Offset [Hz] rel. to ") +
QString().setNum(rFreqOffAcquVal) + " Hz";
enableAxis(QwtPlot::yLeft, TRUE);
setAxisTitle(QwtPlot::yLeft, strYLeftLabel);
/* Customized auto-scaling. We adjust the y scale so that it is not larger
than rMinScaleRange" */
const _REAL rMinScaleRange = (_REAL) 1.0; /* Hz */
/* Get maximum and minimum values */
_REAL MaxFreq = -_MAXREAL;
_REAL MinFreq = _MAXREAL;
_REAL MaxSam = -_MAXREAL;
_REAL MinSam = _MAXREAL;
const int iSize = vecrScale.Size();
for (int i = 0; i < iSize; i++)
{
if (vecrData[i] > MaxFreq)
MaxFreq = vecrData[i];
if (vecrData[i] < MinFreq)
MinFreq = vecrData[i];
if (vecrData2[i] > MaxSam)
MaxSam = vecrData2[i];
if (vecrData2[i] < MinSam)
MinSam = vecrData2[i];
}
/* Apply scale to plot */
setAxisScale(QwtPlot::yLeft, (double) Floor(MinFreq / rMinScaleRange),
(double) Ceil(MaxFreq / rMinScaleRange));
setAxisScale(QwtPlot::yRight, (double) Floor(MinSam / rMinScaleRange),
(double) Ceil(MaxSam / rMinScaleRange));
setAxisScale(QwtPlot::xBottom, (double) vecrScale[0], (double) 0.0);
SetData(vecrData, vecrData2, vecrScale);
replot();
}
void CDRMPlot::SetupDopplerDelayHist()
{
/* Init chart for transfer function. Enable right axis, too */
setTitle(tr("Delay / Doppler History"));
enableAxis(QwtPlot::yRight);
enableGridX(TRUE);
enableGridY(TRUE);
setAxisTitle(QwtPlot::xBottom, tr("Time [min]"));
enableAxis(QwtPlot::yLeft, TRUE);
setAxisTitle(QwtPlot::yLeft, tr("Delay [ms]"));
setAxisTitle(QwtPlot::yRight, tr("Doppler [Hz]"));
canvas()->setBackgroundMode(QWidget::PaletteBackground);
/* Fixed scale */
setAxisScale(QwtPlot::yLeft, (double) 0.0, (double) 10.0);
setAxisScale(QwtPlot::yRight, (double) 0.0, (double) 4.0);
/* Add main curves */
clear();
main1curve = insertCurve(tr("Delay"));
main2curve = insertCurve(tr("Doppler"), QwtPlot::xBottom, QwtPlot::yRight);
/* Curve colors */
setCurvePen(main1curve, QPen(MainPenColorPlot, 2, SolidLine, RoundCap,
RoundJoin));
setCurvePen(main2curve, QPen(SpecLine2ColorPlot, 1, SolidLine, RoundCap,
RoundJoin));
/* Legend */
enableLegend(TRUE, main1curve);
enableLegend(TRUE, main2curve);
}
void CDRMPlot::SetDopplerDelayHist(CVector<_REAL>& vecrData,
CVector<_REAL>& vecrData2,
CVector<_REAL>& vecrScale)
{
/* First check if plot must be set up */
if (InitCharType != DOPPLER_DELAY_HIST)
{
InitCharType = DOPPLER_DELAY_HIST;
SetupDopplerDelayHist();
}
/* Fixed scale */
setAxisScale(QwtPlot::xBottom, (double) vecrScale[0], (double) 0.0);
SetData(vecrData, vecrData2, vecrScale);
replot();
}
void CDRMPlot::SetupSNRAudHist()
{
/* Init chart for transfer function. Enable right axis, too */
setTitle(tr("SNR / Correctly Decoded Audio History"));
enableAxis(QwtPlot::yRight);
enableGridX(TRUE);
enableGridY(TRUE);
setAxisTitle(QwtPlot::xBottom, tr("Time [min]"));
enableAxis(QwtPlot::yLeft, TRUE);
setAxisTitle(QwtPlot::yLeft, tr("SNR [dB]"));
setAxisTitle(QwtPlot::yRight, tr("Corr. Dec. Audio / DRM-Frame"));
canvas()->setBackgroundMode(QWidget::PaletteBackground);
/* Add main curves */
clear();
main1curve = insertCurve("SNR");
main2curve = insertCurve("Audio", QwtPlot::xBottom, QwtPlot::yRight);
/* Curve colors */
setCurvePen(main1curve, QPen(MainPenColorPlot, 2, SolidLine, RoundCap,
RoundJoin));
setCurvePen(main2curve, QPen(SpecLine2ColorPlot, 1, SolidLine, RoundCap,
RoundJoin));
/* Legend */
enableLegend(TRUE, main1curve);
enableLegend(TRUE, main2curve);
}
void CDRMPlot::SetSNRAudHist(CVector<_REAL>& vecrData,
CVector<_REAL>& vecrData2,
CVector<_REAL>& vecrScale)
{
/* First check if plot must be set up */
if (InitCharType != SNR_AUDIO_HIST)
{
InitCharType = SNR_AUDIO_HIST;
SetupSNRAudHist();
}
/* Customized auto-scaling. We adjust the y scale maximum so that it
is not more than "rMaxDisToMax" to the curve */
const int iMaxDisToMax = 5; /* dB */
const int iMinValueSNRYScale = 15; /* dB */
/* Get maximum value */
_REAL MaxSNR = -_MAXREAL;
const int iSize = vecrScale.Size();
for (int i = 0; i < iSize; i++)
{
if (vecrData[i] > MaxSNR)
MaxSNR = vecrData[i];
}
/* Quantize scale to a multiple of "iMaxDisToMax" */
double dMaxYScaleSNR =
(double) (Ceil(MaxSNR / iMaxDisToMax) * iMaxDisToMax);
/* Bound at the minimum allowed value */
if (dMaxYScaleSNR < (double) iMinValueSNRYScale)
dMaxYScaleSNR = (double) iMinValueSNRYScale;
/* Ratio between the maximum values for audio and SNR. The ratio should be
chosen so that the audio curve is not in the same range as the SNR curve
under "normal" conditions to increase readability of curves.
Since at very low SNRs, no audio can received anyway so we do not have to
check whether the audio y-scale is in range of the curve */
const _REAL rRatioAudSNR = (double) 1.5;
const double dMaxYScaleAudio = dMaxYScaleSNR * (double) rRatioAudSNR;
/* Apply scale to plot */
setAxisScale(QwtPlot::yLeft, (double) 0.0, dMaxYScaleSNR);
setAxisScale(QwtPlot::yRight, (double) 0.0, dMaxYScaleAudio);
setAxisScale(QwtPlot::xBottom, (double) vecrScale[0], (double) 0.0);
SetData(vecrData, vecrData2, vecrScale);
replot();
}
void CDRMPlot::SetupPSD()
{
/* Init chart for power spectram density estimation */
setTitle(tr("Shifted Power Spectral Density of Input Signal"));
enableAxis(QwtPlot::yRight, FALSE);
enableGridX(TRUE);
enableGridY(TRUE);
setAxisTitle(QwtPlot::xBottom, tr("Frequency [kHz]"));
enableAxis(QwtPlot::yLeft, TRUE);
setAxisTitle(QwtPlot::yLeft, tr("PSD [dB]"));
canvas()->setBackgroundMode(QWidget::PaletteBackground);
/* Fixed scale */
setAxisScale(QwtPlot::xBottom,
(double) 0.0, (double) SOUNDCRD_SAMPLE_RATE / 2000);
setAxisScale(QwtPlot::yLeft, MIN_VAL_SHIF_PSD_Y_AXIS_DB,
MAX_VAL_SHIF_PSD_Y_AXIS_DB);
/* Insert line for DC carrier */
clear();
curve1 = insertCurve(tr("DC carrier"));
setCurvePen(curve1, QPen(SpecLine1ColorPlot, 1, DotLine));
double dX[2], dY[2];
dX[0] = dX[1] = (_REAL) VIRTUAL_INTERMED_FREQ / 1000;
/* Take the min-max values from scale to get vertical line */
dY[0] = MIN_VAL_SHIF_PSD_Y_AXIS_DB;
dY[1] = MAX_VAL_SHIF_PSD_Y_AXIS_DB;
setCurveData(curve1, dX, dY, 2);
/* Add main curve */
main1curve = insertCurve(tr("Shifted PSD"));
/* Curve color */
setCurvePen(main1curve, QPen(MainPenColorPlot, 1, SolidLine, RoundCap,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -