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

📄 freqsyncacq.cpp

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

#ifdef _DEBUG_
/* Stores all important parameters for last shot */
FILE* pFile1 = fopen("test/freqacq.dat", "w");
int iPeakCnt = 0;
for (i = 1; i < iSearchWinSize; i++) {
	_REAL rPM, rFinPM; /* rPM: peak marker, rFinPM: final peak marker */
	if (iPeakCnt < iNumDetPeaks) {
		if (i == veciPeakIndex[iPeakCnt]) {
			rPM = vecrPSDPilCor[i];
			if (vecbFlagVec[iPeakCnt] == 1) rFinPM = vecrPSDPilCor[i]; else rFinPM = 0;
			iPeakCnt++;
		} else {rPM = 0; rFinPM = 0;}
	} else {rPM = 0; rFinPM = 0;}
	fprintf(pFile1, "%e %e %e\n", vecrPSDPilCor[i], rPM, rFinPM);
}
fclose(pFile1);
// close all;load freqacq.dat;load freqacqFilt.dat;subplot(211),semilogy(freqacq(:,1));hold;plot(freqacq(:,2),'*y');plot(freqacq(:,3),'*k');subplot(212),semilogy(freqacqFilt)
// close all;load freqacq.dat;semilogy(freqacq(:,1));hold;plot(freqacq(:,2),'*y');plot(freqacq(:,3),'*k');
#endif


						/* -----------------------------------------------------
						   An acquisition frequency offest estimation was
						   found */
						/* Calculate frequency offset and set global parameter
						   for offset */
						ReceiverParam.rFreqOffsetAcqui =
							(_REAL) iMaxIndex / iFrAcFFTSize;

						/* Reset acquisition flag */
						bAquisition = FALSE;


						/* Send out the data stored for FFT calculation ----- */
						/* This does not work for bandpass filter. TODO: make
						   this possible for bandpass filter, too */
						if (bUseRecFilter == FALSE)
						{
							iOutputBlockSize = iHistBufSize;

							/* Frequency offset correction */
							const _REAL rNormCurFreqOffsFst = (_REAL) 2.0 * crPi *
								(ReceiverParam.rFreqOffsetAcqui - rInternIFNorm);

							for (i = 0; i < iHistBufSize; i++)
							{
								/* Multiply with exp(j omega t) */
								(*pvecOutputData)[i] = vecrFFTHistory[i] *
									_COMPLEX(Cos(i * rNormCurFreqOffsFst),
									Sin(-i * rNormCurFreqOffsFst));
							}

							/* Init "exp-step" for regular frequency shift which
							   is used in tracking mode to get contiuous mixing
							   signal */
							cCurExp =
								_COMPLEX(Cos(iHistBufSize * rNormCurFreqOffsFst),
								Sin(-iHistBufSize * rNormCurFreqOffsFst));
						}
					}
				}
			}
		}
	}
	else
	{
		/* If synchronized DRM input stream is used, overwrite the detected
		   frequency offest estimate by the desired frequency, because we know
		   this value */
		if (bSyncInput == TRUE)
		{
			ReceiverParam.rFreqOffsetAcqui =
				(_REAL) ReceiverParam.iIndexDCFreq / ReceiverParam.iFFTSizeN;
		}

		/* Use the same block size as input block size */
		iOutputBlockSize = iInputBlockSize;


		/* Frequency offset correction -------------------------------------- */
		/* Total frequency offset from acquisition and tracking (we calculate
		   the normalized frequency offset) */
		const _REAL rNormCurFreqOffset =
			(_REAL) 2.0 * crPi * (ReceiverParam.rFreqOffsetAcqui +
			ReceiverParam.rFreqOffsetTrack - rInternIFNorm);

		/* New rotation vector for exp() calculation */
		const _COMPLEX cExpStep =
			_COMPLEX(Cos(rNormCurFreqOffset), Sin(rNormCurFreqOffset));

		/* Input data is real, make complex and compensate for frequency
		   offset */
		for (i = 0; i < iOutputBlockSize; i++)
		{
			(*pvecOutputData)[i] = (*pvecInputData)[i] * Conj(cCurExp);

			/* Rotate exp-pointer on step further by complex multiplication with
			   precalculated rotation vector cExpStep. This saves us from
			   calling sin() and cos() functions all the time (iterative
			   calculation of these functions) */
			cCurExp *= cExpStep;
		}


		/* Bandpass filter -------------------------------------------------- */
		if (bUseRecFilter == TRUE)
			BPFilter.Process(*pvecOutputData);
	}
}

