All pastes #942455 Raw Edit

lib_UMTS_cell_search_v1_5.h

public text v1 · immutable
·published 2008-03-14 15:11 UTC
rendered paste body
#ifndef _UMTS_CELL_SEARCH_H
#define _UMTS_CELL_SEARCH_H


#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <time.h>
#include <iostream>

#include "ipp.h"
#include "lib_UMTS_cell_search_v1_5.h"

// Required to include CUDA vector types
#include <vector_types.h>
#include "CUDA\cutil.h"

////////////////////////////////////////////////////////////////////////////////
// declaration, forward
extern "C" void runTest(char* data, int2* data_int2, unsigned int len);

void cellSearchCandidate::set_values (int num, int idx, __int64 t0) {
	scrCodeNum = num;
	idxFrameStarts = idx;
	timeFrameStarts = t0;
}

/*============================================================================================================================
 Alpha_cell_search():
   Algorithm:
	1. Find the max corr for each scr. code. -> 512 max values
	2. Sort these 512 max values, pick the top 200 scr codes (because the
       maximums of the rest scr codes will be anyway discaraded later)
	3. For each of these 200 scr-codes, sort their corr values for all
	   positions disregarding the values withing +/-2 chips of a local max, and
	   pick the top 10 or so positions -> In total, this will give us 200x10 =
	   20000 initial candidates
	4. Sort the 2000 candidates to find the final 200 candidates.

   Parameters:
   	    BBsig[len_BBsig]               : Received baseband samples.
		time_snapShotStarts            : Time when the snap shot starts in micro frames [10^8 micro frames /sec].
		sampleRate                     : Number of samples per second in BBsig.
		CPICHsig[512*N_SAMP_CPICH_CORR]: All 512 Primary-Scrambling codes.
		scrCodeTbl[num_elemScrCodeTbl]: The estimates about the p-scr codes are stored to this table.
==============================================================================================================================*/

