⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 drmplot.cpp

📁 Dream.exe soft source (Visual C++)
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/******************************************************************************\
 * Technische Universitaet Darmstadt, Institut fuer Nachrichtentechnik
 * Copyright (c) 2001
 *
 * Author(s):
 *	Volker Fischer
 *
 * Description:
 *	Custom settings of the qwt-plot
 *
 ******************************************************************************
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later 
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT 
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
\******************************************************************************/

#include "DRMPlot.h"


/* Implementation *************************************************************/
CDRMPlot::CDRMPlot(QWidget *p, const char *name) :  
	QwtPlot (p, name), CurCharType(NONE_OLD), InitCharType(NONE_OLD),
	bOnTimerCharMutexFlag(FALSE), pDRMRec(NULL)
{
	/* Grid defaults */
	enableGridX(TRUE);
	enableGridY(TRUE);

	enableGridXMin(FALSE);
	enableGridYMin(FALSE);

	/* Legend should be on the right side */
	setLegendPos(QwtPlot::Right);

	/* Fonts */
	setTitleFont(QFont("SansSerif", 8, QFont::Bold));
	setAxisFont(QwtPlot::xBottom, QFont("SansSerif", 8));
	setAxisFont(QwtPlot::yLeft, QFont("SansSerif", 8));
	setAxisFont(QwtPlot::yRight, QFont("SansSerif", 8));
	setAxisTitleFont(QwtPlot::xBottom, QFont("SansSerif", 8));
	setAxisTitleFont(QwtPlot::yLeft, QFont("SansSerif", 8));
	setAxisTitleFont(QwtPlot::yRight, QFont("SansSerif", 8));

	/* Global frame */
	setFrameStyle(QFrame::Panel|QFrame::Sunken);
	setLineWidth(2);
	setMargin(10);

	/* Canvas */
	setCanvasLineWidth(0);

	/* Set default style */
	SetPlotStyle(0);

	/* Connections */
	connect(this, SIGNAL(plotMouseReleased(const QMouseEvent&)),
		this, SLOT(OnClicked(const QMouseEvent&)));
	connect(&TimerChart, SIGNAL(timeout()),
		this, SLOT(OnTimerChart()));
}

