From e5bdb1a1a310e4a80f280465e8127a7b0b3993f3 Mon Sep 17 00:00:00 2001 From: David Freese Date: Thu, 12 Feb 2009 21:21:39 -0600 Subject: [PATCH] Cosmetic changes to mt63 source - increase white space for easier reading --- src/mt63/mt63.cxx | 3 +- src/mt63/mt63base.cxx | 1884 +++++++++++++++++++++++------------------ 2 files changed, 1054 insertions(+), 833 deletions(-) diff --git a/src/mt63/mt63.cxx b/src/mt63/mt63.cxx index ca38a302..7443519f 100644 --- a/src/mt63/mt63.cxx +++ b/src/mt63/mt63.cxx @@ -120,7 +120,8 @@ int mt63::rx_process(const double *buf, int len) unsigned int c; int i; - if (get_freq() != (500.0 + bandwidth / 2.0)) set_freq(500.0 + bandwidth / 2.0); + if (get_freq() != (500.0 + bandwidth / 2.0)) + set_freq(500.0 + bandwidth / 2.0); if (Interleave != progdefaults.mt63_interleave) { Interleave = progdefaults.mt63_interleave; diff --git a/src/mt63/mt63base.cxx b/src/mt63/mt63base.cxx index 223419da..73ba4f11 100644 --- a/src/mt63/mt63base.cxx +++ b/src/mt63/mt63base.cxx @@ -40,1054 +40,1242 @@ #include "mt63base.h" -//#include "morse.dat" // Morse Code table - -#include "symbol.dat" // symbol shape +#include "symbol.dat" // symbol shape #include "mt63intl.dat" // interleave patterns #include "alias_k5.dat" // anti-alias filter shapes #include "alias_1k.dat" // for 500, 1000 and 2000 Hz modes #include "alias_2k.dat" -// ========================================================================== -// Morse Encoder -/* -MorseEncoder::MorseEncoder() -{ TxMsg=NULL; } -MorseEncoder::~MorseEncoder() -{ free(TxMsg); } - -void MorseEncoder::Free(void) -{ free(TxMsg); TxMsg=NULL; } - -int MorseEncoder::SetTxMsg(char *Msg) -{ int len=strlen(Msg)+1; - if(dspRedspAllocArray(&TxMsg,len)) return -1; - dspCopyArray(TxMsg,Msg,len); TxPtr=0; Code=0L; - return 0; } - -int MorseEncoder::NextKey(void) -{ int key,ch; - if(TxMsg==NULL) return -1; - if(Code<=1) - { ch=TxMsg[TxPtr]; if(ch==0) return -1; - TxPtr++; - if(ch>=1; return key; -} -*/ // ========================================================================== // MT63 transmitter code MT63tx::MT63tx() { - TxVect=NULL; - dspPhaseCorr=NULL; + TxVect = NULL; + dspPhaseCorr = NULL; } MT63tx::~MT63tx() { - free(TxVect); - free(dspPhaseCorr); + free(TxVect); + free(dspPhaseCorr); } void MT63tx::Free(void) -{ free(TxVect); TxVect=NULL; - free(dspPhaseCorr); dspPhaseCorr=NULL; - Encoder.Free(); FFT.Free(); Window.Free(); Comb.Free(); - WindowBuff.Free(); +{ + free(TxVect); + TxVect = NULL; + free(dspPhaseCorr); + dspPhaseCorr = NULL; + Encoder.Free(); + FFT.Free(); + Window.Free(); + Comb.Free(); + WindowBuff.Free(); } int MT63tx::Preset(int BandWidth, int LongInterleave) { - int err; - int i,p,step,incr,mask; + int err; + int i,p,step,incr,mask; - switch(BandWidth) { - case 500: - FirstDataCarr=256; - AliasShapeI=Alias_k5_I; - AliasShapeQ=Alias_k5_Q; - AliasFilterLen=Alias_k5_Len; - DecimateRatio=8; - break; - case 1000: - FirstDataCarr=128; - AliasShapeI=Alias_1k_I; - AliasShapeQ=Alias_1k_Q; - AliasFilterLen=Alias_1k_Len; - DecimateRatio=4; - break; - case 2000: - FirstDataCarr=64; - AliasShapeI=Alias_2k_I; - AliasShapeQ=Alias_2k_Q; - AliasFilterLen=Alias_2k_Len; - DecimateRatio=2; - break; - default: - return -1; - } + switch(BandWidth) { + case 500: + FirstDataCarr = 256; + AliasShapeI = Alias_k5_I; + AliasShapeQ = Alias_k5_Q; + AliasFilterLen = Alias_k5_Len; + DecimateRatio = 8; + break; + case 1000: + FirstDataCarr = 128; + AliasShapeI = Alias_1k_I; + AliasShapeQ = Alias_1k_Q; + AliasFilterLen = Alias_1k_Len; + DecimateRatio = 4; + break; + case 2000: + FirstDataCarr = 64; + AliasShapeI = Alias_2k_I; + AliasShapeQ = Alias_2k_Q; + AliasFilterLen = Alias_2k_Len; + DecimateRatio = 2; + break; + default: + return -1; + } - DataCarriers=64; + DataCarriers = 64; // DataCarrSepar=4; // SymbolSepar=200; - WindowLen=SymbolLen; - TxWindow=SymbolShape; - TxdspAmpl=4.0/DataCarriers; // for maximum output level we can set TxdspAmpl=4.0/DataCarriers - CarrMarkCode=0x16918BBEL; - CarrMarkdspAmpl=0; // WindowLen/32; + WindowLen = SymbolLen; + TxWindow = SymbolShape; + TxdspAmpl = 4.0 / DataCarriers; // for maximum output level we can set TxdspAmpl=4.0/DataCarriers + CarrMarkCode = 0x16918BBEL; + CarrMarkdspAmpl = 0; // WindowLen/32; - if(LongInterleave) { - DataInterleave=64; - InterleavePattern=LongIntlvPatt; - } - else { - DataInterleave=32; - InterleavePattern=ShortIntlvPatt; - } + if (LongInterleave) { + DataInterleave = 64; + InterleavePattern = LongIntlvPatt; + } + else { + DataInterleave = 32; + InterleavePattern = ShortIntlvPatt; + } - if(dspRedspAllocArray(&TxVect, DataCarriers)) goto Error; - if(dspRedspAllocArray(&dspPhaseCorr, DataCarriers)) goto Error; - err=WindowBuff.EnsureSpace(2*WindowLen); if(err) goto Error; - WindowBuff.Len=2*WindowLen; + if (dspRedspAllocArray(&TxVect, DataCarriers)) goto Error; + if (dspRedspAllocArray(&dspPhaseCorr, DataCarriers)) goto Error; + err = WindowBuff.EnsureSpace(2*WindowLen); if (err) goto Error; + WindowBuff.Len = 2 * WindowLen; - err=Encoder.Preset(DataCarriers,DataInterleave,InterleavePattern,1); - if(err) goto Error; - err=FFT.Preset(WindowLen); - if(err) goto Error; - err=Window.Preset(WindowLen,SymbolSepar/2,TxWindow); - if(err) goto Error; - err=Comb.Preset(AliasFilterLen,AliasShapeI,AliasShapeQ,DecimateRatio); - if(err) goto Error; + err = Encoder.Preset(DataCarriers, DataInterleave, InterleavePattern, 1); + if (err) goto Error; + err = FFT.Preset(WindowLen); + if (err) goto Error; + err = Window.Preset(WindowLen, SymbolSepar / 2, TxWindow); + if (err) goto Error; + err = Comb.Preset(AliasFilterLen, AliasShapeI, AliasShapeQ, DecimateRatio); + if (err) goto Error; - mask=FFT.Size-1; + mask = FFT.Size-1; // Preset the initial dspPhase for each data carrier. // Here we only compute indexes to the FFT twiddle factors -// so the actuall vector is FFT.Twiddle[TxVect[i]] - for(step=0,incr=1,p=0,i=0; i ", ch, ch>=' ' ? ch : '.'); - for(i=0; i only dspPhase correction - { TxVect[i]=(TxVect[i]+dspPhaseCorr[i])&mask; } - else // data bit = 0 => dspPhase flip + dspPhase correction - { TxVect[i]=(TxVect[i]+dspPhaseCorr[i]+flip)&mask; } - } + mask = FFT.Size - 1; + flip = FFT.Size / 2; + for (i = 0; i < DataCarriers; i++) { +// data bit = 1 => only dspPhase correction + if (Encoder.Output[i]) + TxVect[i] = (TxVect[i] + dspPhaseCorr[i]) & mask; +// data bit = 0 => dspPhase flip + dspPhase correction + else + TxVect[i] = (TxVect[i] + dspPhaseCorr[i] + flip) & mask; + } - ProcessTxVect(); - return 0; + ProcessTxVect(); + return 0; } int MT63tx::SendJam(void) -{ int i,mask,left,right; +{ + int i,mask,left,right; - mask=FFT.Size-1; left=FFT.Size/4; right=3*(FFT.Size/4); - for(i=0; i=IntlvLen) p-=IntlvLen; } - return 0; + for (p = 0, i = 0; i < DataCarriers; i++) { + IntlvPatt[i] = p * DataCarriers; + p += Pattern[i]; + if (p >= IntlvLen) p -= IntlvLen; + } + return 0; -Error: Free(); return -1; +Error: + Free(); + return -1; } int MT63encoder::Process(char code) // encode an ASCII character "code" -{ int i,k; - code&=CodeMask; - for(i=0; i=IntlvSize) k-=IntlvSize; - Output[i]=IntlvPipe[k+i]; - } IntlvPtr+=DataCarriers; if(IntlvPtr>=IntlvSize) IntlvPtr-=IntlvSize; - } - else - { for(i=0; i= IntlvSize) + k -= IntlvSize; + Output[i] = IntlvPipe[k+i]; + } + IntlvPtr += DataCarriers; + if (IntlvPtr >= IntlvSize) + IntlvPtr -= IntlvSize; + } else + for (i = 0; i < DataCarriers; i++) + Output[i] = (WalshBuff[i] < 0.0); + + return 0; +} - return 0; } // After encoding the "Output" array contains the bits to be transmitted -// ========================================================================== -// MT63 envelope time/frequency synchronizer -// experimental status: results not encouraging. -/* -MT63sync::MT63sync() -{ PwrIntegMid=NULL; PwrIntegOut=NULL; NormPwr=NULL; } - -MT63sync::~MT63sync() -{ free(PwrIntegMid); free(PwrIntegOut); free(NormPwr); } - -void MT63sync::Free(void) -{ free(PwrIntegMid); free(PwrIntegOut); - PwrIntegMid=NULL; PwrIntegOut=NULL; - free(NormPwr); NormPwr=NULL; } - -int MT63sync::Preset(int FFTlen, int FirstCarr, int CarrSepar, int Carriers, int Steps, - int Margin, int Integ) -{ - if(!dspPowerOf2(FFTlen)) goto Error; - FFTmask=FFTlen-1; - FirstDataCarr=FirstCarr; - DataCarrSepar=CarrSepar; - DataCarriers=Carriers; - StepsPerSymb=Steps; - ScanMargin=Margin; - dspLowPass2Coeff(Integ,W1,W2,W5); - ScanFirst=FirstDataCarr-ScanMargin*DataCarrSepar; - ScanLen=(DataCarriers+2*ScanMargin)*DataCarrSepar; - ScanSize=ScanLen*StepsPerSymb; - - if(dspRedspAllocArray(&PwrIntegMid,ScanSize)) goto Error; - dspClearArray(PwrIntegMid,ScanSize); - if(dspRedspAllocArray(&PwrIntegOut,ScanSize)) goto Error; - dspClearArray(PwrIntegOut,ScanSize); - IntegPtr=0; - NodspRMSize=StepsPerSymb*2*DataCarrSepar; - if(dspRedspAllocArray(&NormPwr,NodspRMSize)) goto Error; - - return 0; - -Error: Free(); return -1; -} - -int MT63sync::Process(dspCmpx *SpectraSlice) -{ int i,c,p,n; double Sum; - - for(c=ScanFirst,i=0; i0.0) - { Sum/=StepsPerSymb; Sum*=ScanLen; // printf("%3d: %8.5f\n",c,Sum); - for(p=c,i=0; i=2*DataCarrSepar) n=0; - } - } - - IntegPtr+=ScanLen; if(IntegPtr>=ScanSize) IntegPtr=0; - - if(IntegPtr==0) - { printf("NormPwr:\n"); - for(i=0; i=IntlvLen) p-=IntlvLen; } + IntlvLen = Intlv; // printf("%d:",IntlvLen); + if (dspRedspAllocArray(&IntlvPatt, DataCarriers)) goto Error; + for (p = 0, i = 0; i < DataCarriers; i++) { + IntlvPatt[i] = p * ScanSize; // printf(" %2d",p); + p += Pattern[i]; + if (p >= IntlvLen) p -= IntlvLen; + } // printf("\n"); - IntlvSize=(IntlvLen+1)*ScanSize; - if(dspRedspAllocArray(&IntlvPipe,IntlvSize)) goto Error; - dspClearArray(IntlvPipe,IntlvSize); IntlvPtr=0; + IntlvSize = (IntlvLen + 1) * ScanSize; + if (dspRedspAllocArray(&IntlvPipe, IntlvSize)) goto Error; + dspClearArray(IntlvPipe, IntlvSize); + IntlvPtr = 0; - if(dspRedspAllocArray(&WalshBuff,DataCarriers)) goto Error; + if (dspRedspAllocArray(&WalshBuff, DataCarriers)) goto Error; - if(dspRedspAllocArray(&DecodeSnrMid,ScanLen)) goto Error; - if(dspRedspAllocArray(&DecodeSnrOut,ScanLen)) goto Error; - dspClearArray(DecodeSnrMid,ScanLen); - dspClearArray(DecodeSnrOut,ScanLen); + if (dspRedspAllocArray(&DecodeSnrMid, ScanLen)) goto Error; + if (dspRedspAllocArray(&DecodeSnrOut, ScanLen)) goto Error; + dspClearArray(DecodeSnrMid, ScanLen); + dspClearArray(DecodeSnrOut, ScanLen); - SignalToNoise=0.0; CarrOfs=0; + SignalToNoise = 0.0; + CarrOfs = 0; - return 0; + return 0; Error: - Free(); return -1; + Free(); + return -1; } int MT63decoder::Process(double *data) -{ int s,i,k; double Min,Max,Sig,Noise,SNR; int MinPos,MaxPos,code; +{ + int s, i, k; + double Min, Max, Sig, Noise, SNR; + int MinPos,MaxPos,code; - dspCopyArray(IntlvPipe+IntlvPtr,data,ScanSize); + dspCopyArray(IntlvPipe + IntlvPtr, data, ScanSize); - // printf("Decoder [%d/%d/%d]: \n",IntlvPtr,IntlvSize,ScanSize); - for(s=0; s=IntlvSize) k-=IntlvSize; } - WalshBuff[i]=IntlvPipe[k+s+i]; // printf(" %4d",k/ScanSize); - } // printf("\n"); - dspWalshTrans(WalshBuff,DataCarriers); - Min=dspFindMin(WalshBuff,DataCarriers,MinPos); - Max=dspFindMax(WalshBuff,DataCarriers,MaxPos); - if(fabs(Max)>fabs(Min)) - { code=MaxPos+DataCarriers; - Sig=fabs(Max); WalshBuff[MaxPos]=0.0; } - else - { code=MinPos; - Sig=fabs(Min); WalshBuff[MinPos]=0.0; } - Noise=dspRMS(WalshBuff,DataCarriers); - if(Noise>0.0) SNR=Sig/Noise; else SNR=0.0; - dspLowPass2(SNR,DecodeSnrMid[s],DecodeSnrOut[s],W1,W2,W5); - // printf("%2d: %02x => %c, %5.2f/%5.2f=>%5.2f <%5.2f>\n", - // s,code,code<' ' ? '.' : (char)code, - // Sig,Noise,SNR,DecodeSnrOut[s]); - DecodePipe[DecodePtr+s]=code; - } - IntlvPtr+=ScanSize; if(IntlvPtr>=IntlvSize) IntlvPtr=0; - DecodePtr+=ScanLen; if(DecodePtr>=DecodeSize) DecodePtr=0; - Max=dspFindMax(DecodeSnrOut,ScanLen,MaxPos); - Output=DecodePipe[DecodePtr+MaxPos]; - SignalToNoise=Max; CarrOfs=MaxPos-(ScanLen-1)/2; +// printf("Decoder [%d/%d/%d]: \n",IntlvPtr,IntlvSize,ScanSize); + for (s = 0; s < ScanLen; s++) { +// printf(" %2d:",s); + for (i = 0; i < DataCarriers; i++) { + k = IntlvPtr - ScanSize - IntlvPatt[i]; + if (k < 0) k += IntlvSize; + if ((s & 1) && (i & 1)) { + k += ScanSize; + if (k >= IntlvSize) k-=IntlvSize; + } + WalshBuff[i] = IntlvPipe[k + s + i]; +// printf(" %4d",k/ScanSize); + } +// printf("\n"); + dspWalshTrans(WalshBuff, DataCarriers); + Min = dspFindMin(WalshBuff, DataCarriers, MinPos); + Max = dspFindMax(WalshBuff, DataCarriers, MaxPos); + if (fabs(Max) > fabs(Min)) { + code = MaxPos + DataCarriers; + Sig = fabs(Max); + WalshBuff[MaxPos] = 0.0; + } else { + code = MinPos; + Sig = fabs(Min); + WalshBuff[MinPos] = 0.0; + } + Noise = dspRMS(WalshBuff, DataCarriers); + if (Noise > 0.0) + SNR = Sig/Noise; + else SNR = 0.0; + dspLowPass2(SNR, DecodeSnrMid[s], DecodeSnrOut[s], W1, W2, W5); +// printf("%2d: %02x => %c, %5.2f/%5.2f=>%5.2f <%5.2f>\n", +// s,code,code<' ' ? '.' : (char)code, +// Sig,Noise,SNR,DecodeSnrOut[s]); + DecodePipe[DecodePtr+s]=code; + } + IntlvPtr += ScanSize; + if (IntlvPtr >= IntlvSize) IntlvPtr = 0; + DecodePtr += ScanLen; + if (DecodePtr >= DecodeSize) DecodePtr = 0; + Max = dspFindMax(DecodeSnrOut, ScanLen, MaxPos); + Output = DecodePipe[DecodePtr + MaxPos]; + SignalToNoise = Max; + CarrOfs = MaxPos - (ScanLen - 1) / 2; /* code=Output; - if((code>=' ')||(code=='\n')||(code=='\r')) printf("%c",code); - else if(code!='\0') printf("<%02X>",code); + if ((code>=' ')||(code=='\n')||(code=='\r')) printf("%c",code); + else if (code!='\0') printf("<%02X>",code); */ - return 0; + return 0; } // ========================================================================== // MT63 receiver code MT63rx::MT63rx() -{ int s; +{ + int s; - FFTbuff=NULL; FFTbuff2=NULL; + FFTbuff = NULL; + FFTbuff2 = NULL; - for(s=0; s<4; s++) SyncPipe[s]=NULL; - SyncPhCorr=NULL; - for(s=0; s<4; s++) { CorrelMid[s]=NULL; CorrelOut[s]=NULL; } - dspPowerMid=NULL; dspPowerOut=NULL; - for(s=0; s<4; s++) CorrelNorm[s]=NULL; - for(s=0; s<4; s++) CorrelAver[s]=NULL; - SymbFit=NULL; SymbPipe=NULL; FreqPipe=NULL; + for (s = 0; s < 4; s++) + SyncPipe[s] = NULL; + SyncPhCorr = NULL; + for (s = 0; s < 4; s++) { + CorrelMid[s] = NULL; + CorrelOut[s] = NULL; + } + dspPowerMid = NULL; + dspPowerOut = NULL; + for (s = 0; s < 4; s++) + CorrelNorm[s] = NULL; + for (s = 0; s < 4; s++) + CorrelAver[s] = NULL; + SymbFit = NULL; + SymbPipe = NULL; + FreqPipe = NULL; - RefDataSlice=NULL; + RefDataSlice = NULL; - DataPipeLen=0; DataPipe=NULL; - DataPwrMid=NULL; DataPwrOut=NULL; - DataSqrMid=NULL; DataSqrOut=NULL; + DataPipeLen = 0; + DataPipe = NULL; + DataPwrMid = NULL; + DataPwrOut = NULL; + DataSqrMid = NULL; + DataSqrOut = NULL; - DataVect=NULL; + DataVect = NULL; - DatadspPhase=NULL; - DatadspPhase2=NULL; + DatadspPhase = NULL; + DatadspPhase2 = NULL; - SpectradspPower=NULL; + SpectradspPower = NULL; } MT63rx::~MT63rx() -{ int s; +{ + int s; - free(FFTbuff); free(FFTbuff2); + free(FFTbuff); + free(FFTbuff2); - for(s=0; s<4; s++) free(SyncPipe[s]); - free(SyncPhCorr); - for(s=0; s<4; s++) { free(CorrelMid[s]); free(CorrelOut[s]); } - free(dspPowerMid); free(dspPowerOut); - for(s=0; s<4; s++) free(CorrelNorm[s]); - for(s=0; s<4; s++) free(CorrelAver[s]); - free(SymbFit); free(SymbPipe); free(FreqPipe); + for (s = 0; s < 4; s++) + free(SyncPipe[s]); + free(SyncPhCorr); + for (s = 0; s < 4; s++) { + free(CorrelMid[s]); + free(CorrelOut[s]); + } + free(dspPowerMid); + free(dspPowerOut); + for (s = 0; s < 4; s++) + free(CorrelNorm[s]); + for (s = 0; s < 4; s++) + free(CorrelAver[s]); + free(SymbFit); + free(SymbPipe); + free(FreqPipe); - free(RefDataSlice); + free(RefDataSlice); - dspFreeArray2D(DataPipe,DataPipeLen); - // for(s=0; sLen,ProcLine.InpLen); - while((SyncProcPtr+WindowLen)", - // SyncSymbConf,SyncLocked,SyncProcPtr,SyncPtr,SymbPtr,SyncSymbShift,SyncFreqOfs); - if(SyncPtr==SymbPtr) - { s1=SyncProcPtr-ProcdspDelay+((int)SyncSymbShift-SymbPtr*SyncStep); - s2=s1+SymbolSepar/2; +// printf("New input, Len=%d/%d\n",Input->Len,ProcLine.InpLen); + + while((SyncProcPtr+WindowLen) < ProcLine.InpLen) { + SyncProcess(ProcLine.InpPtr + SyncProcPtr); +// printf("SyncSymbConf=%5.2f, SyncLock=%d, SyncProcPtr=%d, SyncPtr=%d, SymbPtr=%d, SyncSymbShift=%5.1f, SyncFreqOfs=%5.2f =>", +// SyncSymbConf,SyncLocked,SyncProcPtr,SyncPtr,SymbPtr,SyncSymbShift,SyncFreqOfs); + if (SyncPtr == SymbPtr) { + s1 = SyncProcPtr - ProcdspDelay + + ((int)SyncSymbShift - SymbPtr * SyncStep); + s2 = s1 + SymbolSepar / 2; // printf(" SdspAmple at %d,%d (SyncProcPtr-%d), time diff.=%d\n",s1,s2,SyncProcPtr-s1,s1-DataProcPtr); - DataProcess(ProcLine.InpPtr+s1,ProcLine.InpPtr+s2,SyncFreqOfs,s1-DataProcPtr); - DataProcPtr=s1; + DataProcess(ProcLine.InpPtr + s1, ProcLine.InpPtr + s2, + SyncFreqOfs, s1 - DataProcPtr); + DataProcPtr = s1; } - // printf("\n"); - SyncProcPtr+=SyncStep; - } - SyncProcPtr-=ProcLine.InpLen; DataProcPtr-=ProcLine.InpLen; - return 0; +// printf("\n"); + SyncProcPtr += SyncStep; + } + SyncProcPtr -= ProcLine.InpLen; + DataProcPtr -= ProcLine.InpLen; + return 0; } void MT63rx::DoCorrelSum(dspCmpx *Correl1, dspCmpx *Correl2, dspCmpx *Aver) -{ dspCmpx sx; int i,s,d; - s=2*DataCarrSepar; d=DataCarriers*DataCarrSepar; - sx.re=sx.im=0.0; - for(i=0; i0.0) { dI=(I*I-Q*Q)/A; dQ=(2*I*Q)/A; } - else { dI=dQ=0.0; } - dspLowPass2(P,dspPowerMid[i],dspPowerOut[i],W1p,W2p,W5p); - pI=PrevSlice[i].re*SyncPhCorr[i].re-PrevSlice[i].im*SyncPhCorr[i].im; - pQ=PrevSlice[i].re*SyncPhCorr[i].im+PrevSlice[i].im*SyncPhCorr[i].re; - Correl.re=dQ*pQ+dI*pI; - Correl.im=dQ*pI-dI*pQ; - dspLowPass2(&Correl,CorrelMid[SyncPtr]+i,CorrelOut[SyncPtr]+i,W1,W2,W5); - PrevSlice[i].re=dI; PrevSlice[i].im=dQ; - } - - if(SyncPtr==(SymbPtr^2)) - { - for(s=0; s0.0) - { CorrelNorm[s][i].re=CorrelOut[s][i].re/dspPowerOut[i]; - CorrelNorm[s][i].im=CorrelOut[s][i].im/dspPowerOut[i]; } - else CorrelNorm[s][i].im=CorrelNorm[s][i].re=0.0; - } + for (i = 0; i < WindowLen; i++) { + r = FFT.BitRevIdx[i]; + FFTbuff[r].re = Slice[i].re * RxWindow[i]; + FFTbuff[r].im = Slice[i].im * RxWindow[i]; } + FFT.CoreProc(FFTbuff); + + if (SpectraDisplay) { + for ( i = 0, + j = FirstDataCarr + (DataCarriers / 2) * DataCarrSepar - + WindowLen / 2; + (i < WindowLen) && ( j 0.0) { + dI = (I * I - Q * Q) / A; + dQ = (2 * I * Q) / A; + } else { + dI = dQ = 0.0; + } + dspLowPass2(P, dspPowerMid[i], dspPowerOut[i], W1p, W2p, W5p); + pI = PrevSlice[i].re * SyncPhCorr[i].re - + PrevSlice[i].im * SyncPhCorr[i].im; + pQ = PrevSlice[i].re * SyncPhCorr[i].im + + PrevSlice[i].im * SyncPhCorr[i].re; + Correl.re = dQ * pQ + dI * pI; + Correl.im = dQ * pI - dI * pQ; + dspLowPass2(&Correl, CorrelMid[SyncPtr] + i, + CorrelOut[SyncPtr] + i, W1, W2, W5); + PrevSlice[i].re = dI; + PrevSlice[i].im = dQ; + } + + if (SyncPtr == (SymbPtr^2)) { + for (s = 0; s < SymbolDiv; s++) { // normalize the correlations + for (i = 0; i < ScanLen; i++) { + if (dspPowerOut[i] > 0.0) { + CorrelNorm[s][i].re = CorrelOut[s][i].re / dspPowerOut[i]; + CorrelNorm[s][i].im = CorrelOut[s][i].im / dspPowerOut[i]; + } else + CorrelNorm[s][i].im = CorrelNorm[s][i].re = 0.0; + } + } /* // another way to normalize - a better one ? - for(i=0; i0.0) - { for(s=0; s0.0) + { for (s=0; s1) j-=(k-1)*DataCarrSepar; else if(k<(-1)) j-=(k+1)*DataCarrSepar; - SymbFitPos=j; + k = (j - SymbFitPos) / DataCarrSepar; + if (k > 1) + j -= (k - 1) * DataCarrSepar; + else if (k < (-1)) + j -= (k + 1) * DataCarrSepar; + SymbFitPos = j; // printf(" => %2d",j); - if(P>0.0) - { SymbConf=dspAmpl(SymbFit[j]) + 0.5*(dspAmpl(SymbFit[j+1])+dspAmpl(SymbFit[j-1])); - SymbConf*=0.5; - I=SymbFit[j].re + 0.5*(SymbFit[j-1].re+SymbFit[j+1].re); - Q=SymbFit[j].im + 0.5*(SymbFit[j-1].im+SymbFit[j+1].im); - SymbTime.re=I; SymbTime.im=Q; - SymbShift=(dspPhase(SymbTime)/(2*M_PI))*SymbolDiv; - if(SymbShift<0) SymbShift+=SymbolDiv; - // for(i=j-1; i<=j+1; i++) printf(" [%+5.2f,%+5.2f]",SymbFit[i].re,SymbFit[i].im); + if (P > 0.0) { + SymbConf = dspAmpl(SymbFit[j]) + + 0.5 * (dspAmpl(SymbFit[j + 1]) + dspAmpl(SymbFit[j - 1])); + SymbConf *= 0.5; + I = SymbFit[j].re + 0.5 * (SymbFit[j - 1].re + SymbFit[j + 1].re); + Q = SymbFit[j].im + 0.5 * (SymbFit[j - 1].im + SymbFit[j + 1].im); + SymbTime.re = I; + SymbTime.im = Q; + SymbShift = (dspPhase(SymbTime) / (2 * M_PI)) * SymbolDiv; + if (SymbShift < 0) + SymbShift += SymbolDiv; + // for (i=j-1; i<=j+1; i++) printf(" [%+5.2f,%+5.2f]",SymbFit[i].re,SymbFit[i].im); // make first estimation of FreqOfs // printf(" -> [%+5.2f,%+5.2f] =>",I,Q); - // for(i=j-2; i<=j+2; i++) printf(" %+6.3f",I*SymbFit[i].re+Q*SymbFit[i].im); - pI = dspScalProd(I,Q,SymbFit[j]) - + 0.7*dspScalProd(I,Q,SymbFit[j-1]) - + 0.7*dspScalProd(I,Q,SymbFit[j+1]); - pQ = 0.7*dspScalProd(I,Q,SymbFit[j+1]) - - 0.7*dspScalProd(I,Q,SymbFit[j-1]) - + 0.5*dspScalProd(I,Q,SymbFit[j+2]) - - 0.5*dspScalProd(I,Q,SymbFit[j-2]); - FreqOfs=j+dspPhase(pI,pQ)/(2.0*M_PI/8); + // for (i=j-2; i<=j+2; i++) printf(" %+6.3f",I*SymbFit[i].re+Q*SymbFit[i].im); + pI = dspScalProd(I, Q, SymbFit[j]) + + 0.7 * dspScalProd(I, Q, SymbFit[j - 1]) + + 0.7 * dspScalProd(I, Q, SymbFit[j + 1]); + pQ = 0.7 * dspScalProd(I, Q, SymbFit[j + 1]) + - 0.7 * dspScalProd(I, Q, SymbFit[j - 1]) + + 0.5 * dspScalProd(I, Q, SymbFit[j + 2]) + - 0.5 * dspScalProd(I, Q, SymbFit[j - 2]); + FreqOfs = j + dspPhase(pI, pQ) / (2.0 * M_PI / 8); /* SYNC TEST */ // refine the FreqOfs - i=(int)floor(FreqOfs+0.5); - s=(int)floor(SymbShift); s2=(s+1)&(SymbolDiv-1); + i = (int)floor(FreqOfs + 0.5); + s = (int)floor(SymbShift); + s2 = (s + 1) & (SymbolDiv - 1); // printf(" [%5.2f,%2d,%d,%d] ",FreqOfs,i,s,s2); - w0=(s+1-SymbShift); w1=(SymbShift-s); + w0 = (s + 1 - SymbShift); + w1 = (SymbShift - s); // printf(" [%4.2f,%4.2f] ",w0,w1); - A=(0.5*WindowLen)/SymbolSepar; - I=w0*CorrelAver[s][i].re+w1*CorrelAver[s2][i].re; - Q=w0*CorrelAver[s][i].im+w1*CorrelAver[s2][i].im; + A = (0.5 * WindowLen) / SymbolSepar; + I = w0 * CorrelAver[s][i].re + w1 * CorrelAver[s2][i].re; + Q = w0 * CorrelAver[s][i].im + w1 * CorrelAver[s2][i].im; // printf(" [%5.2f,%2d] -> [%+5.2f,%+5.2f]",FreqOfs,i,I,Q); // FreqOfs=i+dspPhase(I,Q)/(2.0*M_PI)*0.5*A; // printf(" => %5.2f",FreqOfs); - F0=i+dspPhase(I,Q)/(2.0*M_PI)*A-FreqOfs; - Fl=F0-A; Fu=F0+A; - if(fabs(Fl) (%5.2f,%5.2f,%5.2f) => %5.2f",Fl,F0,Fu,FreqOfs); - } else { SymbTime.re=SymbTime.im=0.0; SymbConf=0.0; SymbShift=0.0; FreqOfs=0.0; } + } else { + SymbTime.re = SymbTime.im = 0.0; + SymbConf = 0.0; + SymbShift = 0.0; + FreqOfs = 0.0; + } // here we have FreqOfs and SymbTime.re/im // printf("FreqOfs=%5.2f",FreqOfs); - if(SyncLocked) - { // flip the SymbTime if it doesn't agree with the dspAverage - if(dspScalProd(SymbTime,AverSymb)<0.0) - { SymbTime.re=(-SymbTime.re); SymbTime.im=(-SymbTime.im); - FreqOfs-=DataCarrSepar; } + if (SyncLocked) { // flip the SymbTime if it doesn't agree with the dspAverage + if (dspScalProd(SymbTime, AverSymb) < 0.0) { + SymbTime.re = (-SymbTime.re); + SymbTime.im = (-SymbTime.im); + FreqOfs -= DataCarrSepar; + } // reduce the freq. offset towards the dspAverage offset - A=2*DataCarrSepar; - k=(int)floor((FreqOfs-AverFreq)/A+0.5); FreqOfs-=k*A; + A = 2 * DataCarrSepar; + k = (int)floor((FreqOfs - AverFreq) / A + 0.5); + FreqOfs -= k * A; /* SYNC TEST */ - A=(0.5*WindowLen)/SymbolSepar; - F0=FreqOfs-AverFreq; // correct freq. auto-correlator wrap - Fl=F0-A; Fu=F0+A; - if(fabs(Fl) (%5.2f,%5.2f,%5.2f) => %5.2f",Fl,F0,Fu,FreqOfs); + A = (0.5 * WindowLen) / SymbolSepar; + F0 = FreqOfs - AverFreq; // correct freq. auto-correlator wrap + Fl = F0 - A; + Fu = F0 + A; + if (fabs(Fl) < fabs(F0)) + FreqOfs += (fabs(Fu) < fabs(Fl)) ? A : -A; + else + FreqOfs += (fabs(Fu) < fabs(F0)) ? A : 0.0; +// printf(" => (%5.2f,%5.2f,%5.2f) => %5.2f",Fl,F0,Fu,FreqOfs); - } else // of if(SyncLocked) - { // flip SymbTime if it doesn't agree with the previous - if(dspScalProd(SymbTime,SymbPipe[TrackPipePtr])<0.0) - { SymbTime.re=(-SymbTime.re); SymbTime.im=(-SymbTime.im); - FreqOfs-=DataCarrSepar; } - // reduce the FreqOfs towards zero - A=2*DataCarrSepar; - k=(int)floor(FreqOfs/A+0.5); FreqOfs-=k*A; + } else { // of if (SyncLocked) +// flip SymbTime if it doesn't agree with the previous + if (dspScalProd(SymbTime, SymbPipe[TrackPipePtr]) < 0.0) { + SymbTime.re = (-SymbTime.re); + SymbTime.im = (-SymbTime.im); + FreqOfs -= DataCarrSepar; + } +// reduce the FreqOfs towards zero + A = 2 * DataCarrSepar; + k = (int)floor(FreqOfs / A + 0.5); + FreqOfs -= k * A; /* SYNC TEST */ - F0=FreqOfs-FreqPipe[TrackPipePtr]; - Fl=F0-A; Fu=F0+A; - if(fabs(Fl) [%+5.2f,%+5.2f], %5.2f",SymbTime.re,SymbTime.im,FreqOfs); +// printf(" => [%+5.2f,%+5.2f], %5.2f",SymbTime.re,SymbTime.im,FreqOfs); - TrackPipePtr+=1; if(TrackPipePtr>=TrackPipeLen) TrackPipePtr-=TrackPipeLen; - SymbPipe[TrackPipePtr]=SymbTime; // put SymbTime and FreqOfs into pipes - FreqPipe[TrackPipePtr]=FreqOfs; // for averaging + TrackPipePtr += 1; + if (TrackPipePtr >= TrackPipeLen) + TrackPipePtr -= TrackPipeLen; + SymbPipe[TrackPipePtr] = SymbTime; // put SymbTime and FreqOfs into pipes + FreqPipe[TrackPipePtr] = FreqOfs; // for averaging - // find dspAverage symbol time - Loops=dspSelFitAver(SymbPipe,TrackPipeLen,(double)3.0,4,AverSymb,dspRMS,Incl); - // printf(" AverSymb=[%+5.2f,%+5.2f], dspRMS=%5.3f/%2d", - // AverSymb.re,AverSymb.im,dspRMS,Incl); - // find dspAverage freq. offset - Loops=dspSelFitAver(FreqPipe,TrackPipeLen,(double)2.5,4,AverFreq,dspRMS,Incl); - SyncFreqDev=dspRMS; - // printf(" AverFreq=%+5.2f, dspRMS=%5.3f/%2d",AverFreq,dspRMS,Incl); +// find dspAverage symbol time + Loops = dspSelFitAver( SymbPipe, + TrackPipeLen, + (double)3.0, + 4, + AverSymb, + dspRMS, + Incl); +// printf(" AverSymb=[%+5.2f,%+5.2f], dspRMS=%5.3f/%2d", +// AverSymb.re,AverSymb.im,dspRMS,Incl); +// find dspAverage freq. offset + Loops = dspSelFitAver( FreqPipe, + TrackPipeLen, + (double)2.5, + 4, + AverFreq, + dspRMS, + Incl); + SyncFreqDev = dspRMS; +// printf(" AverFreq=%+5.2f, dspRMS=%5.3f/%2d",AverFreq,dspRMS,Incl); - SymbConf=dspAmpl(AverSymb); - SyncSymbConf=SymbConf; - SyncFreqOfs=AverFreq; - if(SymbConf>0.0) - { SymbShift=dspPhase(AverSymb)/(2*M_PI)*SymbolSepar; - if(SymbShift<0.0) SymbShift+=SymbolSepar; - SymbPtr=(int)floor((dspPhase(AverSymb)/(2*M_PI))*SymbolDiv); - if(SymbPtr<0) SymbPtr+=SymbolDiv; - SyncSymbShift=SymbShift; } + SymbConf = dspAmpl(AverSymb); + SyncSymbConf = SymbConf; + SyncFreqOfs = AverFreq; + if (SymbConf > 0.0) { + SymbShift = dspPhase(AverSymb) / (2 * M_PI) * SymbolSepar; + if (SymbShift < 0.0) + SymbShift += SymbolSepar; + SymbPtr = (int)floor((dspPhase(AverSymb) / (2 * M_PI)) * SymbolDiv); + if (SymbPtr < 0) + SymbPtr += SymbolDiv; + SyncSymbShift = SymbShift; + } - if(SyncLocked) - { if((SyncSymbConf0.250)) SyncLocked=0; } - else - { if((SyncSymbConf>SyncLockThres)&&(SyncFreqDev<0.125)) SyncLocked=1; } + if (SyncLocked) { + if ((SyncSymbConf < SyncHoldThres) || (SyncFreqDev > 0.250)) + SyncLocked = 0; + } else { + if ((SyncSymbConf > SyncLockThres) && (SyncFreqDev < 0.125)) + SyncLocked = 1; + } - SyncSymbConf*=0.5; + SyncSymbConf *= 0.5; - // printf(" => SyncLocked=%d, SyncSymbShift=%5.1f, SymbPtr=%d", - // SyncLocked,SyncSymbShift,SymbPtr); +// printf(" => SyncLocked=%d, SyncSymbShift=%5.1f, SymbPtr=%d", +// SyncLocked,SyncSymbShift,SymbPtr); - // printf("\n"); +// printf("\n"); - } // enf of if(SyncPtr==(SymbPtr^2)) + } // enf of if (SyncPtr==(SymbPtr^2)) } void MT63rx::DataProcess(dspCmpx *EvenSlice, dspCmpx *OddSlice, double FreqOfs, int TimeDist) -{ int i,c,r; - dspCmpx Freq,Phas; - int incr,p; - double I,Q,P; - dspCmpx Dtmp; dspCmpx Ftmp; +{ + int i, c, r; + dspCmpx Freq, Phas; + int incr, p; + double I, Q, P; + dspCmpx Dtmp; + dspCmpx Ftmp; + // double Aver,dspRMS; int Loops,Incl; // Here we pickup a symbol in the data history. The time/freq. synchronizer @@ -1098,114 +1286,130 @@ void MT63rx::DataProcess(dspCmpx *EvenSlice, dspCmpx *OddSlice, double FreqOfs, // FreqOfs=0.0; // for DEBUG only ! // printf("DataProcess: FreqOfs=%5.3f, TimeDist=%d, Locked=%d\n", -// FreqOfs,TimeDist,SyncLocked); +// FreqOfs,TimeDist,SyncLocked); - P=(-2*M_PI*FreqOfs)/WindowLen; // make ready for frequency correction - Freq.re=cos(P); Freq.im=sin(P); - Phas.re=1.0; Phas.im=0.0; - for(i=0; i=DataPipeLen) DataPipePtr=0; +// CdspcmpxMultAxB(Dtmp,Ftmp,Ftmp); +// Dtmp.re=Ftmp.re*Ftmp.re-Ftmp.im*Ftmp.im; Dtmp.im=2*Ftmp.re*Ftmp.im; +// dspLowPass2(&Dtmp,DataSqrMid+i,DataSqrOut+i,dW1,dW2,dW5); + DataVect[i] = DataPipe[DataPipePtr][i]; + DataPipe[DataPipePtr][i] = Ftmp; + } + DataPipePtr += 1; + if (DataPipePtr >= DataPipeLen) + DataPipePtr = 0; - for(i=0; i0.0) - { P=DataVect[i].re/DataPwrOut[i]; - if(P>1.0) P=1.0; else if(P<(-1.0)) P=(-1.0); - DatadspPhase[i]=P; - } else DatadspPhase[i]=0.0; - } - Decoder.Process(DatadspPhase); - Output.EnsureSpace(Output.Len+1); - Output.Data[Output.Len]=Decoder.Output; - Output.Len+=1; + for (i = 0; i < DataScanLen; i++) { + if (DataPwrOut[i] > 0.0) { + P = DataVect[i].re / DataPwrOut[i]; + if (P > 1.0) + P = 1.0; + else if (P < (-1.0)) + P = (-1.0); + DatadspPhase[i] = P; + } else + DatadspPhase[i] = 0.0; + } + Decoder.Process(DatadspPhase); + Output.EnsureSpace(Output.Len + 1); + Output.Data[Output.Len] = Decoder.Output; + Output.Len += 1; /* printf("Demodulator output vectors:\n"); - for(i=0; i %8.5f\n", - i,DataVect[i].re,DataVect[i].im,DataPwrOut[i], DatadspPhase[i]); + i,DataVect[i].re,DataVect[i].im,DataPwrOut[i], DatadspPhase[i]); } */ /* - for(i=0; i0.0) P=dspPhase(DataVect[i]); else P=0.0; + if (dspPower(DataVect[i])>0.0) P=dspPhase(DataVect[i]); else P=0.0; DatadspPhase[i]=P; - P*=2; if(P>M_PI) P-=2*M_PI; else if(P<(-M_PI)) P+=2*M_PI; + P*=2; if (P>M_PI) P-=2*M_PI; else if (P<(-M_PI)) P+=2*M_PI; DatadspPhase2[i]=P; printf("%2d: %6.3f [%6.3f,%6.3f] [%8.5f,%8.5f], %5.2f, %5.2f", - i, DataPwrOut[i], DataSqrOut[i].re,DataSqrOut[i].im, - DataVect[i].re,DataVect[i].im, DatadspPhase[i],DatadspPhase2[i]); - if(DataPwrOut[i]>0.0) + i, DataPwrOut[i], DataSqrOut[i].re,DataSqrOut[i].im, + DataVect[i].re,DataVect[i].im, DatadspPhase[i],DatadspPhase2[i]); + if (DataPwrOut[i]>0.0) printf(" %6.3f",dspAmpl(DataSqrOut[i])/DataPwrOut[i]); printf("\n"); } @@ -1214,20 +1418,36 @@ void MT63rx::DataProcess(dspCmpx *EvenSlice, dspCmpx *OddSlice, double FreqOfs, */ } -int MT63rx::SYNC_LockStatus(void) { return SyncLocked; } +int MT63rx::SYNC_LockStatus(void) { + return SyncLocked; +} -double MT63rx::SYNC_Confidence(void) -{ return SyncSymbConf<=1.0 ? SyncSymbConf : 1.0; } +double MT63rx::SYNC_Confidence(void) { + return SyncSymbConf <= 1.0 ? SyncSymbConf : 1.0; +} -double MT63rx::SYNC_FreqOffset(void) { return SyncFreqOfs/DataCarrSepar; } +double MT63rx::SYNC_FreqOffset(void) { + return SyncFreqOfs / DataCarrSepar; +} -double MT63rx::SYNC_FreqDevdspRMS(void) { return SyncFreqDev/DataCarrSepar; } +double MT63rx::SYNC_FreqDevdspRMS(void) { + return SyncFreqDev / DataCarrSepar; +} -double MT63rx::SYNC_TimeOffset(void) { return SyncSymbShift/SymbolSepar; } +double MT63rx::SYNC_TimeOffset(void) { + return SyncSymbShift / SymbolSepar; +} -double MT63rx::FEC_SNR(void) { return Decoder.SignalToNoise; } +double MT63rx::FEC_SNR(void) { + return Decoder.SignalToNoise; +} -int MT63rx::FEC_CarrOffset(void) { return Decoder.CarrOfs; } +int MT63rx::FEC_CarrOffset(void) { + return Decoder.CarrOfs; +} + +double MT63rx::TotalFreqOffset(void) { + return ( SyncFreqOfs + DataCarrSepar * Decoder.CarrOfs) * + (8000.0 / DecimateRatio) / WindowLen; +} -double MT63rx::TotalFreqOffset(void) -{ return (SyncFreqOfs+DataCarrSepar*Decoder.CarrOfs)*(8000.0/DecimateRatio)/WindowLen; }