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

📄 channelestimation.cpp

📁 Dream.exe soft source (Visual C++)
💻 CPP
📖 第 1 页 / 共 3 页
字号:
}

void CChannelEstimation::UpdateWienerFiltCoef(CReal rNewSNR, CReal rRatPDSLen,
											  CReal rRatPDSOffs)
{
	int	j, i;
	int	iDiff;
	int	iCurPil;

	/* Calculate all possible wiener filters */
	for (j = 0; j < iNumWienerFilt; j++)
	{
		matcWienerFilter[j] = FreqOptimalFilter(iScatPilFreqInt, j, rNewSNR,
			rRatPDSLen, rRatPDSOffs, iLengthWiener);
	}


#if 0
/* Save filter coefficients */
static FILE* pFile = fopen("test/wienerfreq.dat", "w");
for (j = 0; j < iNumWienerFilt; j++)
{
	for (i = 0; i < iLengthWiener; i++)
	{
		fprintf(pFile, "%e %e\n", Real(matcWienerFilter[j][i]),
			Imag(matcWienerFilter[j][i]));
	}
}
fflush(pFile);
#endif


	/* Set matrix with filter taps, one filter for each carrier */
	for (j = 0; j < iNumCarrier; j++)
	{
		/* We define the current pilot position as the last pilot which the
		   index "j" has passed */
		iCurPil = (int) (j / iScatPilFreqInt);

		/* Consider special cases at the edges of the DRM spectrum */
		if (iCurPil < iPilOffset)
		{
			/* Special case: left edge */
			veciPilOffTab[j] = 0;
		}
		else if (iCurPil - iPilOffset > iNumIntpFreqPil - iLengthWiener)
		{
			/* Special case: right edge */
			veciPilOffTab[j] = iNumIntpFreqPil - iLengthWiener;
		}
		else
		{
			/* In the middle */
			veciPilOffTab[j] = iCurPil - iPilOffset;
		}

		/* Special case for robustness mode D, since the DC carrier is not used
		   as a pilot and therefore we use the same method for the edges of the
		   spectrum also in the middle of robustness mode D */
		if (iDCPos != 0)
		{
			if ((iDCPos - iCurPil < iLengthWiener) && (iDCPos - iCurPil > 0))
			{
				/* Left side of DC carrier */
				veciPilOffTab[j] = iDCPos - iLengthWiener;
			}

			if ((iCurPil - iDCPos < iLengthWiener) && (iCurPil - iDCPos > 0))
			{
				/* Right side of DC carrier */
				veciPilOffTab[j] = iDCPos + 1;
			}
		}

		/* Difference between the position of the first pilot (for filtering)
		   and the position of the observed carrier */
		iDiff = j - veciPilOffTab[j] * iScatPilFreqInt;

		/* Copy correct filter in matrix */
		for (i = 0; i < iLengthWiener; i++)
			matcFiltFreq[j][i] = matcWienerFilter[iDiff][i];
	}
}

_REAL CChannelEstimation::CalAndBoundSNR(const _REAL rSignalEst,
										 const _REAL rNoiseEst)
{
	_REAL rReturn;

	/* "rNoiseEst" must not be zero */
	if (rNoiseEst != (_REAL) 0.0)
		rReturn = rSignalEst / rNoiseEst;
	else
		rReturn = (_REAL) 1.0;

	/* Bound the SNR at 0 dB */
	if (rReturn < (_REAL) 1.0)
		rReturn = (_REAL) 1.0;

	return rReturn;
}

_BOOLEAN CChannelEstimation::GetSNREstdB(_REAL& rSNREstRes) const
{
	const _REAL rNomBWSNR = rSNREstimate * rSNRSysToNomBWCorrFact;

	/* Bound the SNR at 0 dB */
	if ((rNomBWSNR > (_REAL) 1.0) && (bSNRInitPhase == FALSE))
		rSNREstRes = (_REAL) 10.0 * log10(rNomBWSNR);
	else
		rSNREstRes = (_REAL) 0.0;

	if (bSNRInitPhase == TRUE)
		return FALSE;
	else
		return TRUE;
}