void CDRMPlot::OnTimerChart()
{
	/* In some cases, if the user moves the mouse very fast over the chart
	   selection list view, this function is called by two different threads.
	   Somehow, using QMtuex does not help. Therefore we introduce a flag for
	   doing this job. This solution is a work-around. TODO: better solution */
	if (bOnTimerCharMutexFlag == TRUE)
		return;

	bOnTimerCharMutexFlag = TRUE;


	/* CHART ******************************************************************/
	CVector<_REAL>		vecrData;
	CVector<_REAL>		vecrData2;
	CVector<_COMPLEX>	veccData1, veccData2, veccData3;
	CVector<_REAL>		vecrScale;
	_REAL				rLowerBound, rHigherBound;
	_REAL				rStartGuard, rEndGuard;
	_REAL				rPDSBegin, rPDSEnd;
	_REAL				rFreqAcquVal;
	_REAL				rCenterFreq, rBandwidth;

	switch (CurCharType)
	{
	case AVERAGED_IR:
		/* Get data from module */
		pDRMRec->GetChanEst()->
			GetAvPoDeSp(vecrData, vecrScale, rLowerBound, rHigherBound,
			rStartGuard, rEndGuard, rPDSBegin, rPDSEnd);

		/* Prepare graph and set data */
		SetAvIR(vecrData, vecrScale, rLowerBound, rHigherBound, 
			rStartGuard, rEndGuard, rPDSBegin, rPDSEnd);
		break;

	case TRANSFERFUNCTION:
		/* Get data from module */
		pDRMRec->GetChanEst()->
			GetTransferFunction(vecrData, vecrData2, vecrScale);

		/* Prepare graph and set data */
		SetTranFct(vecrData, vecrData2, vecrScale);
		break;

	case POWER_SPEC_DENSITY:
		/* Get data from module */
		pDRMRec->GetOFDMDemod()->GetPowDenSpec(vecrData, vecrScale);

		/* Prepare graph and set data */
		SetPSD(vecrData, vecrScale);
		break;

	case SNR_SPECTRUM:
		/* Get data from module */
		pDRMRec->GetChanEst()->GetSNRProfile(vecrData, vecrScale);

		/* Prepare graph and set data */
		SetSNRSpectrum(vecrData, vecrScale);
		break;

	case INPUTSPECTRUM_NO_AV:
		/* Get data from module */
		pDRMRec->GetReceiver()->GetInputSpec(vecrData, vecrScale);

		/* Prepare graph and set data */
		SetInpSpec(vecrData, vecrScale,
			pDRMRec->GetParameters()->GetDCFrequency());
		break;

	case INP_SPEC_WATERF:
		/* Get data from module */
		pDRMRec->GetReceiver()->GetInputSpec(vecrData, vecrScale);

		/* Prepare graph and set data */
		SetInpSpecWaterf(vecrData, vecrScale);
		break;

	case INPUT_SIG_PSD:
		/* Get data from module */
		pDRMRec->GetReceiver()->GetInputPSD(vecrData, vecrScale);

		/* Prepare graph and set data */
		SetInpPSD(vecrData, vecrScale,
			pDRMRec->GetParameters()->GetDCFrequency());
		break;

	case INPUT_SIG_PSD_ANALOG:
		/* Get data and parameters from modules */
		pDRMRec->GetReceiver()->GetInputPSD(vecrData, vecrScale);
		pDRMRec->GetAMDemod()->GetBWParameters(rCenterFreq, rBandwidth);

		/* Prepare graph and set data */
		SetInpPSD(vecrData, vecrScale,
			pDRMRec->GetAMDemod()->GetCurMixFreqOffs(), rCenterFreq,
			rBandwidth);
		break;

	case AUDIO_SPECTRUM:
		/* Get data from module */
		pDRMRec->GetWriteData()->GetAudioSpec(vecrData, vecrScale);

		/* Prepare graph and set data */
		SetAudioSpec(vecrData, vecrScale);
		break;

	case FREQ_SAM_OFFS_HIST:
		/* Get data from module */
		pDRMRec->GetFreqSamOffsHist(vecrData, vecrData2, vecrScale,
			rFreqAcquVal);

		/* Prepare graph and set data */
		SetFreqSamOffsHist(vecrData, vecrData2, vecrScale,
			rFreqAcquVal);
		break;

	case DOPPLER_DELAY_HIST:
		/* Get data from module */
		pDRMRec->GetDopplerDelHist(vecrData, vecrData2, vecrScale);

		/* Prepare graph and set data */
		SetDopplerDelayHist(vecrData, vecrData2, vecrScale);
		break;

	case SNR_AUDIO_HIST:
		/* Get data from module */
		pDRMRec->GetSNRHist(vecrData, vecrData2, vecrScale);

		/* Prepare graph and set data */
		SetSNRAudHist(vecrData, vecrData2, vecrScale);
		break;

	case FAC_CONSTELLATION:
		/* Get data vector */
		pDRMRec->GetFACMLC()->GetVectorSpace(veccData1);

		/* Prepare graph and set data */
		SetFACConst(veccData1);
		break;

	case SDC_CONSTELLATION:
		/* Get data vector */
		pDRMRec->GetSDCMLC()->GetVectorSpace(veccData1);

		/* Prepare graph and set data */
		SetSDCConst(veccData1, 
			pDRMRec->GetParameters()->eSDCCodingScheme);
		break;

	case MSC_CONSTELLATION:
		/* Get data vector */
		pDRMRec->GetMSCMLC()->GetVectorSpace(veccData1);

		/* Prepare graph and set data */
		SetMSCConst(veccData1, 
			pDRMRec->GetParameters()->eMSCCodingScheme);
		break;

	case ALL_CONSTELLATION:
		/* Get data vectors */
		pDRMRec->GetMSCMLC()->GetVectorSpace(veccData1);
		pDRMRec->GetSDCMLC()->GetVectorSpace(veccData2);
		pDRMRec->GetFACMLC()->GetVectorSpace(veccData3);

		/* Prepare graph and set data */
		SetAllConst(veccData1, veccData2, veccData3);
		break;
	}

	/* "Unlock" mutex flag */
	bOnTimerCharMutexFlag = FALSE;
}