void Alpha_cell_search(Ipp32fc *BBsig, int len_BBsig, __int64 time_snapShotStarts, double sampRate, Ipp32fc *CPICHsig,
					   int len_corrSegment, int num_corrSegments, cellSearchCandidate *scrCodeTbl, int num_elemScrCodeTbl)
{
	int i, j, k, p, c, cg, code_group, count, exist;
	int scrCodeIdx, scrCodeNum_3gpp, idxFrStarts; 
	__int64 timeFrStarts; 

	Ipp32f *corrMax = ippsMalloc_32f(512);	// corrMax[n]= max_i xcorr(rx,scr_n);  i:Sample index; n: Scr. code index ={0,1,...,511}
	int *corrMaxIdx = new int [512];		// corrMaxIdx[n]= arg_max_i xcorr(rx,scr_n);  n=0,1,...,511
	int *idxScrCodeDescendSortedCorrMax = new int [512]; // Scr-code index after descending sorting of corrMax[]
	Ipp32f *corrCand = ippsMalloc_32f(num_elemScrCodeTbl*N_CAND_PER_SCR_CODE);// xcorr for the candidate scr codes only
	int *idxCorrCand = new int [num_elemScrCodeTbl*N_CAND_PER_SCR_CODE];		 // xcorr positions for the candidate-scr codes only
	int *idxCorrCand_fin = new int [num_elemScrCodeTbl*N_CAND_PER_SCR_CODE];	 // Idx of sroted correlations for the candidate-scr codes only

	Ipp32f *ref_xcorr_CPICH_abs = ippsMalloc_32f(512*len_BBsig);	// Noncoherently summed xcorr(rx,CPICH) for all 512 P-scr codes
	Ipp32f *xcorr_CPICH_abs = ippsMalloc_32f(512*len_BBsig);	// Noncoherently summed xcorr(rx,CPICH) for all 512 P-scr codes
	int *idxDescendSortedCorr = new int [len_BBsig];			// Index of xcorr sorted in descending order
	Ipp32fc *ref_xcorr_CPICH_cmplx_part = ippsMalloc_32fc(len_BBsig);	// xcorr(rx,CPICH_part) for each P-scrambling code
	Ipp32f *ref_xcorr_CPICH_abs_part = ippsMalloc_32f(len_BBsig);	// xcorr(rx,CPICH_part) for each P-scrambling code
	Ipp32fc *xcorr_CPICH_cmplx_part = ippsMalloc_32fc(len_BBsig);	// xcorr(rx,CPICH_part) for each P-scrambling code
	Ipp32f *xcorr_CPICH_abs_part = ippsMalloc_32f(len_BBsig);	// abs(xcorr(rx,CPICH_part))

	Ipp32f *residuals = ippsMalloc_32f(512*len_BBsig);

	//======= CPICH (for all 512 P-scrambling codes) correlation with entire RX signal =======
	ippsZero_32f(ref_xcorr_CPICH_abs,512*len_BBsig);
	ippsZero_32f(xcorr_CPICH_abs,512*len_BBsig);
	ippsZero_32f(residuals,512*len_BBsig);

	int sc;
	for(cg=0; cg<64; cg++) {  // int code_group = 51;	// Each group has 8 codes;  code number = 16*8*code_group+k, (k=0,...,7)
		for(k=0; k<8; k++) {
			sc = 8*cg+k;
			printf("SC %d \r", sc);
			Ipp32fc *CPICH_actptr = &CPICHsig[(sc*N_SAMP_PER_SCR_CODE)];
/*
#ifdef CUDACORR
			cudaCrossCorr_32fc((Complex*)CPICH_actptr, len_corrSegment*num_corrSegments, 
				(Complex*)BBsig, len_BBsig, (Complex*)xcorr_CPICH_cmplx_part, len_BBsig, 0);
			ippsMagnitude_32fc(xcorr_CPICH_cmplx_part, xcorr_CPICH_abs_part, len_BBsig);
			// Combine parts non-coherently
			ippsAdd_32f(xcorr_CPICH_abs_part, &xcorr_CPICH_abs[sc*len_BBsig], 
				&xcorr_CPICH_abs[sc*len_BBsig], len_BBsig);
#endif
*/
			for(p=0; p<num_corrSegments; p++) {   // For each part of CPICH 
				printf("SC %d - p %d/%d\r", sc, p, num_corrSegments);
				CPICH_actptr = &CPICHsig[(sc*N_SAMP_PER_SCR_CODE)+(p*len_corrSegment)];
				// Correlate
#ifdef CUDACORR
				cudaCrossCorr_32fc((Complex*)CPICH_actptr, len_corrSegment, 
					(Complex*)BBsig, len_BBsig, (Complex*)xcorr_CPICH_cmplx_part, len_BBsig, 0);
				ippsMagnitude_32fc(xcorr_CPICH_cmplx_part, xcorr_CPICH_abs_part, len_BBsig);
				// Combine parts non-coherently
				ippsAdd_32f(&xcorr_CPICH_abs_part[p*len_corrSegment], &xcorr_CPICH_abs[sc*len_BBsig], 
					&xcorr_CPICH_abs[sc*len_BBsig], len_BBsig-p*len_corrSegment);
#endif
#ifdef IPPCORR
				ippsCrossCorr_32fc(CPICH_actptr, len_corrSegment, 
					BBsig, len_BBsig, ref_xcorr_CPICH_cmplx_part, len_BBsig, 0);
				ippsMagnitude_32fc(ref_xcorr_CPICH_cmplx_part, ref_xcorr_CPICH_abs_part, len_BBsig);
				// Combine parts non-coherently
				ippsAdd_32f(&ref_xcorr_CPICH_abs_part[p*len_corrSegment], &ref_xcorr_CPICH_abs[sc*len_BBsig], 
								&ref_xcorr_CPICH_abs[sc*len_BBsig], len_BBsig-p*len_corrSegment);
#endif
#ifdef CUDACORRCHECK
				//HAT TRICK
				ippsZero_32f(&ref_xcorr_CPICH_abs_part[len_BBsig-len_corrSegment], len_corrSegment);
				ippsZero_32f(&xcorr_CPICH_abs_part[len_BBsig-len_corrSegment], len_corrSegment);
				ippsSub_32f(ref_xcorr_CPICH_abs_part, xcorr_CPICH_abs_part, residuals, len_BBsig);
				//int splitincr = len_BBsig/10;
				int splitincr = 512;
				for (int i=splitincr; i <= len_BBsig; i+=splitincr){
					Ipp32f L2norm = 0.0f;
					Ipp32f Infnorm = 0.0f;
					ippsNorm_L2_32f(residuals, i, &L2norm);
					ippsNorm_Inf_32f(residuals, i, &Infnorm);
					printf("residual on %d of %d elements\tL2/Inf: %f / %f\n", i, len_BBsig, L2norm, Infnorm);
				}
#endif
			}
//*/
#ifdef CUDACORR
			ippsMaxIndx_32f(&xcorr_CPICH_abs[sc*len_BBsig], len_BBsig, &corrMax[sc], &corrMaxIdx[sc]);
#else
			ippsMaxIndx_32f(&ref_xcorr_CPICH_abs[sc*len_BBsig], len_BBsig, &corrMax[sc], &corrMaxIdx[sc]);
#endif
//			printf("\t cg= %2d, k=%d:  corrMaxIdx = %8d,  corrMax = %8.0f \n", cg, k, corrMaxIdx[sc], corrMax[sc]);
		}
	}
	printf("\r\n");
	//------- Sort all 512 maximums -------
	ippsSortIndexDescend_32f_I(corrMax, idxScrCodeDescendSortedCorrMax, 512);   // Sorted corrMax is stored in corrMax itself
	//--- Global (ML) frame boundary, code number(8*code_group+k),  over all 512 scr. codes --- 
	code_group = (int) (idxScrCodeDescendSortedCorrMax[0]/8);
	printf("\n GLOBAL: code_group= %d,  k= %d,  frBndry_idx= %d \n", code_group, idxScrCodeDescendSortedCorrMax[0]%8, corrMaxIdx[idxScrCodeDescendSortedCorrMax[0]]);
	
	for(c=0; c<num_elemScrCodeTbl; c++){  // For each candidate scr. code, Sort -> Select candidate positions
		// Sort cross-corr in descending order
		ippsSortIndexDescend_32f_I(&xcorr_CPICH_abs[idxScrCodeDescendSortedCorrMax[c]*len_BBsig], idxDescendSortedCorr, len_BBsig);

		//--- Find top N_CAND_PER_SCR_CODE positions per P-scr-code ---
		count = 0; 
		corrCand[c*N_CAND_PER_SCR_CODE] = xcorr_CPICH_abs[idxScrCodeDescendSortedCorrMax[c]*len_BBsig];  // Store the sorted first element, which is the max
		idxCorrCand[c*N_CAND_PER_SCR_CODE] = idxDescendSortedCorr[0];
		//printf("\t Sorted->Selected-> [%2d] :  idxCand= %8d,  corrCand= %8.0lf \n",	count, idxCorrCand[c*N_CAND_PER_SCR_CODE], corrCand[c*N_CAND_PER_SCR_CODE]);
		count++;
		for(i=1; i<len_BBsig; i++){
			exist = 0;  // Assume no positions within 2 chips exist
			for(j=i-1; j>=0; j--){  // Check if atleast one position within 2 chips exist, discard 
				if(abs(idxDescendSortedCorr[j]-idxDescendSortedCorr[i])<2*OSR){
					exist = 1;
					break;
				}
			}
			if(exist==0){  // If no positions within 2 chips exist, store corr-value and position
				corrCand[c*N_CAND_PER_SCR_CODE+count] = xcorr_CPICH_abs[idxScrCodeDescendSortedCorrMax[c]*len_BBsig+i];  // Store the sorted first element, which is the max
				idxCorrCand[c*N_CAND_PER_SCR_CODE+count] = idxDescendSortedCorr[i];
				//printf("\t Sorted->Selected-> [%2d]:  idxCand= %8d,  corrCand= %8.0lf \n",	count, idxCorrCand[c*N_CAND_PER_SCR_CODE+count], corrCand[c*N_CAND_PER_SCR_CODE+count]);
				count++;
			}
			if(count>=N_CAND_PER_SCR_CODE)  // Finding top N_CAND_PER_SCR_CODE positions is completed
				break;
		}
	}

	//------- Sort all (num_elemScrCodeTbl*N_CAND_PER_SCR_CODE) candidates --> Choose final (num_elemScrCodeTbl) candidates -------
	ippsSortIndexDescend_32f_I(corrCand, idxCorrCand_fin, num_elemScrCodeTbl*N_CAND_PER_SCR_CODE);  // Sort candidates corres. all candidate scr. codes
	for(i=0; i<num_elemScrCodeTbl; i++) {  // Choose the final num_elemScrCodeTbl positions
		scrCodeIdx = idxScrCodeDescendSortedCorrMax[(int)(idxCorrCand_fin[i]/N_CAND_PER_SCR_CODE)];  // 0,1,...,511
		scrCodeNum_3gpp = 16*scrCodeIdx;  // 16*8*(int)(scrCodeIdx/8) + 16*(scrCodeIdx%8); // Scrambling code number used in 3GPP standard
		idxFrStarts = idxCorrCand[idxCorrCand_fin[i]];
		timeFrStarts = time_snapShotStarts + (__int64)((idxFrStarts*1e8)/(double)sampRate);
		scrCodeTbl[i].set_values(scrCodeNum_3gpp, idxFrStarts, timeFrStarts);  // Update scr-code-info table
		printf(" ALPHA Cand[%3d]: scrCode: Idx= %3d, Num= %d, frBndry= %6d, corr= %6.0f \n", 
					i, scrCodeIdx, scrCodeNum_3gpp, idxFrStarts, corrCand[i]);
	}

	ippsFree(corrMax);
	delete [] corrMaxIdx;
	delete [] idxScrCodeDescendSortedCorrMax;
	ippsFree(corrCand);
	delete [] idxCorrCand;
	delete [] idxCorrCand_fin;

	ippsFree(xcorr_CPICH_abs);
	delete [] idxDescendSortedCorr;
	ippsFree(xcorr_CPICH_cmplx_part);
	ippsFree(xcorr_CPICH_abs_part);
}