_REAL CChannelEstimation::GetMSCMEREstdB()
{
	/* Calculate final result (signal to noise ratio) and consider correction
	   factor for average signal energy */
	const _REAL rCurMSCMEREst = rSNRSysToNomBWCorrFact *
		CalAndBoundSNR(AV_DATA_CELLS_POWER, rNoiseEstMSCMER);

	/* Bound the MCS MER at 0 dB */
	if (rCurMSCMEREst > (_REAL) 1.0)
		return (_REAL) 10.0 * log10(rCurMSCMEREst);
	else
		return (_REAL) 0.0;
}

_REAL CChannelEstimation::GetMSCWMEREstdB()
{
	_REAL rAvNoiseEstMSC = (_REAL) 0.0;
	_REAL rAvSigEstMSC = (_REAL) 0.0;

	/* Lock resources */
	Lock(); /* Lock start */
	{
		/* Average results from all carriers */
		for (int i = 0; i < iNumCarrier; i++)
		{
			rAvNoiseEstMSC += vecrNoiseEstMSC[i];
			rAvSigEstMSC += vecrSigEstMSC[i];
		}
	}
	Unlock(); /* Lock end */

	/* Calculate final result (signal to noise ratio) and consider correction
	   factor for average signal energy */
	const _REAL rCurMSCWMEREst = rSNRSysToNomBWCorrFact *
		CalAndBoundSNR(rAvSigEstMSC, rAvNoiseEstMSC);

	/* Bound the MCS MER at 0 dB */
	if (rCurMSCWMEREst > (_REAL) 1.0)
		return (_REAL) 10.0 * log10(rCurMSCWMEREst);
	else
		return (_REAL) 0.0;
}

_BOOLEAN CChannelEstimation::GetSigma(_REAL& rSigma)
{
	/* Doppler estimation is only implemented in the Wiener time interpolation
	   module */
	if (TypeIntTime == TWIENER)
	{
		rSigma = TimeWiener.GetSigma();
		return TRUE;
	}
	else
	{
		rSigma = (_REAL) 0.0;
		return FALSE;
	}
}

_REAL CChannelEstimation::GetDelay() const
{
	/* Delay in ms */
	return rLenPDSEst * iFFTSizeN / 
		(SOUNDCRD_SAMPLE_RATE * iNumIntpFreqPil * iScatPilFreqInt) * 1000;
}

_REAL CChannelEstimation::GetMinDelay()
{
	/* Lock because of vector "vecrDelayHist" access */
	Lock();

	/* Return minimum delay in history */
	_REAL rMinDelay = vecrDelayHist[0];
	for (int i = 0; i < iLenDelayHist; i++)
	{
		if (rMinDelay > vecrDelayHist[i])
			rMinDelay = vecrDelayHist[i];
	}

	Unlock();

	/* Return delay in ms */
	return rMinDelay * iFFTSizeN / 
		(SOUNDCRD_SAMPLE_RATE * iNumIntpFreqPil * iScatPilFreqInt) * 1000;
}