void CDRMPlot::SetupChart(const ECharType eNewType)
{
	if (eNewType != NONE_OLD)
	{
		/* Set internal variable */
		CurCharType = eNewType;

		/* Update help text connected with the plot widget */
		AddWhatsThisHelpChar(eNewType);

		/* Update chart */
		OnTimerChart();

		/* Set up timer */
		switch (eNewType)
		{
		case INP_SPEC_WATERF:
			/* Very fast update */
			TimerChart.changeInterval(GUI_CONTROL_UPDATE_WATERFALL);
			break;

		case AVERAGED_IR:
		case TRANSFERFUNCTION:
		case POWER_SPEC_DENSITY:
		case INPUT_SIG_PSD:
		case INPUT_SIG_PSD_ANALOG:
		case SNR_SPECTRUM:
			/* Fast update */
			TimerChart.changeInterval(GUI_CONTROL_UPDATE_TIME_FAST);
			break;

		case FAC_CONSTELLATION:
		case SDC_CONSTELLATION:
		case MSC_CONSTELLATION:
		case ALL_CONSTELLATION:
		case INPUTSPECTRUM_NO_AV:
		case AUDIO_SPECTRUM:
		case FREQ_SAM_OFFS_HIST:
		case DOPPLER_DELAY_HIST:
		case SNR_AUDIO_HIST:
			/* Slow update of plot */
			TimerChart.changeInterval(GUI_CONTROL_UPDATE_TIME);
			break;
		}
	}
}

void CDRMPlot::showEvent(QShowEvent* pEvent)
{
	/* Activte real-time timers when window is shown */
	SetupChart(CurCharType);

	/* Update window */
	OnTimerChart();
}

void CDRMPlot::hideEvent(QHideEvent* pEvent)
{
	/* Deactivate real-time timers when window is hide to save CPU power */
	TimerChart.stop();
}

void CDRMPlot::SetPlotStyle(const int iNewStyleID)
{
	QColor BckgrdColorPlot;

	switch (iNewStyleID)
	{
	case 1:
		MainPenColorPlot = GREENBLACK_MAIN_PEN_COLOR_PLOT;
		MainPenColorConst = GREENBLACK_MAIN_PEN_COLOR_CONSTELLATION;
		BckgrdColorPlot = GREENBLACK_BCKGRD_COLOR_PLOT;
		MainGridColorPlot = GREENBLACK_MAIN_GRID_COLOR_PLOT;
		SpecLine1ColorPlot = GREENBLACK_SPEC_LINE1_COLOR_PLOT;
		SpecLine2ColorPlot = GREENBLACK_SPEC_LINE2_COLOR_PLOT;
		PassBandColorPlot = GREENBLACK_PASS_BAND_COLOR_PLOT;
		break;

	case 2:
		MainPenColorPlot = BLACKGREY_MAIN_PEN_COLOR_PLOT;
		MainPenColorConst = BLACKGREY_MAIN_PEN_COLOR_CONSTELLATION;
		BckgrdColorPlot = BLACKGREY_BCKGRD_COLOR_PLOT;
		MainGridColorPlot = BLACKGREY_MAIN_GRID_COLOR_PLOT;
		SpecLine1ColorPlot = BLACKGREY_SPEC_LINE1_COLOR_PLOT;
		SpecLine2ColorPlot = BLACKGREY_SPEC_LINE2_COLOR_PLOT;
		PassBandColorPlot = BLACKGREY_PASS_BAND_COLOR_PLOT;
		break;

	case 0: /* 0 is default */
	default:
		MainPenColorPlot = BLUEWHITE_MAIN_PEN_COLOR_PLOT;
		MainPenColorConst = BLUEWHITE_MAIN_PEN_COLOR_CONSTELLATION;
		BckgrdColorPlot = BLUEWHITE_BCKGRD_COLOR_PLOT;
		MainGridColorPlot = BLUEWHITE_MAIN_GRID_COLOR_PLOT;
		SpecLine1ColorPlot = BLUEWHITE_SPEC_LINE1_COLOR_PLOT;
		SpecLine2ColorPlot = BLUEWHITE_SPEC_LINE2_COLOR_PLOT;
		PassBandColorPlot = BLUEWHITE_PASS_BAND_COLOR_PLOT;
		break;
	}

	/* Apply colors */
	setGridMajPen(QPen(MainGridColorPlot, 0, DotLine));
	setGridMinPen(QPen(MainGridColorPlot, 0, DotLine));
	setCanvasBackground(QColor(BckgrdColorPlot));

	/* Refresh the plot */
	replot();
}

