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

📄 timesync.cpp

📁 数字音频广播中的同步算法在pc上的实现 主要运用了导频、最大似然估计等算法结合
💻 CPP
📖 第 1 页 / 共 2 页
字号:
				/* If pre-defined number of outliers is exceed, correct */				if (iCorrCounter > NUM_SYM_BEFORE_RESET)				{					/* If this is the first correction after an initialization					   was done, reset flag and do not show red light */					if (bInitTimingAcqu == TRUE)					{						/* Reset flag */						bInitTimingAcqu = FALSE;						/* Right after initialization, the first estimate is						   used for correction */						rStartIndex = (CReal) iNewStartIndexField[i];					}					else					{						/* Correct filter-output */						rStartIndex =							(CReal) iAveCorr / (NUM_SYM_BEFORE_RESET + 1);						/* GUI message that timing was corrected (red light) */						PostWinMessage(MS_TIME_SYNC, 2);					}					/* Reset counters */					iCorrCounter = 0;					iAveCorr = 0;				}				else				{					/* GUI message that timing is yet ok (yellow light). Do not					   show any light if init was done right before this */					if (bInitTimingAcqu == FALSE)						PostWinMessage(MS_TIME_SYNC, 1);				} 				ReceiverParam.ReceptLog.SetSync(FALSE);			}#ifdef _DEBUG_/* Save estimated positions of timing (acquisition) */static FILE* pFile = fopen("test/testtime.dat", "w");fprintf(pFile, "%d %d\n", iNewStartIndexField[i], iInputBlockSize);fflush(pFile);#endif		}		/* Convert result to integer format for cutting out the FFT-window */		iStartIndex = (int) rStartIndex;	}	else	{		/* Detect situation when acquisition was deactivated right now */		if (bAcqWasActive == TRUE)		{			bAcqWasActive = FALSE;			/* Reset also the tracking value since the tracking could not get			   right parameters since the timing was not yet correct */			ReceiverParam.iTimingOffsTrack = 0;		}		/* In case of tracking only, use final acquisition result "rStartIndex"		   (which is not updated any more) and add tracking correction */		iStartIndex = (int) rStartIndex + ReceiverParam.iTimingOffsTrack;		/* Timing acquisition was successfully finished, show always green		   light */		PostWinMessage(MS_TIME_SYNC, 0);		ReceiverParam.ReceptLog.SetSync(TRUE);#ifdef _DEBUG_/* Save estimated positions of timing (tracking) */static FILE* pFile = fopen("test/testtimetrack.dat", "w");static int iTimeTrackAbs = 0;iTimeTrackAbs += ReceiverParam.iTimingOffsTrack; /* Integration */fprintf(pFile, "%d\n", iTimeTrackAbs);fflush(pFile);#endif	}	/* -------------------------------------------------------------------------	   Cut out the estimated optimal time window and write it to the output	   vector. Add the acquisition and tracking offset together for the final	   timing */	/* Check range of "iStartIndex" to prevent from vector overwrites. It must	   be larger than "0" since then the input block size would be also "0" and	   than the processing routine of the modul would not be called any more */	const int i2SymBlSize = iSymbolBlockSize + iSymbolBlockSize;	if (iStartIndex <= 0)		iStartIndex = 1;	if (iStartIndex >= i2SymBlSize)		iStartIndex = i2SymBlSize;	/* Cut out the useful part of the OFDM symbol */	for (k = iStartIndex; k < iStartIndex + iDFTSize; k++)		(*pvecOutputData)[k - iStartIndex] = HistoryBuf[k];	/* If synchronized DRM input stream is used, overwrite the detected	   timing */	if (bSyncInput == TRUE)	{		/* Set fixed timing position */		iStartIndex = iSymbolBlockSize;		/* Cut out guard-interval at right position -> no channel estimation		   needed when having only one path. No delay introduced in this		   module  */		for (k = iGuardSize; k < iSymbolBlockSize; k++)		{			(*pvecOutputData)[k - iGuardSize] = 				HistoryBuf[iTotalBufferSize - iInputBlockSize + k];		}	}	/* -------------------------------------------------------------------------	   Adjust filtered measurement so that it is back in the center of the	   buffer */	/* Integer part of the difference between filtered measurement and the	   center of the buffer */	iIntDiffToCenter = iCenterOfBuf - iStartIndex;	/* Set input block size for next block and reset filtered measurement. This	   is equal to a global shift of the observation window by the	   rearrangement of the filtered measurement */	iInputBlockSize = iSymbolBlockSize - iIntDiffToCenter;	/* In acquisition mode, correct start index */	if (bTimingAcqu == TRUE)		rStartIndex += (CReal) iIntDiffToCenter;	/* -------------------------------------------------------------------------	   The channel estimation needs information about timing corrections,	   because it is using information from the symbol memory. After a	   timing correction all old symbols must be corrected by a phase	   rotation as well */	(*pvecOutputData).GetExData().iCurTimeCorr = iIntDiffToCenter;}void CTimeSync::InitInternal(CParameter& ReceiverParam){	int		i, j;	int		iMaxSymbolBlockSize;	int		iObservedFreqBin;	CReal	rArgTemp;	int		iCorrBuffSize;	/* Get parameters from info class */	iGuardSize = ReceiverParam.iGuardSize;	iDFTSize = ReceiverParam.iFFTSizeN;	iSymbolBlockSize = ReceiverParam.iSymbolBlockSize;	/* Decimated symbol block size */	iDecSymBS = iSymbolBlockSize / GRDCRR_DEC_FACT;	/* Calculate maximum symbol block size (This is Rob. Mode A) */	iMaxSymbolBlockSize = RMA_FFT_SIZE_N + 		RMA_FFT_SIZE_N * RMA_ENUM_TG_TU / RMA_DENOM_TG_TU;	/* We need at least two blocks of data for determining the timing */	iTotalBufferSize = 2 * iSymbolBlockSize + iMaxSymbolBlockSize;	iCorrBuffSize = iTotalBufferSize / GRDCRR_DEC_FACT;	/* Set step size of the guard-interval correlation */	iStepSizeGuardCorr = STEP_SIZE_GUARD_CORR;	/* Size for moving average buffer for guard-interval correlation */	iMovAvBufSize = 		(int) ((CReal) iGuardSize / GRDCRR_DEC_FACT / iStepSizeGuardCorr);	/* Size of buffer, storing the moving-average results for 	   maximum detection */	iMaxDetBufSize = 		(int) ((CReal) iDecSymBS / iStepSizeGuardCorr);	/* Center of maximum detection buffer */	iCenterOfMaxDetBuf = (iMaxDetBufSize - 1) / 2;	/* Init Energy calculation after guard-interval correlation (moving	   average) */	vecrGuardEnMovAv.Init(iMovAvBufSize);	/* Start position of this value must be at the end of the observation       window because we reset it at the beginning of the loop */	iTimeSyncPos = 2 * iDecSymBS;	/* Calculate center of buffer */	iCenterOfBuf = iSymbolBlockSize;	/* Init rStartIndex only if acquisition was activated */	if (bTimingAcqu == TRUE)		rStartIndex = (CReal) iCenterOfBuf;	/* Some inits */	iAveCorr = 0;	bInitTimingAcqu = TRUE; /* Flag to show that init was done */	/* Set correction counter so that a non-linear correction is performed right	   at the beginning */	iCorrCounter = NUM_SYM_BEFORE_RESET;	/* Allocate memory for vectors and zero out */	HistoryBuf.Init(iTotalBufferSize, (CReal) 0.0);	pMaxDetBuffer.Init(iMaxDetBufSize, (CReal) 0.0);	HistoryBufCorr.Init(iCorrBuffSize, (CReal) 0.0);	/* Inits for averaging the guard-interval correlation */	vecCorrAvBuf.Init(iMaxDetBufSize, (CReal) 0.0);	iCorrAvInd = 0;	/* Set the selected robustness mode index */	iSelectedMode = GetIndFromRMode(ReceiverParam.GetWaveMode());	/* Init init count for timing sync (one symbol) */	iTiSyncInitCnt = iDecSymBS / iStepSizeGuardCorr;	/* Inits for guard-interval correlation and robustness mode detection --- */	/* Size for robustness mode correlation buffer */	iRMCorrBufSize = (int) ((CReal) NUM_BLOCKS_FOR_RM_CORR * iDecSymBS		/ STEP_SIZE_GUARD_CORR);	/* Init init count for robustness mode detection (do not use the very first	   block) */	iRobModInitCnt = NUM_BLOCKS_FOR_RM_CORR + 1;	for (i = 0; i < NUM_ROBUSTNESS_MODES; i++)	{		cGuardCorr[i] = (CReal) 0.0;		cGuardCorrBlock[i] = (CReal) 0.0;		rGuardPow[i] = (CReal) 0.0;		rGuardPowBlock[i] = (CReal) 0.0;		iPosInIntermCResBuf[i] = 0;		/* Set length of the useful part of the symbol and guard size */		switch (i)		{		case 0:			iLenUsefPart[i] = RMA_FFT_SIZE_N / GRDCRR_DEC_FACT;			iLenGuardInt[i] = (int) ((CReal) RMA_FFT_SIZE_N * 				RMA_ENUM_TG_TU / RMA_DENOM_TG_TU / GRDCRR_DEC_FACT);			break;		case 1:			iLenUsefPart[i] = RMB_FFT_SIZE_N / GRDCRR_DEC_FACT;			iLenGuardInt[i] = (int) ((CReal) RMB_FFT_SIZE_N * 				RMB_ENUM_TG_TU / RMB_DENOM_TG_TU / GRDCRR_DEC_FACT);			break;		case 2:			iLenUsefPart[i] = RMC_FFT_SIZE_N / GRDCRR_DEC_FACT;			iLenGuardInt[i] = (int) ((CReal) RMC_FFT_SIZE_N * 				RMC_ENUM_TG_TU / RMC_DENOM_TG_TU / GRDCRR_DEC_FACT);			break;		case 3:			iLenUsefPart[i] = RMD_FFT_SIZE_N / GRDCRR_DEC_FACT;			iLenGuardInt[i] = (int) ((CReal) RMD_FFT_SIZE_N * 				RMD_ENUM_TG_TU / RMD_DENOM_TG_TU / GRDCRR_DEC_FACT);			break;		}		/* Number of correlation result blocks to be stored in a vector. This is		   the total length of the guard-interval divided by the step size.		   Since the guard-size must not be a multiple of "iStepSizeGuardCorr",		   we need to cut-off the fractional part */		iLengthIntermCRes[i] = (int) ((CReal) iLenGuardInt[i] / 			iStepSizeGuardCorr);		/* This length is the start point for the "for"-loop */		iLengthOverlap[i] = iLenGuardInt[i] - 			iStepSizeGuardCorr;		/* Intermediate correlation results vector (init, zero out) */		veccIntermCorrRes[i].Init(iLengthIntermCRes[i], (CReal) 0.0);		vecrIntermPowRes[i].Init(iLengthIntermCRes[i], (CReal) 0.0);		/* Allocate memory for correlation input buffers */		vecrRMCorrBuffer[i].Init(iRMCorrBufSize);		/* Tables for sin and cos function for the desired frequency band */		/* First, allocate memory for vector */		vecrCos[i].Init(iRMCorrBufSize);		/* Build table */		for (j = 0; j < iRMCorrBufSize; j++)		{			/* Calculate frequency bins which has to be observed for each			   mode.			   Mode A: f_A = 1 / T_s = 1 / 26.66 ms = 37.5 Hz			   Mode B: f_B = 1 / T_s = 1 / 26.66 ms = 37.5 Hz			   Mode C: f_C = 1 / T_s = 1 / 20 ms = 50 Hz			   Mode D: f_D = 1 / T_s = 1 / 16.66 ms = 60 Hz */			iObservedFreqBin = 				(int) ((CReal) iRMCorrBufSize * STEP_SIZE_GUARD_CORR /				(iLenUsefPart[i] + iLenGuardInt[i]));			rArgTemp = (CReal) 2.0 * crPi / iRMCorrBufSize * j;			vecrCos[i][j] = cos(rArgTemp * iObservedFreqBin);		}	}#ifdef USE_FRQOFFS_TRACK_GUARDCORR	/* Init vector for averaging the frequency offset estimation */	cFreqOffAv = CComplex((CReal) 0.0, (CReal) 0.0);	/* Init time constant for IIR filter for frequency offset estimation */	rLamFreqOff = IIR1Lam(TICONST_FREQ_OFF_EST_GUCORR,		(CReal) SOUNDCRD_SAMPLE_RATE / ReceiverParam.iSymbolBlockSize);	/* Nomalization constant for frequency offset estimation */	rNormConstFOE = (CReal) 1.0 /		((CReal) 2.0 * crPi * ReceiverParam.iFFTSizeN * GRDCRR_DEC_FACT);#endif	/* Define block-sizes for input and output */	iInputBlockSize = iSymbolBlockSize; /* For the first loop */	iOutputBlockSize = iDFTSize;}void CTimeSync::StartAcquisition(){// TODO: check which initialization should be done here and which should be// moved to / from the "InitInternal()" function	/* The regular acquisition flags */	bTimingAcqu = TRUE;	bRobModAcqu = TRUE;	/* Set the init flag so that the "rStartIndex" can be initialized with the	   center of the buffer and other important settings can be done */	SetInitFlag();		/* This second flag is to determine the moment when the acquisition just	   finished. In this case, the tracking value must be reset */	bAcqWasActive = TRUE;	iCorrCounter = NUM_SYM_BEFORE_RESET;	/* Reset the buffers which are storing data for correlation (for robustness	   mode detection) */	for (int i = 0; i < NUM_ROBUSTNESS_MODES; i++)		vecrRMCorrBuffer[i] = Zeros(iRMCorrBufSize);	/* Reset lambda for averaging the guard-interval correlation results */	rLambdaCoAv = (CReal) 1.0;	iCorrAvInd = 0;}void CTimeSync::SetFilterTaps(const CReal rNewOffsetNorm){#ifndef USE_10_KHZ_HILBFILT	/* The filter should be on the right of the DC carrier in 5 kHz mode */	rNewOffsetNorm += (CReal) HILB_FILT_BNDWIDTH / 2 / SOUNDCRD_SAMPLE_RATE;#endif	/* Calculate filter taps for complex Hilbert filter */	cvecB.Init(NUM_TAPS_HILB_FILT);	for (int i = 0; i < NUM_TAPS_HILB_FILT; i++)		cvecB[i] = CComplex(			fHilLPProt[i] * Cos((CReal) 2.0 * crPi * rNewOffsetNorm * i),			fHilLPProt[i] * Sin((CReal) 2.0 * crPi * rNewOffsetNorm * i));	/* Init state vector for filtering with zeros */	cvecZ.Init(NUM_TAPS_HILB_FILT - 1, (CReal) 0.0);}CTimeSync::CTimeSync() : iTimeSyncPos(0), bSyncInput(FALSE), bTimingAcqu(FALSE),	bAcqWasActive(FALSE), bRobModAcqu(FALSE),	iLengthIntermCRes(NUM_ROBUSTNESS_MODES),	iPosInIntermCResBuf(NUM_ROBUSTNESS_MODES),	iLengthOverlap(NUM_ROBUSTNESS_MODES), iLenUsefPart(NUM_ROBUSTNESS_MODES),	iLenGuardInt(NUM_ROBUSTNESS_MODES), cGuardCorr(NUM_ROBUSTNESS_MODES),	rGuardPow(NUM_ROBUSTNESS_MODES), cGuardCorrBlock(NUM_ROBUSTNESS_MODES),	rGuardPowBlock(NUM_ROBUSTNESS_MODES), rLambdaCoAv((CReal) 1.0){	/* Init Hilbert filter. Since the frequency offset correction was	   done in the previous module, the offset for the filter is	   always "VIRTUAL_INTERMED_FREQ" */	SetFilterTaps((_REAL) VIRTUAL_INTERMED_FREQ / SOUNDCRD_SAMPLE_RATE);}int CTimeSync::GetIndFromRMode(ERobMode eNewMode){	/* Get the robustness mode index. We define:	   A: 0, B: 1, C: 2, D: 3 */	switch (eNewMode)	{	case RM_ROBUSTNESS_MODE_A:		return 0;	case RM_ROBUSTNESS_MODE_B:		return 1;	case RM_ROBUSTNESS_MODE_C:		return 2;	case RM_ROBUSTNESS_MODE_D:		return 3;	default:		return 0;	}}ERobMode CTimeSync::GetRModeFromInd(int iNewInd){	/* Get the robustness mode index. We define:	   A: 0, B: 1, C: 2, D: 3 */	switch (iNewInd)	{	case 0:		return RM_ROBUSTNESS_MODE_A;	case 1:		return RM_ROBUSTNESS_MODE_B;	case 2:		return RM_ROBUSTNESS_MODE_C;	case 3:		return RM_ROBUSTNESS_MODE_D;	default:		return RM_ROBUSTNESS_MODE_A;	}}

⌨️ 快捷键说明

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