void CFreqSyncAcq::InitInternal(CParameter& ReceiverParam)
{
	/* Needed for calculating offset in Hertz in case of synchronized input
	   (for simulation) */
	iFFTSize = ReceiverParam.iFFTSizeN;

	/* We using parameters from robustness mode B as pattern for the desired
	   frequency pilot positions */
	veciTableFreqPilots[0] =
		iTableFreqPilRobModB[0][0] * NUM_BLOCKS_4_FREQ_ACQU;
	veciTableFreqPilots[1] =
		iTableFreqPilRobModB[1][0] * NUM_BLOCKS_4_FREQ_ACQU;
	veciTableFreqPilots[2] =
		iTableFreqPilRobModB[2][0] * NUM_BLOCKS_4_FREQ_ACQU;

	/* Size of FFT */
	iFrAcFFTSize = RMB_FFT_SIZE_N * NUM_BLOCKS_4_FREQ_ACQU;


	/* -------------------------------------------------------------------------
	   Set start- and endpoint of search window for DC carrier after the
	   correlation with the known pilot structure */
	/* Normalize the desired position and window size which are in Hertz */
	const _REAL rNormDesPos = rCenterFreq / SOUNDCRD_SAMPLE_RATE * 2;
	const _REAL rNormHalfWinSize = rWinSize / SOUNDCRD_SAMPLE_RATE;

	/* Length of the half of the spectrum of real input signal (the other half
	   is the same because of the real input signal). We have to consider the
	   Nyquist frequency ("iFrAcFFTSize" is always even!) */
	iHalfBuffer = iFrAcFFTSize / 2 + 1;

	/* Search window is smaller than haft-buffer size because of correlation
	   with pilot positions */
	iSearchWinSize = iHalfBuffer - veciTableFreqPilots[2];

	/* Calculate actual indices of start and end of search window */
	iStartDCSearch =
		(int) Floor((rNormDesPos - rNormHalfWinSize) * iHalfBuffer);
	iEndDCSearch = (int) Ceil((rNormDesPos + rNormHalfWinSize) * iHalfBuffer);

	/* Check range. If out of range -> correct */
	if (!((iStartDCSearch > 0) && (iStartDCSearch < iSearchWinSize)))
		iStartDCSearch = 0;

	if (!((iEndDCSearch > 0) && (iEndDCSearch < iSearchWinSize)))
		iEndDCSearch = iSearchWinSize;

	/* Set bound for ratio between filtered signal to signal. Use a lower bound
	   if the search window is smaller */
	if (((_REAL) iEndDCSearch - iStartDCSearch) / iHalfBuffer < (_REAL) 0.042)
		rPeakBoundFiltToSig = PEAK_BOUND_FILT2SIGNAL_0_042;
	else
		rPeakBoundFiltToSig = PEAK_BOUND_FILT2SIGNAL_1;


	/* Init vectors and FFT-plan -------------------------------------------- */
	/* Allocate memory for FFT-histories and init with zeros */
	iHistBufSize = iFrAcFFTSize * NUM_BLOCKS_USED_FOR_AV;
	vecrFFTHistory.Init(iHistBufSize, (_REAL) 0.0);
	vecrFFTInput.Init(iFrAcFFTSize);
	vecrSqMagFFTOut.Init(iHalfBuffer);

	/* Allocate memory for PSD after pilot correlation */
	vecrPSDPilCor.Init(iHalfBuffer);

	/* Init vectors for filtering in frequency direction */
	vecrFiltResLR.Init(iHalfBuffer);
	vecrFiltResRL.Init(iHalfBuffer);
	vecrFiltRes.Init(iHalfBuffer);

	/* Index memory for detected peaks (assume worst case with the size) */
	veciPeakIndex.Init(iHalfBuffer);

	/* Init plans for FFT (faster processing of Fft and Ifft commands) */
	FftPlan.Init(iFrAcFFTSize);

	/* Init Hamming window */
	vecrHammingWin.Init(iFrAcFFTSize);
	vecrHammingWin = Hamming(iFrAcFFTSize);

	/* Init moving average class for SqMag FFT results */
	vvrPSDMovAv.InitVec(NUM_FFT_RES_AV_BLOCKS, iHalfBuffer);


	/* Frequency correction */
	/* Start with phase null (arbitrary) */
	cCurExp = (_REAL) 1.0;
	rInternIFNorm = (_REAL) ReceiverParam.iIndexDCFreq / iFFTSize;


	/* Init bandpass filter object */
	BPFilter.Init(ReceiverParam.iSymbolBlockSize, VIRTUAL_INTERMED_FREQ,
		ReceiverParam.GetSpectrumOccup(), CDRMBandpassFilt::FT_RECEIVER);


	/* Define block-sizes for input (The output block size is set inside
	   the processing routine, therefore only a maximum block size is set
	   here) */
	iInputBlockSize = ReceiverParam.iSymbolBlockSize;

	/* We have to consider that the next module can take up to two symbols per
	   step. This can be satisfied be multiplying with "3". We also want to ship
	   the whole FFT buffer after finishing the frequency acquisition so that
	   these samples can be reused for synchronization and do not get lost */
	iMaxOutputBlockSize = 3 * ReceiverParam.iSymbolBlockSize + iHistBufSize;
}

void CFreqSyncAcq::SetSearchWindow(_REAL rNewCenterFreq, _REAL rNewWinSize)
{
	/* Set internal parameters */
	rCenterFreq = rNewCenterFreq;
	rWinSize = rNewWinSize;

	/* Set flag to initialize the module to the new parameters */
	SetInitFlag();
}

void CFreqSyncAcq::StartAcquisition()
{
	/* Set flag so that the actual acquisition routine is entered */
	bAquisition = TRUE;

	/* Reset (or init) counters */
	iAquisitionCounter = NUM_BLOCKS_4_FREQ_ACQU;
	iAverageCounter = NUM_FFT_RES_AV_BLOCKS;

	/* Reset FFT-history */
	vecrFFTHistory.Reset((_REAL) 0.0);
}

⌨️ 快捷键说明

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