//=============================================================================================================
// Beta(): CPICH correlation for given scr-codes and frame-boundaries.
//  Parameters:
//		num_candToScan: Number of top candidates from the scrCodeTbl to searched in Beta mode
//
//============================================================================================================

void Beta(Ipp32fc *BBsig, int len_BBsig, __int64 time_snapShotStarts, double sampRate, Ipp32fc *CPICHsig,
					   int len_corrSegment, int num_corrSegments, cellSearchCandidate *scrCodeTbl, int num_candToScan)
{
	int i, p, cs, scrCodeIdx, corrMaxIdx, idx_scrCodeAtSnapShotStart;
	__int64 idxFrameStarts, d_samp;
	double d_Fr;   // Distance between Alpha's timeFrameStarts and Beta's time_SnapShotStarts [in frames or slots]
	int len_cpich_tem = len_corrSegment*num_corrSegments + N_SAMP_MAX_CORR_SPREAD;
	Ipp32fc *cpich_tem = ippsMalloc_32fc(len_cpich_tem);  // CPICH template to be correlated
	Ipp32f *xcorr_CPICH_abs = ippsMalloc_32f(2*N_SAMP_MAX_CORR_SPREAD+1);	// Noncoherently summed xcorr(rx,CPICH) for cand P-scr code and positions.
	Ipp32fc *xcorr_CPICH_cmplx_part = ippsMalloc_32fc(2*N_SAMP_MAX_CORR_SPREAD+1);
	Ipp32f *xcorr_CPICH_abs_part = ippsMalloc_32f(2*N_SAMP_MAX_CORR_SPREAD+1);
	Ipp32f corrMax;	// corrMax= max_i  xcorr_CPICH_abs

	//------- Calculate r.m.s. of rx signal ------
	Ipp32f meanSqr_BBsig;
	Ipp32f *MagnitudeSqr_BBsig = ippsMalloc_32f(len_BBsig);
	ippsPowerSpectr_32fc(BBsig, MagnitudeSqr_BBsig, len_BBsig);
	ippsMean_32f(MagnitudeSqr_BBsig, len_BBsig, &meanSqr_BBsig, ippAlgHintAccurate);

	for(i=0; i<num_candToScan; i++){
		//--- Calculate frame boundary idx for Beta using Alpha's timeFrameStarts & Beta's time_snapShotStarts (time_snapShotStarts_Beta > timeFrameStarts_Alpha) ---
		d_Fr =  (double)(time_snapShotStarts - scrCodeTbl[i].timeFrameStarts)/1.0e6;
		//printf("\n d_Fr_direct= %lf \n", (time_snapShotStarts/1.0e6 - scrCodeTbl[i].timeFrameStarts/1.0e6));
		idxFrameStarts = (__int64)(sampRate*FRAME_PERIOD_SEC*(ceil(d_Fr)-d_Fr) + 0.5);
		d_samp = (__int64)(sampRate*FRAME_PERIOD_SEC*d_Fr + 0.5);
		idx_scrCodeAtSnapShotStart = (int)(d_samp % N_SAMP_PER_FRAME);
		idx_scrCodeAtSnapShotStart = (idx_scrCodeAtSnapShotStart<0)? (idx_scrCodeAtSnapShotStart+N_SAMP_PER_FRAME):idx_scrCodeAtSnapShotStart;  // Idx of scr code where snap shot starts
		printf("\nBeta():\n Alpha timeFrameStarts = %I64d,  d_Fr= %g \n", scrCodeTbl[i].timeFrameStarts, d_Fr);
		printf("  d_samp = %I64d, idx_scrCodeAtSnapShotStart= %d, ", d_samp, idx_scrCodeAtSnapShotStart);
		printf(" idxFrameStarts = %I64d \n", idxFrameStarts);		

		scrCodeIdx = scrCodeTbl[i].scrCodeNum/16;   // {0,1,...,511} -> Use to access CPICHsig (scr code)
		printf("\n Cand[%2d] - scrCode: Idx= %d, Num= %3d, ", i, scrCodeIdx, scrCodeTbl[i].scrCodeNum);

		// Construct CPICH (scr code) template ---  *** When full scr-code table is used, replace i by scrCodeIdx = {0,1,...,511}
		if( (idx_scrCodeAtSnapShotStart+len_cpich_tem) < N_SAMP_PER_FRAME ){
			ippsCopy_32fc(&CPICHsig[i*N_SAMP_PER_FRAME+idx_scrCodeAtSnapShotStart], cpich_tem, len_cpich_tem); 
		} else {
			ippsCopy_32fc(&CPICHsig[i*N_SAMP_PER_FRAME+idx_scrCodeAtSnapShotStart], cpich_tem, N_SAMP_PER_FRAME-idx_scrCodeAtSnapShotStart);
			ippsCopy_32fc(&CPICHsig[i*N_SAMP_PER_FRAME], &cpich_tem[N_SAMP_PER_FRAME-idx_scrCodeAtSnapShotStart], len_cpich_tem-(N_SAMP_PER_FRAME-idx_scrCodeAtSnapShotStart));
		}

		cs = 4; // = scrCodeTbl[i].corrSpreadInSamples; // And collection software should set scrCodeTbl[i].corrSpreadInSamples before calling Beta()

		ippsZero_32f(xcorr_CPICH_abs, 2*N_SAMP_MAX_CORR_SPREAD+1);
		for(p=0; p<num_corrSegments; p++){
			ippsCrossCorr_32fc(&cpich_tem[N_SAMP_MAX_CORR_SPREAD+p*len_corrSegment], len_corrSegment, 
								&BBsig[N_SAMP_MAX_CORR_SPREAD+p*len_corrSegment], len_corrSegment, xcorr_CPICH_cmplx_part, 2*cs+1, -cs);
			ippsMagnitude_32fc(xcorr_CPICH_cmplx_part, xcorr_CPICH_abs_part, 2*cs+1);
			ippsAdd_32f(xcorr_CPICH_abs_part, xcorr_CPICH_abs, xcorr_CPICH_abs, 2*cs+1);  // Add
		}
		// Find max corr position --> Update scrCodeTbl.timeFrameStarts
		ippsMaxIndx_32f(xcorr_CPICH_abs, 2*cs+1, &corrMax, &corrMaxIdx);
		printf(" corrMax[Idx=%d]= %.0f <-> corrMax[cs]= %.0f \n", corrMaxIdx, corrMax, xcorr_CPICH_abs[cs]);  // Verify for the same rx signal, will be different when the rx sig is udated for next cell search 

		//--- Update Info: Frame boundary, CPICH amplitude ---
		scrCodeTbl[i].timeFrameStarts = time_snapShotStarts + (__int64)((idxFrameStarts+corrMaxIdx-cs)*(1.0e8/sampRate)+0.5);  // In micro frames
		scrCodeTbl[i].cpichCorrRMS = corrMax/(double)(len_corrSegment*num_corrSegments);  // Assumeing CPICH-spread signal is normalized s.t. mean power is 1.
		scrCodeTbl[i].sigRMS = sqrt((double)meanSqr_BBsig);  // Write BBsig rms value
		printf("\n Cand-%d: Amplitude_CPICH= %.2f, sigRMS= %.2f, ", i, scrCodeTbl[i].cpichCorrRMS, scrCodeTbl[i].sigRMS);
		printf(" Ec/Io= %.2f [dB],  FrBndry_new= %I64d \n\n", 20*log10(scrCodeTbl[i].cpichCorrRMS/scrCodeTbl[i].sigRMS), scrCodeTbl[i].timeFrameStarts);
	}

	ippsFree(MagnitudeSqr_BBsig);
	ippsFree(cpich_tem);
	ippsFree(xcorr_CPICH_abs);
	ippsFree(xcorr_CPICH_cmplx_part);
	ippsFree(xcorr_CPICH_abs_part);
}


//------------------------------------------------------------------------------------------
// UMTS_resample(): Resamples UMTS signal
//------------------------------------------------------------------------------------------

//void UMTS_resample(Ipp32fc *In, int inLen, Ipp32fc *Out)
//{
//	int i, numIters = (int)ceil((double)inLen/(double)UMTS_DOWNSAMPLE_RATE);
//	//--- Generate filter taps (coefficients) ---
//	Ipp64f* taps_64f = ippsMalloc_64f(UMTS_RESAMPLE_TAP_LEN);  // ippsMalloc_64f(tapslen*sizeof(Ipp64f));
//	ippsFIRGenLowpass_64f(UMTS_NORM_CUTOFF_FREQ, taps_64f, UMTS_RESAMPLE_TAP_LEN, ippWinHamming, ippTrue);
//	// Convert real to complex with Typecast, 64f -> 32fc
//	Ipp64fc* taps_64fc = ippsMalloc_64fc(UMTS_RESAMPLE_TAP_LEN);
//	for(i=0; i<UMTS_RESAMPLE_TAP_LEN; i++){
//		taps_64fc[i].re = taps_64f[i];
//		taps_64fc[i].im = 0.0;
//	}
//
//	//--- Initialize multirate (MR) filter state ---
//	IppsFIRState64fc_32fc *pState; // IppsFIRState_32fc *pState;
//	Ipp32fc *pDlyLine = NULL;
//	IppStatus status;
//	//status = ippsFIRMRInitAlloc_32fc(&pState, taps_32fc, UMTS_RESAMPLE_TAP_LEN, UMTS_UPSAMPLE_RATE, UMTS_UPSAMPLE_PHASE, 
//	//			UMTS_DOWNSAMPLE_RATE, UMTS_DOWNSAMPLE_PHASE, pDlyLine);
//	status = ippsFIRMRInitAlloc64fc_32fc(&pState, taps_64fc, UMTS_RESAMPLE_TAP_LEN, UMTS_UPSAMPLE_RATE, UMTS_UPSAMPLE_PHASE, 
//				UMTS_DOWNSAMPLE_RATE, UMTS_DOWNSAMPLE_PHASE, pDlyLine);
//
//	//if( ippStsNoErr != status) return error;
//
//	//--- Filter input signal ---
//	status = ippsFIR64fc_32fc(In, Out, numIters, pState);
//	//if( ippStsNoErr != status) return error;
//
//	ippsFree(taps_64f);
//	ippsFree(taps_64fc);
//	ippsFIRFree64fc_32fc(pState);
//}
//


//======================================================================================
// Generate primary scrambling code: cf. 3GPP TS 25.213 v7.3.0 (2007-09)
// Created by Galib M.M.
//  Parameters: 
//		code_num[numOfCodes]: Code numbers, e.g. 16*8*51 + 16*[0:7]; code group is 51
//      N_codes			: Number of codes to be generated
//      scr_code[N_codes*38400]: Generated scr codes
//======================================================================================
void scrambling_code(int *code_num, int N_codes, Ipp32fc *scr_code)   // int *scr_code_re, int *scr_code_im)
{
	int i, n, bin_num,mSeq_len = (int)pow(2.0,18.0) - 1;

	int *x = new int [mSeq_len];	// x = 9*zeros(1,mSeq_len);
	int *y = new int [mSeq_len];	// y = 9*zeros(1,mSeq_len);
	int *z_n = new int [mSeq_len];	// z_n = 9*zeros(1,mSeq_len);

	// ippsSet_32fc(0, scr_code, N_codes*38400);	//	scr_code = zeros(length(code_num),38400);

	//--- Initialize register ---
	x[0]=1;				// x(1) = 1;
	y[0]=1;
	for(i=1; i<17; i++){
		x[i] = 0;	// x(1)=...= x(17)=0	// x(2:18) = zeros(1,17);
		y[i] = 1;	// y(0)=...=y(17)=1		// y(1:18) = ones(1,18);
	}

	//--- m-sequences ---
	for(i=0; i<mSeq_len-19; i++){
		x[i+18] = (x[i+7]+x[i]) % 2;
		y[i+18] = (y[i+10]+y[i+7]+y[i+5]+y[i]) % 2;
	}

	//------- Scrambling Code -------
	for(n=0; n<N_codes; n++){   // n=1:length(code_num)
		// Gold code sequence, z_n
		for(i=0; i<mSeq_len; i++){ // i=0:mSeq_len-1
			bin_num = (x[(i+code_num[n])%mSeq_len]+y[i]) % 2;  // mod(x(mod(i+code_num(n),mSeq_len)+1)+y(i+1), 2);
			z_n[i] = 1 - 2*bin_num;  // Anti-podal
		}
		//--- n-th complex scrambling code ---
		for(i=0; i<38400; i++){  // i=0:38399
			// scr_code(n,i+1) = z_n(i+1) + j*z_n(mod((i+131072),mSeq_len)+1);
			scr_code[n*38400+i].re = (Ipp32f) (float) z_n[i];
			scr_code[n*38400+i].im = (Ipp32f) (float) z_n[(i+131072)%mSeq_len];
		}
	}

	delete [] x;
	delete [] y;
	delete [] z_n;
}


#endif