void CChannelEstimation::GetTransferFunction(CVector<_REAL>& vecrData,
											 CVector<_REAL>& vecrGrpDly,
											 CVector<_REAL>& vecrScale)
{
	/* Init output vectors */
	vecrData.Init(iNumCarrier, (_REAL) 0.0);
	vecrGrpDly.Init(iNumCarrier, (_REAL) 0.0);
	vecrScale.Init(iNumCarrier, (_REAL) 0.0);

	/* Do copying of data only if vector is of non-zero length which means that
	   the module was already initialized */
	if (iNumCarrier != 0)
	{
		_REAL rDiffPhase, rOldPhase;

		/* Lock resources */
		Lock();

		/* Init constants for normalization */
		const _REAL rTu = (CReal) iFFTSizeN / SOUNDCRD_SAMPLE_RATE;
		const _REAL rNormData = (_REAL) _MAXSHORT * _MAXSHORT;

		/* Copy data in output vector and set scale 
		   (carrier index as x-scale) */
		for (int i = 0; i < iNumCarrier; i++)
		{
			/* Transfer function */
			const _REAL rNormSqMagChanEst = SqMag(veccChanEst[i]) / rNormData;

			if (rNormSqMagChanEst > 0)
				vecrData[i] = (_REAL) 10.0 * Log10(rNormSqMagChanEst);
			else
				vecrData[i] = RET_VAL_LOG_0;

			/* Group delay */
			if (i == 0)
			{
				/* At position 0 we cannot calculate a derivation -> use
				   the same value as position 0 */
				rDiffPhase = Angle(veccChanEst[1]) - Angle(veccChanEst[0]);
			}
			else
				rDiffPhase = Angle(veccChanEst[i]) - rOldPhase;

			/* Take care of wrap around of angle() function */
			if (rDiffPhase > WRAP_AROUND_BOUND_GRP_DLY)
				rDiffPhase -= 2.0 * crPi;
			if (rDiffPhase < -WRAP_AROUND_BOUND_GRP_DLY)
				rDiffPhase += 2.0 * crPi;

			/* Apply normalization */
			vecrGrpDly[i] = rDiffPhase * rTu * 1000.0 /* ms */;

			/* Store old phase */
			rOldPhase = Angle(veccChanEst[i]);

			/* Scale (carrier index) */
			vecrScale[i] = i;
		}

		/* Release resources */
		Unlock();
	}
}

void CChannelEstimation::GetSNRProfile(CVector<_REAL>& vecrData,
									   CVector<_REAL>& vecrScale)
{
	int i;

	/* Init output vectors */
	vecrData.Init(iNumCarrier, (_REAL) 0.0);
	vecrScale.Init(iNumCarrier, (_REAL) 0.0);

	/* Do copying of data only if vector is of non-zero length which means that
	   the module was already initialized */
	if (iNumCarrier != 0)
	{
		/* Lock resources */
		Lock();

		/* We want to suppress the carriers on which no SNR measurement can be
		   performed (DC carrier, frequency pilots carriers) */
		int iNewNumCar = 0;
		for (i = 0; i < iNumCarrier; i++)
		{
			if (vecrSigEstMSC[i] != (_REAL) 0.0)
				iNewNumCar++;
		}

		/* Init output vectors for new size */
		vecrData.Init(iNewNumCar, (_REAL) 0.0);
		vecrScale.Init(iNewNumCar, (_REAL) 0.0);

		/* Copy data in output vector and set scale 
		   (carrier index as x-scale) */
		int iCurOutIndx = 0;
		for (i = 0; i < iNumCarrier; i++)
		{
			/* Suppress carriers where no SNR measurement is possible */
			if (vecrSigEstMSC[i] != (_REAL) 0.0)
			{
				/* Calculate final result (signal to noise ratio). Consider
				   correction factor for average signal energy */
				const _REAL rNomBWSNR =
					CalAndBoundSNR(vecrSigEstMSC[i], vecrNoiseEstMSC[i]) *
					rSNRFACSigCorrFact * rSNRSysToNomBWCorrFact;

				/* Bound the SNR at 0 dB */
				if ((rNomBWSNR > (_REAL) 1.0) && (bSNRInitPhase == FALSE))
					vecrData[iCurOutIndx] = (_REAL) 10.0 * Log10(rNomBWSNR);
				else
					vecrData[iCurOutIndx] = (_REAL) 0.0;

				/* Scale (carrier index) */
				vecrScale[iCurOutIndx] = i;

				iCurOutIndx++;
			}
		}

		/* Release resources */
		Unlock();
	}
}

void CChannelEstimation::GetAvPoDeSp(CVector<_REAL>& vecrData,
									 CVector<_REAL>& vecrScale,
									 _REAL& rLowerBound, _REAL& rHigherBound,
									 _REAL& rStartGuard, _REAL& rEndGuard,
									 _REAL& rPDSBegin, _REAL& rPDSEnd)
{
	/* Lock resources */
	Lock();

	TimeSyncTrack.GetAvPoDeSp(vecrData, vecrScale, rLowerBound,
		rHigherBound, rStartGuard, rEndGuard, rPDSBegin, rPDSEnd);

	/* Release resources */
	Unlock();
}

⌨️ 快捷键说明

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