diff --git a/src/dialogs/confdialog.cxx b/src/dialogs/confdialog.cxx index d1593826..ff0554ff 100644 --- a/src/dialogs/confdialog.cxx +++ b/src/dialogs/confdialog.cxx @@ -818,6 +818,27 @@ static void cb_btnMT63_8bit(Fl_Check_Button* o, void*) { progdefaults.changed = true; } +Fl_Check_Button *btnMT63_rx_integration=(Fl_Check_Button *)0; + +static void cb_btnMT63_rx_integration(Fl_Check_Button* o, void*) { + progdefaults.mt63_rx_integration = o->value(); +progdefaults.changed = true; +} + +Fl_Check_Button *btnMT63_usetones=(Fl_Check_Button *)0; + +static void cb_btnMT63_usetones(Fl_Check_Button* o, void*) { + progdefaults.mt63_usetones = o->value(); +progdefaults.changed = true; +} + +Fl_Check_Button *btnMT63_upper_lower=(Fl_Check_Button *)0; + +static void cb_btnMT63_upper_lower(Fl_Check_Button* o, void*) { + progdefaults.mt63_twotones = o->value(); +progdefaults.changed = true; +} + Fl_Group *tabOlivia=(Fl_Group *)0; Fl_Choice *mnuOlivia_Bandwidth=(Fl_Choice *)0; @@ -2123,6 +2144,7 @@ static const char szBaudRates[] = "300|600|1200|2400|4800|9600|19200|38400|57600 { tabOperator = new Fl_Group(0, 25, 500, 345, _("Operator")); tabOperator->callback((Fl_Callback*)cb_tabOperator); tabOperator->when(FL_WHEN_CHANGED); + tabOperator->hide(); { Fl_Group* o = new Fl_Group(5, 35, 490, 165, _("Station")); o->box(FL_ENGRAVED_FRAME); o->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE); @@ -2707,11 +2729,11 @@ an merging")); tabWaterfall->end(); } // Fl_Group* tabWaterfall { tabModems = new Fl_Group(0, 25, 500, 345, _("Modems")); - tabModems->hide(); { tabsModems = new Fl_Tabs(0, 25, 500, 345); tabsModems->selection_color(FL_LIGHT1); tabsModems->align(FL_ALIGN_TOP_RIGHT); { tabCW = new Fl_Group(0, 50, 500, 320, _("CW")); + tabCW->hide(); { tabsCW = new Fl_Tabs(0, 50, 500, 320); tabsCW->selection_color(FL_LIGHT1); { Fl_Group* o = new Fl_Group(0, 75, 500, 295, _("General")); @@ -3076,8 +3098,7 @@ an merging")); tabFeld->end(); } // Fl_Group* tabFeld { tabMT63 = new Fl_Group(0, 50, 500, 320, _("MT-63")); - tabMT63->hide(); - { Fl_Group* o = new Fl_Group(5, 60, 490, 85); + { Fl_Group* o = new Fl_Group(5, 60, 490, 184); o->box(FL_ENGRAVED_FRAME); o->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE); { Fl_Check_Button* o = btnmt63_interleave = new Fl_Check_Button(150, 78, 185, 20, _("64-bit (long) interleave")); @@ -3087,12 +3108,30 @@ an merging")); btnmt63_interleave->callback((Fl_Callback*)cb_btnmt63_interleave); o->value(0);if (progdefaults.mt63_interleave == 64) o->value(1); } // Fl_Check_Button* btnmt63_interleave - { Fl_Check_Button* o = btnMT63_8bit = new Fl_Check_Button(150, 113, 205, 20, _("8-bit extended characters")); + { Fl_Check_Button* o = btnMT63_8bit = new Fl_Check_Button(150, 114, 205, 20, _("8-bit extended characters")); btnMT63_8bit->tooltip(_("Enable this for Latin-1 accented characters")); btnMT63_8bit->down_box(FL_DOWN_BOX); btnMT63_8bit->callback((Fl_Callback*)cb_btnMT63_8bit); o->value(progdefaults.mt63_8bit); } // Fl_Check_Button* btnMT63_8bit + { Fl_Check_Button* o = btnMT63_rx_integration = new Fl_Check_Button(150, 151, 167, 15, _("Long Rx Integration")); + btnMT63_rx_integration->tooltip(_("Enable for very weak signals")); + btnMT63_rx_integration->down_box(FL_DOWN_BOX); + btnMT63_rx_integration->callback((Fl_Callback*)cb_btnMT63_rx_integration); + o->value(progdefaults.mt63_rx_integration); + } // Fl_Check_Button* btnMT63_rx_integration + { Fl_Check_Button* o = btnMT63_usetones = new Fl_Check_Button(150, 183, 133, 15, _("Use start tones")); + btnMT63_usetones->tooltip(_("Xmt startup tones in first / last frequency bins")); + btnMT63_usetones->down_box(FL_DOWN_BOX); + btnMT63_usetones->callback((Fl_Callback*)cb_btnMT63_usetones); + o->value(progdefaults.mt63_usetones); + } // Fl_Check_Button* btnMT63_usetones + { Fl_Check_Button* o = btnMT63_upper_lower = new Fl_Check_Button(150, 215, 136, 15, _("Upper && Lower")); + btnMT63_upper_lower->tooltip(_("Select for two / clear for only lower tone")); + btnMT63_upper_lower->down_box(FL_DOWN_BOX); + btnMT63_upper_lower->callback((Fl_Callback*)cb_btnMT63_upper_lower); + o->value(progdefaults.mt63_twotones); + } // Fl_Check_Button* btnMT63_upper_lower o->end(); } // Fl_Group* o tabMT63->end(); diff --git a/src/dialogs/confdialog.fl b/src/dialogs/confdialog.fl index 82c1278c..5fedee5d 100644 --- a/src/dialogs/confdialog.fl +++ b/src/dialogs/confdialog.fl @@ -80,15 +80,15 @@ static const char szBaudRates[] = "300|600|1200|2400|4800|9600|19200|38400|57600 code {} {} Fl_Window {} { label {Fldigi configuration} open - xywh {326 139 500 400} type Double color 45 selection_color 51 labelsize 18 align 80 visible + xywh {536 199 500 400} type Double color 45 selection_color 51 labelsize 18 align 80 visible } { Fl_Tabs tabsConfigure {open xywh {0 0 505 372} color 50 selection_color 50 } { Fl_Group tabOperator { label Operator - callback {progdefaults.changed = true;} open selected - xywh {0 25 500 345} when 1 + callback {progdefaults.changed = true;} open + xywh {0 25 500 345} when 1 hide } { Fl_Group {} { label Station open @@ -699,14 +699,14 @@ behaves inside the waterfall} xywh {15 196 150 22} down_box BORDER_BOX align 8 } Fl_Group tabModems { label Modems open - xywh {0 25 500 345} hide + xywh {0 25 500 345} } { Fl_Tabs tabsModems {open xywh {0 25 500 345} selection_color 50 align 9 } { Fl_Group tabCW { label CW open - xywh {0 50 500 320} + xywh {0 50 500 320} hide } { Fl_Tabs tabsCW {open xywh {0 50 500 320} selection_color 50 @@ -830,14 +830,14 @@ progdefaults.changed = true;} label {Dash to dot ratio} callback {progdefaults.CWdash2dot=o->value(); progdefaults.changed = true;} - tooltip {Dash to dot ratio} xywh {240 114 64 20} type Simple align 8 minimum 2.5 maximum 4 step 0.1 value 3 + tooltip {Dash to dot ratio} xywh {240 114 64 20} type Simple align 8 minimum 2.5 maximum 4 value 3 code0 {o->value(progdefaults.CWdash2dot);} } Fl_Counter cntCWrisetime { label {Edge timing} callback {progdefaults.CWrisetime=o->value(); progdefaults.changed = true;} - tooltip {Leading and Trailing edge risetimes (msec)} xywh {240 145 65 20} type Simple align 8 minimum 0 maximum 15 step 0.1 value 4 + tooltip {Leading and Trailing edge risetimes (msec)} xywh {240 145 65 20} type Simple align 8 minimum 0 maximum 15 value 4 code0 {o->value(progdefaults.CWrisetime);} } Fl_Choice mnuQSKshape { @@ -927,7 +927,7 @@ progdefaults.changed = true;} callback {progdefaults.DOMINOEX_BW = o->value(); resetDOMEX(); progdefaults.changed = true;} - tooltip {Filter bandwidth relative to signal width} xywh {156 141 63 20} type Simple align 8 minimum 1 maximum 2 step 0.1 value 1.5 + tooltip {Filter bandwidth relative to signal width} xywh {156 141 63 20} type Simple align 8 minimum 1 maximum 2 value 1.5 code0 {o->value(progdefaults.DOMINOEX_BW);} } Fl_Check_Button chkDominoEX_FEC { @@ -941,7 +941,7 @@ progdefaults.changed = true;} label {CWI threshold} callback {progdefaults.DomCWI = o->value(); progdefaults.changed = true;} - tooltip {CWI detection and suppression} xywh {15 207 260 20} type Horizontal align 1 step 0.01 textsize 14 + tooltip {CWI detection and suppression} xywh {15 207 260 20} type Horizontal align 1 textsize 14 code0 {o->value(progdefaults.DomCWI);} } Fl_Counter valDominoEX_PATHS { @@ -1025,10 +1025,10 @@ progdefaults.changed = true;} } Fl_Group tabMT63 { label {MT-63} open - xywh {0 50 500 320} hide + xywh {0 50 500 320} } { Fl_Group {} {open - xywh {5 60 490 85} box ENGRAVED_FRAME align 21 + xywh {5 60 490 184} box ENGRAVED_FRAME align 21 } { Fl_Check_Button btnmt63_interleave { label {64-bit (long) interleave} @@ -1044,9 +1044,30 @@ progdefaults.changed = true;} label {8-bit extended characters} callback {progdefaults.mt63_8bit = o->value(); progdefaults.changed = true;} - tooltip {Enable this for Latin-1 accented characters} xywh {150 113 205 20} down_box DOWN_BOX + tooltip {Enable this for Latin-1 accented characters} xywh {150 114 205 20} down_box DOWN_BOX code0 {o->value(progdefaults.mt63_8bit);} } + Fl_Check_Button btnMT63_rx_integration { + label {Long Rx Integration} + callback {progdefaults.mt63_rx_integration = o->value(); +progdefaults.changed = true;} + tooltip {Enable for very weak signals} xywh {150 151 167 15} down_box DOWN_BOX + code0 {o->value(progdefaults.mt63_rx_integration);} + } + Fl_Check_Button btnMT63_usetones { + label {Use start tones} + callback {progdefaults.mt63_usetones = o->value(); +progdefaults.changed = true;} + tooltip {Xmt startup tones in first / last frequency bins} xywh {150 183 133 15} down_box DOWN_BOX + code0 {o->value(progdefaults.mt63_usetones);} + } + Fl_Check_Button btnMT63_upper_lower { + label {Upper && Lower} + callback {progdefaults.mt63_twotones = o->value(); +progdefaults.changed = true;} selected + tooltip {Select for two / clear for only lower tone} xywh {150 215 136 15} down_box DOWN_BOX + code0 {o->value(progdefaults.mt63_twotones);} + } } } Fl_Group tabOlivia { @@ -1402,7 +1423,7 @@ progdefaults.changed = true;} callback {progdefaults.THOR_BW = o->value(); resetTHOR(); progdefaults.changed = true;} - tooltip {Filter bandwidth relative to signal width} xywh {156 141 63 20} type Simple align 8 minimum 1 maximum 2 step 0.1 value 1.5 + tooltip {Filter bandwidth relative to signal width} xywh {156 141 63 20} type Simple align 8 minimum 1 maximum 2 value 1.5 code0 {o->value(progdefaults.THOR_BW);} } Fl_Check_Button valTHOR_SOFT { @@ -1416,7 +1437,7 @@ progdefaults.changed = true;} label {CWI threshold} callback {progdefaults.ThorCWI = o->value(); progdefaults.changed = true;} - tooltip {CWI detection and suppression} xywh {15 218 260 20} type Horizontal align 1 step 0.01 textsize 14 + tooltip {CWI detection and suppression} xywh {15 218 260 20} type Horizontal align 1 textsize 14 code0 {o->value(progdefaults.ThorCWI);} } Fl_Counter valTHOR_PATHS { @@ -2191,7 +2212,7 @@ progdefaults.changed = true;} label PCM callback {setPCMvolume(o->value()); progdefaults.changed = true;} - tooltip {Set the sound card PCM level} xywh {15 167 340 20} type Horizontal selection_color 15 align 8 step 0.01 value 0.8 textsize 14 + tooltip {Set the sound card PCM level} xywh {15 167 340 20} type Horizontal selection_color 15 align 8 value 0.8 textsize 14 code0 {extern void setPCMvolume(double);} } } diff --git a/src/include/confdialog.h b/src/include/confdialog.h index 4ecb1925..180422b0 100644 --- a/src/include/confdialog.h +++ b/src/include/confdialog.h @@ -139,6 +139,9 @@ extern Fl_Check_Button *btnHellXmtWidth; extern Fl_Group *tabMT63; extern Fl_Check_Button *btnmt63_interleave; extern Fl_Check_Button *btnMT63_8bit; +extern Fl_Check_Button *btnMT63_rx_integration; +extern Fl_Check_Button *btnMT63_usetones; +extern Fl_Check_Button *btnMT63_upper_lower; extern Fl_Group *tabOlivia; extern Fl_Choice *mnuOlivia_Bandwidth; extern Fl_Choice *mnuOlivia_Tones; diff --git a/src/include/configuration.h b/src/include/configuration.h index 49f22014..dafccc29 100644 --- a/src/include/configuration.h +++ b/src/include/configuration.h @@ -143,6 +143,9 @@ /* MT63 */ \ ELEM_(bool, mt63_8bit, "MT638BIT", false) \ ELEM_(int, mt63_interleave, "MT63INTERLEAVE", 64) /* long interleave */ \ + ELEM_(bool, mt63_rx_integration, "MT63INTEGRATION", false) \ + ELEM_(bool, mt63_twotones, "MT63TWOTONES", true) \ + ELEM_(bool, mt63_usetones, "MT63USETONES", true) \ /* Waterfall & UI */ \ ELEM_(uchar, red, "", 0) \ ELEM_(uchar, green, "", 255) \ diff --git a/src/include/modem.h b/src/include/modem.h index 4f0e50f6..929f9908 100644 --- a/src/include/modem.h +++ b/src/include/modem.h @@ -22,7 +22,7 @@ class modem : public morse { protected: trx_mode mode; SoundBase *scard; - + bool stopflag; int fragmentsize; int samplerate; @@ -57,7 +57,7 @@ protected: bool historyON; Digiscope::scope_mode scopemode; - + int scptr; unsigned cap; @@ -76,7 +76,7 @@ public: virtual void set1(int, int){}; virtual void set2(int, int){}; virtual void makeTxViewer(int W, int H){}; - + virtual void searchDown() {}; virtual void searchUp() {}; @@ -109,12 +109,12 @@ public: void set_samplerate(int); void init_queues(); int get_echo_char(); - + void ModulateXmtr(double *, int); void ModulateStereo(double *, double *, int); - + void videoText(); - + void set_stopflag(bool b) { stopflag = b;}; unsigned get_cap(void) { return cap; } @@ -132,15 +132,15 @@ public: virtual void incWPM() {}; virtual void decWPM() {}; virtual void toggleWPM() {}; - + // for waterfall id transmission private: - + static int wfid_mask[]; static double wfid_w[]; static double wfid_txpulse[]; static double wfid_outbuf[]; - + void wfid_make_pulse(); void wfid_make_tones(); void wfid_send(long int); @@ -149,7 +149,7 @@ private: void wfid_sendchar(char c); void wfid_sendchars(std::string s); - + double PTTnco(); public: diff --git a/src/include/mt63.h b/src/include/mt63.h index f19c05b3..3855c903 100644 --- a/src/include/mt63.h +++ b/src/include/mt63.h @@ -4,7 +4,7 @@ // Copyright (C) 2006 // Dave Freese, W1HKJ // -// This file is part of fldigi. Adapted from code contained in gmfsk source code +// This file is part of fldigi. Adapted from code contained in gmfsk source code // distribution. // Copyright (C) 2005 // Tomi Manninen (oh2bns@sral.fi) @@ -37,6 +37,7 @@ private: int Interleave; int flush; int escape; + bool long_integral; MT63tx *Tx; MT63rx *Rx; @@ -47,7 +48,7 @@ private: bool flushbuffer; double FEC_offset; double FEC_snr; - + public: mt63(trx_mode mode); ~mt63(); @@ -57,7 +58,7 @@ public: void restart(); int rx_process(const double *buf, int len); int tx_process(); - + void rx_flush(); }; diff --git a/src/include/mt63base.h b/src/include/mt63base.h index f3d72a55..1af19cfa 100644 --- a/src/include/mt63base.h +++ b/src/include/mt63base.h @@ -2,7 +2,7 @@ * mt63base.h -- MT63 transmitter and receiver in C++ for LINUX * * Copyright (c) 2007, 2008 Dave Freese, W1HKJ - * + * * base class for use by fldigi * modified from original * excluded CW_ID which is a part of the base modem class for fldigi @@ -57,7 +57,7 @@ How to use this class: // Date: 05-NOV-1999 class MT63encoder -{ +{ public: MT63encoder(); ~MT63encoder(); @@ -180,7 +180,7 @@ public: ~MT63tx(); void Free(void); int Preset(int BandWidth=1000, int LongInterleave=0);//, char *ID=NULL); - int SendTune(void); + int SendTune(bool twotones); int SendChar(char ch); int SendJam(void); int SendSilence(void); @@ -280,7 +280,7 @@ private: int DecimateRatio; // decimation/interpolation after/before filter // how the bits of one block are placed on data carriers - int *InterleavePattern; + int *InterleavePattern; int DataInterleave; // data interleave depth int DataCarriers; // number of carriers @@ -308,9 +308,9 @@ private: dspCmpx *SyncPhCorr; // dspPhase corrections for the sync. processor - dspCmpx *CorrelMid[4], + dspCmpx *CorrelMid[4], *CorrelOut[4]; // correlation integrator - double *dspPowerMid, + double *dspPowerMid, *dspPowerOut; // carrier dspPower integrator dspCmpx *CorrelNorm[4]; // normalized correlation double W1, W2, W5; // correlation integrator weights @@ -341,9 +341,9 @@ private: double SyncSymbShift; // current smoothed symbol time shift // here starts the data decoder - void DataProcess( dspCmpx *EvenSlice, - dspCmpx *OddSlice, - double FreqOfs, + void DataProcess( dspCmpx *EvenSlice, + dspCmpx *OddSlice, + double FreqOfs, int TimeDist); int DataScanMargin; // +/- data carriers to scan for best FEC match diff --git a/src/mt63/dsp.cxx b/src/mt63/dsp.cxx index 1a097824..bc933bae 100644 --- a/src/mt63/dsp.cxx +++ b/src/mt63/dsp.cxx @@ -1,25 +1,25 @@ /* - * dsp.cc -- various DSP algorithms - * - * based on mt63 code by Pawel Jalocha - * Copyright (C) 1999-2004 Pawel Jalocha, SP9VRC - * Copyright (c) 2007-2008 Dave Freese, W1HKJ + * dsp.cc -- various DSP algorithms * - * This file is part of fldigi. + * based on mt63 code by Pawel Jalocha + * Copyright (C) 1999-2004 Pawel Jalocha, SP9VRC + * Copyright (c) 2007-2008 Dave Freese, W1HKJ * - * fldigi is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This file is part of fldigi. * - * fldigi is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty oF - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * fldigi is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * You should have received a copy of the GNU General Public License - * along with MT63; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * fldigi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty oF + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MT63; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ @@ -40,19 +40,19 @@ double dspPower(double *X, int Len) { double Sum; for(Sum=0.0; Len; Len--,X++) - Sum+=(*X)*(*X); + Sum+=(*X)*(*X); return Sum; } double dspPower(double *I, double *Q, int Len) { double Sum; for(Sum=0.0; Len; Len--,I++,Q++) - Sum+=(*I)*(*I)+(*Q)*(*Q); + Sum+=(*I)*(*I)+(*Q)*(*Q); return Sum; } double dspPower(dspCmpx *X, int Len) { double Sum; for(Sum=0.0; Len; Len--,X++) - Sum+=(X->re)*(X->re)+(X->im)*(X->im); + Sum+=(X->re)*(X->re)+(X->im)*(X->im); return Sum; } // ---------------------------------------------------------------------------- @@ -87,10 +87,10 @@ double dspFitPoly1(double *Data, int Len, double &A, double &B) { double Sum; int i; A=(Data[Len-1]-Data[0])/(Len-1); for(Sum=0.0,i=0; i32767.0) out=32767.0; - else if(out<(-32767.0)) out=(-32767.0); - (*dspS16++)=(short int)floor(out+0.5); } + if(out>32767.0) out=32767.0; + else if(out<(-32767.0)) out=(-32767.0); + (*dspS16++)=(short int)floor(out+0.5); } } // we could count the over/underflows ? void dspConvU8todouble(unsigned char *U8, double *dble, int Len, double Gain) @@ -229,12 +229,12 @@ int dspPulseLimiter::Process(double *Inp, int InpLen, double *Out) { int i,o; double Lim; for(i=0; i=Len) Ptr-=Len; - o=Ptr+(Len/2); if(o>=Len) o-=Len; - Lim=Thres*PwrSum/Len; - if(Tap[o]*Tap[o]<=Lim) Out[i]=Tap[o]; - else { if(Tap[o]>0.0) Out[i]=sqrt(Lim); else Out[i]=(-sqrt(Lim)); } + Tap[Ptr++]=Inp[i]; PwrSum+=Inp[i]*Inp[i]; + if(Ptr>=Len) Ptr-=Len; + o=Ptr+(Len/2); if(o>=Len) o-=Len; + Lim=Thres*PwrSum/Len; + if(Tap[o]*Tap[o]<=Lim) Out[i]=Tap[o]; + else { if(Tap[o]>0.0) Out[i]=sqrt(Lim); else Out[i]=(-sqrt(Lim)); } } for(PwrSum=0.0, i=0; iMaxMS) { Level-=AdjStep; if(LevelMaxLevel) Level=MaxLevel; - Hold=0; return 1; } + Hold=0; return 1; } return 0; } @@ -348,9 +348,9 @@ int dspPeriodLowPass2::Process(double *Inp, int InpLen, double *Out) { int i,batch; for(i=0; i=Len) TapPtr=0; } + { dspLowPass2(*Inp++,TapMid[TapPtr],TapOut[TapPtr],W1,W2,W5); + (*Out++)=TapOut[TapPtr++]; } + if(TapPtr>=Len) TapPtr=0; } return 0; } @@ -380,8 +380,8 @@ int dspBoxFilter::Process(double *Inp, int InpLen, double *Out) { int i,batch; for( i=0; i=Len) TapPtr=0; } + { Sum-=Tap[TapPtr]; Out[i]=(Sum+=Tap[TapPtr++]=Inp[i]); } + if(TapPtr>=Len) TapPtr=0; } for(Sum=0, i=0; i=Len) TapPtr=0; } + { Sum.re-=Tap[TapPtr].re; Sum.im-=Tap[TapPtr].im; + Tap[TapPtr]=Inp[i]; Sum.re+=Inp[i].re; Sum.im+=Inp[i].im; + Out[i].re=Sum.re; Out[i].im=Sum.im; } + if(TapPtr>=Len) TapPtr=0; } for(Sum.re=Sum.im=0.0, i=0; i=Len) TapPtr=0; - for(Sum=0,s=0,t=TapPtr; tLen; - err = Tap.EnsureSpace(Tap.Len + InpLen); + err = Tap.EnsureSpace(Tap.Len + InpLen); if(err) return err; dspCopyArray(Tap.Data+Tap.Len,Input->Data,InpLen); // printf("dspQuadrSplit: InpLen=%d, Tap.Len=%d",InpLen,Tap.Len); - Tap.Len += InpLen; + Tap.Len += InpLen; Inp = Tap.Data; // printf(" -> %d",Tap.Len); - err = Output.EnsureSpace( InpLen / Rate + 2); + err = Output.EnsureSpace( InpLen / Rate + 2); if(err) return err; Out = Output.Data; - for(l = Tap.Len-Len,o = 0, i = 0; i < l; i += Rate) { - for(SumI = SumQ = 0.0, s = i,t = 0; t < Len; t++,s++) { - SumI += Inp[s] * ShapeI[t]; - SumQ += Inp[s] * ShapeQ[t]; + for(l = Tap.Len-Len,o = 0, i = 0; i < l; i += Rate) { + for(SumI = SumQ = 0.0, s = i,t = 0; t < Len; t++,s++) { + SumI += Inp[s] * ShapeI[t]; + SumQ += Inp[s] * ShapeQ[t]; } - Out[o].re=SumI; - Out[o++].im=SumQ; - } - Tap.Len -= i; - dspMoveArray(Tap.Data,Tap.Data+i,Tap.Len); + Out[o].re=SumI; + Out[o++].im=SumQ; + } + Tap.Len -= i; + dspMoveArray(Tap.Data,Tap.Data+i,Tap.Len); Output.Len = o; // printf(" => Tap.Len=%d\n",Tap.Len); return 0; @@ -585,8 +585,8 @@ void dspQuadrComb::Free(void) Output.Free(); } int dspQuadrComb::Preset(int FilterLen, - double *FilterShape_I, double *FilterShape_Q, - int DecimateRate) + double *FilterShape_I, double *FilterShape_Q, + int DecimateRate) { int i; Len=FilterLen; if(dspRedspAllocArray(&Tap,Len)) return -1; @@ -597,7 +597,7 @@ int dspQuadrComb::Preset(int FilterLen, return 0; } int dspQuadrComb::ComputeShape(double LowOmega,double UppOmega, - double (*Window)(double)) + double (*Window)(double)) { if(ExternShape) { ShapeI=NULL; ShapeQ=NULL; ExternShape=0; } if(dspRedspAllocArray(&ShapeI,Len)) return -1; @@ -614,15 +614,15 @@ int dspQuadrComb::Process(dspCmpx_buff *Input) Inp=Input->Data; Out=Output.Data; Output.Len=InpLen*Rate; for(o=0,i=0; i=2*M_PI) dspPhase-=2*M_PI; } + OutI[i]=I*InpI[i]+Q*InpQ[i]; OutQ[i]=I*InpQ[i]-Q*InpI[i]; + dspPhase+=Omega; if(dspPhase>=2*M_PI) dspPhase-=2*M_PI; } return InpLen; } @@ -654,7 +654,7 @@ int dspCmpxMixer::ProcessFast(double *InpI, double *InpQ, int InpLen, I=cos(dspPhase); Q=sin(dspPhase); for(i=0; i=2*M_PI) dspPhase-=2*M_PI; } + Out[i].re=I*Inp[i].re+Q*Inp[i].im; Out[i].im=I*Inp[i].im-Q*Inp[i].re; + dspPhase+=Omega; if(dspPhase>=2*M_PI) dspPhase-=2*M_PI; } return InpLen; } @@ -675,7 +675,7 @@ int dspCmpxMixer::ProcessFast(dspCmpx *Inp, int InpLen, dspCmpx *Out) I=cos(dspPhase); Q=sin(dspPhase); for(i=0; i=M_PI) dspPhaseDiff-=2*M_PI; - else if(dspPhaseDiff<(-M_PI)) dspPhaseDiff+=2*M_PI; - Out[i]=dspPhaseDiff; PrevdspPhase=dspPhase; + else dspPhase=atan2(InpQ[i],InpI[i]); + dspPhaseDiff=dspPhase-PrevdspPhase-RefOmega; + if(dspPhaseDiff>=M_PI) dspPhaseDiff-=2*M_PI; + else if(dspPhaseDiff<(-M_PI)) dspPhaseDiff+=2*M_PI; + Out[i]=dspPhaseDiff; PrevdspPhase=dspPhase; } return InpLen; } @@ -713,11 +713,11 @@ int dspFMdemod::Process(dspCmpx *Inp, int InpLen, double *Out) { int i; double dspPhase,dspPhaseDiff; for(i=0; i=M_PI) dspPhaseDiff-=2*M_PI; - else if(dspPhaseDiff<(-M_PI)) dspPhaseDiff+=2*M_PI; - Out[i]=dspPhaseDiff; PrevdspPhase=dspPhase; + else dspPhase=atan2(Inp[i].im,Inp[i].re); + dspPhaseDiff=dspPhase-PrevdspPhase-RefOmega; + if(dspPhaseDiff>=M_PI) dspPhaseDiff-=2*M_PI; + else if(dspPhaseDiff<(-M_PI)) dspPhaseDiff+=2*M_PI; + Out[i]=dspPhaseDiff; PrevdspPhase=dspPhase; } return InpLen; } @@ -747,7 +747,7 @@ int dspRateConvLin::Process(double_buff *Input) { Out[o++]=Inp[0]*(1.0+OutdspPhase)-OutdspPhase*PrevSdspAmple; OutdspPhase+=OutStep; } for(i=0; i<(InpLen-1); ) { if(OutdspPhase>=1.0) { OutdspPhase-=1.0; i++; } - else { Out[o++]=Inp[i]*(1.0-OutdspPhase)+Inp[i+1]*OutdspPhase; + else { Out[o++]=Inp[i]*(1.0-OutdspPhase)+Inp[i+1]*OutdspPhase; OutdspPhase+=OutStep; } } Output.Len=o; PrevSdspAmple=Inp[i]; OutdspPhase-=1.0; return 0; @@ -770,13 +770,13 @@ int dspRateConvQuadr::Process(double *Inp, int InpLen, { int i,o,t; double Ref0,Ref1,Diff0,Diff1; for(o=i=0; (i=1.0) - { Tap[TapPtr]=(*Inp++); i++; TapPtr=(TapPtr+1)&3; OutdspPhase-=1.0; } - else - { t=TapPtr; Diff0=(Tap[t^2]-Tap[t])/2; Ref1=Tap[t^2]; - t=(t+1)&3; Diff1=(Tap[t^2]-Tap[t])/2; Ref0=Tap[t]; - (*Out++)=Ref0*(1.0-OutdspPhase)+Ref1*OutdspPhase // linear piece - -(Diff1-Diff0)*OutdspPhase*(1.0-OutdspPhase)/2; // quadr. piece - o++; OutdspPhase+=OutStep; } + { Tap[TapPtr]=(*Inp++); i++; TapPtr=(TapPtr+1)&3; OutdspPhase-=1.0; } + else + { t=TapPtr; Diff0=(Tap[t^2]-Tap[t])/2; Ref1=Tap[t^2]; + t=(t+1)&3; Diff1=(Tap[t^2]-Tap[t])/2; Ref0=Tap[t]; + (*Out++)=Ref0*(1.0-OutdspPhase)+Ref1*OutdspPhase // linear piece + -(Diff1-Diff0)*OutdspPhase*(1.0-OutdspPhase)/2; // quadr. piece + o++; OutdspPhase+=OutStep; } } (*OutLen)=o; return i; } @@ -787,13 +787,13 @@ int dspRateConvQuadr::Process(double_buff *Input) Out=Output.Data; for(o=i=0; i=1.0) - { Tap[TapPtr]=(*Inp++); i++; TapPtr=(TapPtr+1)&3; OutdspPhase-=1.0; } - else - { t=TapPtr; Diff0=(Tap[t^2]-Tap[t])/2; Ref1=Tap[t^2]; - t=(t+1)&3; Diff1=(Tap[t^2]-Tap[t])/2; Ref0=Tap[t]; - (*Out++)=Ref0*(1.0-OutdspPhase)+Ref1*OutdspPhase // linear piece - -(Diff1-Diff0)*OutdspPhase*(1.0-OutdspPhase)/2; // quadr. piece - o++; OutdspPhase+=OutStep; } + { Tap[TapPtr]=(*Inp++); i++; TapPtr=(TapPtr+1)&3; OutdspPhase-=1.0; } + else + { t=TapPtr; Diff0=(Tap[t^2]-Tap[t])/2; Ref1=Tap[t^2]; + t=(t+1)&3; Diff1=(Tap[t^2]-Tap[t])/2; Ref0=Tap[t]; + (*Out++)=Ref0*(1.0-OutdspPhase)+Ref1*OutdspPhase // linear piece + -(Diff1-Diff0)*OutdspPhase*(1.0-OutdspPhase)/2; // quadr. piece + o++; OutdspPhase+=OutStep; } } Output.Len=o; return 0; } @@ -812,7 +812,7 @@ void dspRateConvBL::Free(void) free(Tap); Tap=NULL; if(ExternShape) return; if(Shape) { for(s=0; sTapSize) { Tap=(double*)realloc(Tap,(Len+InpLen)*sizeof(double)); if(Tap==NULL) return -1; - TapSize=Len+InpLen; } + TapSize=Len+InpLen; } memcpy(Tap+Len,Inp,InpLen*sizeof(double)); for(o=i=0; i=1.0) { OutdspPhase-=1.0; i++; } - else { idx=(int)floor(OutdspPhase*ShapeNum); shape=Shape[idx]; + else { idx=(int)floor(OutdspPhase*ShapeNum); shape=Shape[idx]; for(Sum=0.0,t=0; tTapSize) { Tap=(double*)realloc(Tap,(Len+InpLen)*sizeof(double)); if(Tap==NULL) return -1; - TapSize=Len+InpLen; } + TapSize=Len+InpLen; } memcpy(Tap+Len,Inp,InpLen*sizeof(double)); for(o=i=0; i=1.0) { OutdspPhase-=1.0; i++; } - else { idx=(int)floor(OutdspPhase*ShapeNum); d=OutdspPhase*ShapeNum-idx; + else { idx=(int)floor(OutdspPhase*ShapeNum); d=OutdspPhase*ShapeNum-idx; shape=Shape[idx]; for(Sum0=0.0,t=0; t=ShapeNum) { idx=0; i++; } @@ -929,7 +929,7 @@ int dspCmpxSlideWindow::SetWindow(double (*NewWindow)(double dspPhase), double S if(ExternWindow) { Window=NULL; ExternWindow=0; } if(dspRedspAllocArray(&Window,Len)) return -1; for(idx=0; idx0) { len=dspIntmin(Len-Ptr,InpLen); - memcpy(Buff+Ptr,Inp,len*sizeof(dspCmpx)); Ptr+=len; Inp+=len; InpLen-=len; - if(Ptr>=Len) - { len=Output.Len; err=Output.EnsureSpace(len+Len); if(err) return err; - if(Window==NULL) memcpy(Output.Data,Buff,Len*sizeof(dspCmpx)); - else for(i=0; i=Len) + { len=Output.Len; err=Output.EnsureSpace(len+Len); if(err) return err; + if(Window==NULL) memcpy(Output.Data,Buff,Len*sizeof(dspCmpx)); + else for(i=0; iLen; i+=Len) { err=Output.EnsureSpace(Output.Len+Dist); if(err) return err; - Process(Input->Data+i,Output.Data+Output.Len); - Output.Len+=Dist; } + Process(Input->Data+i,Output.Data+Output.Len); + Output.Len+=Dist; } return 0; } @@ -1008,25 +1008,25 @@ void dspCmpxOverlapWindow::Process(dspCmpx *Inp, dspCmpx *Out) { int i; if(Window==NULL) { for(i=0; i=InpTapLen) InpTapPtr=0; - diff+=(InpTap[InpTapPtr]=(*Inp++)); DiffTapPtr=(DiffTapPtr+1)&3; - dspLowPass2(diff*diff,DiffInteg0[DiffTapPtr],DiffInteg[DiffTapPtr],W1,W2,W5); - if(DiffTapPtr==BitPtr) - { for(Sum=0,t=0; t<4; t++) Sum+=DiffInteg[t]; - t=DiffTapPtr; SumI = DiffInteg[t]-DiffInteg[t^2]; - t=(t+1)&3; SumQ = DiffInteg[t]-DiffInteg[t^2]; - if((Sum==0.0)||((SyncConfid=(SumI*SumI+SumQ*SumQ)/(Sum*Sum))==0.0)) - { (*BitOut++)=0; (*IbitOut++)=0; o++; continue; } - dspPhase=atan2(-SumQ,-SumI)*(4/(2*M_PI)); - dspLowPass2(dspPhase-SyncdspPhase,SyncDrift0,SyncDrift,W1,W2,W5); SyncdspPhase=dspPhase; - if(dspPhase>0.52) { step=1; SyncdspPhase-=1.0; } - else if(dspPhase<(-0.52)) { step=(-1); SyncdspPhase+=1.0; } + diff+=(InpTap[InpTapPtr]=(*Inp++)); DiffTapPtr=(DiffTapPtr+1)&3; + dspLowPass2(diff*diff,DiffInteg0[DiffTapPtr],DiffInteg[DiffTapPtr],W1,W2,W5); + if(DiffTapPtr==BitPtr) + { for(Sum=0,t=0; t<4; t++) Sum+=DiffInteg[t]; + t=DiffTapPtr; SumI = DiffInteg[t]-DiffInteg[t^2]; + t=(t+1)&3; SumQ = DiffInteg[t]-DiffInteg[t^2]; + if((Sum==0.0)||((SyncConfid=(SumI*SumI+SumQ*SumQ)/(Sum*Sum))==0.0)) + { (*BitOut++)=0; (*IbitOut++)=0; o++; continue; } + dspPhase=atan2(-SumQ,-SumI)*(4/(2*M_PI)); + dspLowPass2(dspPhase-SyncdspPhase,SyncDrift0,SyncDrift,W1,W2,W5); SyncdspPhase=dspPhase; + if(dspPhase>0.52) { step=1; SyncdspPhase-=1.0; } + else if(dspPhase<(-0.52)) { step=(-1); SyncdspPhase+=1.0; } else step=0; double Samp[5],bit,ibit,dx; int p; - p=InpTapPtr-4*IntegLen-2; if(p<0) p+=InpTapLen; - for(t=0; t<5; t++) { Samp[t]=InpTap[p++]; if(p>=InpTapLen) p=0; } - dx=dspPhase-0.5; - // bit=Samp[2]+dx*(Samp[2]-Samp[1]); // linear interpolation - bit=Samp[2]*(1.0+dx)-Samp[1]*dx // or quadratic - +((Samp[3]-Samp[1])-(Samp[2]-Samp[0]))/2*dx*(1.0+dx)/2; - ibit=Samp[4]+dx*(Samp[4]-Samp[3]); //linear interpolation is enough - (*BitOut++)=bit; (*IbitOut++)=ibit; o++; - } else if(DiffTapPtr==(BitPtr^2)) - { BitPtr=(BitPtr+step)&3; step=0; } + p=InpTapPtr-4*IntegLen-2; if(p<0) p+=InpTapLen; + for(t=0; t<5; t++) { Samp[t]=InpTap[p++]; if(p>=InpTapLen) p=0; } + dx=dspPhase-0.5; + // bit=Samp[2]+dx*(Samp[2]-Samp[1]); // linear interpolation + bit=Samp[2]*(1.0+dx)-Samp[1]*dx // or quadratic + +((Samp[3]-Samp[1])-(Samp[2]-Samp[0]))/2*dx*(1.0+dx)/2; + ibit=Samp[4]+dx*(Samp[4]-Samp[3]); //linear interpolation is enough + (*BitOut++)=bit; (*IbitOut++)=ibit; o++; + } else if(DiffTapPtr==(BitPtr^2)) + { BitPtr=(BitPtr+step)&3; step=0; } } (*OutLen)=o; return i; } @@ -1136,8 +1136,8 @@ dspBitSlicer::dspBitSlicer(int IntegBits) Tap=(double *)malloc(TapLen*sizeof(double)); for(i=0; i0; - dspLowPass2(Bit,Sum0[l],Sum[l],W1,W2,W5); - dspLowPass2(Bit*Bit,SumSq0[l],SumSq[l],W1,W2,W5); - Noise[l]=sqrt(SumSq[l]-Sum[l]*Sum[l]); - if(Noise[0]+Noise[1]<=0) OptimThres=0; - else OptimThres=(Sum[0]*Noise[1]+Sum[1]*Noise[0])/(Noise[0]+Noise[1]); - soft=Tap[TapPtr]-OptimThres; // we could do a better soft-decision - if(Bit*PrevBit<0) - { dspLowPass2(PrevIBit,dspAmplAsym0,dspAmplAsym,W1,W2,W5); - if(Bit>0) PrevIBit=(-PrevIBit); - dspLowPass2(PrevIBit,TimeAsym0,TimeAsym,W1,W2,W5); } - (*OutBits++)=soft; PrevBit=Bit; PrevIBit=IBits[i]; - Tap[TapPtr]=Bit; TapPtr++; if(TapPtr>=TapLen) TapPtr=0; + dspLowPass2(Bit,Sum0[l],Sum[l],W1,W2,W5); + dspLowPass2(Bit*Bit,SumSq0[l],SumSq[l],W1,W2,W5); + Noise[l]=sqrt(SumSq[l]-Sum[l]*Sum[l]); + if(Noise[0]+Noise[1]<=0) OptimThres=0; + else OptimThres=(Sum[0]*Noise[1]+Sum[1]*Noise[0])/(Noise[0]+Noise[1]); + soft=Tap[TapPtr]-OptimThres; // we could do a better soft-decision + if(Bit*PrevBit<0) + { dspLowPass2(PrevIBit,dspAmplAsym0,dspAmplAsym,W1,W2,W5); + if(Bit>0) PrevIBit=(-PrevIBit); + dspLowPass2(PrevIBit,TimeAsym0,TimeAsym,W1,W2,W5); } + (*OutBits++)=soft; PrevBit=Bit; PrevIBit=IBits[i]; + Tap[TapPtr]=Bit; TapPtr++; if(TapPtr>=TapLen) TapPtr=0; } return InpLen; } @@ -1179,7 +1179,7 @@ double dspBitSlicer::GetTimeAsym() // however it does not pass frames with non-complete bytes. dspHDLCdecoder::dspHDLCdecoder(int minlen, int maxlen, int diff, int invert, - int chan, int (*handler)(int, char *, int)) + int chan, int (*handler)(int, char *, int)) { MinLen=minlen; MaxLen=maxlen; RxDiff=diff; RxInvert=invert; ChanId=chan; FrameHandler=handler; Buff=(char *)malloc(MaxLen); Len=(-1); @@ -1195,21 +1195,21 @@ int dspHDLCdecoder::Process(double *Inp, int InpLen) for(i=0; i0; - bit=(lev^(PrevLev&RxDiff))^RxInvert; PrevLev=lev; - ShiftReg=(ShiftReg>>1)|(bit<<7); BitCount+=1; Flag=0; - if(bit) Count1s+=1; else - { if(Count1s>=7) Len=(-1); - else if(Count1s==6) Flag=1; - else if(Count1s==5) { ShiftReg<<=1; BitCount-=1; } - Count1s=0; } - if(Flag) - { if((Len>=MinLen)&&(BitCount==8)) (*FrameHandler)(ChanId,Buff,Len); - Len=0; BitCount=0; } - else if(Len>=0) - { if(BitCount==8) - { if(Len>1)|(bit<<7); BitCount+=1; Flag=0; + if(bit) Count1s+=1; else + { if(Count1s>=7) Len=(-1); + else if(Count1s==6) Flag=1; + else if(Count1s==5) { ShiftReg<<=1; BitCount-=1; } + Count1s=0; } + if(Flag) + { if((Len>=MinLen)&&(BitCount==8)) (*FrameHandler)(ChanId,Buff,Len); + Len=0; BitCount=0; } + else if(Len>=0) + { if(BitCount==8) + { if(Len>8)^dspAX25CRCtable[idx]; + CRC=(CRC>>8)^dspAX25CRCtable[idx]; } CRC^=0xFFFF; return CRC; } @@ -1278,7 +1278,7 @@ void dsp_r2FFT::Free(void) // a radix-2 FFT bufferfly inline void dsp_r2FFT::FFTbf(dspCmpx &x0, dspCmpx &x1, dspCmpx &W) { dspCmpx x1W; - x1W.re=x1.re*W.re+x1.im*W.im; // x1W.re=x1.re*W.re-x1.im*W.im; + x1W.re=x1.re*W.re+x1.im*W.im; // x1W.re=x1.re*W.re-x1.im*W.im; x1W.im=(-x1.re*W.im)+x1.im*W.re; // x1W.im=x1.re*W.im+x1.im*W.re; x1.re=x0.re-x1W.re; x1.im=x0.im-x1W.im; @@ -1322,8 +1322,8 @@ void dsp_r2FFT::Scramble(dspCmpx x[]) { int idx,ridx; dspCmpx tmp; for(idx=0; idxidx) - { tmp=x[idx]; x[idx]=x[ridx]; x[ridx]=tmp; - /* printf("%d <=> %d\n",idx,ridx); */ } + { tmp=x[idx]; x[idx]=x[ridx]; x[ridx]=tmp; + /* printf("%d <=> %d\n",idx,ridx); */ } } // Preset for given processing size @@ -1335,13 +1335,13 @@ int dsp_r2FFT::Preset(int size) err=dspRedspAllocArray(&Twiddle,Size); if(err) goto Error; for(idx=0; idx %6.4f => %6.4f %6.4f\n", + Twiddle[idx].re=cos(dspPhase); Twiddle[idx].im=sin(dspPhase); + /* printf("%2d => %6.4f => %6.4f %6.4f\n", idx,dspPhase,Twiddle[idx].re,Twiddle[idx].im); */ } for(ridx=0,idx=0; idx>=1,rmask<<=1) - { if(idx&mask) ridx|=rmask; } - BitRevIdx[idx]=ridx; /* printf("%04x %04x\n",idx,ridx); */ } + { if(idx&mask) ridx|=rmask; } + BitRevIdx[idx]=ridx; /* printf("%04x %04x\n",idx,ridx); */ } // free(Window); Window=NULL; WinInpScale=1.0/Size; WinOutScale=0.5; return 0; @@ -1359,9 +1359,9 @@ void dsp_r2FFT::CoreProc(dspCmpx x[]) for(Bf=0; Bf>=1, GroupHalfSize<<=1) - for(Group=0,Bf=0; GroupData; InpLen=Input->Len; Output.Len=0; while(InpLen) { for(i=len=dspIntmin(InpLen,Left); i; i--) - { SlideBuff[SlidePtr++]=(*Inp++); SlidePtr&=SizeMask; } - InpLen-=len; Left-=len; - if(Left==0) - { Slide^=1; Left=Dist; - if(Slide) - { for(t=0,i=SlidePtr; iData; InpLen=Input->Len; Output.Len=0; while(InpLen) { for(i=len=dspIntmin(InpLen,Left); i; i--) - { SlideBuff[SlidePtr++]=(*Inp++); SlidePtr&=SizeMask; } - InpLen-=len; Left-=len; - if(Left==0) - { Slide^=1; Left=Dist; - if(Slide) - { for(t=0,i=SlidePtr; iDataInterleave; videoText(); + startflag = true; } void mt63::rx_init() { - Rx->Preset((int)bandwidth, Interleave == 64 ? 1 : 0, IntegLen); + Rx->Preset( (int)bandwidth, + Interleave == 64 ? 1 : 0, + long_integral ? 32 : 16 ); set_freq(500.0 + bandwidth / 2.0); InpLevel->Preset(64.0, 0.75); escape = 0; @@ -59,7 +61,24 @@ int mt63::tx_process() double maxval = 0; rx_flush(); - + + if (startflag == true) { + startflag = false; + for (int i = 0; i < Tx->DataInterleave; i++) Tx->SendChar(0); + if (progdefaults.mt63_usetones) { + double maxval = 0.0; + for (int i = 0; i < Tx->DataInterleave / 2; i++) { + Tx->SendTune( progdefaults.mt63_twotones ); + for (int i = 0; i < Tx->Comb.Output.Len; i++) + if (fabs(Tx->Comb.Output.Data[i]) > maxval) + maxval = fabs(Tx->Comb.Output.Data[i]); + for (int i = 0; i < Tx->Comb.Output.Len; i++) + Tx->Comb.Output.Data[i] /= maxval; + ModulateXmtr((Tx->Comb.Output.Data), Tx->Comb.Output.Len); + } + } + } + c = get_tx_char(); if (c == 0x03) { stopflag = true; @@ -68,7 +87,7 @@ int mt63::tx_process() } if (c == -1 || stopflag == true) c = 0; - + if (stopflag && flush-- == 0) { stopflag = false; Tx->SendJam(); @@ -86,7 +105,7 @@ int mt63::tx_process() c = '.'; put_echo_char(c); - + if (c > 127) { c &= 127; Tx->SendChar(127); @@ -99,12 +118,12 @@ int mt63::tx_process() } Tx->SendChar(c); - for (int i = 0; i < Tx->Comb.Output.Len; i++) - if (fabs(Tx->Comb.Output.Data[i]) > maxval) - maxval = fabs(Tx->Comb.Output.Data[i]); - for (int i = 0; i < Tx->Comb.Output.Len; i++) { - Tx->Comb.Output.Data[i] /= maxval; - } + for (int i = 0; i < Tx->Comb.Output.Len; i++) + if (fabs(Tx->Comb.Output.Data[i]) > maxval) + maxval = fabs(Tx->Comb.Output.Data[i]); + for (int i = 0; i < Tx->Comb.Output.Len; i++) { + Tx->Comb.Output.Data[i] /= maxval; + } ModulateXmtr((Tx->Comb.Output.Data), Tx->Comb.Output.Len); return 0; @@ -125,21 +144,26 @@ int mt63::rx_process(const double *buf, int len) Interleave = progdefaults.mt63_interleave; restart(); } - + if (long_integral != progdefaults.mt63_rx_integration) { + long_integral = progdefaults.mt63_rx_integration; + restart(); + } + if (InpBuff->EnsureSpace(len) == -1) { fprintf(stderr, "mt63_rxprocess: buffer error\n"); return -1; } + for (i = 0; i < len; i++) InpBuff->Data[i] = buf[i]; - InpBuff->Len = len; + InpBuff->Len = len; InpLevel->Process(InpBuff); - + Rx->Process(InpBuff); snr = Rx->FEC_SNR(); - + if (progStatus.sqlonoff && snr < progStatus.sldrSquelchValue) { put_Status1(""); put_Status2(""); @@ -152,12 +176,12 @@ int mt63::rx_process(const double *buf, int len) display_metric(snr); double s2n = 10.0*log10( snr == 0 ? 0.001 : snr); - snprintf(msg1, sizeof(msg1), "s/n %2d dB", (int)(floor(s2n))); + snprintf(msg1, sizeof(msg1), "s/n %2d dB", (int)(floor(s2n))); put_Status1(msg1); snprintf(msg2, sizeof(msg2), "f/o %+4.1f Hz", Rx->TotalFreqOffset()); put_Status2(msg2, 5, STATUS_CLEAR); - + for (i = 0; i < Rx->Output.Len; i++) { c = Rx->Output.Data[i]; @@ -182,7 +206,7 @@ int mt63::rx_process(const double *buf, int len) put_rx_char(c); } flushbuffer = true; - + return 0; } @@ -193,7 +217,7 @@ void mt63::rx_flush() int dlen = 0; if (!flushbuffer) return; - + if (emptyBuff->EnsureSpace(len) == -1) { flushbuffer = false; return; @@ -233,7 +257,7 @@ void mt63::rx_flush() dlen = Rx->Output.Len; } flushbuffer = false; - + return; } @@ -250,11 +274,9 @@ void mt63::restart() fprintf(stderr, "mt63_txinit: init failed\n"); flush = Tx->DataInterleave; -// Rx->Preset( int BandWidth = 1000, -// int LongInterleave = 0, -// int Integ = 16, -// void (*Display)(double *Spectra, int Len) = NULL); - err = Rx->Preset((int)bandwidth, Interleave == 64 ? 1 : 0, IntegLen); + err = Rx->Preset( (int)bandwidth, + Interleave == 64 ? 1 : 0, + long_integral ? 32 : 16); if (err) fprintf(stderr, "mt63_rxinit: init failed\n"); InpLevel->Preset(64.0, 0.75); @@ -282,6 +304,7 @@ mt63::mt63 (trx_mode mt63_mode) : modem() break; } Interleave = progdefaults.mt63_interleave; + long_integral = progdefaults.mt63_rx_integration; Tx = new MT63tx; Rx = new MT63rx; diff --git a/src/mt63/mt63base.cxx b/src/mt63/mt63base.cxx index 41403cdf..25825528 100644 --- a/src/mt63/mt63base.cxx +++ b/src/mt63/mt63base.cxx @@ -1,8 +1,8 @@ /* * mt63base.cc -- MT63 transmitter and receiver in C++ for LINUX - * + * * Copyright (c) 2007, 2008 Dave Freese, W1HKJ - * + * * base class for use by fldigi * modified from original * excluded CW_ID which is a part of the base modem class for fldigi @@ -52,22 +52,22 @@ // 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); + free(dspPhaseCorr); dspPhaseCorr = NULL; Encoder.Free(); FFT.Free(); @@ -77,10 +77,10 @@ void MT63tx::Free(void) } int MT63tx::Preset(int BandWidth, int LongInterleave) -{ +{ int i, p, step, incr, mask; - switch(BandWidth) { + switch(BandWidth) { case 500: FirstDataCarr = 256; AliasShapeI = Alias_k5_I; @@ -102,7 +102,7 @@ int MT63tx::Preset(int BandWidth, int LongInterleave) AliasFilterLen = Alias_2k_Len; DecimateRatio = 2; break; - default: + default: return -1; } @@ -115,13 +115,13 @@ int MT63tx::Preset(int BandWidth, int LongInterleave) CarrMarkCode = 0x16918BBEL; CarrMarkdspAmpl = 0; // WindowLen/32; - if (LongInterleave) { - DataInterleave = 64; - InterleavePattern = LongIntlvPatt; + if (LongInterleave) { + DataInterleave = 64; + InterleavePattern = LongIntlvPatt; } - else { - DataInterleave = 32; - InterleavePattern = ShortIntlvPatt; + else { + DataInterleave = 32; + InterleavePattern = ShortIntlvPatt; } if (dspRedspAllocArray(&TxVect, DataCarriers)) @@ -147,27 +147,27 @@ int MT63tx::Preset(int BandWidth, int LongInterleave) // Here we only compute indexes to the FFT twiddle factors // so the actual vector is FFT.Twiddle[TxVect[i]] - for (step = 0, incr = 1, p = 0, i = 0; i < DataCarriers; i++) { - TxVect[i] = p; - step += incr; - p = (p + step) & mask; + for (step = 0, incr = 1, p = 0, i = 0; i < DataCarriers; i++) { + TxVect[i] = p; + step += incr; + p = (p + step) & mask; } // compute dspPhase correction between successive FFTs separated by SymbolSepar // Like above we compute indexes to the FFT.Twiddle[] incr = (SymbolSepar * DataCarrSepar) & mask; - for (p = (SymbolSepar * FirstDataCarr) & mask, i = 0; i < DataCarriers; i++) { - dspPhaseCorr[i] = p; + for (p = (SymbolSepar * FirstDataCarr) & mask, i = 0; i < DataCarriers; i++) { + dspPhaseCorr[i] = p; p = (p + incr) & mask; } return 0; -Error: - Free(); +Error: + Free(); return -1; } -int MT63tx::SendTune(void) +int MT63tx::SendTune(bool twotones) { int i, c, r, mask; double dspAmpl; @@ -178,7 +178,7 @@ int MT63tx::SendTune(void) for (i = 0; i < DataCarriers; i++) TxVect[i] = (TxVect[i] + dspPhaseCorr[i]) & mask; - for (i = 0; i < 2 * WindowLen; i++) + for (i = 0; i < 2 * WindowLen; i++) WindowBuff.Data[i].im = WindowBuff.Data[i].re = 0.0; i = 0; @@ -187,18 +187,19 @@ int MT63tx::SendTune(void) WindowBuff.Data[r].re = dspAmpl * FFT.Twiddle[TxVect[i]].re; WindowBuff.Data[r].im = (-dspAmpl) * FFT.Twiddle[TxVect[i]].im; - i = DataCarriers - 1; - c = FirstDataCarr + i * DataCarrSepar; - c &= mask; - r = WindowLen + FFT.BitRevIdx[c]; - WindowBuff.Data[r].re = dspAmpl * FFT.Twiddle[TxVect[i]].re; - WindowBuff.Data[r].im = (-dspAmpl) * FFT.Twiddle[TxVect[i]].im; - -// inverse FFT: WindowBuff is already scrmabled + if (twotones) { + i = DataCarriers - 1; + c = FirstDataCarr + i * DataCarrSepar; + c &= mask; + r = WindowLen + FFT.BitRevIdx[c]; + WindowBuff.Data[r].re = dspAmpl * FFT.Twiddle[TxVect[i]].re; + WindowBuff.Data[r].im = (-dspAmpl) * FFT.Twiddle[TxVect[i]].im; + } +// inverse FFT: WindowBuff is already scrambled FFT.CoreProc(WindowBuff.Data); FFT.CoreProc(WindowBuff.Data + WindowLen); // negate the imaginary part for the IFFT - for (i = 0; i < 2 * WindowLen; i++) + for (i = 0; i < 2 * WindowLen; i++) WindowBuff.Data[i].im *= (-1.0); Window.Process(&WindowBuff); @@ -237,7 +238,7 @@ int MT63tx::SendChar(char ch) } int MT63tx::SendJam(void) -{ +{ int i,mask,left,right; mask = FFT.Size-1; @@ -245,7 +246,7 @@ int MT63tx::SendJam(void) right = 3 * (FFT.Size / 4); for (i = 0; i < DataCarriers; i++) { if (rand() & 0x100) // turn left 90 degrees - TxVect[i] = (TxVect[i] + dspPhaseCorr[i] + left) & mask; + TxVect[i] = (TxVect[i] + dspPhaseCorr[i] + left) & mask; else // turn right 90 degrees TxVect[i] = (TxVect[i] + dspPhaseCorr[i] + right) & mask; } @@ -255,33 +256,33 @@ int MT63tx::SendJam(void) } int MT63tx::ProcessTxVect(void) -{ +{ int i, c, r, mask; mask = FFT.Size - 1; - for (i = 0; i < 2 * WindowLen; i++) + for (i = 0; i < 2 * WindowLen; i++) WindowBuff.Data[i].im = WindowBuff.Data[i].re = 0.0; - for ( c = FirstDataCarr, i = 0; - i < DataCarriers; - i += 2, c = (c + 2 * DataCarrSepar) & mask) { + for ( c = FirstDataCarr, i = 0; + i < DataCarriers; + i += 2, c = (c + 2 * DataCarrSepar) & mask) { r = FFT.BitRevIdx[c]; WindowBuff.Data[r].re = TxdspAmpl*FFT.Twiddle[TxVect[i]].re; - WindowBuff.Data[r].im = (-TxdspAmpl)*FFT.Twiddle[TxVect[i]].im; + WindowBuff.Data[r].im = (-TxdspAmpl)*FFT.Twiddle[TxVect[i]].im; } - for ( c = FirstDataCarr + DataCarrSepar, i = 1; - i < DataCarriers; + for ( c = FirstDataCarr + DataCarrSepar, i = 1; + i < DataCarriers; i += 2, c = (c + 2 * DataCarrSepar) & mask) { r = WindowLen + FFT.BitRevIdx[c]; WindowBuff.Data[r].re = TxdspAmpl * FFT.Twiddle[TxVect[i]].re; - WindowBuff.Data[r].im = (-TxdspAmpl) * FFT.Twiddle[TxVect[i]].im; + WindowBuff.Data[r].im = (-TxdspAmpl) * FFT.Twiddle[TxVect[i]].im; } FFT.CoreProc(WindowBuff.Data); FFT.CoreProc(WindowBuff.Data + WindowLen); // negate the imaginary part for the IFFT - for (i = 0; i < 2 * WindowLen; i++) + for (i = 0; i < 2 * WindowLen; i++) WindowBuff.Data[i].im *= (-1.0); // we could be faster by avoiding Scramble and using the FFT.RevIdx[] @@ -294,7 +295,7 @@ int MT63tx::ProcessTxVect(void) } int MT63tx::SendSilence(void) -{ +{ Window.ProcessSilence(2); Comb.Process(&Window.Output); return 0; @@ -304,7 +305,7 @@ int MT63tx::SendSilence(void) // Character encoder and block interleave for the MT63 modem MT63encoder::MT63encoder() -{ +{ IntlvPipe = NULL; WalshBuff = NULL; Output = NULL; @@ -320,12 +321,12 @@ MT63encoder::~MT63encoder() } void MT63encoder::Free() -{ +{ free(IntlvPipe); free(WalshBuff); free(Output); free(IntlvPatt); - IntlvPipe = NULL; + IntlvPipe = NULL; WalshBuff = NULL; Output = NULL; IntlvPatt = NULL; @@ -341,10 +342,10 @@ int MT63encoder::Preset(int Carriers, int Intlv, int *Pattern, int PreFill) IntlvSize = IntlvLen * DataCarriers; if (IntlvLen) { if (dspRedspAllocArray(&IntlvPipe, IntlvSize)) goto Error; - if (PreFill) - for (i = 0; i < IntlvSize; i++) + if (PreFill) + for (i = 0; i < IntlvSize; i++) IntlvPipe[i] = rand() & 1; - else + else dspClearArray(IntlvPipe,IntlvSize); if (dspRedspAllocArray(&IntlvPatt, DataCarriers)) goto Error; IntlvPtr = 0; @@ -360,21 +361,21 @@ int MT63encoder::Preset(int Carriers, int Intlv, int *Pattern, int PreFill) } return 0; -Error: +Error: Free(); return -1; } int MT63encoder::Process(char code) // encode an ASCII character "code" -{ +{ int i, k; code &= CodeMask; - for (i = 0; i < DataCarriers; i++) + for (i = 0; i < DataCarriers; i++) WalshBuff[i] = 0; - if (code < DataCarriers) + if (code < DataCarriers) WalshBuff[(int)code] = 1.0; else WalshBuff[code-DataCarriers] = (-1.0); - + dspWalshInvTrans(WalshBuff, DataCarriers); if (IntlvLen) { @@ -382,7 +383,7 @@ int MT63encoder::Process(char code) // encode an ASCII character "code" IntlvPipe[IntlvPtr + i] = (WalshBuff[i] < 0.0); for (i = 0; i < DataCarriers; i++) { k = IntlvPtr + IntlvPatt[i]; - if (k >= IntlvSize) + if (k >= IntlvSize) k -= IntlvSize; Output[i] = IntlvPipe[k+i]; } @@ -390,7 +391,7 @@ int MT63encoder::Process(char code) // encode an ASCII character "code" if (IntlvPtr >= IntlvSize) IntlvPtr -= IntlvSize; } else - for (i = 0; i < DataCarriers; i++) + for (i = 0; i < DataCarriers; i++) Output[i] = (WalshBuff[i] < 0.0); return 0; @@ -402,7 +403,7 @@ int MT63encoder::Process(char code) // encode an ASCII character "code" // MT63 decoder and deinterleaver MT63decoder::MT63decoder() -{ +{ IntlvPipe = NULL; IntlvPatt = NULL; WalshBuff = NULL; @@ -438,11 +439,11 @@ void MT63decoder::Free() } int MT63decoder::Preset(int Carriers, int Intlv, int *Pattern, int Margin, int Integ) -{ +{ int i,p; if (!dspPowerOf2(Carriers)) goto Error; - DataCarriers = Carriers; + DataCarriers = Carriers; ScanLen = 2 * Margin + 1; ScanSize = DataCarriers + 2 * Margin; @@ -458,7 +459,7 @@ int MT63decoder::Preset(int Carriers, int Intlv, int *Pattern, int Margin, int I for (p = 0, i = 0; i < DataCarriers; i++) { IntlvPatt[i] = p * ScanSize; // printf(" %2d",p); p += Pattern[i]; - if (p >= IntlvLen) p -= IntlvLen; + if (p >= IntlvLen) p -= IntlvLen; } // printf("\n"); @@ -497,13 +498,13 @@ int MT63decoder::Process(double *data) for (i = 0; i < DataCarriers; i++) { k = IntlvPtr - ScanSize - IntlvPatt[i]; if (k < 0) k += IntlvSize; - if ((s & 1) && (i & 1)) { - k += ScanSize; + if ((s & 1) && (i & 1)) { + k += ScanSize; if (k >= IntlvSize) k-=IntlvSize; } - WalshBuff[i] = IntlvPipe[k + s + i]; + WalshBuff[i] = IntlvPipe[k + s + i]; // printf(" %4d",k/ScanSize); - } + } // printf("\n"); dspWalshTrans(WalshBuff, DataCarriers); Min = dspFindMin(WalshBuff, DataCarriers, MinPos); @@ -518,7 +519,7 @@ int MT63decoder::Process(double *data) WalshBuff[MinPos] = 0.0; } Noise = dspRMS(WalshBuff, DataCarriers); - if (Noise > 0.0) + if (Noise > 0.0) SNR = Sig/Noise; else SNR = 0.0; dspLowPass2(SNR, DecodeSnrMid[s], DecodeSnrOut[s], W1, W2, W5); @@ -529,7 +530,7 @@ int MT63decoder::Process(double *data) } IntlvPtr += ScanSize; if (IntlvPtr >= IntlvSize) IntlvPtr = 0; - DecodePtr += ScanLen; + DecodePtr += ScanLen; if (DecodePtr >= DecodeSize) DecodePtr = 0; Max = dspFindMax(DecodeSnrOut, ScanLen, MaxPos); Output = DecodePipe[DecodePtr + MaxPos]; @@ -547,13 +548,13 @@ int MT63decoder::Process(double *data) // MT63 receiver code MT63rx::MT63rx() -{ +{ int s; FFTbuff = NULL; FFTbuff2 = NULL; - for (s = 0; s < 4; s++) + for (s = 0; s < 4; s++) SyncPipe[s] = NULL; SyncPhCorr = NULL; for (s = 0; s < 4; s++) { @@ -588,16 +589,16 @@ MT63rx::MT63rx() } MT63rx::~MT63rx() -{ +{ int s; free(FFTbuff); free(FFTbuff2); - for (s = 0; s < 4; s++) + for (s = 0; s < 4; s++) free(SyncPipe[s]); free(SyncPhCorr); - for (s = 0; s < 4; s++) { + for (s = 0; s < 4; s++) { free(CorrelMid[s]); free(CorrelOut[s]); } @@ -631,7 +632,7 @@ MT63rx::~MT63rx() void MT63rx::Free(void) { int s; - FFT.Free(); + FFT.Free(); InpSplit.Free(); TestOfs.Free(); ProcLine.Free(); @@ -641,11 +642,11 @@ void MT63rx::Free(void) free(FFTbuff2); FFTbuff2 = NULL; - for (s = 0; s < 4; s++) { - free(SyncPipe[s]); + for (s = 0; s < 4; s++) { + free(SyncPipe[s]); SyncPipe[s] = NULL; } - free(SyncPhCorr); + free(SyncPhCorr); SyncPhCorr = NULL; for (s = 0; s < 4; s++) { free(CorrelMid[s]); @@ -700,13 +701,13 @@ void MT63rx::Free(void) Decoder.Free(); - free(SpectradspPower); + free(SpectradspPower); SpectradspPower = NULL; } int MT63rx::Preset(int BandWidth, int LongInterleave, int Integ, void (*Display)(double *Spectra, int Len)) -{ +{ int err,s,i,c; switch(BandWidth) { @@ -809,9 +810,9 @@ int MT63rx::Preset(int BandWidth, int LongInterleave, int Integ, SyncPtr = 0; if (dspRedspAllocArray(&SyncPhCorr, ScanLen)) goto Error; - + for (c = (ScanFirst * SymbolSepar) & WindowLenMask, i = 0; i < ScanLen; i++) { - SyncPhCorr[i].re = FFT.Twiddle[c].re * FFT.Twiddle[c].re - + SyncPhCorr[i].re = FFT.Twiddle[c].re * FFT.Twiddle[c].re - FFT.Twiddle[c].im * FFT.Twiddle[c].im; SyncPhCorr[i].im = 2 * FFT.Twiddle[c].re * FFT.Twiddle[c].im; c = (c + SymbolSepar) & WindowLenMask; @@ -915,7 +916,7 @@ int MT63rx::Preset(int BandWidth, int LongInterleave, int Integ, if (dspRedspAllocArray(&DatadspPhase, DataScanLen)) goto Error; if (dspRedspAllocArray(&DatadspPhase2, DataScanLen)) goto Error; - err = Decoder.Preset(DataCarriers, DataInterleave, + err = Decoder.Preset(DataCarriers, DataInterleave, InterleavePattern, DataScanMargin, IntegLen); if (err) goto Error; @@ -935,7 +936,7 @@ Error: } int MT63rx::Process(double_buff *Input) -{ +{ int s1,s2; // TestOfs.Omega+=(-0.005*(2.0*M_PI/512)); // simulate frequency drift @@ -955,7 +956,7 @@ int MT63rx::Process(double_buff *Input) // 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 + + 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); @@ -975,7 +976,7 @@ 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; @@ -1027,8 +1028,8 @@ void MT63rx::SyncProcess(dspCmpx *Slice) FFT.CoreProc(FFTbuff); if (SpectraDisplay) { - for ( i = 0, - j = FirstDataCarr + (DataCarriers / 2) * DataCarrSepar - + 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 { + } else { dI = dQ = 0.0; } dspLowPass2(P, dspPowerMid[i], dspPowerOut[i], W1p, W2p, W5p); - pI = PrevSlice[i].re * SyncPhCorr[i].re - + 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; @@ -1070,8 +1071,8 @@ void MT63rx::SyncProcess(dspCmpx *Slice) 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 = CorrelOut[s][i].im / dspPowerOut[i]; + } else CorrelNorm[s][i].im = CorrelNorm[s][i].re = 0.0; } } @@ -1087,11 +1088,11 @@ void MT63rx::SyncProcess(dspCmpx *Slice) CorrelNorm[s][i].im=CorrelOut[s][i].im/P; } } else { for (s=0; s 1) - j -= (k - 1) * DataCarrSepar; - else 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]) + + 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); @@ -1158,13 +1159,13 @@ void MT63rx::SyncProcess(dspCmpx *Slice) F0 = i + dspPhase(I, Q) / (2.0 * M_PI) * A - FreqOfs; Fl = F0 - A; Fu = F0 + A; - if (fabs(Fl) < fabs(F0)) + if (fabs(Fl) < fabs(F0)) FreqOfs += (fabs(Fu) < fabs(Fl)) ? Fu : Fl; - else + else FreqOfs += (fabs(Fu) < fabs(F0)) ? Fu : F0; // printf(" => (%5.2f,%5.2f,%5.2f) => %5.2f",Fl,F0,Fu,FreqOfs); - } else { + } else { SymbTime.re = SymbTime.im = 0.0; SymbConf = 0.0; SymbShift = 0.0; @@ -1211,16 +1212,16 @@ void MT63rx::SyncProcess(dspCmpx *Slice) F0 = FreqOfs - FreqPipe[TrackPipePtr]; Fl = F0 - A; Fu = F0 + A; - if (fabs(Fl) < fabs(F0)) + if (fabs(Fl) < fabs(F0)) FreqOfs += (fabs(Fu) < fabs(Fl)) ? A : -A; - else + else FreqOfs += (fabs(Fu) < fabs(F0)) ? A : 0.0; } // printf(" => [%+5.2f,%+5.2f], %5.2f",SymbTime.re,SymbTime.im,FreqOfs); TrackPipePtr += 1; - if (TrackPipePtr >= TrackPipeLen) + if (TrackPipePtr >= TrackPipeLen) TrackPipePtr -= TrackPipeLen; SymbPipe[TrackPipePtr] = SymbTime; // put SymbTime and FreqOfs into pipes FreqPipe[TrackPipePtr] = FreqOfs; // for averaging @@ -1251,7 +1252,7 @@ void MT63rx::SyncProcess(dspCmpx *Slice) SyncFreqOfs = AverFreq; if (SymbConf > 0.0) { SymbShift = dspPhase(AverSymb) / (2 * M_PI) * SymbolSepar; - if (SymbShift < 0.0) + if (SymbShift < 0.0) SymbShift += SymbolSepar; SymbPtr = (int)floor((dspPhase(AverSymb) / (2 * M_PI)) * SymbolDiv); if (SymbPtr < 0) @@ -1353,12 +1354,12 @@ void MT63rx::DataProcess(dspCmpx *EvenSlice, dspCmpx *OddSlice, double FreqOfs, // printf("%3d,%2d: [%8.5f,%8.5f] / %8.5f\n", // c,i,FFTbuff[c].re,FFTbuff[c].im,DataPwrOut[i]); dspLowPass2( dspPower(FFTbuff[c]), - DataPwrMid[i], + DataPwrMid[i], DataPwrOut[i], dW1, dW2, dW5); RefDataSlice[i++] = FFTbuff[c]; c = (c + DataCarrSepar) & WindowLenMask; p = (p + incr) & WindowLenMask; - + Phas = FFT.Twiddle[p]; CdspcmpxMultAxB(Dtmp, RefDataSlice[i], Phas); CdspcmpxMultAxBs(DataVect[i], FFTbuff2[c], Dtmp); @@ -1374,7 +1375,7 @@ void MT63rx::DataProcess(dspCmpx *EvenSlice, dspCmpx *OddSlice, double FreqOfs, P = (-TimeDist * 2 * M_PI * FreqOfs) / WindowLen; Freq.re = cos(P); - Freq.im = sin(P); + Freq.im = sin(P); for (i = 0; i < DataScanLen; i++) { CdspcmpxMultAxB(Ftmp, DataVect[i], Freq); // dspLowPass2(dspPower(Ftmp),DataPwrMid[i],DataPwrOut[i],dW1,dW2,dW5); @@ -1391,12 +1392,12 @@ void MT63rx::DataProcess(dspCmpx *EvenSlice, dspCmpx *OddSlice, double FreqOfs, 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)) + if (P > 1.0) + P = 1.0; + else if (P < (-1.0)) P = (-1.0); DatadspPhase[i] = P; - } else + } else DatadspPhase[i] = 0.0; } Decoder.Process(DatadspPhase); @@ -1429,7 +1430,7 @@ void MT63rx::DataProcess(dspCmpx *EvenSlice, dspCmpx *OddSlice, double FreqOfs, */ } -int MT63rx::SYNC_LockStatus(void) { +int MT63rx::SYNC_LockStatus(void) { return SyncLocked; } @@ -1458,7 +1459,7 @@ int MT63rx::FEC_CarrOffset(void) { } double MT63rx::TotalFreqOffset(void) { - return ( SyncFreqOfs + DataCarrSepar * Decoder.CarrOfs) * + return ( SyncFreqOfs + DataCarrSepar * Decoder.CarrOfs) * (8000.0 / DecimateRatio) / WindowLen; }