📄 freqsyncacq.cpp
字号:
#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 + -