void CDRMPlot::SetData(CVector<_REAL>& vecrData, CVector<_REAL>& vecrScale)
{
	double* pdData = new double[vecrData.Size()];
	double* pdScale = new double[vecrScale.Size()];

	/* Copy data from vectors in temporary arrays */
	const int iScaleSize = vecrScale.Size();
	for (int i = 0; i < iScaleSize; i++)
	{
		pdData[i] = vecrData[i];
		pdScale[i] = vecrScale[i];
	}

	setCurveData(main1curve, pdScale, pdData, vecrData.Size());

	delete[] pdData;
	delete[] pdScale;
}

void CDRMPlot::SetData(CVector<_REAL>& vecrData1, CVector<_REAL>& vecrData2,
					   CVector<_REAL>& vecrScale)
{
	double* pdData1 = new double[vecrData1.Size()];
	double* pdData2 = new double[vecrData2.Size()];
	double* pdScale = new double[vecrScale.Size()];

	/* Copy data from vectors in temporary arrays */
	const int iScaleSize = vecrScale.Size();
	for (int i = 0; i < iScaleSize; i++)
	{
		pdData1[i] = vecrData1[i];
		pdData2[i] = vecrData2[i];
		pdScale[i] = vecrScale[i];
	}

	setCurveData(main1curve, pdScale, pdData1, vecrData1.Size());
	setCurveData(main2curve, pdScale, pdData2, vecrData2.Size());

	delete[] pdData1;
	delete[] pdData2;
	delete[] pdScale;
}

void CDRMPlot::SetData(CVector<_COMPLEX>& veccData)
{
	/* Copy data from vectors in temporary arrays */
	const int iDataSize = veccData.Size();
	for (int i = 0; i < iDataSize; i++)
	{
		const long lMarkerKey = insertMarker();
		setMarkerSymbol(lMarkerKey, MarkerSym1);
		setMarkerPos(lMarkerKey, veccData[i].real(), veccData[i].imag());
	}
}

void CDRMPlot::SetData(CVector<_COMPLEX>& veccMSCConst,
					   CVector<_COMPLEX>& veccSDCConst,
					   CVector<_COMPLEX>& veccFACConst)
{
	int i;

	/* Copy data from vectors in temporary arrays */
	const int iMSCSize = veccMSCConst.Size();
	for (i = 0; i < iMSCSize; i++)
	{
		const long lMarkerKey = insertMarker();
		setMarkerSymbol(lMarkerKey, MarkerSym1);
		setMarkerPos(lMarkerKey,
			veccMSCConst[i].real(), veccMSCConst[i].imag());
	}

	const int iSDCSize = veccSDCConst.Size();
	for (i = 0; i < iSDCSize; i++)
	{
		const long lMarkerKey = insertMarker();
		setMarkerSymbol(lMarkerKey, MarkerSym2);
		setMarkerPos(lMarkerKey,
			veccSDCConst[i].real(), veccSDCConst[i].imag());
	}

	const int iFACSize = veccFACConst.Size();
	for (i = 0; i < iFACSize; i++)
	{
		const long lMarkerKey = insertMarker();
		setMarkerSymbol(lMarkerKey, MarkerSym3);
		setMarkerPos(lMarkerKey,
			veccFACConst[i].real(), veccFACConst[i].imag());
	}
}

void CDRMPlot::SetupAvIR()
{
	/* Init chart for averaged impulse response */
	setTitle(tr("Channel Impulse Response"));
	enableAxis(QwtPlot::yRight, FALSE);
	enableGridX(TRUE);
	enableGridY(TRUE);
	setAxisTitle(QwtPlot::xBottom, tr("Time [ms]"));
	enableAxis(QwtPlot::yLeft, TRUE);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -