请教level_sensing例程里关于Zoom FFT的计算方法

大家好,

最近在看level_sensing就是高精度测距例程的代码,关于Zoom FFT的代码没有看明白,没有找到旋转因子抽取的规律,也就不明白提高距离精度或者分辨率的根本原因。请大家帮忙看看,感谢!

具体的代码从下面c文件的251行开始:

/*! 
 *  \file   RADARDEMO_highAccuRangeProc_priv.c
 *
 *  \brief   Windowing functions for range processing.
 *
 * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/ 
 * 
 * 
 *  Redistribution and use in source and binary forms, with or without 
 *  modification, are permitted provided that the following conditions 
 *  are met:
 *
 *    Redistributions of source code must retain the above copyright 
 *    notice, this list of conditions and the following disclaimer.
 *
 *    Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the 
 *    documentation and/or other materials provided with the   
 *    distribution.
 *
 *    Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
 *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
*/

#include "RADARDEMO_highAccuRangeProc_priv.h"

#ifdef _TMS320C6X
#include "c6x.h"
#endif

#ifdef ARMVERSION
extern void dft(int size, float * input, float * output);
#endif

#ifndef ARMVERSION

/*!
   \fn     RADARDEMO_highAccuRangeProc_accumulateInput

   \brief   Accumulate signals from all chirps and convert to floating-point format with 1D windowing.

   \param[in]    nSamplesPerChirp
               Number of samples per chirp.

   \param[in]    fftSize1D
               1D FFT size.

   \param[in]    nChirpPerFrame
               Number of chirps per frame.

   \param[in]    fftWin1D
               Input pointer to 1D window function.
			   
   \param[in]    fftWin1DSize
               Number of ADC bits.

   \param[in]    inputPtr
               Pointer to input signal.

   \param[in]    chirpInd
               Flag to enable DC adjustment for ADC samples when set to 1. Otherwise, no preprocessing for ADC samples.

   \param[out]    outputPtr
               Pointer to the output signal.

   \pre       none

   \post      none


 */

void	RADARDEMO_highAccuRangeProc_accumulateInput(
                            IN  uint32_t nSamplesPerChirp,
                            IN  uint32_t fftSize1D,
                            IN  uint32_t nChirpPerFrame,
                            IN  float   * RESTRICT fftWin1D,
							IN 	int16_t  fftWin1DSize,
							IN  cplx16_t * RESTRICT inputPtr,
							IN  int32_t  chirpInd,
							OUT float * outputPtr)
{
	int32_t i, itemp;
	int64_t input;

	if (chirpInd == 0)
	{
		for( i = 0; i < ((int32_t)nSamplesPerChirp>> 1); i++)
		{
			input							=	_amem8(&inputPtr[2 * i]);
			_amem8_f2(&outputPtr[4*i])		=	_ftof2((float)_ext(_loll(input), 16, 16), (float)_ext(_loll(input), 0, 16));
			_amem8_f2(&outputPtr[4*i + 2])	=	_ftof2((float)_ext(_hill(input), 16, 16), (float)_ext(_hill(input), 0, 16));
		}
		if((int32_t)nSamplesPerChirp & 1)
		{
			itemp							=	_amem4(&inputPtr[nSamplesPerChirp - 1]);
			_amem8_f2(&outputPtr[2*(nSamplesPerChirp - 1)])	=	_ftof2((float)_ext(itemp, 16, 16), (float)_ext(itemp, 0, 16));
		}
	}
	else
	{
		for( i = 0; i < ((int32_t)nSamplesPerChirp>> 1); i++)
		{
			input							=	_amem8(&inputPtr[2 * i]);
			_amem8_f2(&outputPtr[4*i])		=	_daddsp(_amem8_f2(&outputPtr[4*i]), _ftof2((float)_ext(_loll(input), 16, 16), (float)_ext(_loll(input), 0, 16)));
			_amem8_f2(&outputPtr[4*i + 2])	=	_daddsp(_amem8_f2(&outputPtr[4*i + 2]), _ftof2((float)_ext(_hill(input), 16, 16), (float)_ext(_hill(input), 0, 16)));
		}
		if((int32_t)nSamplesPerChirp & 1)
		{
			itemp							=	_amem4(&inputPtr[nSamplesPerChirp - 1]);
			_amem8_f2(&outputPtr[2*(nSamplesPerChirp - 1)]) = _daddsp(_amem8_f2(&outputPtr[2*(nSamplesPerChirp - 1)]), _ftof2((float)_ext(itemp, 16, 16), (float)_ext(itemp, 0, 16)));
		}

		if (chirpInd == ((int32_t)nChirpPerFrame - 1))
		{
			__float2_t f2win1D;

			for( i = 0; i < fftWin1DSize; i++)
			{
				f2win1D						=	_ftof2(fftWin1D[i], fftWin1D[i]);
				_amem8_f2(&outputPtr[2*i])	=	_dmpysp(_amem8_f2(&outputPtr[2*i]), f2win1D);
				_amem8_f2(&outputPtr[2*(nSamplesPerChirp - i - 1)])	=	_dmpysp(_amem8_f2(&outputPtr[2*(nSamplesPerChirp - i - 1)]), f2win1D);
			}
			if (((int32_t)fftSize1D - (int32_t)nSamplesPerChirp) > 0)
			{
				for( i = 0; i < ((int32_t)fftSize1D - (int32_t)nSamplesPerChirp); i++);
				{
					_amem8_f2(&outputPtr[2*nSamplesPerChirp + 2*i])	=	_ftof2(0.f, 0.f);
				}
			}
		}
	}
}


/*!
   \fn     RADARDEMO_highAccuRangeProc_rangeEst

   \brief   Windowing function for 2D FFT and prepare for the input.

   \param[in]    highAccuRangeHandle
               Handle to the module.

   \param[out]    estRange
               Estimated range.

   \param[out]    deltaPhaseEst
               Estimated delta phase.

   \param[out]    estLinearSNR
               Estimated SNR.

   \pre       none

   \post      none


 */

void	RADARDEMO_highAccuRangeProc_rangeEst(
                            IN  RADARDEMO_highAccuRangeProc_handle *highAccuRangeHandle,
							OUT  float * estRange,
							OUT  float * deltaPhaseEst,
							OUT float * estLinearSNR)
{
	int32_t			i, j, k, rad1D, coarseRangeInd;
	unsigned char	* brev = NULL;
	float			totalPower, max, ftemp, sigPower, * RESTRICT powerPtr;
	__float2_t		f2input, * RESTRICT inputPtr, * RESTRICT inputPtr1;

	int32_t			zoomStartInd, zoomEndInd, itemp, tempIndFine1, tempIndFine2, tempIndCoarse, indMask, shift;
	int32_t			fineRangeInd, tempFineSearchIdx, tempCoarseSearchIdx;
	__float2_t		*RESTRICT wncPtr, wncoarse, *RESTRICT wnfPtr, wnfine1, sigAcc, f2temp;
	double			freqFineEst, fdelta, interpIndx;
	float           currP, prevP, maxPrevP, maxNextP;

	j  = 30 - _norm(highAccuRangeHandle->fft1DSize);
	if ((j & 1) == 0)
		rad1D = 4;
	else
		rad1D = 2;

	/* copy to scratch is needed because FFT function will corrupt the input. We need to preserve if for zoom-in FFT */
	inputPtr	=	(__float2_t *) highAccuRangeHandle->inputSig;
	inputPtr1	=	(__float2_t *) &highAccuRangeHandle->scratchPad[2 * highAccuRangeHandle->fft1DSize];
	for (i = 0; i < (int32_t)highAccuRangeHandle->fft1DSize; i++ )
	{
		f2input					=	_amem8_f2(inputPtr);
		_amem8_f2(inputPtr1++)	=	f2input;
		_amem8_f2(inputPtr)   =	_ftof2(_lof2(f2input), _hif2(f2input));
		inputPtr++;
	}

	inputPtr1	=	(__float2_t *) &highAccuRangeHandle->scratchPad[2 * highAccuRangeHandle->fft1DSize];
	DSPF_sp_fftSPxSP (
			highAccuRangeHandle->fft1DSize,
			(float*) inputPtr1,
			(float *)highAccuRangeHandle->twiddle, 
			highAccuRangeHandle->fft1DOutSig,
			brev,
			rad1D,
			0,
			highAccuRangeHandle->fft1DSize);

	for( i = 0; i < (int32_t)highAccuRangeHandle->skipLeft;  i++ )
	{
		_amem8_f2(&highAccuRangeHandle->fft1DOutSig[2*i]) = _ftof2(0.f, 0.f);
	}
	for( i = (int32_t)highAccuRangeHandle->fft1DSize- (int32_t)highAccuRangeHandle->skipRight; i < (int32_t)highAccuRangeHandle->fft1DSize; i++ )
	{
		_amem8_f2(&highAccuRangeHandle->fft1DOutSig[2*i]) = _ftof2(0.f, 0.f);
	}
	max			=	0.f;
	totalPower	=	0.f;
	coarseRangeInd	=	0;
	inputPtr	=	(__float2_t *)highAccuRangeHandle->fft1DOutSig;
	powerPtr	=	(float *)highAccuRangeHandle->scratchPad;
	for( i = 0; i < (int32_t)highAccuRangeHandle->fft1DSize; i++ )
	{
		f2input		=	_amem8_f2(inputPtr++);
		f2input		=	_dmpysp(f2input, f2input);
		ftemp		=	_hif2(f2input) + _lof2(f2input);
		powerPtr[i] =	ftemp;
		totalPower	+=	ftemp;
		if( max < ftemp )
		{
			max			=	ftemp;
			coarseRangeInd	=	i;
		}
	}
	
	i			=	coarseRangeInd;
	sigPower	=	powerPtr[i-2] + powerPtr[i-1] + powerPtr[i] + powerPtr[i+1] + powerPtr[i+2];

	*estLinearSNR	=	divsp((float)((int32_t)highAccuRangeHandle->fft1DSize  - (int32_t)highAccuRangeHandle->skipLeft - (int32_t)highAccuRangeHandle->skipRight- 5) * sigPower, (totalPower - sigPower));

	/* zoom in FFT: assuming always size of fft1DSize x fft1DSize */
	zoomStartInd	=	coarseRangeInd - highAccuRangeHandle->numRangeBinZoomIn;
	zoomEndInd		=	coarseRangeInd + highAccuRangeHandle->numRangeBinZoomIn;
	indMask			=	highAccuRangeHandle->fft1DSize - 1;
	shift			=	30 - _norm(highAccuRangeHandle->fft1DSize);
	inputPtr		=	(__float2_t *)highAccuRangeHandle->inputSig;
	wncPtr			=	(__float2_t *)highAccuRangeHandle->wnCoarse;
	wnfPtr			=	(__float2_t *)highAccuRangeHandle->wnFine;
	max				=	0.f;
	itemp			=	0;
	currP			=	0.f;
	prevP			=	0.f;
	maxNextP		=	0.f;
	maxPrevP		=	0.f;
	for( i = zoomStartInd; i < zoomEndInd; i++)
	{
		for( j = 0; j < (int32_t)highAccuRangeHandle->fft1DSize; j ++)
		{
			tempFineSearchIdx	=	j;
			sigAcc  =	_ftof2(0.f, 0.f); 
			tempCoarseSearchIdx	=	0;
#ifdef _TMS320C6X
#pragma UNROLL(2);
#endif
			for( k = 0; k < (int32_t)highAccuRangeHandle->nSamplesPerChirp; k ++)
			{
#if 0
				tempIndFine1	=	tempFineSearchIdx & indMask;
				tempIndFine2	=	tempFineSearchIdx >> shift;
				tempFineSearchIdx		+=	j;
				tempIndCoarse	=	tempCoarseSearchIdx & indMask;
				tempCoarseSearchIdx		+=	i;

				f2input			=	_amem8_f2(&inputPtr[k]);
				wncoarse		=	_amem8_f2(&wncPtr[tempIndCoarse]);
				wnfine1			=	_amem8_f2(&wnfPtr[tempIndFine1]);
				wnfine2			=	_amem8_f2(&wncPtr[tempIndFine2]);

				f2temp			=	_complex_mpysp(f2input, wnfine1);
				f2temp			=	_complex_mpysp(f2temp, wnfine2);
				f2temp			=	_complex_mpysp(f2temp, wncoarse);
				sigAcc			=	_daddsp(sigAcc, f2temp);
#else
				tempIndFine1	=	tempFineSearchIdx & indMask;
				tempIndFine2	=	tempFineSearchIdx >> shift;
				tempFineSearchIdx		+=	j;
				tempIndCoarse	=	(tempCoarseSearchIdx + tempIndFine2) & indMask;
				tempCoarseSearchIdx		+=	i;

				f2input			=	_amem8_f2(&inputPtr[k]);
				wncoarse		=	_amem8_f2(&wncPtr[tempIndCoarse]);
				wnfine1			=	_amem8_f2(&wnfPtr[tempIndFine1]);

				f2temp			=	_complex_mpysp(f2input, wnfine1);
				f2temp			=	_complex_mpysp(f2temp, wncoarse);
				sigAcc			=	_daddsp(sigAcc, f2temp);
#endif
			}
			prevP				=	currP;
			f2temp				=	_dmpysp(sigAcc,sigAcc);
			ftemp				=	_hif2(f2temp) + _lof2(f2temp);
			currP				=	ftemp;
			if( max < ftemp)
			{
				max				=	ftemp;
				fineRangeInd	=	itemp;
				maxPrevP		=	prevP;
			}
			if(itemp == fineRangeInd + 1)
				maxNextP		=	currP;
			itemp++;
		}
	}

	interpIndx  =   0.5 * divdp((double)maxPrevP - (double)maxNextP, (double)maxPrevP + (double)maxNextP -2.0 * (double) max);

	fdelta			=	divdp((double)highAccuRangeHandle->maxBeatFreq, (double)highAccuRangeHandle->fft1DSize * (double)highAccuRangeHandle->fft1DSize);
	freqFineEst		=	fdelta * ((double)(zoomStartInd * highAccuRangeHandle->fft1DSize + fineRangeInd) + interpIndx); 

	*estRange		=	(float)divdp(freqFineEst * 3.0e8 * (double)highAccuRangeHandle->chirpRampTime, (2.0 * (double)highAccuRangeHandle->chirpBandwidth));

	if (highAccuRangeHandle->enablePhaseEst)
	{
		float phaseCoarseEst1, phaseCoarseEst2, phaseInitial;
		double PI = 3.14159265358979323846f;
		double real, imag, denom, initReal, initImag, dtemp1, dtemp2, dtemp;
		float phaseEst, totalPhase = 0.f, phaseCorrection, rangePhaseCorrection;
		__float2_t demodSig, corrSig;

		inputPtr			=	(__float2_t *)highAccuRangeHandle->inputSig;
		phaseCoarseEst1		=	2 * (float)PI * highAccuRangeHandle->fc * (divsp(2 * (*estRange), (float)3e8) + highAccuRangeHandle->adcStartTimeConst);
		phaseCoarseEst2		=	(float)PI * highAccuRangeHandle->chirpSlope * (divsp(2 * (*estRange), (float)3e8)  + highAccuRangeHandle->adcStartTimeConst) * (divsp(2 * (*estRange), (float)3e8)  + highAccuRangeHandle->adcStartTimeConst);
		phaseInitial		=	phaseCoarseEst1 - phaseCoarseEst2;

		denom				=	divdp(1.0, (double)highAccuRangeHandle->fft1DSize);
#if 0
		dtemp1				=	cos((double)phaseInitial);
		dtemp2				=	sin(-(double)phaseInitial);
		initReal			=	cos(2.0 * PI * highAccuRangeHandle->chirpRampTime * (double) freqFineEst * denom) ;
		initImag			=	sin(-2.0 * PI * highAccuRangeHandle->chirpRampTime * (double) freqFineEst * denom);
#else
		dtemp1				=	cosdp_i((double)phaseInitial);
		dtemp2				=	sindp_i(-(double)phaseInitial);
		initReal			=	cosdp_i(2.0 * PI * highAccuRangeHandle->chirpRampTime * (double) freqFineEst * denom) ;
		initImag			=	sindp_i(-2.0 * PI * highAccuRangeHandle->chirpRampTime * (double) freqFineEst * denom);
#endif
		
		//sample @ t = 0;
		corrSig				=	_ftof2((float)dtemp1, (float)dtemp2);
		demodSig			=	_complex_mpysp(_amem8_f2(inputPtr++), corrSig);
		RADARDEMO_atan((cplxf_t *)&demodSig, &phaseEst);
		totalPhase			+=	phaseEst;

		if ((highAccuRangeHandle->enableFilter == 0) && (highAccuRangeHandle->enableLinearFit == 0))
		{
			//sample @ t = 1;
			dtemp			=	dtemp1 * initReal - dtemp2 * initImag;
			imag			=	dtemp1 * initImag + dtemp2 * initReal;
			real			=	dtemp;
			corrSig				=	_ftof2((float)real, (float)imag);
			demodSig			=	_complex_mpysp(_amem8_f2(inputPtr++), corrSig);
			RADARDEMO_atan((cplxf_t *)&demodSig, &phaseEst);
			totalPhase			+=	phaseEst;

			for( j = 2; j < (int32_t)highAccuRangeHandle->fft1DSize; j ++)
			{
				dtemp			=	real * initReal - imag * initImag;
				imag			=	real * initImag + imag * initReal;
				real			=	dtemp;
				corrSig			=	_ftof2((float)real, (float)imag);
				demodSig		=	_complex_mpysp(_amem8_f2(inputPtr++), corrSig);
				RADARDEMO_atan((cplxf_t *)&demodSig, &phaseEst);
				totalPhase		+=	phaseEst;
			}
			phaseCorrection		=	totalPhase * (float)denom;
			rangePhaseCorrection= divsp((phaseCorrection*(float)3e8), (4.f * (float) PI * highAccuRangeHandle->fc));
			*estRange			+=	rangePhaseCorrection;
		}
		else
		{
			//Not implemented yet
		}
	}
	return;
}

#endif



/*!
   \fn     RADARDEMO_highAccuRangeProc_accumulateInputGeneric

   \brief   Accumulate signals from all chirps and convert to floating-point format with 1D windowing.

   \param[in]    nSamplesPerChirp
               Number of samples per chirp.

   \param[in]    fftSize1D
               1D FFT size.

   \param[in]    nChirpPerFrame
               Number of chirps per frame.

   \param[in]    fftWin1D
               Input pointer to 1D window function.
			   
   \param[in]    fftWin1DSize
               Number of ADC bits.

   \param[in]    inputPtr
               Pointer to input signal.

   \param[in]    chirpInd
               Flag to enable DC adjustment for ADC samples when set to 1. Otherwise, no preprocessing for ADC samples.

   \param[out]    outputPtr
               Pointer to the output signal.

   \pre       none

   \post      none


 */

void	RADARDEMO_highAccuRangeProc_accumulateInputGeneric(
                            IN  uint32_t nSamplesPerChirp,
                            IN  uint32_t fftSize1D,
                            IN  uint32_t nChirpPerFrame,
                            IN  float   * RESTRICT fftWin1D,
							IN 	int16_t  fftWin1DSize,
							IN  cplx16_t * RESTRICT inputPtr,
							IN  int32_t  chirpInd,
							OUT float * outputPtr)
{
	int32_t i;
	float * tempOutputPtr;

	if (chirpInd == 0)
	{
		for( i = (int32_t)nSamplesPerChirp - 1; i >= 0; i--)
		{
			*outputPtr++					=	(float)inputPtr->real;
			*outputPtr++					=	(float)inputPtr->imag;
			inputPtr++;
		}
	}
	else
	{
		tempOutputPtr		=	outputPtr;
		for( i = (int32_t)nSamplesPerChirp - 1; i >= 0; i--)
		{
			*tempOutputPtr++					+=	(float)inputPtr->real;
			*tempOutputPtr++					+=	(float)inputPtr->imag;
			inputPtr++;
		}

		if (chirpInd == ((int32_t)nChirpPerFrame - 1))
		{
			float fwin1D;
			float *tempOutputPtr;

			tempOutputPtr	=	&outputPtr[2*nSamplesPerChirp - 1];

			for( i = fftWin1DSize - 1; i >= 0; i--)
			{
				fwin1D						=	*fftWin1D++;
				*outputPtr					=	*outputPtr * fwin1D;
				outputPtr++;
				*outputPtr					=	*outputPtr * fwin1D;
				outputPtr++;
				*tempOutputPtr				=	*tempOutputPtr * fwin1D;
				tempOutputPtr--;
				*tempOutputPtr				=	*tempOutputPtr * fwin1D;
				tempOutputPtr--;
			}
			if (((int32_t)fftSize1D - (int32_t)nSamplesPerChirp) > 0)
			{
				tempOutputPtr	=	&outputPtr[2*nSamplesPerChirp];
				for( i = 0; i < ((int32_t)fftSize1D - (int32_t)nSamplesPerChirp); i++);
				{
					*tempOutputPtr++	=	0.f;
					*tempOutputPtr++	=	0.f;
				}
			}
		}
	}
}


/*!
   \fn     RADARDEMO_highAccuRangeProc_rangeEstGeneric

   \brief   Windowing function for 2D FFT and prepare for the input.

   \param[in]    procStep
               processing step, if 1, do preprocessing of the estimation, up to coarse range estimation, if 2, do the rest of estimation (fine freq and phase).

   \param[in]    highAccuRangeHandle
               Handle to the module.

   \param[out]    estRange
               Estimated range.

   \param[out]    deltaPhaseEst
               Estimated delta phase.

   \param[out]    estLinearSNR
               Estimated SNR.

   \pre       none

   \post      none


 */

void	RADARDEMO_highAccuRangeProc_rangeEstGeneric(
							IN int8_t procStep,
                            IN  RADARDEMO_highAccuRangeProc_handle *highAccuRangeHandle,
							OUT  float * estRange,
							OUT  float * deltaPhaseEst,
							OUT float * estLinearSNR)
{
	if (procStep == 1)
	{
		int32_t			i, j, rad1D, coarseRangeInd;
		unsigned char	* brev = NULL;
		float			totalPower, max, ftemp, sigPower, * RESTRICT powerPtr;
		float		finput, * RESTRICT inputPtr, * RESTRICT inputPtr1;

		j  = highAccuRangeHandle->log2fft1DSize;
		if ((j & 1) == 0)
			rad1D = 4;
		else
			rad1D = 2;

		/* copy to scratch is needed because FFT function will corrupt the input. We need to preserve if for zoom-in FFT */
		inputPtr	=	(float *) highAccuRangeHandle->inputSig;
		inputPtr1	=	(float *) &highAccuRangeHandle->scratchPad[2 * highAccuRangeHandle->fft1DSize];
		for (i = 0; i < (int32_t)highAccuRangeHandle->fft1DSize; i++ )
		{
			*inputPtr1++		=	*inputPtr++;
			*inputPtr1++		=	*inputPtr++;
		}

		inputPtr1	=	(float *) &highAccuRangeHandle->scratchPad[2 * highAccuRangeHandle->fft1DSize];
#if 0
		DSPF_sp_fftSPxSP_cn (
				highAccuRangeHandle->fft1DSize,
				(float*) inputPtr1,
				(float *)highAccuRangeHandle->twiddle, 
				highAccuRangeHandle->fft1DOutSig,
				brev,
				rad1D,
				0,
				highAccuRangeHandle->fft1DSize);
#endif

		dft(highAccuRangeHandle->fft1DSize, (float*) inputPtr1, highAccuRangeHandle->fft1DOutSig);

		inputPtr1	=	(float *) &highAccuRangeHandle->fft1DOutSig[0];
		for( i = 0; i < (int32_t)highAccuRangeHandle->skipLeft;  i++ )
		{
			*inputPtr1++	=	0.f;
			*inputPtr1++	=	0.f;
		}
		inputPtr1	=	(float *) &highAccuRangeHandle->fft1DOutSig[2*((int32_t)highAccuRangeHandle->fft1DSize- (int32_t)highAccuRangeHandle->skipRight)];
		for( i = (int32_t)highAccuRangeHandle->fft1DSize- (int32_t)highAccuRangeHandle->skipRight; i < (int32_t)highAccuRangeHandle->fft1DSize; i++ )
		{
			*inputPtr1++	=	0.f;
			*inputPtr1++	=	0.f;
		}
		max			=	0.f;
		totalPower	=	0.f;
		coarseRangeInd	=	0;
		inputPtr	=	(float *)highAccuRangeHandle->fft1DOutSig;
		powerPtr	=	(float *)highAccuRangeHandle->scratchPad;
		for( i = 0; i < (int32_t)highAccuRangeHandle->fft1DSize; i++ )
		{
			finput		=	(*inputPtr) * (*inputPtr);
			inputPtr++;
			finput		+=	(*inputPtr) * (*inputPtr);
			inputPtr++;
			ftemp		=	finput;
			powerPtr[i] =	ftemp;
			totalPower	+=	ftemp;
			if( max < ftemp )
			{
				max			=	ftemp;
				coarseRangeInd	=	i;
			}
		}
	
		highAccuRangeHandle->coarseRangeInd = coarseRangeInd;
		i			=	coarseRangeInd;
		sigPower	=	powerPtr[i-2] + powerPtr[i-1] + powerPtr[i] + powerPtr[i+1] + powerPtr[i+2];

		*estLinearSNR	=	((float)((int32_t)highAccuRangeHandle->fft1DSize  - (int32_t)highAccuRangeHandle->skipLeft - (int32_t)highAccuRangeHandle->skipRight- 5) * sigPower) / (totalPower - sigPower);
	}
	else if (procStep == 2)
	{
		int32_t			i, j, k, coarseRangeInd = highAccuRangeHandle->coarseRangeInd;
		float			max, ftemp;

		int32_t			zoomStartInd, zoomEndInd, itemp, tempIndFine1, tempIndFine2, tempIndCoarse, indMask, shift;
		int32_t			fineRangeInd, tempFineSearchIdx, tempCoarseSearchIdx;
		float		*RESTRICT inputPtr, *RESTRICT wncPtr, *RESTRICT wnfPtr, sigAccReal, sigAccImag;
		float			freqFineEst, fdelta, finputReal, finputImag, tempReal, tempImag;

		/* zoom in FFT: assuming always size of fft1DSize x fft1DSize */
		zoomStartInd	=	coarseRangeInd - highAccuRangeHandle->numRangeBinZoomIn;
		zoomEndInd		=	coarseRangeInd + highAccuRangeHandle->numRangeBinZoomIn;
		indMask			=	highAccuRangeHandle->fft1DSize - 1;
		shift			=	highAccuRangeHandle->log2fft1DSize;
		inputPtr		=	(float *)highAccuRangeHandle->inputSig;
		wncPtr			=	(float *)highAccuRangeHandle->wnCoarse;
		wnfPtr			=	(float *)highAccuRangeHandle->wnFine;
		max				=	0.0;
		itemp			=	0;
		for( i = zoomStartInd; i < zoomEndInd; i++)
		{
			for( j = 0; j < (int32_t)highAccuRangeHandle->fft1DSize; j ++)
			{
				tempFineSearchIdx	=	j;
				sigAccReal  =	0.f; 
				sigAccImag  =	0.f; 
				tempCoarseSearchIdx	=	0;
				for( k = 0; k < (int32_t)highAccuRangeHandle->nSamplesPerChirp; k ++)
				{
					tempIndFine1	=	tempFineSearchIdx & indMask;
					tempIndFine2	=	tempFineSearchIdx >> shift;
					tempFineSearchIdx		+=	j;
					tempIndCoarse	=	(tempCoarseSearchIdx + tempIndFine2) & indMask;
					tempCoarseSearchIdx		+=	i;

					finputReal		=	inputPtr[2 * k];
					finputImag		=	inputPtr[2 * k + 1];
					tempReal		=	wncPtr[2 * tempIndCoarse + 1] * finputReal - wncPtr[2 * tempIndCoarse] * finputImag;
					tempImag		=	wncPtr[2 * tempIndCoarse] * finputReal + wncPtr[2 * tempIndCoarse + 1] * finputImag;

					sigAccReal		+=	wnfPtr[2 * tempIndFine1 + 1] * tempReal - wnfPtr[2 * tempIndFine1] * tempImag;
					sigAccImag		+=	wnfPtr[2 * tempIndFine1] * tempReal + wnfPtr[2 * tempIndFine1 + 1] * tempImag;
				}
				ftemp				=	sigAccReal * sigAccReal + sigAccImag * sigAccImag;
				if( max < ftemp)
				{
					max				=	ftemp;
					fineRangeInd	=	itemp;
				}
				itemp++;
			}
		}

		fdelta			=	(highAccuRangeHandle->maxBeatFreq) / ((float)highAccuRangeHandle->fft1DSize * (float)highAccuRangeHandle->fft1DSize);
		freqFineEst		=	fdelta * (float)(zoomStartInd * highAccuRangeHandle->fft1DSize + fineRangeInd); 

		*estRange		=	(freqFineEst * (float)3e8 * highAccuRangeHandle->chirpRampTime) / (2.f * highAccuRangeHandle->chirpBandwidth);
#if 0
		if (highAccuRangeHandle->enablePhaseEst)
		{
			float phaseCoarseEst1, phaseCoarseEst2, phaseInitial;
			double PI = 3.14159265358979323846f;
			double real, imag, denom, initReal, initImag, dtemp1, dtemp2, dtemp;
			float phaseEst, totalPhase = 0.f, phaseCorrection, rangePhaseCorrection;
			__float2_t demodSig, corrSig;

			inputPtr			=	(__float2_t *)highAccuRangeHandle->inputSig;
			phaseCoarseEst1		=	2 * (float)PI * highAccuRangeHandle->fc * (divsp(2 * (*estRange), (float)3e8) + highAccuRangeHandle->adcStartTimeConst);
			phaseCoarseEst2		=	(float)PI * highAccuRangeHandle->chirpSlope * (divsp(2 * (*estRange), (float)3e8)  + highAccuRangeHandle->adcStartTimeConst) * (divsp(2 * (*estRange), (float)3e8)  + highAccuRangeHandle->adcStartTimeConst);
			phaseInitial		=	phaseCoarseEst1 - phaseCoarseEst2;

			denom				=	divdp(1.0, (double)highAccuRangeHandle->fft1DSize);
	#if 0
			dtemp1				=	cos((double)phaseInitial);
			dtemp2				=	sin(-(double)phaseInitial);
			initReal			=	cos(2.0 * PI * highAccuRangeHandle->chirpRampTime * (double) freqFineEst * denom) ;
			initImag			=	sin(-2.0 * PI * highAccuRangeHandle->chirpRampTime * (double) freqFineEst * denom);
	#else
			dtemp1				=	cosdp_i((double)phaseInitial);
			dtemp2				=	sindp_i(-(double)phaseInitial);
			initReal			=	cosdp_i(2.0 * PI * highAccuRangeHandle->chirpRampTime * (double) freqFineEst * denom) ;
			initImag			=	sindp_i(-2.0 * PI * highAccuRangeHandle->chirpRampTime * (double) freqFineEst * denom);
	#endif
		
			//sample @ t = 0;
			corrSig				=	_ftof2((float)dtemp1, (float)dtemp2);
			demodSig			=	_complex_mpysp(_amem8_f2(inputPtr++), corrSig);
			RADARDEMO_atan((cplxf_t *)&demodSig, &phaseEst);
			totalPhase			+=	phaseEst;

			if ((highAccuRangeHandle->enableFilter == 0) && (highAccuRangeHandle->enableLinearFit == 0))
			{
				//sample @ t = 1;
				dtemp			=	dtemp1 * initReal - dtemp2 * initImag;
				imag			=	dtemp1 * initImag + dtemp2 * initReal;
				real			=	dtemp;
				corrSig				=	_ftof2((float)real, (float)imag);
				demodSig			=	_complex_mpysp(_amem8_f2(inputPtr++), corrSig);
				RADARDEMO_atan((cplxf_t *)&demodSig, &phaseEst);
				totalPhase			+=	phaseEst;

				for( j = 2; j < (int32_t)highAccuRangeHandle->fft1DSize; j ++)
				{
					dtemp			=	real * initReal - imag * initImag;
					imag			=	real * initImag + imag * initReal;
					real			=	dtemp;
					corrSig			=	_ftof2((float)real, (float)imag);
					demodSig		=	_complex_mpysp(_amem8_f2(inputPtr++), corrSig);
					RADARDEMO_atan((cplxf_t *)&demodSig, &phaseEst);
					totalPhase		+=	phaseEst;
				}
				phaseCorrection		=	totalPhase * (float)denom;
				rangePhaseCorrection= divsp((phaseCorrection*(float)3e8), (4.f * (float) PI * highAccuRangeHandle->fc));
				*estRange			+=	rangePhaseCorrection;
			}
			else
			{
				//Not implemented yet
			}
		}
#endif
	}
	return;
}

请帮忙看看,十分感谢!