kopia lustrzana https://github.com/jamescoxon/dl-fldigi
				
				
				
			High Speed / Multi-Carrier Modems
* This commit contributed to by:
    - John Douyere <vk2eta@gmail.com>
    - Dave Freese <w1hkj@w1hkj.com>
    - John Phelps <kl4yfd@gmail.com>
    - Andrej Lajovic <s57ln@hamradio.si>
  * New high speed and multi carrier modems
    - psk, pskr
    - DominoEX
    - Thor
  * Added separate modem initialization for
    Olivia tone / bandwidth pairs:
    - 4/250, 8/250
    - 4/500, 8/500, 16/500
    - 8/1000, 16/1000, 32/1000
    - 64/2000
  * RSID changes
    - Added secondary RsID code set
    - RsID code 263 enables detection of the secondary
      RsID code burst.
  * MFSK UTF-8 tx
    - corrected transmit of two-byte UTF-8 characters
  * PSK-UTF-8 tx
    - corrected transmit of two-byte UTF-8 characters
  * Changed PSK multicarrier bandwidth markers to show full
    extent of signal in the waterfall.
  * THOR modem updates
    - Added Thor high speed modes
      25x4, 50, 50x2, 100 Baud, all < 1800 Hz bandwidth
    - IFK+ Softdecode function for THOR
      dynamically detects and suppresses CWI
      Rx printing is disabled when "File IO only" is selected for
      soundcard.  Decoder uses puncture in this condition.
    - THOR FEC confidence indicator
      Uses the actual path-metrics from the Viterbi decoder.
      Displays next to the S/N in the main dialog.
			
			
				pull/1/head
			
			
		
							rodzic
							
								
									ce1d5c2104
								
							
						
					
					
						commit
						14329e533d
					
				
							
								
								
									
										50
									
								
								ChangeLog
								
								
								
								
							
							
						
						
									
										50
									
								
								ChangeLog
								
								
								
								
							| 
						 | 
				
			
			@ -1,3 +1,53 @@
 | 
			
		|||
2013-01-10  David Freese  <w1hkj@w1hkj.com>
 | 
			
		||||
 | 
			
		||||
	d946848: High Speed / Multi-Carrier Modems
 | 
			
		||||
	ce1d5c2: User configurable items
 | 
			
		||||
 | 
			
		||||
2012-12-26  Makoto Fujiwara  <makoto@ki.nu>
 | 
			
		||||
 | 
			
		||||
	2a22c31: NetBSD compile error
 | 
			
		||||
 | 
			
		||||
2012-12-15  David Freese  <w1hkj@w1hkj.com>
 | 
			
		||||
 | 
			
		||||
	6fe5fee: Dup Cty lookup
 | 
			
		||||
	2a3d1ae: Get RX buffer
 | 
			
		||||
	2004343: Util.h mod
 | 
			
		||||
	1884f2f: Capture Alt-F4
 | 
			
		||||
	2719b0f: Macros LOG LNW EXEC
 | 
			
		||||
 | 
			
		||||
2012-12-03  Remi Chateauneu  <remi.chateauneu@gmail.com>
 | 
			
		||||
 | 
			
		||||
	836c5c3: Progress widget
 | 
			
		||||
 | 
			
		||||
2012-11-25  David Freese  <w1hkj@w1hkj.com>
 | 
			
		||||
 | 
			
		||||
	2252cab: ARQ Socket
 | 
			
		||||
	5b9e09f: NBEMS modes
 | 
			
		||||
	cb82ed8: Escape aborts
 | 
			
		||||
 | 
			
		||||
2012-10-31  John Phelps  <kl4yfd@gmail.com>
 | 
			
		||||
 | 
			
		||||
	51db482: Allow xmit of EOT character
 | 
			
		||||
 | 
			
		||||
2012-10-29  Andrej Lajovic  <s57ln@hamradio.si>
 | 
			
		||||
 | 
			
		||||
	87afa66: UTF-8 overhaul
 | 
			
		||||
 | 
			
		||||
2012-10-26  David Freese  <w1hkj@w1hkj.com>
 | 
			
		||||
 | 
			
		||||
	600db9e: Thumbdrive
 | 
			
		||||
	0fa9396: TLF arq
 | 
			
		||||
	5ac5065: Logbook Dialogs
 | 
			
		||||
	c17590e: ARQ rx/tx
 | 
			
		||||
	9006fde: View browser
 | 
			
		||||
	2a0f09d: FLAMP interface fix
 | 
			
		||||
 | 
			
		||||
2012-10-04  Andrej Lajovic  <s57ln@hamradio.si>
 | 
			
		||||
 | 
			
		||||
	7bdf035: UTF-8 wide characters
 | 
			
		||||
	6706da0: flarq bug fix
 | 
			
		||||
	1d7f8c2: Add_tx_char
 | 
			
		||||
 | 
			
		||||
2012-10-03  David Freese  <w1hkj@w1hkj.com>
 | 
			
		||||
 | 
			
		||||
	d43f564: UI update
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -597,6 +597,7 @@ EXTRA_fldigi_SOURCES += \
 | 
			
		|||
	mt63/symbol.dat \
 | 
			
		||||
	mt63/alias_k5.dat \
 | 
			
		||||
	mt63/mt63intl.dat \
 | 
			
		||||
	rsid/rsid_defs.cxx \
 | 
			
		||||
	trx/tune.cxx \
 | 
			
		||||
	dialogs/guide.cxx \
 | 
			
		||||
	widgets/Fl_Text_Buffer_mod_1_1.cxx \
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1941,20 +1941,6 @@ resetTHOR();
 | 
			
		|||
progdefaults.changed = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Fl_Value_Slider2 *valThorCWI=(Fl_Value_Slider2 *)0;
 | 
			
		||||
 | 
			
		||||
static void cb_valThorCWI(Fl_Value_Slider2* o, void*) {
 | 
			
		||||
  progdefaults.ThorCWI = o->value();
 | 
			
		||||
progdefaults.changed = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Fl_Counter2 *valTHOR_PATHS=(Fl_Counter2 *)0;
 | 
			
		||||
 | 
			
		||||
static void cb_valTHOR_PATHS(Fl_Counter2* o, void*) {
 | 
			
		||||
  progdefaults.THOR_PATHS = (int)o->value();
 | 
			
		||||
progdefaults.changed = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Fl_Check_Button *valTHOR_PREAMBLE=(Fl_Check_Button *)0;
 | 
			
		||||
 | 
			
		||||
static void cb_valTHOR_PREAMBLE(Fl_Check_Button* o, void*) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1976,6 +1962,20 @@ static void cb_valTHOR_SOFTBITS(Fl_Check_Button* o, void*) {
 | 
			
		|||
progdefaults.changed = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Fl_Value_Slider2 *valThorCWI=(Fl_Value_Slider2 *)0;
 | 
			
		||||
 | 
			
		||||
static void cb_valThorCWI(Fl_Value_Slider2* o, void*) {
 | 
			
		||||
  progdefaults.ThorCWI = o->value();
 | 
			
		||||
progdefaults.changed = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Fl_Counter2 *valTHOR_PATHS=(Fl_Counter2 *)0;
 | 
			
		||||
 | 
			
		||||
static void cb_valTHOR_PATHS(Fl_Counter2* o, void*) {
 | 
			
		||||
  progdefaults.THOR_PATHS = (int)o->value();
 | 
			
		||||
progdefaults.changed = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Fl_Group *tabPacket=(Fl_Group *)0;
 | 
			
		||||
 | 
			
		||||
Fl_Choice *selPacket_Baud=(Fl_Choice *)0;
 | 
			
		||||
| 
						 | 
				
			
			@ -3165,6 +3165,13 @@ static void cb_sldrRSIDsquelch(Fl_Value_Slider2* o, void*) {
 | 
			
		|||
progdefaults.changed = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Fl_Value_Slider2 *sldrRSIDresolution=(Fl_Value_Slider2 *)0;
 | 
			
		||||
 | 
			
		||||
static void cb_sldrRSIDresolution(Fl_Value_Slider2* o, void*) {
 | 
			
		||||
  progdefaults.rsid_resolution = (int)o->value();
 | 
			
		||||
progdefaults.changed = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Fl_Button *bRSIDTxModes=(Fl_Button *)0;
 | 
			
		||||
 | 
			
		||||
static void cb_bRSIDTxModes(Fl_Button* o, void*) {
 | 
			
		||||
| 
						 | 
				
			
			@ -3720,13 +3727,14 @@ Fl_Double_Window* ConfigureDialog() {
 | 
			
		|||
    o->selection_color((Fl_Color)51);
 | 
			
		||||
    o->labelsize(18);
 | 
			
		||||
    o->align(Fl_Align(FL_ALIGN_CLIP|FL_ALIGN_INSIDE));
 | 
			
		||||
    { tabsConfigure = new Fl_Tabs(0, 0, 598, 370);
 | 
			
		||||
    { tabsConfigure = new Fl_Tabs(0, 0, 599, 370);
 | 
			
		||||
      tabsConfigure->color(FL_LIGHT1);
 | 
			
		||||
      tabsConfigure->selection_color(FL_LIGHT1);
 | 
			
		||||
      { tabOperator = new Fl_Group(0, 25, 598, 345, _("Operator"));
 | 
			
		||||
      { tabOperator = new Fl_Group(1, 25, 598, 343, _("Operator"));
 | 
			
		||||
        tabOperator->tooltip(_("Operator information"));
 | 
			
		||||
        tabOperator->callback((Fl_Callback*)cb_tabOperator);
 | 
			
		||||
        tabOperator->when(FL_WHEN_CHANGED);
 | 
			
		||||
        tabOperator->hide();
 | 
			
		||||
        { Fl_Group* o = new Fl_Group(4, 35, 592, 165, _("Station"));
 | 
			
		||||
          o->box(FL_ENGRAVED_FRAME);
 | 
			
		||||
          o->align(Fl_Align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE));
 | 
			
		||||
| 
						 | 
				
			
			@ -3833,11 +3841,12 @@ Fl_Double_Window* ConfigureDialog() {
 | 
			
		|||
        } // Fl_Group* grpNoise
 | 
			
		||||
        tabOperator->end();
 | 
			
		||||
      } // Fl_Group* tabOperator
 | 
			
		||||
      { tabUI = new Fl_Group(0, 25, 598, 345, _("UI"));
 | 
			
		||||
      { tabUI = new Fl_Group(1, 25, 598, 345, _("UI"));
 | 
			
		||||
        tabUI->hide();
 | 
			
		||||
        { tabsUI = new Fl_Tabs(2, 25, 596, 345);
 | 
			
		||||
          tabsUI->selection_color(FL_LIGHT1);
 | 
			
		||||
          { tabBrowser = new Fl_Group(0, 50, 598, 320, _("Browser"));
 | 
			
		||||
          { tabBrowser = new Fl_Group(2, 50, 596, 316, _("Browser"));
 | 
			
		||||
            tabBrowser->hide();
 | 
			
		||||
            { Fl_Group* o = new Fl_Group(6, 59, 588, 300);
 | 
			
		||||
              o->box(FL_ENGRAVED_FRAME);
 | 
			
		||||
              { Fl_Spinner2* o = cntChannels = new Fl_Spinner2(18, 69, 50, 24, _("Channels, first channel starts at waterfall lower limit"));
 | 
			
		||||
| 
						 | 
				
			
			@ -3949,7 +3958,7 @@ Fl_Double_Window* ConfigureDialog() {
 | 
			
		|||
            } // Fl_Group* o
 | 
			
		||||
            tabBrowser->end();
 | 
			
		||||
          } // Fl_Group* tabBrowser
 | 
			
		||||
          { tabContest = new Fl_Group(0, 50, 598, 320, _("Contest"));
 | 
			
		||||
          { tabContest = new Fl_Group(2, 50, 596, 316, _("Contest"));
 | 
			
		||||
            tabContest->hide();
 | 
			
		||||
            { Fl_Group* o = new Fl_Group(8, 60, 584, 80, _("Exchanges"));
 | 
			
		||||
              o->box(FL_ENGRAVED_FRAME);
 | 
			
		||||
| 
						 | 
				
			
			@ -4102,7 +4111,7 @@ Fl_Double_Window* ConfigureDialog() {
 | 
			
		|||
            } // Fl_Group* o
 | 
			
		||||
            tabContest->end();
 | 
			
		||||
          } // Fl_Group* tabContest
 | 
			
		||||
          { tabUserInterface = new Fl_Group(0, 50, 598, 320, _("General"));
 | 
			
		||||
          { tabUserInterface = new Fl_Group(2, 50, 596, 316, _("General"));
 | 
			
		||||
            tabUserInterface->hide();
 | 
			
		||||
            { Fl_Group* o = new Fl_Group(6, 55, 586, 76);
 | 
			
		||||
              o->box(FL_ENGRAVED_FRAME);
 | 
			
		||||
| 
						 | 
				
			
			@ -4183,7 +4192,7 @@ ndow decoration close button pressed."));
 | 
			
		|||
              } // Fl_Check_Button* btn2_confirm_exit
 | 
			
		||||
              o->end();
 | 
			
		||||
            } // Fl_Group* o
 | 
			
		||||
            { Fl_Group* o = new Fl_Group(6, 315, 586, 50, _("Check for updates"));
 | 
			
		||||
            { Fl_Group* o = new Fl_Group(6, 315, 586, 48, _("Check for updates"));
 | 
			
		||||
              o->box(FL_ENGRAVED_FRAME);
 | 
			
		||||
              o->align(Fl_Align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE));
 | 
			
		||||
              { Fl_Check_Button* o = btn_check_for_updates = new Fl_Check_Button(47, 336, 383, 18, _("Check for updates when starting program"));
 | 
			
		||||
| 
						 | 
				
			
			@ -4195,7 +4204,7 @@ ndow decoration close button pressed."));
 | 
			
		|||
            } // Fl_Group* o
 | 
			
		||||
            tabUserInterface->end();
 | 
			
		||||
          } // Fl_Group* tabUserInterface
 | 
			
		||||
          { tabLogServer = new Fl_Group(0, 50, 598, 320, _("Logging"));
 | 
			
		||||
          { tabLogServer = new Fl_Group(2, 50, 596, 316, _("Logging"));
 | 
			
		||||
            tabLogServer->hide();
 | 
			
		||||
            { Fl_Group* o = new Fl_Group(6, 57, 586, 180, _("QSO logging"));
 | 
			
		||||
              o->box(FL_ENGRAVED_FRAME);
 | 
			
		||||
| 
						 | 
				
			
			@ -4325,7 +4334,7 @@ ab and newline are automatically included."));
 | 
			
		|||
              } // Fl_Input2* inpNonword
 | 
			
		||||
              o->end();
 | 
			
		||||
            } // Fl_Group* o
 | 
			
		||||
            { Fl_Group* o = new Fl_Group(6, 313, 586, 55, _("Client/Server Logbook"));
 | 
			
		||||
            { Fl_Group* o = new Fl_Group(6, 313, 586, 51, _("Client/Server Logbook"));
 | 
			
		||||
              o->box(FL_ENGRAVED_FRAME);
 | 
			
		||||
              o->align(Fl_Align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE));
 | 
			
		||||
              { Fl_Input* o = xmllogServerAddress = new Fl_Input(157, 334, 100, 24, _("Address:"));
 | 
			
		||||
| 
						 | 
				
			
			@ -4345,7 +4354,7 @@ ab and newline are automatically included."));
 | 
			
		|||
            } // Fl_Group* o
 | 
			
		||||
            tabLogServer->end();
 | 
			
		||||
          } // Fl_Group* tabLogServer
 | 
			
		||||
          { tabMBars = new Fl_Group(0, 50, 598, 320, _("Macros"));
 | 
			
		||||
          { tabMBars = new Fl_Group(2, 50, 596, 316, _("Macros"));
 | 
			
		||||
            tabMBars->hide();
 | 
			
		||||
            { Fl_Group* o = new Fl_Group(6, 54, 586, 195, _("Number and position of macro bars"));
 | 
			
		||||
              o->box(FL_ENGRAVED_FRAME);
 | 
			
		||||
| 
						 | 
				
			
			@ -4402,7 +4411,7 @@ ab and newline are automatically included."));
 | 
			
		|||
              } // Fl_Check_Button* btnMacroMouseWheel
 | 
			
		||||
              o->end();
 | 
			
		||||
            } // Fl_Group* o
 | 
			
		||||
            { Fl_Group* o = new Fl_Group(6, 292, 586, 76);
 | 
			
		||||
            { Fl_Group* o = new Fl_Group(6, 292, 586, 72);
 | 
			
		||||
              o->box(FL_ENGRAVED_FRAME);
 | 
			
		||||
              { Fl_Check_Button* o = btnUseLastMacro = new Fl_Check_Button(71, 298, 277, 20, _("Load last used macro file on startup"));
 | 
			
		||||
                btnUseLastMacro->tooltip(_("ON - use last set of macros\nOFF - use default set"));
 | 
			
		||||
| 
						 | 
				
			
			@ -4426,8 +4435,7 @@ ab and newline are automatically included."));
 | 
			
		|||
            } // Fl_Group* o
 | 
			
		||||
            tabMBars->end();
 | 
			
		||||
          } // Fl_Group* tabMBars
 | 
			
		||||
          { tabWF_UI = new Fl_Group(0, 50, 598, 320, _("WF Ctrls"));
 | 
			
		||||
            tabWF_UI->hide();
 | 
			
		||||
          { tabWF_UI = new Fl_Group(2, 50, 596, 316, _("WF Ctrls"));
 | 
			
		||||
            { Fl_Group* o = new Fl_Group(6, 58, 586, 306);
 | 
			
		||||
              o->box(FL_ENGRAVED_BOX);
 | 
			
		||||
              { Fl_Box* o = new Fl_Box(31, 65, 446, 25, _("Enable check box to show each respective operator control"));
 | 
			
		||||
| 
						 | 
				
			
			@ -4514,12 +4522,13 @@ ab and newline are automatically included."));
 | 
			
		|||
        } // Fl_Tabs* tabsUI
 | 
			
		||||
        tabUI->end();
 | 
			
		||||
      } // Fl_Group* tabUI
 | 
			
		||||
      { tabWaterfall = new Fl_Group(0, 25, 598, 345, _("Waterfall"));
 | 
			
		||||
      { tabWaterfall = new Fl_Group(1, 25, 598, 345, _("Waterfall"));
 | 
			
		||||
        tabWaterfall->hide();
 | 
			
		||||
        { tabsWaterfall = new Fl_Tabs(2, 25, 596, 345);
 | 
			
		||||
          tabsWaterfall->color(FL_LIGHT1);
 | 
			
		||||
          tabsWaterfall->selection_color(FL_LIGHT1);
 | 
			
		||||
          { Fl_Group* o = new Fl_Group(0, 50, 598, 320, _("Display"));
 | 
			
		||||
          { Fl_Group* o = new Fl_Group(2, 50, 596, 316, _("Display"));
 | 
			
		||||
            o->hide();
 | 
			
		||||
            { Fl_Group* o = new Fl_Group(6, 60, 588, 194, _("Colors and cursors"));
 | 
			
		||||
              o->box(FL_ENGRAVED_FRAME);
 | 
			
		||||
              o->align(Fl_Align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE));
 | 
			
		||||
| 
						 | 
				
			
			@ -4714,7 +4723,7 @@ ab and newline are automatically included."));
 | 
			
		|||
            } // Fl_Group* o
 | 
			
		||||
            o->end();
 | 
			
		||||
          } // Fl_Group* o
 | 
			
		||||
          { Fl_Group* o = new Fl_Group(0, 50, 598, 320, _("FFT Processing"));
 | 
			
		||||
          { Fl_Group* o = new Fl_Group(2, 50, 596, 316, _("FFT Processing"));
 | 
			
		||||
            o->hide();
 | 
			
		||||
            { Fl_Group* o = new Fl_Group(6, 62, 588, 135);
 | 
			
		||||
              o->box(FL_ENGRAVED_FRAME);
 | 
			
		||||
| 
						 | 
				
			
			@ -4825,8 +4834,7 @@ an merging"));
 | 
			
		|||
            } // Fl_Group* o
 | 
			
		||||
            o->end();
 | 
			
		||||
          } // Fl_Group* o
 | 
			
		||||
          { Fl_Group* o = new Fl_Group(0, 50, 598, 320, _("Mouse"));
 | 
			
		||||
            o->hide();
 | 
			
		||||
          { Fl_Group* o = new Fl_Group(2, 50, 596, 316, _("Mouse"));
 | 
			
		||||
            { Fl_Group* o = new Fl_Group(6, 62, 588, 170);
 | 
			
		||||
              o->box(FL_ENGRAVED_FRAME);
 | 
			
		||||
              { Fl_Check_Button* o = btnWaterfallHistoryDefault = new Fl_Check_Button(69, 76, 340, 20, _("Left or right click always replays audio history"));
 | 
			
		||||
| 
						 | 
				
			
			@ -4874,12 +4882,12 @@ an merging"));
 | 
			
		|||
        } // Fl_Tabs* tabsWaterfall
 | 
			
		||||
        tabWaterfall->end();
 | 
			
		||||
      } // Fl_Group* tabWaterfall
 | 
			
		||||
      { tabModems = new Fl_Group(0, 25, 598, 345, _("Modems"));
 | 
			
		||||
        tabModems->hide();
 | 
			
		||||
        { tabsModems = new Fl_Tabs(0, 25, 598, 345, _("2"));
 | 
			
		||||
      { tabModems = new Fl_Group(1, 25, 598, 343, _("Modems"));
 | 
			
		||||
        { tabsModems = new Fl_Tabs(1, 25, 598, 343, _("2"));
 | 
			
		||||
          tabsModems->selection_color(FL_LIGHT1);
 | 
			
		||||
          tabsModems->align(Fl_Align(FL_ALIGN_TOP_RIGHT));
 | 
			
		||||
          { tabContestia = new Fl_Group(0, 50, 598, 320, _("Cntst\'"));
 | 
			
		||||
          { tabContestia = new Fl_Group(2, 50, 596, 316, _("Cntst\'"));
 | 
			
		||||
            tabContestia->hide();
 | 
			
		||||
            { Fl_Group* o = new Fl_Group(6, 60, 588, 200, _("Contestia"));
 | 
			
		||||
              o->box(FL_ENGRAVED_FRAME);
 | 
			
		||||
              o->align(Fl_Align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE));
 | 
			
		||||
| 
						 | 
				
			
			@ -4952,11 +4960,11 @@ an merging"));
 | 
			
		|||
            } // Fl_Group* o
 | 
			
		||||
            tabContestia->end();
 | 
			
		||||
          } // Fl_Group* tabContestia
 | 
			
		||||
          { tabCW = new Fl_Group(0, 50, 598, 320, _("CW"));
 | 
			
		||||
          { tabCW = new Fl_Group(2, 50, 596, 316, _("CW"));
 | 
			
		||||
            tabCW->hide();
 | 
			
		||||
            { tabsCW = new Fl_Tabs(0, 50, 598, 320);
 | 
			
		||||
            { tabsCW = new Fl_Tabs(2, 50, 596, 316);
 | 
			
		||||
              tabsCW->selection_color(FL_LIGHT1);
 | 
			
		||||
              { Fl_Group* o = new Fl_Group(0, 75, 598, 295, _("General"));
 | 
			
		||||
              { Fl_Group* o = new Fl_Group(4, 75, 592, 288, _("General"));
 | 
			
		||||
                o->align(Fl_Align(FL_ALIGN_TOP_LEFT));
 | 
			
		||||
                { Fl_Group* o = new Fl_Group(6, 85, 588, 153, _("Receive"));
 | 
			
		||||
                o->box(FL_ENGRAVED_FRAME);
 | 
			
		||||
| 
						 | 
				
			
			@ -5085,7 +5093,7 @@ an merging"));
 | 
			
		|||
                } // Fl_Box* o
 | 
			
		||||
                o->end();
 | 
			
		||||
                } // Fl_Group* o
 | 
			
		||||
                { Fl_Group* o = new Fl_Group(6, 239, 588, 126, _("Transmit"));
 | 
			
		||||
                { Fl_Group* o = new Fl_Group(6, 239, 588, 123, _("Transmit"));
 | 
			
		||||
                o->box(FL_ENGRAVED_FRAME);
 | 
			
		||||
                o->align(Fl_Align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE));
 | 
			
		||||
                { Fl_Value_Slider2* o = sldrCWxmtWPM = new Fl_Value_Slider2(20, 267, 400, 20, _("TX WPM"));
 | 
			
		||||
| 
						 | 
				
			
			@ -5183,7 +5191,7 @@ an merging"));
 | 
			
		|||
                } // Fl_Group* o
 | 
			
		||||
                o->end();
 | 
			
		||||
              } // Fl_Group* o
 | 
			
		||||
              { Fl_Group* o = new Fl_Group(0, 75, 598, 295, _("Timing and QSK"));
 | 
			
		||||
              { Fl_Group* o = new Fl_Group(4, 75, 592, 288, _("Timing and QSK"));
 | 
			
		||||
                o->align(Fl_Align(FL_ALIGN_TOP_LEFT));
 | 
			
		||||
                o->hide();
 | 
			
		||||
                { Fl_Group* o = new Fl_Group(6, 85, 588, 120, _("Timing"));
 | 
			
		||||
| 
						 | 
				
			
			@ -5329,7 +5337,7 @@ an merging"));
 | 
			
		|||
                } // Fl_Group* o
 | 
			
		||||
                o->end();
 | 
			
		||||
              } // Fl_Group* o
 | 
			
		||||
              { Fl_Group* o = new Fl_Group(0, 75, 598, 295, _("Prosigns"));
 | 
			
		||||
              { Fl_Group* o = new Fl_Group(2, 75, 592, 289, _("Prosigns"));
 | 
			
		||||
                o->align(Fl_Align(FL_ALIGN_TOP_LEFT));
 | 
			
		||||
                o->hide();
 | 
			
		||||
                { Fl_Group* o = new Fl_Group(6, 84, 588, 280);
 | 
			
		||||
| 
						 | 
				
			
			@ -5410,7 +5418,7 @@ an merging"));
 | 
			
		|||
            } // Fl_Tabs* tabsCW
 | 
			
		||||
            tabCW->end();
 | 
			
		||||
          } // Fl_Group* tabCW
 | 
			
		||||
          { tabDomEX = new Fl_Group(0, 50, 598, 320, _("Dom"));
 | 
			
		||||
          { tabDomEX = new Fl_Group(2, 50, 596, 316, _("Dom"));
 | 
			
		||||
            tabDomEX->hide();
 | 
			
		||||
            { Fl_Group* o = new Fl_Group(6, 60, 588, 180);
 | 
			
		||||
              o->box(FL_ENGRAVED_FRAME);
 | 
			
		||||
| 
						 | 
				
			
			@ -5502,7 +5510,7 @@ an merging"));
 | 
			
		|||
            } // Fl_Group* o
 | 
			
		||||
            tabDomEX->end();
 | 
			
		||||
          } // Fl_Group* tabDomEX
 | 
			
		||||
          { tabFeld = new Fl_Group(0, 50, 598, 320, _("Feld"));
 | 
			
		||||
          { tabFeld = new Fl_Group(2, 50, 596, 316, _("Feld"));
 | 
			
		||||
            tabFeld->hide();
 | 
			
		||||
            { Fl_Group* o = new Fl_Group(6, 60, 588, 150);
 | 
			
		||||
              o->box(FL_ENGRAVED_FRAME);
 | 
			
		||||
| 
						 | 
				
			
			@ -5589,7 +5597,7 @@ an merging"));
 | 
			
		|||
            } // Fl_Group* o
 | 
			
		||||
            tabFeld->end();
 | 
			
		||||
          } // Fl_Group* tabFeld
 | 
			
		||||
          { tabMT63 = new Fl_Group(0, 50, 598, 320, _("MT63"));
 | 
			
		||||
          { tabMT63 = new Fl_Group(2, 50, 596, 316, _("MT63"));
 | 
			
		||||
            tabMT63->hide();
 | 
			
		||||
            { Fl_Group* o = new Fl_Group(6, 60, 588, 115);
 | 
			
		||||
              o->box(FL_ENGRAVED_FRAME);
 | 
			
		||||
| 
						 | 
				
			
			@ -5652,7 +5660,7 @@ an merging"));
 | 
			
		|||
            } // Fl_Group* o
 | 
			
		||||
            tabMT63->end();
 | 
			
		||||
          } // Fl_Group* tabMT63
 | 
			
		||||
          { tabOlivia = new Fl_Group(0, 50, 598, 320, _("Olivia"));
 | 
			
		||||
          { tabOlivia = new Fl_Group(2, 50, 596, 316, _("Olivia"));
 | 
			
		||||
            tabOlivia->hide();
 | 
			
		||||
            { Fl_Group* o = new Fl_Group(6, 60, 588, 200);
 | 
			
		||||
              o->box(FL_ENGRAVED_FRAME);
 | 
			
		||||
| 
						 | 
				
			
			@ -5724,7 +5732,7 @@ an merging"));
 | 
			
		|||
            } // Fl_Group* o
 | 
			
		||||
            tabOlivia->end();
 | 
			
		||||
          } // Fl_Group* tabOlivia
 | 
			
		||||
          { tabPSK = new Fl_Group(0, 50, 598, 320, _("PSK"));
 | 
			
		||||
          { tabPSK = new Fl_Group(2, 50, 596, 316, _("PSK"));
 | 
			
		||||
            tabPSK->hide();
 | 
			
		||||
            { Fl_Group* o = new Fl_Group(6, 60, 588, 98, _("AFC behavior"));
 | 
			
		||||
              o->box(FL_ENGRAVED_FRAME);
 | 
			
		||||
| 
						 | 
				
			
			@ -5818,7 +5826,7 @@ an merging"));
 | 
			
		|||
            } // Fl_Group* o
 | 
			
		||||
            tabPSK->end();
 | 
			
		||||
          } // Fl_Group* tabPSK
 | 
			
		||||
          { tabRTTY = new Fl_Group(0, 50, 598, 320, _("RTTY"));
 | 
			
		||||
          { tabRTTY = new Fl_Group(2, 50, 596, 316, _("RTTY"));
 | 
			
		||||
            tabRTTY->hide();
 | 
			
		||||
            { Fl_Group* o = new Fl_Group(6, 60, 588, 300);
 | 
			
		||||
              o->box(FL_ENGRAVED_FRAME);
 | 
			
		||||
| 
						 | 
				
			
			@ -6006,8 +6014,7 @@ an merging"));
 | 
			
		|||
            } // Fl_Group* o
 | 
			
		||||
            tabRTTY->end();
 | 
			
		||||
          } // Fl_Group* tabRTTY
 | 
			
		||||
          { tabTHOR = new Fl_Group(0, 50, 598, 320, _("Thor"));
 | 
			
		||||
            tabTHOR->hide();
 | 
			
		||||
          { tabTHOR = new Fl_Group(2, 50, 596, 316, _("Thor"));
 | 
			
		||||
            { Fl_Group* o = new Fl_Group(5, 60, 588, 270);
 | 
			
		||||
              o->box(FL_ENGRAVED_FRAME);
 | 
			
		||||
              { txtTHORSecondary = new Fl_Input2(91, 87, 360, 40, _("Secondary Text"));
 | 
			
		||||
| 
						 | 
				
			
			@ -6051,7 +6058,27 @@ an merging"));
 | 
			
		|||
                o->value(progdefaults.THOR_BW);
 | 
			
		||||
                o->labelsize(FL_NORMAL_SIZE);
 | 
			
		||||
              } // Fl_Counter2* valTHOR_BW
 | 
			
		||||
              { Fl_Value_Slider2* o = valThorCWI = new Fl_Value_Slider2(89, 295, 260, 20, _("CWI threshold"));
 | 
			
		||||
              { Fl_Check_Button* o = valTHOR_PREAMBLE = new Fl_Check_Button(90, 222, 200, 20, _("Preamble Detection"));
 | 
			
		||||
                valTHOR_PREAMBLE->tooltip(_("Detect the THOR preamble (and clear the Rx pipeline in preparation for data)"));
 | 
			
		||||
                valTHOR_PREAMBLE->down_box(FL_DOWN_BOX);
 | 
			
		||||
                valTHOR_PREAMBLE->callback((Fl_Callback*)cb_valTHOR_PREAMBLE);
 | 
			
		||||
                o->value(progdefaults.THOR_PREAMBLE);
 | 
			
		||||
              } // Fl_Check_Button* valTHOR_PREAMBLE
 | 
			
		||||
              { Fl_Check_Button* o = valTHOR_SOFTSYMBOLS = new Fl_Check_Button(90, 252, 190, 20, _("Soft-symbol decoding"));
 | 
			
		||||
                valTHOR_SOFTSYMBOLS->tooltip(_("Use soft-decision decoding for symbol detection (also assists soft-bit decodi\
 | 
			
		||||
ng)"));
 | 
			
		||||
                valTHOR_SOFTSYMBOLS->down_box(FL_DOWN_BOX);
 | 
			
		||||
                valTHOR_SOFTSYMBOLS->callback((Fl_Callback*)cb_valTHOR_SOFTSYMBOLS);
 | 
			
		||||
                o->value(progdefaults.THOR_SOFTSYMBOLS);
 | 
			
		||||
              } // Fl_Check_Button* valTHOR_SOFTSYMBOLS
 | 
			
		||||
              { Fl_Check_Button* o = valTHOR_SOFTBITS = new Fl_Check_Button(90, 282, 170, 20, _("Soft-bit decoding"));
 | 
			
		||||
                valTHOR_SOFTBITS->tooltip(_("Use soft-bit viterbi decoding for better Forward Error Correction (works best\
 | 
			
		||||
 with soft-symbol decoding enabled)"));
 | 
			
		||||
                valTHOR_SOFTBITS->down_box(FL_DOWN_BOX);
 | 
			
		||||
                valTHOR_SOFTBITS->callback((Fl_Callback*)cb_valTHOR_SOFTBITS);
 | 
			
		||||
                o->value(progdefaults.THOR_SOFTBITS);
 | 
			
		||||
              } // Fl_Check_Button* valTHOR_SOFTBITS
 | 
			
		||||
              { Fl_Value_Slider2* o = valThorCWI = new Fl_Value_Slider2(90, 196, 260, 20, _("CWI threshold"));
 | 
			
		||||
                valThorCWI->tooltip(_("CWI detection and suppression"));
 | 
			
		||||
                valThorCWI->type(1);
 | 
			
		||||
                valThorCWI->box(FL_DOWN_BOX);
 | 
			
		||||
| 
						 | 
				
			
			@ -6068,7 +6095,7 @@ an merging"));
 | 
			
		|||
                o->value(progdefaults.ThorCWI);
 | 
			
		||||
                o->labelsize(FL_NORMAL_SIZE); o->textsize(FL_NORMAL_SIZE);
 | 
			
		||||
              } // Fl_Value_Slider2* valThorCWI
 | 
			
		||||
              { Fl_Counter2* o = valTHOR_PATHS = new Fl_Counter2(429, 193, 75, 21, _("Paths (hidden)"));
 | 
			
		||||
              { Fl_Counter2* o = valTHOR_PATHS = new Fl_Counter2(468, 274, 75, 21, _("Paths (hidden)"));
 | 
			
		||||
                valTHOR_PATHS->type(1);
 | 
			
		||||
                valTHOR_PATHS->box(FL_UP_BOX);
 | 
			
		||||
                valTHOR_PATHS->color(FL_BACKGROUND_COLOR);
 | 
			
		||||
| 
						 | 
				
			
			@ -6088,31 +6115,11 @@ an merging"));
 | 
			
		|||
                o->labelsize(FL_NORMAL_SIZE);
 | 
			
		||||
                o->hide();
 | 
			
		||||
              } // Fl_Counter2* valTHOR_PATHS
 | 
			
		||||
              { Fl_Check_Button* o = valTHOR_PREAMBLE = new Fl_Check_Button(90, 170, 200, 20, _("Preamble Detection"));
 | 
			
		||||
                valTHOR_PREAMBLE->tooltip(_("Detect the THOR preamble (and clear the Rx pipeline in preparation for data)"));
 | 
			
		||||
                valTHOR_PREAMBLE->down_box(FL_DOWN_BOX);
 | 
			
		||||
                valTHOR_PREAMBLE->callback((Fl_Callback*)cb_valTHOR_PREAMBLE);
 | 
			
		||||
                o->value(progdefaults.THOR_PREAMBLE);
 | 
			
		||||
              } // Fl_Check_Button* valTHOR_PREAMBLE
 | 
			
		||||
              { Fl_Check_Button* o = valTHOR_SOFTSYMBOLS = new Fl_Check_Button(90, 200, 190, 20, _("Soft-symbol decoding"));
 | 
			
		||||
                valTHOR_SOFTSYMBOLS->tooltip(_("Use soft-decision decoding for symbol detection (also assists soft-bit decodi\
 | 
			
		||||
ng)"));
 | 
			
		||||
                valTHOR_SOFTSYMBOLS->down_box(FL_DOWN_BOX);
 | 
			
		||||
                valTHOR_SOFTSYMBOLS->callback((Fl_Callback*)cb_valTHOR_SOFTSYMBOLS);
 | 
			
		||||
                o->value(progdefaults.THOR_SOFTSYMBOLS);
 | 
			
		||||
              } // Fl_Check_Button* valTHOR_SOFTSYMBOLS
 | 
			
		||||
              { Fl_Check_Button* o = valTHOR_SOFTBITS = new Fl_Check_Button(90, 230, 170, 20, _("Soft-bit decoding"));
 | 
			
		||||
                valTHOR_SOFTBITS->tooltip(_("Use soft-bit viterbi decoding for better Forward Error Correction (works best\
 | 
			
		||||
 with soft-symbol decoding enabled)"));
 | 
			
		||||
                valTHOR_SOFTBITS->down_box(FL_DOWN_BOX);
 | 
			
		||||
                valTHOR_SOFTBITS->callback((Fl_Callback*)cb_valTHOR_SOFTBITS);
 | 
			
		||||
                o->value(progdefaults.THOR_SOFTBITS);
 | 
			
		||||
              } // Fl_Check_Button* valTHOR_SOFTBITS
 | 
			
		||||
              o->end();
 | 
			
		||||
            } // Fl_Group* o
 | 
			
		||||
            tabTHOR->end();
 | 
			
		||||
          } // Fl_Group* tabTHOR
 | 
			
		||||
          { tabPacket = new Fl_Group(0, 50, 598, 320, _("Packet"));
 | 
			
		||||
          { tabPacket = new Fl_Group(2, 50, 596, 316, _("Packet"));
 | 
			
		||||
            tabPacket->hide();
 | 
			
		||||
            { Fl_Group* o = new Fl_Group(6, 60, 588, 296);
 | 
			
		||||
              o->box(FL_ENGRAVED_FRAME);
 | 
			
		||||
| 
						 | 
				
			
			@ -6253,7 +6260,7 @@ ng)"));
 | 
			
		|||
            } // Fl_Group* o
 | 
			
		||||
            tabPacket->end();
 | 
			
		||||
          } // Fl_Group* tabPacket
 | 
			
		||||
          { tabNavtex = new Fl_Group(0, 50, 598, 320, _("Navtex"));
 | 
			
		||||
          { tabNavtex = new Fl_Group(2, 50, 596, 316, _("Navtex"));
 | 
			
		||||
            tabNavtex->hide();
 | 
			
		||||
            { Fl_Group* o = new Fl_Group(6, 60, 588, 300);
 | 
			
		||||
              { Fl_Check_Button* o = btnNvtxAdifLog = new Fl_Check_Button(81, 87, 235, 30, _("Log Navtex messages to Adif file"));
 | 
			
		||||
| 
						 | 
				
			
			@ -6275,7 +6282,7 @@ ng)"));
 | 
			
		|||
            } // Fl_Group* o
 | 
			
		||||
            tabNavtex->end();
 | 
			
		||||
          } // Fl_Group* tabNavtex
 | 
			
		||||
          { tabWefax = new Fl_Group(0, 50, 598, 320, _("Wefax"));
 | 
			
		||||
          { tabWefax = new Fl_Group(2, 50, 596, 316, _("Wefax"));
 | 
			
		||||
            tabWefax->hide();
 | 
			
		||||
            { Fl_Group* o = new Fl_Group(6, 60, 588, 300);
 | 
			
		||||
              { Fl_Check_Button* o = btnWefaxAdifLog = new Fl_Check_Button(97, 141, 235, 30, _("Log Wefax messages to Adif file"));
 | 
			
		||||
| 
						 | 
				
			
			@ -6348,12 +6355,12 @@ ng)"));
 | 
			
		|||
        } // Fl_Tabs* tabsModems
 | 
			
		||||
        tabModems->end();
 | 
			
		||||
      } // Fl_Group* tabModems
 | 
			
		||||
      { tabRig = new Fl_Group(0, 25, 598, 345, _("Rig"));
 | 
			
		||||
      { tabRig = new Fl_Group(1, 25, 598, 345, _("Rig"));
 | 
			
		||||
        tabRig->tooltip(_("Transceiver control"));
 | 
			
		||||
        tabRig->hide();
 | 
			
		||||
        { tabsRig = new Fl_Tabs(4, 25, 592, 345);
 | 
			
		||||
        { tabsRig = new Fl_Tabs(2, 25, 596, 345);
 | 
			
		||||
          tabsRig->selection_color(FL_LIGHT1);
 | 
			
		||||
          { Fl_Group* o = new Fl_Group(0, 50, 598, 320, _("Hardware PTT"));
 | 
			
		||||
          { Fl_Group* o = new Fl_Group(2, 50, 596, 316, _("Hardware PTT"));
 | 
			
		||||
            { Fl_Group* o = new Fl_Group(6, 57, 588, 38);
 | 
			
		||||
              o->box(FL_ENGRAVED_FRAME);
 | 
			
		||||
              { Fl_Check_Button* o = btnPTTrightchannel = new Fl_Check_Button(175, 66, 250, 20, _("PTT tone on right audio channel "));
 | 
			
		||||
| 
						 | 
				
			
			@ -6439,7 +6446,7 @@ ng)"));
 | 
			
		|||
            } // Fl_Group* grpPTTdelays
 | 
			
		||||
            o->end();
 | 
			
		||||
          } // Fl_Group* o
 | 
			
		||||
          { Fl_Group* o = new Fl_Group(0, 50, 598, 320, _("RigCAT"));
 | 
			
		||||
          { Fl_Group* o = new Fl_Group(2, 50, 596, 316, _("RigCAT"));
 | 
			
		||||
            o->tooltip(_("Rig Control using xml spec file"));
 | 
			
		||||
            o->hide();
 | 
			
		||||
            { chkUSERIGCAT = new Fl_Check_Button(245, 58, 110, 20, _("Use RigCAT"));
 | 
			
		||||
| 
						 | 
				
			
			@ -6602,7 +6609,7 @@ ng)"));
 | 
			
		|||
            } // Fl_Group* grpRigCAT
 | 
			
		||||
            o->end();
 | 
			
		||||
          } // Fl_Group* o
 | 
			
		||||
          { tabHamlib = new Fl_Group(0, 50, 598, 320, _("Hamlib"));
 | 
			
		||||
          { tabHamlib = new Fl_Group(2, 50, 596, 316, _("Hamlib"));
 | 
			
		||||
            tabHamlib->hide();
 | 
			
		||||
            { chkUSEHAMLIB = new Fl_Check_Button(250, 58, 100, 20, _("Use Hamlib"));
 | 
			
		||||
              chkUSEHAMLIB->tooltip(_("Hamlib used for rig control"));
 | 
			
		||||
| 
						 | 
				
			
			@ -6811,7 +6818,7 @@ ng)"));
 | 
			
		|||
            } // Fl_Group* grpHamlib
 | 
			
		||||
            tabHamlib->end();
 | 
			
		||||
          } // Fl_Group* tabHamlib
 | 
			
		||||
          { Fl_Group* o = new Fl_Group(0, 50, 598, 320, _("MemMap"));
 | 
			
		||||
          { Fl_Group* o = new Fl_Group(2, 50, 596, 316, _("MemMap"));
 | 
			
		||||
            o->hide();
 | 
			
		||||
            { grpMemmap = new Fl_Group(6, 58, 588, 185);
 | 
			
		||||
              grpMemmap->box(FL_ENGRAVED_FRAME);
 | 
			
		||||
| 
						 | 
				
			
			@ -6840,7 +6847,7 @@ ng)"));
 | 
			
		|||
            } // Fl_Group* grpMemmap
 | 
			
		||||
            o->end();
 | 
			
		||||
          } // Fl_Group* o
 | 
			
		||||
          { tabXMLRPC = new Fl_Group(0, 50, 598, 320, _("XML-RPC"));
 | 
			
		||||
          { tabXMLRPC = new Fl_Group(2, 50, 596, 316, _("XML-RPC"));
 | 
			
		||||
            tabXMLRPC->hide();
 | 
			
		||||
            { grpXMLRPC = new Fl_Group(6, 58, 588, 160);
 | 
			
		||||
              grpXMLRPC->box(FL_ENGRAVED_FRAME);
 | 
			
		||||
| 
						 | 
				
			
			@ -6867,12 +6874,12 @@ ng)"));
 | 
			
		|||
        } // Fl_Tabs* tabsRig
 | 
			
		||||
        tabRig->end();
 | 
			
		||||
      } // Fl_Group* tabRig
 | 
			
		||||
      { tabSoundCard = new Fl_Group(0, 25, 598, 345, _("Audio"));
 | 
			
		||||
      { tabSoundCard = new Fl_Group(1, 25, 598, 345, _("Audio"));
 | 
			
		||||
        tabSoundCard->tooltip(_("Audio devices"));
 | 
			
		||||
        tabSoundCard->hide();
 | 
			
		||||
        { tabsSoundCard = new Fl_Tabs(2, 25, 596, 345);
 | 
			
		||||
          tabsSoundCard->selection_color(FL_LIGHT1);
 | 
			
		||||
          { tabAudio = new Fl_Group(0, 50, 598, 320, _("Devices"));
 | 
			
		||||
          { tabAudio = new Fl_Group(2, 50, 596, 316, _("Devices"));
 | 
			
		||||
            { AudioOSS = new Fl_Group(6, 60, 588, 45);
 | 
			
		||||
              AudioOSS->box(FL_ENGRAVED_FRAME);
 | 
			
		||||
              { btnAudioIO[0] = new Fl_Round_Button(15, 70, 53, 25, _("OSS"));
 | 
			
		||||
| 
						 | 
				
			
			@ -6945,7 +6952,7 @@ ng)"));
 | 
			
		|||
            } // Fl_Group* AudioNull
 | 
			
		||||
            tabAudio->end();
 | 
			
		||||
          } // Fl_Group* tabAudio
 | 
			
		||||
          { tabAudioOpt = new Fl_Group(0, 50, 598, 320, _("Settings"));
 | 
			
		||||
          { tabAudioOpt = new Fl_Group(2, 50, 596, 316, _("Settings"));
 | 
			
		||||
            tabAudioOpt->hide();
 | 
			
		||||
            { grpAudioSampleRate = new Fl_Group(10, 60, 580, 90, _("Sample rate"));
 | 
			
		||||
              grpAudioSampleRate->box(FL_ENGRAVED_FRAME);
 | 
			
		||||
| 
						 | 
				
			
			@ -7035,7 +7042,7 @@ ll with your audio device."));
 | 
			
		|||
            } // Fl_Group* o
 | 
			
		||||
            tabAudioOpt->end();
 | 
			
		||||
          } // Fl_Group* tabAudioOpt
 | 
			
		||||
          { tabMixer = new Fl_Group(0, 50, 598, 320, _("Mixer"));
 | 
			
		||||
          { tabMixer = new Fl_Group(2, 50, 596, 316, _("Mixer"));
 | 
			
		||||
            tabMixer->hide();
 | 
			
		||||
            { Fl_Group* o = new Fl_Group(10, 57, 580, 145, _("OSS mixer"));
 | 
			
		||||
              o->box(FL_ENGRAVED_FRAME);
 | 
			
		||||
| 
						 | 
				
			
			@ -7081,7 +7088,7 @@ ll with your audio device."));
 | 
			
		|||
            } // Fl_Group* o
 | 
			
		||||
            tabMixer->end();
 | 
			
		||||
          } // Fl_Group* tabMixer
 | 
			
		||||
          { tabAudioRightChannel = new Fl_Group(0, 50, 598, 320, _("Right channel"));
 | 
			
		||||
          { tabAudioRightChannel = new Fl_Group(2, 50, 596, 316, _("Right channel"));
 | 
			
		||||
            tabAudioRightChannel->hide();
 | 
			
		||||
            { chkForceMono = new Fl_Check_Button(145, 66, 332, 20, _("Mono audio output"));
 | 
			
		||||
              chkForceMono->tooltip(_("Force output audio to single channel"));
 | 
			
		||||
| 
						 | 
				
			
			@ -7132,7 +7139,7 @@ nce.\nYou may change the state from either location.\n..."));
 | 
			
		|||
        } // Fl_Tabs* tabsSoundCard
 | 
			
		||||
        tabSoundCard->end();
 | 
			
		||||
      } // Fl_Group* tabSoundCard
 | 
			
		||||
      { tabID = new Fl_Group(0, 25, 598, 345, _("ID"));
 | 
			
		||||
      { tabID = new Fl_Group(1, 25, 598, 343, _("ID"));
 | 
			
		||||
        tabID->hide();
 | 
			
		||||
        { Fl_Group* o = new Fl_Group(6, 35, 588, 103, _("Video Preamble ID"));
 | 
			
		||||
          o->box(FL_ENGRAVED_FRAME);
 | 
			
		||||
| 
						 | 
				
			
			@ -7264,7 +7271,7 @@ nce.\nYou may change the state from either location.\n..."));
 | 
			
		|||
            chkRSidAutoDisable->value(progdefaults.rsid_auto_disable);
 | 
			
		||||
            if (progdefaults.rsid_notify_only) chkRSidAutoDisable->deactivate();
 | 
			
		||||
          } // Fl_Check_Button* chkRSidAutoDisable
 | 
			
		||||
          { chkRSidNotifyOnly = new Fl_Check_Button(44, 317, 155, 20, _("Notifications only"));
 | 
			
		||||
          { chkRSidNotifyOnly = new Fl_Check_Button(44, 317, 155, 20, _("Notify only"));
 | 
			
		||||
            chkRSidNotifyOnly->tooltip(_("Check this to be notified when an RSID is received\nwithout changing modem an\
 | 
			
		||||
d frequency"));
 | 
			
		||||
            chkRSidNotifyOnly->down_box(FL_DOWN_BOX);
 | 
			
		||||
| 
						 | 
				
			
			@ -7293,6 +7300,28 @@ d frequency"));
 | 
			
		|||
            o->value(progdefaults.rsid_squelch);
 | 
			
		||||
            o->labelsize(FL_NORMAL_SIZE); o->textsize(FL_NORMAL_SIZE);
 | 
			
		||||
          } // Fl_Value_Slider2* sldrRSIDsquelch
 | 
			
		||||
          { Fl_Value_Slider2* o = sldrRSIDresolution = new Fl_Value_Slider2(133, 317, 90, 18, _("Sensitivity"));
 | 
			
		||||
            sldrRSIDresolution->tooltip(_("2 = low sensitivity / decreased false detection\n5 = high sensitivity / incre\
 | 
			
		||||
ased false detection"));
 | 
			
		||||
            sldrRSIDresolution->type(1);
 | 
			
		||||
            sldrRSIDresolution->box(FL_DOWN_BOX);
 | 
			
		||||
            sldrRSIDresolution->color(FL_BACKGROUND_COLOR);
 | 
			
		||||
            sldrRSIDresolution->selection_color(FL_BACKGROUND_COLOR);
 | 
			
		||||
            sldrRSIDresolution->labeltype(FL_NORMAL_LABEL);
 | 
			
		||||
            sldrRSIDresolution->labelfont(0);
 | 
			
		||||
            sldrRSIDresolution->labelsize(14);
 | 
			
		||||
            sldrRSIDresolution->labelcolor(FL_FOREGROUND_COLOR);
 | 
			
		||||
            sldrRSIDresolution->minimum(2);
 | 
			
		||||
            sldrRSIDresolution->maximum(5);
 | 
			
		||||
            sldrRSIDresolution->step(1);
 | 
			
		||||
            sldrRSIDresolution->value(5);
 | 
			
		||||
            sldrRSIDresolution->textsize(14);
 | 
			
		||||
            sldrRSIDresolution->callback((Fl_Callback*)cb_sldrRSIDresolution);
 | 
			
		||||
            sldrRSIDresolution->align(Fl_Align(FL_ALIGN_RIGHT));
 | 
			
		||||
            sldrRSIDresolution->when(FL_WHEN_CHANGED);
 | 
			
		||||
            o->value(progdefaults.rsid_resolution);
 | 
			
		||||
            o->labelsize(FL_NORMAL_SIZE); o->textsize(FL_NORMAL_SIZE);
 | 
			
		||||
          } // Fl_Value_Slider2* sldrRSIDresolution
 | 
			
		||||
          o->end();
 | 
			
		||||
        } // Fl_Group* o
 | 
			
		||||
        { Fl_Group* o = new Fl_Group(340, 198, 253, 85, _("Reed-Solomon ID (Tx)"));
 | 
			
		||||
| 
						 | 
				
			
			@ -7323,11 +7352,11 @@ d frequency"));
 | 
			
		|||
        } // Fl_Group* o
 | 
			
		||||
        tabID->end();
 | 
			
		||||
      } // Fl_Group* tabID
 | 
			
		||||
      { tabMisc = new Fl_Group(0, 25, 598, 345, _("Misc"));
 | 
			
		||||
      { tabMisc = new Fl_Group(1, 25, 598, 345, _("Misc"));
 | 
			
		||||
        tabMisc->hide();
 | 
			
		||||
        { tabsMisc = new Fl_Tabs(4, 25, 592, 345);
 | 
			
		||||
        { tabsMisc = new Fl_Tabs(2, 25, 596, 345);
 | 
			
		||||
          tabsMisc->selection_color(FL_LIGHT1);
 | 
			
		||||
          { tabCPUspeed = new Fl_Group(0, 50, 598, 320, _("CPU"));
 | 
			
		||||
          { tabCPUspeed = new Fl_Group(2, 50, 596, 316, _("CPU"));
 | 
			
		||||
            { Fl_Group* o = new Fl_Group(6, 60, 588, 51);
 | 
			
		||||
              o->box(FL_ENGRAVED_FRAME);
 | 
			
		||||
              o->align(Fl_Align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE));
 | 
			
		||||
| 
						 | 
				
			
			@ -7341,7 +7370,7 @@ d frequency"));
 | 
			
		|||
            } // Fl_Group* o
 | 
			
		||||
            tabCPUspeed->end();
 | 
			
		||||
          } // Fl_Group* tabCPUspeed
 | 
			
		||||
          { tabNBEMS = new Fl_Group(0, 50, 598, 320, _("NBEMS"));
 | 
			
		||||
          { tabNBEMS = new Fl_Group(2, 50, 596, 316, _("NBEMS"));
 | 
			
		||||
            tabNBEMS->hide();
 | 
			
		||||
            { Fl_Group* o = new Fl_Group(6, 60, 588, 75, _("NBEMS data file interface"));
 | 
			
		||||
              o->box(FL_ENGRAVED_FRAME);
 | 
			
		||||
| 
						 | 
				
			
			@ -7411,7 +7440,7 @@ d frequency"));
 | 
			
		|||
            } // Fl_Group* o
 | 
			
		||||
            tabNBEMS->end();
 | 
			
		||||
          } // Fl_Group* tabNBEMS
 | 
			
		||||
          { tabPskmail = new Fl_Group(0, 50, 598, 320, _("Pskmail"));
 | 
			
		||||
          { tabPskmail = new Fl_Group(2, 50, 596, 316, _("Pskmail"));
 | 
			
		||||
            tabPskmail->align(Fl_Align(FL_ALIGN_TOP_LEFT));
 | 
			
		||||
            tabPskmail->hide();
 | 
			
		||||
            { Fl_Group* o = new Fl_Group(6, 58, 588, 174, _("Mail Server Attributes"));
 | 
			
		||||
| 
						 | 
				
			
			@ -7518,7 +7547,7 @@ d frequency"));
 | 
			
		|||
            } // Fl_Group* o
 | 
			
		||||
            tabPskmail->end();
 | 
			
		||||
          } // Fl_Group* tabPskmail
 | 
			
		||||
          { tabSpot = new Fl_Group(0, 50, 598, 320, _("Spotting"));
 | 
			
		||||
          { tabSpot = new Fl_Group(2, 50, 596, 316, _("Spotting"));
 | 
			
		||||
            tabSpot->hide();
 | 
			
		||||
            { Fl_Group* o = new Fl_Group(6, 60, 588, 215, _("PSK Reporter"));
 | 
			
		||||
              o->box(FL_ENGRAVED_FRAME);
 | 
			
		||||
| 
						 | 
				
			
			@ -7583,7 +7612,7 @@ d frequency"));
 | 
			
		|||
            } // Fl_Group* o
 | 
			
		||||
            tabSpot->end();
 | 
			
		||||
          } // Fl_Group* tabSpot
 | 
			
		||||
          { tabSweetSpot = new Fl_Group(0, 50, 598, 320, _("Sweet Spot"));
 | 
			
		||||
          { tabSweetSpot = new Fl_Group(2, 50, 596, 316, _("Sweet Spot"));
 | 
			
		||||
            tabSweetSpot->hide();
 | 
			
		||||
            { Fl_Group* o = new Fl_Group(6, 60, 588, 75);
 | 
			
		||||
              o->box(FL_ENGRAVED_FRAME);
 | 
			
		||||
| 
						 | 
				
			
			@ -7674,7 +7703,7 @@ d frequency"));
 | 
			
		|||
            } // Fl_Group* o
 | 
			
		||||
            tabSweetSpot->end();
 | 
			
		||||
          } // Fl_Group* tabSweetSpot
 | 
			
		||||
          { tabText_IO = new Fl_Group(0, 50, 598, 320, _("Text i/o"));
 | 
			
		||||
          { tabText_IO = new Fl_Group(2, 50, 596, 316, _("Text i/o"));
 | 
			
		||||
            tabText_IO->hide();
 | 
			
		||||
            { grpTalker = new Fl_Group(6, 117, 588, 80, _("Talker Socket (MS only)"));
 | 
			
		||||
              grpTalker->box(FL_ENGRAVED_FRAME);
 | 
			
		||||
| 
						 | 
				
			
			@ -7706,7 +7735,7 @@ d frequency"));
 | 
			
		|||
            } // Fl_Group* o
 | 
			
		||||
            tabText_IO->end();
 | 
			
		||||
          } // Fl_Group* tabText_IO
 | 
			
		||||
          { tabDTMFdecode = new Fl_Group(0, 50, 598, 320, _("DTMF"));
 | 
			
		||||
          { tabDTMFdecode = new Fl_Group(2, 50, 596, 316, _("DTMF"));
 | 
			
		||||
            tabDTMFdecode->hide();
 | 
			
		||||
            { Fl_Check_Button* o = chkDTMFdecode = new Fl_Check_Button(212, 85, 175, 20, _("Decode DTMF tones"));
 | 
			
		||||
              chkDTMFdecode->tooltip(_("Send rx text to file: textout.txt"));
 | 
			
		||||
| 
						 | 
				
			
			@ -7716,7 +7745,7 @@ d frequency"));
 | 
			
		|||
            } // Fl_Check_Button* chkDTMFdecode
 | 
			
		||||
            tabDTMFdecode->end();
 | 
			
		||||
          } // Fl_Group* tabDTMFdecode
 | 
			
		||||
          { tabWX = new Fl_Group(0, 50, 598, 320, _("WX"));
 | 
			
		||||
          { tabWX = new Fl_Group(2, 50, 596, 316, _("WX"));
 | 
			
		||||
            tabWX->hide();
 | 
			
		||||
            { Fl_Group* o = new Fl_Group(6, 60, 588, 300, _("Weather query specification"));
 | 
			
		||||
              o->box(FL_ENGRAVED_FRAME);
 | 
			
		||||
| 
						 | 
				
			
			@ -7801,12 +7830,12 @@ d frequency"));
 | 
			
		|||
        } // Fl_Tabs* tabsMisc
 | 
			
		||||
        tabMisc->end();
 | 
			
		||||
      } // Fl_Group* tabMisc
 | 
			
		||||
      { tabQRZ = new Fl_Group(0, 25, 598, 345, _("Web"));
 | 
			
		||||
      { tabQRZ = new Fl_Group(1, 25, 598, 345, _("Web"));
 | 
			
		||||
        tabQRZ->tooltip(_("Callsign database"));
 | 
			
		||||
        tabQRZ->hide();
 | 
			
		||||
        { Fl_Tabs* o = new Fl_Tabs(4, 25, 592, 345);
 | 
			
		||||
          { Fl_Group* o = new Fl_Group(0, 50, 598, 320, _("Call Lookup"));
 | 
			
		||||
            { Fl_Group* o = new Fl_Group(6, 52, 588, 122, _("Web Browser lookup"));
 | 
			
		||||
        { Fl_Tabs* o = new Fl_Tabs(2, 25, 596, 345);
 | 
			
		||||
          { Fl_Group* o = new Fl_Group(2, 50, 596, 316, _("Call Lookup"));
 | 
			
		||||
            { Fl_Group* o = new Fl_Group(6, 53, 588, 122, _("Web Browser lookup"));
 | 
			
		||||
              o->box(FL_ENGRAVED_FRAME);
 | 
			
		||||
              o->align(Fl_Align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE));
 | 
			
		||||
              { Fl_Round_Button* o = btnQRZWEBnotavailable = new Fl_Round_Button(168, 66, 337, 20, _("None"));
 | 
			
		||||
| 
						 | 
				
			
			@ -7930,7 +7959,7 @@ d frequency"));
 | 
			
		|||
            } // Fl_Group* o
 | 
			
		||||
            o->end();
 | 
			
		||||
          } // Fl_Group* o
 | 
			
		||||
          { Fl_Group* o = new Fl_Group(0, 50, 598, 320, _("eQSL"));
 | 
			
		||||
          { Fl_Group* o = new Fl_Group(2, 50, 596, 316, _("eQSL"));
 | 
			
		||||
            o->hide();
 | 
			
		||||
            { Fl_Input2* o = inpEQSL_id = new Fl_Input2(225, 58, 150, 20, _("User ID"));
 | 
			
		||||
              inpEQSL_id->tooltip(_("Your login name"));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -133,15 +133,15 @@ static const char szBaudRates[] = "300|600|1200|2400|4800|9600|19200|38400|57600
 | 
			
		|||
static const char szProsigns[] = "~|%|&|+|=|{|}|<|>|[|]| ";} {}
 | 
			
		||||
  Fl_Window {} {
 | 
			
		||||
    label {Fldigi configuration} open
 | 
			
		||||
    xywh {604 62 600 400} type Double color 45 selection_color 51 labelsize 18 align 80 non_modal visible
 | 
			
		||||
    xywh {598 533 600 400} type Double color 45 selection_color 51 labelsize 18 align 80 hide non_modal
 | 
			
		||||
  } {
 | 
			
		||||
    Fl_Tabs tabsConfigure {open
 | 
			
		||||
      xywh {0 0 598 370} color 50 selection_color 50
 | 
			
		||||
      xywh {0 0 599 370} color 50 selection_color 50
 | 
			
		||||
    } {
 | 
			
		||||
      Fl_Group tabOperator {
 | 
			
		||||
        label Operator
 | 
			
		||||
        callback {progdefaults.changed = true;} selected
 | 
			
		||||
        tooltip {Operator information} xywh {0 25 598 345} when 1
 | 
			
		||||
        callback {progdefaults.changed = true;}
 | 
			
		||||
        tooltip {Operator information} xywh {1 25 598 343} when 1 hide
 | 
			
		||||
      } {
 | 
			
		||||
        Fl_Group {} {
 | 
			
		||||
          label Station open
 | 
			
		||||
| 
						 | 
				
			
			@ -220,15 +220,15 @@ progdefaults.changed = true;}
 | 
			
		|||
        }
 | 
			
		||||
      }
 | 
			
		||||
      Fl_Group tabUI {
 | 
			
		||||
        label UI
 | 
			
		||||
        xywh {0 25 598 345} hide
 | 
			
		||||
        label UI open
 | 
			
		||||
        xywh {1 25 598 345} hide
 | 
			
		||||
      } {
 | 
			
		||||
        Fl_Tabs tabsUI {open
 | 
			
		||||
          xywh {2 25 596 345} selection_color 50
 | 
			
		||||
        } {
 | 
			
		||||
          Fl_Group tabBrowser {
 | 
			
		||||
            label Browser
 | 
			
		||||
            xywh {0 50 598 320}
 | 
			
		||||
            xywh {2 50 596 316} hide
 | 
			
		||||
          } {
 | 
			
		||||
            Fl_Group {} {open
 | 
			
		||||
              xywh {6 59 588 300} box ENGRAVED_FRAME
 | 
			
		||||
| 
						 | 
				
			
			@ -407,7 +407,7 @@ progdefaults.changed = true;}
 | 
			
		|||
          }
 | 
			
		||||
          Fl_Group tabContest {
 | 
			
		||||
            label Contest
 | 
			
		||||
            xywh {0 50 598 320} hide
 | 
			
		||||
            xywh {2 50 596 316} hide
 | 
			
		||||
          } {
 | 
			
		||||
            Fl_Group {} {
 | 
			
		||||
              label Exchanges open
 | 
			
		||||
| 
						 | 
				
			
			@ -547,7 +547,7 @@ progdefaults.changed = true;}
 | 
			
		|||
          }
 | 
			
		||||
          Fl_Group tabUserInterface {
 | 
			
		||||
            label General open
 | 
			
		||||
            xywh {0 50 598 320} hide
 | 
			
		||||
            xywh {2 50 596 316} hide
 | 
			
		||||
          } {
 | 
			
		||||
            Fl_Group {} {open
 | 
			
		||||
              xywh {6 55 586 76} box ENGRAVED_FRAME
 | 
			
		||||
| 
						 | 
				
			
			@ -649,7 +649,7 @@ progdefaults.changed = true;}
 | 
			
		|||
            }
 | 
			
		||||
            Fl_Group {} {
 | 
			
		||||
              label {Check for updates} open
 | 
			
		||||
              xywh {6 315 586 50} box ENGRAVED_FRAME align 21
 | 
			
		||||
              xywh {6 315 586 48} box ENGRAVED_FRAME align 21
 | 
			
		||||
            } {
 | 
			
		||||
              Fl_Check_Button btn_check_for_updates {
 | 
			
		||||
                label {Check for updates when starting program}
 | 
			
		||||
| 
						 | 
				
			
			@ -662,7 +662,7 @@ progdefaults.changed = true;}
 | 
			
		|||
          }
 | 
			
		||||
          Fl_Group tabLogServer {
 | 
			
		||||
            label Logging
 | 
			
		||||
            xywh {0 50 598 320} hide
 | 
			
		||||
            xywh {2 50 596 316} hide
 | 
			
		||||
          } {
 | 
			
		||||
            Fl_Group {} {
 | 
			
		||||
              label {QSO logging} open
 | 
			
		||||
| 
						 | 
				
			
			@ -791,7 +791,7 @@ defined here. Tab and newline are automatically included.} xywh {199 258 279 24}
 | 
			
		|||
            }
 | 
			
		||||
            Fl_Group {} {
 | 
			
		||||
              label {Client/Server Logbook} open
 | 
			
		||||
              xywh {6 313 586 55} box ENGRAVED_FRAME align 21
 | 
			
		||||
              xywh {6 313 586 51} box ENGRAVED_FRAME align 21
 | 
			
		||||
            } {
 | 
			
		||||
              Fl_Input xmllogServerAddress {
 | 
			
		||||
                label {Address:}
 | 
			
		||||
| 
						 | 
				
			
			@ -815,7 +815,7 @@ connect_to_log_server();}
 | 
			
		|||
          }
 | 
			
		||||
          Fl_Group tabMBars {
 | 
			
		||||
            label Macros
 | 
			
		||||
            xywh {0 50 598 320} hide
 | 
			
		||||
            xywh {2 50 596 316} hide
 | 
			
		||||
          } {
 | 
			
		||||
            Fl_Group {} {
 | 
			
		||||
              label {Number and position of macro bars} open
 | 
			
		||||
| 
						 | 
				
			
			@ -906,7 +906,7 @@ progdefaults.changed = true;}
 | 
			
		|||
              }
 | 
			
		||||
            }
 | 
			
		||||
            Fl_Group {} {open
 | 
			
		||||
              xywh {6 292 586 76} box ENGRAVED_FRAME
 | 
			
		||||
              xywh {6 292 586 72} box ENGRAVED_FRAME
 | 
			
		||||
            } {
 | 
			
		||||
              Fl_Check_Button btnUseLastMacro {
 | 
			
		||||
                label {Load last used macro file on startup}
 | 
			
		||||
| 
						 | 
				
			
			@ -936,7 +936,7 @@ progdefaults.changed = true;}
 | 
			
		|||
          }
 | 
			
		||||
          Fl_Group tabWF_UI {
 | 
			
		||||
            label {WF Ctrls}
 | 
			
		||||
            xywh {0 50 598 320} hide
 | 
			
		||||
            xywh {2 50 596 316}
 | 
			
		||||
          } {
 | 
			
		||||
            Fl_Group {} {open
 | 
			
		||||
              xywh {6 58 586 306} box ENGRAVED_BOX
 | 
			
		||||
| 
						 | 
				
			
			@ -1077,14 +1077,14 @@ WF_UI();}
 | 
			
		|||
      }
 | 
			
		||||
      Fl_Group tabWaterfall {
 | 
			
		||||
        label Waterfall
 | 
			
		||||
        xywh {0 25 598 345} hide
 | 
			
		||||
        xywh {1 25 598 345} hide
 | 
			
		||||
      } {
 | 
			
		||||
        Fl_Tabs tabsWaterfall {open
 | 
			
		||||
          xywh {2 25 596 345} color 50 selection_color 50
 | 
			
		||||
        } {
 | 
			
		||||
          Fl_Group {} {
 | 
			
		||||
            label Display open
 | 
			
		||||
            xywh {0 50 598 320}
 | 
			
		||||
            xywh {2 50 596 316} hide
 | 
			
		||||
          } {
 | 
			
		||||
            Fl_Group {} {
 | 
			
		||||
              label {Colors and cursors} open
 | 
			
		||||
| 
						 | 
				
			
			@ -1325,7 +1325,7 @@ progdefaults.changed = true;}
 | 
			
		|||
          }
 | 
			
		||||
          Fl_Group {} {
 | 
			
		||||
            label {FFT Processing}
 | 
			
		||||
            xywh {0 50 598 320} hide
 | 
			
		||||
            xywh {2 50 596 316} hide
 | 
			
		||||
          } {
 | 
			
		||||
            Fl_Group {} {open
 | 
			
		||||
              xywh {6 62 588 135} box ENGRAVED_FRAME
 | 
			
		||||
| 
						 | 
				
			
			@ -1395,7 +1395,7 @@ progdefaults.changed = true;}
 | 
			
		|||
          }
 | 
			
		||||
          Fl_Group {} {
 | 
			
		||||
            label Mouse
 | 
			
		||||
            xywh {0 50 598 320} hide
 | 
			
		||||
            xywh {2 50 596 316}
 | 
			
		||||
          } {
 | 
			
		||||
            Fl_Group {} {open
 | 
			
		||||
              xywh {6 62 588 170} box ENGRAVED_FRAME
 | 
			
		||||
| 
						 | 
				
			
			@ -1446,15 +1446,15 @@ behaves inside the waterfall} xywh {69 196 150 22} down_box BORDER_BOX align 8
 | 
			
		|||
      }
 | 
			
		||||
      Fl_Group tabModems {
 | 
			
		||||
        label Modems open
 | 
			
		||||
        xywh {0 25 598 345} hide
 | 
			
		||||
        xywh {1 25 598 343}
 | 
			
		||||
      } {
 | 
			
		||||
        Fl_Tabs tabsModems {
 | 
			
		||||
          label 2 open
 | 
			
		||||
          xywh {0 25 598 345} selection_color 50 align 9
 | 
			
		||||
          xywh {1 25 598 343} selection_color 50 align 9
 | 
			
		||||
        } {
 | 
			
		||||
          Fl_Group tabContestia {
 | 
			
		||||
            label {Cntst'}
 | 
			
		||||
            xywh {0 50 598 320}
 | 
			
		||||
            xywh {2 50 596 316} hide
 | 
			
		||||
          } {
 | 
			
		||||
            Fl_Group {} {
 | 
			
		||||
              label Contestia
 | 
			
		||||
| 
						 | 
				
			
			@ -1513,14 +1513,14 @@ progdefaults.changed = true;}
 | 
			
		|||
          }
 | 
			
		||||
          Fl_Group tabCW {
 | 
			
		||||
            label CW open
 | 
			
		||||
            xywh {0 50 598 320} hide
 | 
			
		||||
            xywh {2 50 596 316} hide
 | 
			
		||||
          } {
 | 
			
		||||
            Fl_Tabs tabsCW {open
 | 
			
		||||
              xywh {0 50 598 320} selection_color 50
 | 
			
		||||
              xywh {2 50 596 316} selection_color 50
 | 
			
		||||
            } {
 | 
			
		||||
              Fl_Group {} {
 | 
			
		||||
                label General
 | 
			
		||||
                xywh {0 75 598 295} align 5
 | 
			
		||||
                xywh {4 75 592 288} align 5
 | 
			
		||||
              } {
 | 
			
		||||
                Fl_Group {} {
 | 
			
		||||
                  label Receive open
 | 
			
		||||
| 
						 | 
				
			
			@ -1605,7 +1605,7 @@ progdefaults.changed = true;}
 | 
			
		|||
                }
 | 
			
		||||
                Fl_Group {} {
 | 
			
		||||
                  label Transmit open
 | 
			
		||||
                  xywh {6 239 588 126} box ENGRAVED_FRAME align 21
 | 
			
		||||
                  xywh {6 239 588 123} box ENGRAVED_FRAME align 21
 | 
			
		||||
                } {
 | 
			
		||||
                  Fl_Value_Slider sldrCWxmtWPM {
 | 
			
		||||
                    label {TX WPM}
 | 
			
		||||
| 
						 | 
				
			
			@ -1676,7 +1676,7 @@ progdefaults.changed = true;}
 | 
			
		|||
              }
 | 
			
		||||
              Fl_Group {} {
 | 
			
		||||
                label {Timing and QSK}
 | 
			
		||||
                xywh {0 75 598 295} align 5 hide
 | 
			
		||||
                xywh {4 75 592 288} align 5 hide
 | 
			
		||||
              } {
 | 
			
		||||
                Fl_Group {} {
 | 
			
		||||
                  label Timing open
 | 
			
		||||
| 
						 | 
				
			
			@ -1785,7 +1785,7 @@ progdefaults.changed = true;}
 | 
			
		|||
              }
 | 
			
		||||
              Fl_Group {} {
 | 
			
		||||
                label Prosigns
 | 
			
		||||
                xywh {0 75 598 295} align 5 hide
 | 
			
		||||
                xywh {2 75 592 289} align 5 hide
 | 
			
		||||
              } {
 | 
			
		||||
                Fl_Group {} {open
 | 
			
		||||
                  xywh {6 84 588 280} box ENGRAVED_FRAME
 | 
			
		||||
| 
						 | 
				
			
			@ -1956,7 +1956,7 @@ progdefaults.changed = true;} open
 | 
			
		|||
          }
 | 
			
		||||
          Fl_Group tabDomEX {
 | 
			
		||||
            label Dom
 | 
			
		||||
            xywh {0 50 598 320} hide
 | 
			
		||||
            xywh {2 50 596 316} hide
 | 
			
		||||
          } {
 | 
			
		||||
            Fl_Group {} {open
 | 
			
		||||
              xywh {6 60 588 180} box ENGRAVED_FRAME
 | 
			
		||||
| 
						 | 
				
			
			@ -2017,7 +2017,7 @@ progdefaults.changed = true;}
 | 
			
		|||
          }
 | 
			
		||||
          Fl_Group tabFeld {
 | 
			
		||||
            label Feld
 | 
			
		||||
            xywh {0 50 598 320} hide
 | 
			
		||||
            xywh {2 50 596 316} hide
 | 
			
		||||
          } {
 | 
			
		||||
            Fl_Group {} {open
 | 
			
		||||
              xywh {6 60 588 150} box ENGRAVED_FRAME
 | 
			
		||||
| 
						 | 
				
			
			@ -2090,7 +2090,7 @@ progdefaults.changed = true;}
 | 
			
		|||
          }
 | 
			
		||||
          Fl_Group tabMT63 {
 | 
			
		||||
            label MT63
 | 
			
		||||
            xywh {0 50 598 320} hide
 | 
			
		||||
            xywh {2 50 596 316} hide
 | 
			
		||||
          } {
 | 
			
		||||
            Fl_Group {} {open
 | 
			
		||||
              xywh {6 60 588 115} box ENGRAVED_FRAME align 21
 | 
			
		||||
| 
						 | 
				
			
			@ -2165,7 +2165,7 @@ progdefaults.changed = true;}
 | 
			
		|||
          }
 | 
			
		||||
          Fl_Group tabOlivia {
 | 
			
		||||
            label Olivia
 | 
			
		||||
            xywh {0 50 598 320} hide
 | 
			
		||||
            xywh {2 50 596 316} hide
 | 
			
		||||
          } {
 | 
			
		||||
            Fl_Group {} {open
 | 
			
		||||
              xywh {6 60 588 200} box ENGRAVED_FRAME
 | 
			
		||||
| 
						 | 
				
			
			@ -2223,7 +2223,7 @@ progdefaults.changed = true;}
 | 
			
		|||
          }
 | 
			
		||||
          Fl_Group tabPSK {
 | 
			
		||||
            label PSK
 | 
			
		||||
            xywh {0 50 598 320} hide
 | 
			
		||||
            xywh {2 50 596 316} hide
 | 
			
		||||
          } {
 | 
			
		||||
            Fl_Group {} {
 | 
			
		||||
              label {AFC behavior} open
 | 
			
		||||
| 
						 | 
				
			
			@ -2290,7 +2290,7 @@ progdefaults.changed = true;}
 | 
			
		|||
          }
 | 
			
		||||
          Fl_Group tabRTTY {
 | 
			
		||||
            label RTTY
 | 
			
		||||
            xywh {0 50 598 320} hide
 | 
			
		||||
            xywh {2 50 596 316} hide
 | 
			
		||||
          } {
 | 
			
		||||
            Fl_Group {} {open
 | 
			
		||||
              xywh {6 60 588 300} box ENGRAVED_FRAME
 | 
			
		||||
| 
						 | 
				
			
			@ -2481,8 +2481,8 @@ progdefaults.changed = true;}
 | 
			
		|||
            }
 | 
			
		||||
          }
 | 
			
		||||
          Fl_Group tabTHOR {
 | 
			
		||||
            label Thor
 | 
			
		||||
            xywh {0 50 598 320} hide
 | 
			
		||||
            label Thor open
 | 
			
		||||
            xywh {2 50 596 316}
 | 
			
		||||
          } {
 | 
			
		||||
            Fl_Group {} {open
 | 
			
		||||
              xywh {5 60 588 270} box ENGRAVED_FRAME
 | 
			
		||||
| 
						 | 
				
			
			@ -2513,11 +2513,32 @@ progdefaults.changed = true;}
 | 
			
		|||
                code1 {o->labelsize(FL_NORMAL_SIZE);}
 | 
			
		||||
                class Fl_Counter2
 | 
			
		||||
              }
 | 
			
		||||
              Fl_Check_Button valTHOR_PREAMBLE {
 | 
			
		||||
                label {Preamble Detection}
 | 
			
		||||
                callback {progdefaults.THOR_PREAMBLE = o->value();
 | 
			
		||||
progdefaults.changed = true;}
 | 
			
		||||
                tooltip {Detect the THOR preamble (and clear the Rx pipeline in preparation for data)} xywh {90 222 200 20} down_box DOWN_BOX
 | 
			
		||||
                code0 {o->value(progdefaults.THOR_PREAMBLE);}
 | 
			
		||||
              }
 | 
			
		||||
              Fl_Check_Button valTHOR_SOFTSYMBOLS {
 | 
			
		||||
                label {Soft-symbol decoding}
 | 
			
		||||
                callback {progdefaults.THOR_SOFTSYMBOLS = o->value();
 | 
			
		||||
progdefaults.changed = true;}
 | 
			
		||||
                tooltip {Use soft-decision decoding for symbol detection (also assists soft-bit decoding)} xywh {90 252 190 20} down_box DOWN_BOX
 | 
			
		||||
                code0 {o->value(progdefaults.THOR_SOFTSYMBOLS);}
 | 
			
		||||
              }
 | 
			
		||||
              Fl_Check_Button valTHOR_SOFTBITS {
 | 
			
		||||
                label {Soft-bit decoding}
 | 
			
		||||
                callback {progdefaults.THOR_SOFTBITS = o->value();
 | 
			
		||||
progdefaults.changed = true;}
 | 
			
		||||
                tooltip {Use soft-bit viterbi decoding for better Forward Error Correction (works best with soft-symbol decoding enabled)} xywh {90 282 170 20} down_box DOWN_BOX
 | 
			
		||||
                code0 {o->value(progdefaults.THOR_SOFTBITS);}
 | 
			
		||||
              }
 | 
			
		||||
              Fl_Value_Slider valThorCWI {
 | 
			
		||||
                label {CWI threshold}
 | 
			
		||||
                callback {progdefaults.ThorCWI = o->value();
 | 
			
		||||
progdefaults.changed = true;}
 | 
			
		||||
                tooltip {CWI detection and suppression} xywh {89 295 260 20} type Horizontal align 1 textsize 14
 | 
			
		||||
                tooltip {CWI detection and suppression} xywh {90 196 260 20} type Horizontal align 1 textsize 14
 | 
			
		||||
                code0 {o->value(progdefaults.ThorCWI);}
 | 
			
		||||
                code1 {o->labelsize(FL_NORMAL_SIZE); o->textsize(FL_NORMAL_SIZE);}
 | 
			
		||||
                class Fl_Value_Slider2
 | 
			
		||||
| 
						 | 
				
			
			@ -2525,39 +2546,18 @@ progdefaults.changed = true;}
 | 
			
		|||
              Fl_Counter valTHOR_PATHS {
 | 
			
		||||
                label {Paths (hidden)}
 | 
			
		||||
                callback {progdefaults.THOR_PATHS = (int)o->value();
 | 
			
		||||
progdefaults.changed = true;}
 | 
			
		||||
                xywh {429 193 75 21} type Simple align 1 minimum 4 maximum 8 step 1 value 5
 | 
			
		||||
progdefaults.changed = true;} selected
 | 
			
		||||
                xywh {468 274 75 21} type Simple align 1 minimum 4 maximum 8 step 1 value 5
 | 
			
		||||
                code0 {o->value(progdefaults.THOR_PATHS);}
 | 
			
		||||
                code1 {o->labelsize(FL_NORMAL_SIZE);}
 | 
			
		||||
                code2 {o->hide();}
 | 
			
		||||
                class Fl_Counter2
 | 
			
		||||
              }
 | 
			
		||||
              Fl_Check_Button valTHOR_PREAMBLE {
 | 
			
		||||
                label {Preamble Detection}
 | 
			
		||||
                callback {progdefaults.THOR_PREAMBLE = o->value();
 | 
			
		||||
progdefaults.changed = true;}
 | 
			
		||||
                tooltip {Detect the THOR preamble (and clear the Rx pipeline in preparation for data)} xywh {90 170 200 20} down_box DOWN_BOX
 | 
			
		||||
                code0 {o->value(progdefaults.THOR_PREAMBLE);}
 | 
			
		||||
              }
 | 
			
		||||
              Fl_Check_Button valTHOR_SOFTSYMBOLS {
 | 
			
		||||
                label {Soft-symbol decoding}
 | 
			
		||||
                callback {progdefaults.THOR_SOFTSYMBOLS = o->value();
 | 
			
		||||
progdefaults.changed = true;}
 | 
			
		||||
                tooltip {Use soft-decision decoding for symbol detection (also assists soft-bit decoding)} xywh {90 200 190 20} down_box DOWN_BOX
 | 
			
		||||
                code0 {o->value(progdefaults.THOR_SOFTSYMBOLS);}
 | 
			
		||||
              }
 | 
			
		||||
              Fl_Check_Button valTHOR_SOFTBITS {
 | 
			
		||||
                label {Soft-bit decoding}
 | 
			
		||||
                callback {progdefaults.THOR_SOFTBITS = o->value();
 | 
			
		||||
progdefaults.changed = true;}
 | 
			
		||||
                tooltip {Use soft-bit viterbi decoding for better Forward Error Correction (works best with soft-symbol decoding enabled)} xywh {90 230 170 20} down_box DOWN_BOX
 | 
			
		||||
                code0 {o->value(progdefaults.THOR_SOFTBITS);}
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
          Fl_Group tabPacket {
 | 
			
		||||
            label Packet
 | 
			
		||||
            xywh {0 50 598 320} hide
 | 
			
		||||
            xywh {2 50 596 316} hide
 | 
			
		||||
          } {
 | 
			
		||||
            Fl_Group {} {open
 | 
			
		||||
              xywh {6 60 588 296} box ENGRAVED_FRAME
 | 
			
		||||
| 
						 | 
				
			
			@ -2679,7 +2679,7 @@ progdefaults.changed = true;}
 | 
			
		|||
          }
 | 
			
		||||
          Fl_Group tabNavtex {
 | 
			
		||||
            label Navtex
 | 
			
		||||
            xywh {0 50 598 320} hide
 | 
			
		||||
            xywh {2 50 596 316} hide
 | 
			
		||||
          } {
 | 
			
		||||
            Fl_Group {} {open
 | 
			
		||||
              xywh {6 60 588 300}
 | 
			
		||||
| 
						 | 
				
			
			@ -2709,7 +2709,7 @@ fc->show();}
 | 
			
		|||
          }
 | 
			
		||||
          Fl_Group tabWefax {
 | 
			
		||||
            label Wefax
 | 
			
		||||
            xywh {0 50 598 320} hide
 | 
			
		||||
            xywh {2 50 596 316} hide
 | 
			
		||||
          } {
 | 
			
		||||
            Fl_Group {} {open
 | 
			
		||||
              xywh {6 60 588 300}
 | 
			
		||||
| 
						 | 
				
			
			@ -2782,14 +2782,14 @@ progdefaults.changed = true;}
 | 
			
		|||
      }
 | 
			
		||||
      Fl_Group tabRig {
 | 
			
		||||
        label Rig
 | 
			
		||||
        tooltip {Transceiver control} xywh {0 25 598 345} hide
 | 
			
		||||
        tooltip {Transceiver control} xywh {1 25 598 345} hide
 | 
			
		||||
      } {
 | 
			
		||||
        Fl_Tabs tabsRig {open
 | 
			
		||||
          xywh {4 25 592 345} selection_color 50
 | 
			
		||||
          xywh {2 25 596 345} selection_color 50
 | 
			
		||||
        } {
 | 
			
		||||
          Fl_Group {} {
 | 
			
		||||
            label {Hardware PTT}
 | 
			
		||||
            xywh {0 50 598 320}
 | 
			
		||||
            xywh {2 50 596 316}
 | 
			
		||||
          } {
 | 
			
		||||
            Fl_Group {} {open
 | 
			
		||||
              xywh {6 57 588 38} box ENGRAVED_FRAME
 | 
			
		||||
| 
						 | 
				
			
			@ -2926,7 +2926,7 @@ progdefaults.changed = true;}
 | 
			
		|||
          }
 | 
			
		||||
          Fl_Group {} {
 | 
			
		||||
            label RigCAT
 | 
			
		||||
            tooltip {Rig Control using xml spec file} xywh {0 50 598 320} hide
 | 
			
		||||
            tooltip {Rig Control using xml spec file} xywh {2 50 596 316} hide
 | 
			
		||||
          } {
 | 
			
		||||
            Fl_Check_Button chkUSERIGCAT {
 | 
			
		||||
              label {Use RigCAT}
 | 
			
		||||
| 
						 | 
				
			
			@ -3116,7 +3116,7 @@ btnRevertRIGCAT->activate();}
 | 
			
		|||
          }
 | 
			
		||||
          Fl_Group tabHamlib {
 | 
			
		||||
            label Hamlib
 | 
			
		||||
            xywh {0 50 598 320} hide
 | 
			
		||||
            xywh {2 50 596 316} hide
 | 
			
		||||
          } {
 | 
			
		||||
            Fl_Check_Button chkUSEHAMLIB {
 | 
			
		||||
              label {Use Hamlib}
 | 
			
		||||
| 
						 | 
				
			
			@ -3317,7 +3317,7 @@ hamlib_restore_defaults();
 | 
			
		|||
          }
 | 
			
		||||
          Fl_Group {} {
 | 
			
		||||
            label MemMap
 | 
			
		||||
            xywh {0 50 598 320} hide
 | 
			
		||||
            xywh {2 50 596 316} hide
 | 
			
		||||
          } {
 | 
			
		||||
            Fl_Group grpMemmap {open
 | 
			
		||||
              xywh {6 58 588 185} box ENGRAVED_FRAME
 | 
			
		||||
| 
						 | 
				
			
			@ -3364,7 +3364,7 @@ progdefaults.changed = true;}
 | 
			
		|||
          }
 | 
			
		||||
          Fl_Group tabXMLRPC {
 | 
			
		||||
            label {XML-RPC}
 | 
			
		||||
            xywh {0 50 598 320} hide
 | 
			
		||||
            xywh {2 50 596 316} hide
 | 
			
		||||
          } {
 | 
			
		||||
            Fl_Group grpXMLRPC {open
 | 
			
		||||
              xywh {6 58 588 160} box ENGRAVED_FRAME
 | 
			
		||||
| 
						 | 
				
			
			@ -3403,14 +3403,14 @@ progdefaults.changed = true;}
 | 
			
		|||
      }
 | 
			
		||||
      Fl_Group tabSoundCard {
 | 
			
		||||
        label Audio
 | 
			
		||||
        tooltip {Audio devices} xywh {0 25 598 345} hide
 | 
			
		||||
        tooltip {Audio devices} xywh {1 25 598 345} hide
 | 
			
		||||
      } {
 | 
			
		||||
        Fl_Tabs tabsSoundCard {open
 | 
			
		||||
          xywh {2 25 596 345} selection_color 50
 | 
			
		||||
        } {
 | 
			
		||||
          Fl_Group tabAudio {
 | 
			
		||||
            label Devices
 | 
			
		||||
            xywh {0 50 598 320}
 | 
			
		||||
            xywh {2 50 596 316}
 | 
			
		||||
          } {
 | 
			
		||||
            Fl_Group AudioOSS {
 | 
			
		||||
              xywh {6 60 588 45} box ENGRAVED_FRAME
 | 
			
		||||
| 
						 | 
				
			
			@ -3494,7 +3494,7 @@ resetSoundCard();}
 | 
			
		|||
          }
 | 
			
		||||
          Fl_Group tabAudioOpt {
 | 
			
		||||
            label Settings
 | 
			
		||||
            xywh {0 50 598 320} hide
 | 
			
		||||
            xywh {2 50 596 316} hide
 | 
			
		||||
          } {
 | 
			
		||||
            Fl_Group grpAudioSampleRate {
 | 
			
		||||
              label {Sample rate} open
 | 
			
		||||
| 
						 | 
				
			
			@ -3575,7 +3575,7 @@ progdefaults.changed = true;}
 | 
			
		|||
          }
 | 
			
		||||
          Fl_Group tabMixer {
 | 
			
		||||
            label Mixer open
 | 
			
		||||
            xywh {0 50 598 320} hide
 | 
			
		||||
            xywh {2 50 596 316} hide
 | 
			
		||||
          } {
 | 
			
		||||
            Fl_Group {} {
 | 
			
		||||
              label {OSS mixer} open
 | 
			
		||||
| 
						 | 
				
			
			@ -3640,7 +3640,7 @@ progdefaults.changed = true;}
 | 
			
		|||
          }
 | 
			
		||||
          Fl_Group tabAudioRightChannel {
 | 
			
		||||
            label {Right channel} open
 | 
			
		||||
            xywh {0 50 598 320} hide
 | 
			
		||||
            xywh {2 50 596 316} hide
 | 
			
		||||
          } {
 | 
			
		||||
            Fl_Check_Button chkForceMono {
 | 
			
		||||
              label {Mono audio output}
 | 
			
		||||
| 
						 | 
				
			
			@ -3778,7 +3778,7 @@ if (o->value()) {
 | 
			
		|||
      }
 | 
			
		||||
      Fl_Group tabID {
 | 
			
		||||
        label ID open
 | 
			
		||||
        xywh {0 25 598 345} hide
 | 
			
		||||
        xywh {1 25 598 343} hide
 | 
			
		||||
      } {
 | 
			
		||||
        Fl_Group {} {
 | 
			
		||||
          label {Video Preamble ID} open
 | 
			
		||||
| 
						 | 
				
			
			@ -3906,7 +3906,7 @@ progdefaults.changed = true;}
 | 
			
		|||
            code2 {if (progdefaults.rsid_notify_only) chkRSidAutoDisable->deactivate();}
 | 
			
		||||
          }
 | 
			
		||||
          Fl_Check_Button chkRSidNotifyOnly {
 | 
			
		||||
            label {Notifications only}
 | 
			
		||||
            label {Notify only}
 | 
			
		||||
            callback {progdefaults.rsid_notify_only = o->value();
 | 
			
		||||
notify_create_rsid_event(progdefaults.rsid_notify_only);
 | 
			
		||||
if (progdefaults.rsid_notify_only) {
 | 
			
		||||
| 
						 | 
				
			
			@ -3937,6 +3937,16 @@ progdefaults.changed = true;}
 | 
			
		|||
            code2 {o->labelsize(FL_NORMAL_SIZE); o->textsize(FL_NORMAL_SIZE);}
 | 
			
		||||
            class Fl_Value_Slider2
 | 
			
		||||
          }
 | 
			
		||||
          Fl_Value_Slider sldrRSIDresolution {
 | 
			
		||||
            label Sensitivity
 | 
			
		||||
            callback {progdefaults.rsid_resolution = (int)o->value();
 | 
			
		||||
progdefaults.changed = true;}
 | 
			
		||||
            tooltip {2 = low sensitivity / decreased false detection
 | 
			
		||||
5 = high sensitivity / increased false detection} xywh {133 317 90 18} type Horizontal align 8 minimum 2 maximum 5 step 1 value 5 textsize 14
 | 
			
		||||
            code0 {o->value(progdefaults.rsid_resolution);}
 | 
			
		||||
            code2 {o->labelsize(FL_NORMAL_SIZE); o->textsize(FL_NORMAL_SIZE);}
 | 
			
		||||
            class Fl_Value_Slider2
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        Fl_Group {} {
 | 
			
		||||
          label {Reed-Solomon ID (Tx)} open
 | 
			
		||||
| 
						 | 
				
			
			@ -3973,14 +3983,14 @@ progdefaults.changed = true;}
 | 
			
		|||
      }
 | 
			
		||||
      Fl_Group tabMisc {
 | 
			
		||||
        label Misc open
 | 
			
		||||
        xywh {0 25 598 345} hide
 | 
			
		||||
        xywh {1 25 598 345} hide
 | 
			
		||||
      } {
 | 
			
		||||
        Fl_Tabs tabsMisc {open
 | 
			
		||||
          xywh {4 25 592 345} selection_color 50
 | 
			
		||||
          xywh {2 25 596 345} selection_color 50
 | 
			
		||||
        } {
 | 
			
		||||
          Fl_Group tabCPUspeed {
 | 
			
		||||
            label CPU open
 | 
			
		||||
            xywh {0 50 598 320}
 | 
			
		||||
            xywh {2 50 596 316}
 | 
			
		||||
          } {
 | 
			
		||||
            Fl_Group {} {open
 | 
			
		||||
              xywh {6 60 588 51} box ENGRAVED_FRAME align 21
 | 
			
		||||
| 
						 | 
				
			
			@ -3996,7 +4006,7 @@ progdefaults.changed = true;}
 | 
			
		|||
          }
 | 
			
		||||
          Fl_Group tabNBEMS {
 | 
			
		||||
            label NBEMS open
 | 
			
		||||
            xywh {0 50 598 320} hide
 | 
			
		||||
            xywh {2 50 596 316} hide
 | 
			
		||||
          } {
 | 
			
		||||
            Fl_Group {} {
 | 
			
		||||
              label {NBEMS data file interface} open
 | 
			
		||||
| 
						 | 
				
			
			@ -4059,7 +4069,7 @@ progdefaults.changed=true;}
 | 
			
		|||
          }
 | 
			
		||||
          Fl_Group tabPskmail {
 | 
			
		||||
            label Pskmail
 | 
			
		||||
            xywh {0 50 598 320} align 5 hide
 | 
			
		||||
            xywh {2 50 596 316} align 5 hide
 | 
			
		||||
          } {
 | 
			
		||||
            Fl_Group {} {
 | 
			
		||||
              label {Mail Server Attributes} open
 | 
			
		||||
| 
						 | 
				
			
			@ -4126,7 +4136,7 @@ progdefaults.changed = true;}
 | 
			
		|||
          }
 | 
			
		||||
          Fl_Group tabSpot {
 | 
			
		||||
            label Spotting
 | 
			
		||||
            xywh {0 50 598 320} hide
 | 
			
		||||
            xywh {2 50 596 316} hide
 | 
			
		||||
          } {
 | 
			
		||||
            Fl_Group {} {
 | 
			
		||||
              label {PSK Reporter} open
 | 
			
		||||
| 
						 | 
				
			
			@ -4202,7 +4212,7 @@ progdefaults.changed = true;}
 | 
			
		|||
          }
 | 
			
		||||
          Fl_Group tabSweetSpot {
 | 
			
		||||
            label {Sweet Spot}
 | 
			
		||||
            xywh {0 50 598 320} hide
 | 
			
		||||
            xywh {2 50 596 316} hide
 | 
			
		||||
          } {
 | 
			
		||||
            Fl_Group {} {open
 | 
			
		||||
              xywh {6 60 588 75} box ENGRAVED_FRAME align 21
 | 
			
		||||
| 
						 | 
				
			
			@ -4266,7 +4276,7 @@ progdefaults.changed=true;}
 | 
			
		|||
          }
 | 
			
		||||
          Fl_Group tabText_IO {
 | 
			
		||||
            label {Text i/o}
 | 
			
		||||
            xywh {0 50 598 320} hide
 | 
			
		||||
            xywh {2 50 596 316} hide
 | 
			
		||||
          } {
 | 
			
		||||
            Fl_Group grpTalker {
 | 
			
		||||
              label {Talker Socket (MS only)} open
 | 
			
		||||
| 
						 | 
				
			
			@ -4306,7 +4316,7 @@ progdefaults.changed = true;}
 | 
			
		|||
          }
 | 
			
		||||
          Fl_Group tabDTMFdecode {
 | 
			
		||||
            label DTMF
 | 
			
		||||
            xywh {0 50 598 320} hide
 | 
			
		||||
            xywh {2 50 596 316} hide
 | 
			
		||||
          } {
 | 
			
		||||
            Fl_Check_Button chkDTMFdecode {
 | 
			
		||||
              label {Decode DTMF tones}
 | 
			
		||||
| 
						 | 
				
			
			@ -4317,7 +4327,7 @@ progdefaults.changed = true;}
 | 
			
		|||
          }
 | 
			
		||||
          Fl_Group tabWX {
 | 
			
		||||
            label WX
 | 
			
		||||
            xywh {0 50 598 320} hide
 | 
			
		||||
            xywh {2 50 596 316} hide
 | 
			
		||||
          } {
 | 
			
		||||
            Fl_Group {} {
 | 
			
		||||
              label {Weather query specification} open
 | 
			
		||||
| 
						 | 
				
			
			@ -4417,19 +4427,19 @@ progdefaults.changed = true;}
 | 
			
		|||
        }
 | 
			
		||||
      }
 | 
			
		||||
      Fl_Group tabQRZ {
 | 
			
		||||
        label Web
 | 
			
		||||
        tooltip {Callsign database} xywh {0 25 598 345} hide
 | 
			
		||||
        label Web open
 | 
			
		||||
        tooltip {Callsign database} xywh {1 25 598 345} hide
 | 
			
		||||
      } {
 | 
			
		||||
        Fl_Tabs {} {open
 | 
			
		||||
          xywh {4 25 592 345}
 | 
			
		||||
          xywh {2 25 596 345}
 | 
			
		||||
        } {
 | 
			
		||||
          Fl_Group {} {
 | 
			
		||||
            label {Call Lookup}
 | 
			
		||||
            xywh {0 50 598 320}
 | 
			
		||||
            label {Call Lookup} open
 | 
			
		||||
            xywh {2 50 596 316}
 | 
			
		||||
          } {
 | 
			
		||||
            Fl_Group {} {
 | 
			
		||||
              label {Web Browser lookup} open
 | 
			
		||||
              xywh {6 52 588 122} box ENGRAVED_FRAME align 21
 | 
			
		||||
              xywh {6 53 588 122} box ENGRAVED_FRAME align 21
 | 
			
		||||
            } {
 | 
			
		||||
              Fl_Round_Button btnQRZWEBnotavailable {
 | 
			
		||||
                label None
 | 
			
		||||
| 
						 | 
				
			
			@ -4559,7 +4569,7 @@ o->label((inpQRZuserpassword->type() & FL_SECRET_INPUT) ? "Show" : "Hide");}
 | 
			
		|||
          }
 | 
			
		||||
          Fl_Group {} {
 | 
			
		||||
            label eQSL open
 | 
			
		||||
            xywh {0 50 598 320} hide
 | 
			
		||||
            xywh {2 50 596 316} hide
 | 
			
		||||
          } {
 | 
			
		||||
            Fl_Input inpEQSL_id {
 | 
			
		||||
              label {User ID}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -436,13 +436,6 @@ bool clean_exit(bool ask);
 | 
			
		|||
 | 
			
		||||
void cb_init_mode(Fl_Widget *, void *arg);
 | 
			
		||||
 | 
			
		||||
void cb_oliviaA(Fl_Widget *w, void *arg);
 | 
			
		||||
void cb_oliviaB(Fl_Widget *w, void *arg);
 | 
			
		||||
void cb_oliviaC(Fl_Widget *w, void *arg);
 | 
			
		||||
void cb_oliviaD(Fl_Widget *w, void *arg);
 | 
			
		||||
void cb_oliviaE(Fl_Widget *w, void *arg);
 | 
			
		||||
void cb_oliviaF(Fl_Widget *w, void *arg);
 | 
			
		||||
void cb_oliviaG(Fl_Widget *w, void *arg);
 | 
			
		||||
void cb_oliviaCustom(Fl_Widget *w, void *arg);
 | 
			
		||||
 | 
			
		||||
void cb_contestiaA(Fl_Widget *w, void *arg);
 | 
			
		||||
| 
						 | 
				
			
			@ -477,6 +470,7 @@ Fl_Menu_Item quick_change_psk[] = {
 | 
			
		|||
	{ mode_info[MODE_PSK125].name, 0, cb_init_mode, (void *)MODE_PSK125 },
 | 
			
		||||
	{ mode_info[MODE_PSK250].name, 0, cb_init_mode, (void *)MODE_PSK250 },
 | 
			
		||||
	{ mode_info[MODE_PSK500].name, 0, cb_init_mode, (void *)MODE_PSK500 },
 | 
			
		||||
	{ mode_info[MODE_PSK1000].name, 0, cb_init_mode, (void *)MODE_PSK1000 },
 | 
			
		||||
	{ 0 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -493,6 +487,46 @@ Fl_Menu_Item quick_change_pskr[] = {
 | 
			
		|||
	{ mode_info[MODE_PSK125R].name, 0, cb_init_mode, (void *)MODE_PSK125R },
 | 
			
		||||
	{ mode_info[MODE_PSK250R].name, 0, cb_init_mode, (void *)MODE_PSK250R },
 | 
			
		||||
	{ mode_info[MODE_PSK500R].name, 0, cb_init_mode, (void *)MODE_PSK500R },
 | 
			
		||||
	{ mode_info[MODE_PSK1000R].name, 0, cb_init_mode, (void *)MODE_PSK1000R },
 | 
			
		||||
	{ 0 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Fl_Menu_Item quick_change_psk_multiR[] = {
 | 
			
		||||
	{ mode_info[MODE_4X_PSK63R].name, 0, cb_init_mode, (void *)MODE_4X_PSK63R },
 | 
			
		||||
	{ mode_info[MODE_5X_PSK63R].name, 0, cb_init_mode, (void *)MODE_5X_PSK63R },
 | 
			
		||||
	{ mode_info[MODE_10X_PSK63R].name, 0, cb_init_mode, (void *)MODE_10X_PSK63R },
 | 
			
		||||
	{ mode_info[MODE_20X_PSK63R].name, 0, cb_init_mode, (void *)MODE_20X_PSK63R },
 | 
			
		||||
	{ mode_info[MODE_32X_PSK63R].name, 0, cb_init_mode, (void *)MODE_32X_PSK63R },
 | 
			
		||||
 | 
			
		||||
	{ mode_info[MODE_4X_PSK125R].name, 0, cb_init_mode, (void *)MODE_4X_PSK125R },
 | 
			
		||||
	{ mode_info[MODE_5X_PSK125R].name, 0, cb_init_mode, (void *)MODE_5X_PSK125R },
 | 
			
		||||
	{ mode_info[MODE_10X_PSK125R].name, 0, cb_init_mode, (void *)MODE_10X_PSK125R },
 | 
			
		||||
	{ mode_info[MODE_12X_PSK125R].name, 0, cb_init_mode, (void *)MODE_12X_PSK125R },
 | 
			
		||||
	{ mode_info[MODE_16X_PSK125R].name, 0, cb_init_mode, (void *)MODE_16X_PSK125R },
 | 
			
		||||
 | 
			
		||||
	{ mode_info[MODE_2X_PSK250R].name, 0, cb_init_mode, (void *)MODE_2X_PSK250R },
 | 
			
		||||
	{ mode_info[MODE_3X_PSK250R].name, 0, cb_init_mode, (void *)MODE_3X_PSK250R },
 | 
			
		||||
	{ mode_info[MODE_5X_PSK250R].name, 0, cb_init_mode, (void *)MODE_5X_PSK250R },
 | 
			
		||||
	{ mode_info[MODE_6X_PSK250R].name, 0, cb_init_mode, (void *)MODE_6X_PSK250R },
 | 
			
		||||
	{ mode_info[MODE_7X_PSK250R].name, 0, cb_init_mode, (void *)MODE_7X_PSK250R },
 | 
			
		||||
 | 
			
		||||
	{ mode_info[MODE_2X_PSK500R].name, 0, cb_init_mode, (void *)MODE_2X_PSK500R },
 | 
			
		||||
	{ mode_info[MODE_3X_PSK500R].name, 0, cb_init_mode, (void *)MODE_3X_PSK500R },
 | 
			
		||||
	{ mode_info[MODE_4X_PSK500R].name, 0, cb_init_mode, (void *)MODE_4X_PSK500R },
 | 
			
		||||
 | 
			
		||||
	{ mode_info[MODE_2X_PSK800R].name, 0, cb_init_mode, (void *)MODE_2X_PSK800R },
 | 
			
		||||
 | 
			
		||||
	{ mode_info[MODE_2X_PSK1000R].name, 0, cb_init_mode, (void *)MODE_2X_PSK1000R },
 | 
			
		||||
	{ 0 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Fl_Menu_Item quick_change_psk_multi[] = {
 | 
			
		||||
	{ mode_info[MODE_12X_PSK125].name, 0, cb_init_mode, (void *)MODE_12X_PSK125 },
 | 
			
		||||
	{ mode_info[MODE_6X_PSK250].name, 0, cb_init_mode, (void *)MODE_6X_PSK250 },
 | 
			
		||||
	{ mode_info[MODE_2X_PSK500].name, 0, cb_init_mode, (void *)MODE_2X_PSK500 },
 | 
			
		||||
	{ mode_info[MODE_4X_PSK500].name, 0, cb_init_mode, (void *)MODE_4X_PSK500 },
 | 
			
		||||
	{ mode_info[MODE_2X_PSK800].name, 0, cb_init_mode, (void *)MODE_2X_PSK800 },
 | 
			
		||||
	{ mode_info[MODE_2X_PSK1000].name, 0, cb_init_mode, (void *)MODE_2X_PSK1000 },
 | 
			
		||||
	{ 0 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -505,6 +539,7 @@ Fl_Menu_Item quick_change_mfsk[] = {
 | 
			
		|||
	{ mode_info[MODE_MFSK31].name, 0, cb_init_mode, (void *)MODE_MFSK31 },
 | 
			
		||||
	{ mode_info[MODE_MFSK32].name, 0, cb_init_mode, (void *)MODE_MFSK32 },
 | 
			
		||||
	{ mode_info[MODE_MFSK64].name, 0, cb_init_mode, (void *)MODE_MFSK64 },
 | 
			
		||||
	{ mode_info[MODE_MFSK128].name, 0, cb_init_mode, (void *)MODE_MFSK128 },
 | 
			
		||||
	{ 0 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -534,8 +569,10 @@ Fl_Menu_Item quick_change_thor[] = {
 | 
			
		|||
	{ mode_info[MODE_THOR11].name, 0, cb_init_mode, (void *)MODE_THOR11 },
 | 
			
		||||
	{ mode_info[MODE_THOR16].name, 0, cb_init_mode, (void *)MODE_THOR16 },
 | 
			
		||||
	{ mode_info[MODE_THOR22].name, 0, cb_init_mode, (void *)MODE_THOR22 },
 | 
			
		||||
	{ mode_info[MODE_THOR44].name, 0, cb_init_mode, (void *)MODE_THOR44 },
 | 
			
		||||
	{ mode_info[MODE_THOR88].name, 0, cb_init_mode, (void *)MODE_THOR88 },
 | 
			
		||||
	{ mode_info[MODE_THOR25x4].name, 0, cb_init_mode, (void *)MODE_THOR25x4 },
 | 
			
		||||
	{ mode_info[MODE_THOR50x1].name, 0, cb_init_mode, (void *)MODE_THOR50x1 },
 | 
			
		||||
	{ mode_info[MODE_THOR50x2].name, 0, cb_init_mode, (void *)MODE_THOR50x2 },
 | 
			
		||||
	{ mode_info[MODE_THOR100].name, 0, cb_init_mode, (void *)MODE_THOR100 },
 | 
			
		||||
	{ 0 }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -573,13 +610,15 @@ Fl_Menu_Item quick_change_throb[] = {
 | 
			
		|||
};
 | 
			
		||||
 | 
			
		||||
Fl_Menu_Item quick_change_olivia[] = {
 | 
			
		||||
	{ "8/250", 0, cb_oliviaA, (void *)MODE_OLIVIA },
 | 
			
		||||
	{ "4/500", 0, cb_oliviaF, (void *)MODE_OLIVIA },
 | 
			
		||||
	{ "8/500", 0, cb_oliviaB, (void *)MODE_OLIVIA },
 | 
			
		||||
	{ "16/500", 0, cb_oliviaC, (void *)MODE_OLIVIA },
 | 
			
		||||
	{ "8/1000", 0, cb_oliviaD, (void *)MODE_OLIVIA },
 | 
			
		||||
	{ "32/1000", 0, cb_oliviaE, (void *)MODE_OLIVIA },
 | 
			
		||||
	{ "64/2000", 0, cb_oliviaG, (void *)MODE_OLIVIA },
 | 
			
		||||
	{ mode_info[MODE_OLIVIA_4_250].name, 0, cb_init_mode, (void *)MODE_OLIVIA_4_250 },
 | 
			
		||||
	{ mode_info[MODE_OLIVIA_8_250].name, 0, cb_init_mode, (void *)MODE_OLIVIA_8_250 },
 | 
			
		||||
	{ mode_info[MODE_OLIVIA_4_500].name, 0, cb_init_mode, (void *)MODE_OLIVIA_4_500 },
 | 
			
		||||
	{ mode_info[MODE_OLIVIA_8_500].name, 0, cb_init_mode, (void *)MODE_OLIVIA_8_500 },
 | 
			
		||||
	{ mode_info[MODE_OLIVIA_16_500].name, 0, cb_init_mode, (void *)MODE_OLIVIA_16_500 },
 | 
			
		||||
	{ mode_info[MODE_OLIVIA_8_1000].name, 0, cb_init_mode, (void *)MODE_OLIVIA_8_1000 },
 | 
			
		||||
	{ mode_info[MODE_OLIVIA_16_1000].name, 0, cb_init_mode, (void *)MODE_OLIVIA_16_1000 },
 | 
			
		||||
	{ mode_info[MODE_OLIVIA_32_1000].name, 0, cb_init_mode, (void *)MODE_OLIVIA_32_1000 },
 | 
			
		||||
	{ mode_info[MODE_OLIVIA_64_2000].name, 0, cb_init_mode, (void *)MODE_OLIVIA_64_2000 },
 | 
			
		||||
	{ _("Custom..."), 0, cb_oliviaCustom, (void *)MODE_OLIVIA },
 | 
			
		||||
	{ 0 }
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -641,62 +680,6 @@ void set_olivia_tab_widgets()
 | 
			
		|||
	set_olivia_default_integ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cb_oliviaA(Fl_Widget *w, void *arg)
 | 
			
		||||
{
 | 
			
		||||
	progdefaults.oliviatones = 2;
 | 
			
		||||
	progdefaults.oliviabw = 1;
 | 
			
		||||
	set_olivia_tab_widgets();
 | 
			
		||||
	cb_init_mode(w, arg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cb_oliviaB(Fl_Widget *w, void *arg)
 | 
			
		||||
{
 | 
			
		||||
	progdefaults.oliviatones = 2;
 | 
			
		||||
	progdefaults.oliviabw = 2;
 | 
			
		||||
	set_olivia_tab_widgets();
 | 
			
		||||
	cb_init_mode(w, arg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cb_oliviaC(Fl_Widget *w, void *arg)
 | 
			
		||||
{
 | 
			
		||||
	progdefaults.oliviatones = 3;
 | 
			
		||||
	progdefaults.oliviabw = 2;
 | 
			
		||||
	set_olivia_tab_widgets();
 | 
			
		||||
	cb_init_mode(w, arg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cb_oliviaD(Fl_Widget *w, void *arg)
 | 
			
		||||
{
 | 
			
		||||
	progdefaults.oliviatones = 2;
 | 
			
		||||
	progdefaults.oliviabw = 3;
 | 
			
		||||
	set_olivia_tab_widgets();
 | 
			
		||||
	cb_init_mode(w, arg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cb_oliviaE(Fl_Widget *w, void *arg)
 | 
			
		||||
{
 | 
			
		||||
	progdefaults.oliviatones = 4;
 | 
			
		||||
	progdefaults.oliviabw = 3;
 | 
			
		||||
	set_olivia_tab_widgets();
 | 
			
		||||
	cb_init_mode(w, arg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cb_oliviaF(Fl_Widget *w, void *arg)
 | 
			
		||||
{
 | 
			
		||||
	progdefaults.oliviatones = 1;
 | 
			
		||||
	progdefaults.oliviabw = 2;
 | 
			
		||||
	set_olivia_tab_widgets();
 | 
			
		||||
	cb_init_mode(w, arg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cb_oliviaG(Fl_Widget *w, void *arg)
 | 
			
		||||
{
 | 
			
		||||
	progdefaults.oliviatones = 5;
 | 
			
		||||
	progdefaults.oliviabw = 4;
 | 
			
		||||
	set_olivia_tab_widgets();
 | 
			
		||||
	cb_init_mode(w, arg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cb_oliviaCustom(Fl_Widget *w, void *arg)
 | 
			
		||||
{
 | 
			
		||||
	modem_config_tab = tabOlivia;
 | 
			
		||||
| 
						 | 
				
			
			@ -1162,7 +1145,7 @@ void init_modem(trx_mode mode, int freq)
 | 
			
		|||
 | 
			
		||||
	case MODE_THOR4: case MODE_THOR5: case MODE_THOR8:
 | 
			
		||||
	case MODE_THOR11:case MODE_THOR16: case MODE_THOR22: 
 | 
			
		||||
	case MODE_THOR44: case MODE_THOR88:
 | 
			
		||||
	case MODE_THOR25x4: case MODE_THOR50x1: case MODE_THOR50x2: case MODE_THOR100: 
 | 
			
		||||
		startup_modem(*mode_info[mode].modem ? *mode_info[mode].modem :
 | 
			
		||||
			      *mode_info[mode].modem = new thor(mode), freq);
 | 
			
		||||
		quick_change = quick_change_thor;
 | 
			
		||||
| 
						 | 
				
			
			@ -1199,6 +1182,7 @@ void init_modem(trx_mode mode, int freq)
 | 
			
		|||
	case MODE_MFSK8:
 | 
			
		||||
	case MODE_MFSK16:
 | 
			
		||||
	case MODE_MFSK32:
 | 
			
		||||
	case MODE_MFSK128 :
 | 
			
		||||
		startup_modem(*mode_info[mode].modem ? *mode_info[mode].modem :
 | 
			
		||||
			      *mode_info[mode].modem = new mfsk(mode), freq);
 | 
			
		||||
		quick_change = quick_change_mfsk;
 | 
			
		||||
| 
						 | 
				
			
			@ -1229,6 +1213,7 @@ void init_modem(trx_mode mode, int freq)
 | 
			
		|||
 | 
			
		||||
	case MODE_PSK31: case MODE_PSK63: case MODE_PSK63F:
 | 
			
		||||
	case MODE_PSK125: case MODE_PSK250: case MODE_PSK500:
 | 
			
		||||
	case MODE_PSK1000:
 | 
			
		||||
		startup_modem(*mode_info[mode].modem ? *mode_info[mode].modem :
 | 
			
		||||
			      *mode_info[mode].modem = new psk(mode), freq);
 | 
			
		||||
		quick_change = quick_change_psk;
 | 
			
		||||
| 
						 | 
				
			
			@ -1241,15 +1226,67 @@ void init_modem(trx_mode mode, int freq)
 | 
			
		|||
		modem_config_tab = tabPSK;
 | 
			
		||||
		break;
 | 
			
		||||
	case MODE_PSK125R: case MODE_PSK250R: case MODE_PSK500R:
 | 
			
		||||
	case MODE_PSK1000R:
 | 
			
		||||
		startup_modem(*mode_info[mode].modem ? *mode_info[mode].modem :
 | 
			
		||||
			      *mode_info[mode].modem = new psk(mode), freq);
 | 
			
		||||
		quick_change = quick_change_pskr;
 | 
			
		||||
		modem_config_tab = tabPSK;
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case MODE_OLIVIA:
 | 
			
		||||
	case MODE_12X_PSK125 :
 | 
			
		||||
	case MODE_6X_PSK250 :
 | 
			
		||||
	case MODE_2X_PSK500 :
 | 
			
		||||
	case MODE_4X_PSK500 :
 | 
			
		||||
	case MODE_2X_PSK800 :
 | 
			
		||||
	case MODE_2X_PSK1000 :
 | 
			
		||||
		startup_modem(*mode_info[mode].modem ? *mode_info[mode].modem :
 | 
			
		||||
			      *mode_info[mode].modem = new olivia, freq);
 | 
			
		||||
			      *mode_info[mode].modem = new psk(mode), freq);
 | 
			
		||||
		quick_change = quick_change_psk_multi;
 | 
			
		||||
		modem_config_tab = tabPSK;
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case MODE_4X_PSK63R :
 | 
			
		||||
	case MODE_5X_PSK63R :
 | 
			
		||||
	case MODE_10X_PSK63R :
 | 
			
		||||
	case MODE_20X_PSK63R :
 | 
			
		||||
	case MODE_32X_PSK63R :
 | 
			
		||||
 | 
			
		||||
	case MODE_4X_PSK125R :
 | 
			
		||||
	case MODE_5X_PSK125R :
 | 
			
		||||
	case MODE_10X_PSK125R :
 | 
			
		||||
	case MODE_12X_PSK125R :
 | 
			
		||||
	case MODE_16X_PSK125R :
 | 
			
		||||
 | 
			
		||||
	case MODE_2X_PSK250R :
 | 
			
		||||
	case MODE_3X_PSK250R :
 | 
			
		||||
	case MODE_5X_PSK250R :
 | 
			
		||||
	case MODE_6X_PSK250R :
 | 
			
		||||
	case MODE_7X_PSK250R :
 | 
			
		||||
 | 
			
		||||
	case MODE_2X_PSK500R :
 | 
			
		||||
	case MODE_3X_PSK500R :
 | 
			
		||||
	case MODE_4X_PSK500R :
 | 
			
		||||
 | 
			
		||||
	case MODE_2X_PSK800R :
 | 
			
		||||
	case MODE_2X_PSK1000R :
 | 
			
		||||
		startup_modem(*mode_info[mode].modem ? *mode_info[mode].modem :
 | 
			
		||||
			      *mode_info[mode].modem = new psk(mode), freq);
 | 
			
		||||
		quick_change = quick_change_psk_multiR;
 | 
			
		||||
		modem_config_tab = tabPSK;
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case MODE_OLIVIA:
 | 
			
		||||
	case MODE_OLIVIA_4_250:
 | 
			
		||||
	case MODE_OLIVIA_8_250:
 | 
			
		||||
	case MODE_OLIVIA_4_500:
 | 
			
		||||
	case MODE_OLIVIA_8_500:
 | 
			
		||||
	case MODE_OLIVIA_16_500:
 | 
			
		||||
	case MODE_OLIVIA_8_1000:
 | 
			
		||||
	case MODE_OLIVIA_16_1000:
 | 
			
		||||
	case MODE_OLIVIA_32_1000:
 | 
			
		||||
	case MODE_OLIVIA_64_2000:
 | 
			
		||||
		startup_modem(*mode_info[mode].modem ? *mode_info[mode].modem :
 | 
			
		||||
			      *mode_info[mode].modem = new olivia(mode), freq);
 | 
			
		||||
		modem_config_tab = tabOlivia;
 | 
			
		||||
		quick_change = quick_change_olivia;
 | 
			
		||||
		break;
 | 
			
		||||
| 
						 | 
				
			
			@ -2590,10 +2627,10 @@ int default_handler(int event)
 | 
			
		|||
 | 
			
		||||
	Fl_Widget* w = Fl::focus();
 | 
			
		||||
 | 
			
		||||
	int key = Fl::event_key();
 | 
			
		||||
	if ((key == FL_F + 4) && Fl::event_alt()) clean_exit(true);
 | 
			
		||||
 | 
			
		||||
	if (w == fl_digi_main || w->window() == fl_digi_main) {
 | 
			
		||||
		int key = Fl::event_key();
 | 
			
		||||
		if (key == FL_Escape || (key >= FL_F && key <= FL_F_Last) ||
 | 
			
		||||
			((key == '1' || key == '2' || key == '3' || key == '4') && Fl::event_alt())) {
 | 
			
		||||
			TransmitText->take_focus();
 | 
			
		||||
| 
						 | 
				
			
			@ -3243,10 +3280,10 @@ Fl_Menu_Item menu_[] = {
 | 
			
		|||
{ mode_info[MODE_DOMINOEX5].name, 0, cb_init_mode, (void *)MODE_DOMINOEX5, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_DOMINOEX8].name, 0, cb_init_mode, (void *)MODE_DOMINOEX8, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_DOMINOEX11].name, 0, cb_init_mode, (void *)MODE_DOMINOEX11, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_DOMINOEX16].name, 0, cb_init_mode, (void *)MODE_DOMINOEX16, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_DOMINOEX16].name, 0, cb_init_mode, (void *)MODE_DOMINOEX16, FL_MENU_DIVIDER, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_DOMINOEX22].name, 0, cb_init_mode, (void *)MODE_DOMINOEX22, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_DOMINOEX44].name, 0, cb_init_mode, (void *)MODE_DOMINOEX44, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_DOMINOEX88].name, 0, cb_init_mode, (void *)MODE_DOMINOEX88, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_DOMINOEX44].name, 0,  cb_init_mode, (void *)MODE_DOMINOEX44, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_DOMINOEX88].name, 0,  cb_init_mode, (void *)MODE_DOMINOEX88, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{0,0,0,0,0,0,0,0,0},
 | 
			
		||||
 | 
			
		||||
{"Hell", 0, 0, 0, FL_SUBMENU, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
| 
						 | 
				
			
			@ -3264,10 +3301,11 @@ Fl_Menu_Item menu_[] = {
 | 
			
		|||
{ mode_info[MODE_MFSK8].name, 0,  cb_init_mode, (void *)MODE_MFSK8, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_MFSK11].name, 0,  cb_init_mode, (void *)MODE_MFSK11, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_MFSK16].name, 0,  cb_init_mode, (void *)MODE_MFSK16, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_MFSK22].name, 0,  cb_init_mode, (void *)MODE_MFSK22, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_MFSK22].name, 0,  cb_init_mode, (void *)MODE_MFSK22, FL_MENU_DIVIDER, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_MFSK31].name, 0,  cb_init_mode, (void *)MODE_MFSK31, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_MFSK32].name, 0,  cb_init_mode, (void *)MODE_MFSK32, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_MFSK64].name, 0,  cb_init_mode, (void *)MODE_MFSK64, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_MFSK128].name, 0,  cb_init_mode, (void *)MODE_MFSK128, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{0,0,0,0,0,0,0,0,0},
 | 
			
		||||
 | 
			
		||||
{"MT63", 0, 0, 0, FL_SUBMENU, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
| 
						 | 
				
			
			@ -3277,13 +3315,15 @@ Fl_Menu_Item menu_[] = {
 | 
			
		|||
{0,0,0,0,0,0,0,0,0},
 | 
			
		||||
 | 
			
		||||
{ OLIVIA_MLABEL, 0, 0, 0, FL_SUBMENU, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ "8/250", 0, cb_oliviaA, (void *)MODE_OLIVIA, FL_MENU_DIVIDER, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ "4/500", 0, cb_oliviaF, (void *)MODE_OLIVIA, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ "8/500", 0, cb_oliviaB, (void *)MODE_OLIVIA, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ "16/500", 0, cb_oliviaC, (void *)MODE_OLIVIA, FL_MENU_DIVIDER, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ "8/1000", 0, cb_oliviaD, (void *)MODE_OLIVIA, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ "32/1000", 0, cb_oliviaE, (void *)MODE_OLIVIA, FL_MENU_DIVIDER, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ "64/2000", 0, cb_oliviaG, (void *)MODE_OLIVIA, FL_MENU_DIVIDER, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_OLIVIA_4_250].name, 0, cb_init_mode, (void *)MODE_OLIVIA_4_250, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_OLIVIA_8_250].name, 0, cb_init_mode, (void *)MODE_OLIVIA_8_250, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_OLIVIA_4_500].name, 0, cb_init_mode, (void *)MODE_OLIVIA_4_500, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_OLIVIA_8_500].name, 0, cb_init_mode, (void *)MODE_OLIVIA_8_500, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_OLIVIA_16_500].name, 0, cb_init_mode, (void *)MODE_OLIVIA_16_500, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_OLIVIA_8_1000].name, 0, cb_init_mode, (void *)MODE_OLIVIA_8_1000, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_OLIVIA_16_1000].name, 0, cb_init_mode, (void *)MODE_OLIVIA_16_1000, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_OLIVIA_32_1000].name, 0, cb_init_mode, (void *)MODE_OLIVIA_32_1000, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_OLIVIA_64_2000].name, 0, cb_init_mode, (void *)MODE_OLIVIA_64_2000, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ _("Custom..."), 0, cb_oliviaCustom, (void *)MODE_OLIVIA, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{0,0,0,0,0,0,0,0,0},
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -3294,6 +3334,15 @@ Fl_Menu_Item menu_[] = {
 | 
			
		|||
{ mode_info[MODE_PSK125].name, 0, cb_init_mode, (void *)MODE_PSK125, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_PSK250].name, 0, cb_init_mode, (void *)MODE_PSK250, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_PSK500].name, 0, cb_init_mode, (void *)MODE_PSK500, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_PSK1000].name, 0, cb_init_mode, (void *)MODE_PSK1000, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{"MultiCarrier", 0, 0, 0, FL_SUBMENU, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_12X_PSK125].name, 0, cb_init_mode, (void *)MODE_12X_PSK125, FL_MENU_DIVIDER, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_6X_PSK250].name, 0, cb_init_mode, (void *)MODE_6X_PSK250, FL_MENU_DIVIDER, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_2X_PSK500].name, 0, cb_init_mode, (void *)MODE_2X_PSK500, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_4X_PSK500].name, 0, cb_init_mode, (void *)MODE_4X_PSK500, FL_MENU_DIVIDER, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_2X_PSK800].name, 0, cb_init_mode, (void *)MODE_2X_PSK800, FL_MENU_DIVIDER, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_2X_PSK1000].name, 0, cb_init_mode, (void *)MODE_2X_PSK1000, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{0,0,0,0,0,0,0,0,0},
 | 
			
		||||
{0,0,0,0,0,0,0,0,0},
 | 
			
		||||
 | 
			
		||||
{"QPSK", 0, 0, 0, FL_SUBMENU, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
| 
						 | 
				
			
			@ -3308,6 +3357,29 @@ Fl_Menu_Item menu_[] = {
 | 
			
		|||
{ mode_info[MODE_PSK125R].name, 0, cb_init_mode, (void *)MODE_PSK125R, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_PSK250R].name, 0, cb_init_mode, (void *)MODE_PSK250R, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_PSK500R].name, 0, cb_init_mode, (void *)MODE_PSK500R, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_PSK1000R].name, 0, cb_init_mode, (void *)MODE_PSK1000R, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{"MultiCarrier", 0, 0, 0, FL_SUBMENU, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_4X_PSK63R].name, 0, cb_init_mode, (void *)MODE_4X_PSK63R, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_5X_PSK63R].name, 0, cb_init_mode, (void *)MODE_5X_PSK63R, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_10X_PSK63R].name, 0, cb_init_mode, (void *)MODE_10X_PSK63R, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_20X_PSK63R].name, 0, cb_init_mode, (void *)MODE_20X_PSK63R, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_32X_PSK63R].name, 0, cb_init_mode, (void *)MODE_32X_PSK63R, FL_MENU_DIVIDER, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_4X_PSK125R].name, 0, cb_init_mode, (void *)MODE_4X_PSK125R, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_5X_PSK125R].name, 0, cb_init_mode, (void *)MODE_5X_PSK125R, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_10X_PSK125R].name, 0, cb_init_mode, (void *)MODE_10X_PSK125R, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_12X_PSK125R].name, 0, cb_init_mode, (void *)MODE_12X_PSK125R, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_16X_PSK125R].name, 0, cb_init_mode, (void *)MODE_16X_PSK125R, FL_MENU_DIVIDER, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_2X_PSK250R].name, 0, cb_init_mode, (void *)MODE_2X_PSK250R, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_3X_PSK250R].name, 0, cb_init_mode, (void *)MODE_3X_PSK250R, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_5X_PSK250R].name, 0, cb_init_mode, (void *)MODE_5X_PSK250R, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_6X_PSK250R].name, 0, cb_init_mode, (void *)MODE_6X_PSK250R, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_7X_PSK250R].name, 0, cb_init_mode, (void *)MODE_7X_PSK250R, FL_MENU_DIVIDER, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_2X_PSK500R].name, 0, cb_init_mode, (void *)MODE_2X_PSK500R, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_3X_PSK500R].name, 0, cb_init_mode, (void *)MODE_3X_PSK500R, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_4X_PSK500R].name, 0, cb_init_mode, (void *)MODE_4X_PSK500R, FL_MENU_DIVIDER, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_2X_PSK800R].name, 0, cb_init_mode, (void *)MODE_2X_PSK800R, FL_MENU_DIVIDER, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_2X_PSK1000R].name, 0, cb_init_mode, (void *)MODE_2X_PSK1000R, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{0,0,0,0,0,0,0,0,0},
 | 
			
		||||
{0,0,0,0,0,0,0,0,0},
 | 
			
		||||
 | 
			
		||||
{ RTTY_MLABEL, 0, 0, 0, FL_SUBMENU, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
| 
						 | 
				
			
			@ -3323,10 +3395,12 @@ Fl_Menu_Item menu_[] = {
 | 
			
		|||
{ mode_info[MODE_THOR5].name, 0, cb_init_mode, (void *)MODE_THOR5, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_THOR8].name, 0, cb_init_mode, (void *)MODE_THOR8, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_THOR11].name, 0, cb_init_mode, (void *)MODE_THOR11, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_THOR16].name, 0, cb_init_mode, (void *)MODE_THOR16, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_THOR16].name, 0, cb_init_mode, (void *)MODE_THOR16, FL_MENU_DIVIDER, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_THOR22].name, 0, cb_init_mode, (void *)MODE_THOR22, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_THOR44].name, 0, cb_init_mode, (void *)MODE_THOR44, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_THOR88].name, 0, cb_init_mode, (void *)MODE_THOR88, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_THOR25x4].name, 0,  cb_init_mode, (void *)MODE_THOR25x4, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_THOR50x1].name, 0,  cb_init_mode, (void *)MODE_THOR50x1, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_THOR50x2].name, 0,  cb_init_mode, (void *)MODE_THOR50x2, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_THOR100].name, 0,  cb_init_mode, (void *)MODE_THOR100, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{0,0,0,0,0,0,0,0,0},
 | 
			
		||||
 | 
			
		||||
{"Throb", 0, 0, 0, FL_SUBMENU, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
| 
						 | 
				
			
			@ -3347,17 +3421,17 @@ Fl_Menu_Item menu_[] = {
 | 
			
		|||
{ mode_info[MODE_WEFAX_288].name, 0,  cb_init_mode, (void *)MODE_WEFAX_288, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{0,0,0,0,0,0,0,0,0},
 | 
			
		||||
 | 
			
		||||
{"Navtex/SitorB", 0, 0, 0, FL_SUBMENU, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{"Navtex/SitorB", 0, 0, 0, FL_SUBMENU | FL_MENU_DIVIDER, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_NAVTEX].name, 0,  cb_init_mode, (void *)MODE_NAVTEX, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_SITORB].name, 0,  cb_init_mode, (void *)MODE_SITORB, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{0,0,0,0,0,0,0,0,0},
 | 
			
		||||
 | 
			
		||||
{ mode_info[MODE_WWV].name, 0, cb_init_mode, (void *)MODE_WWV, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_ANALYSIS].name, 0, cb_init_mode, (void *)MODE_ANALYSIS, FL_MENU_DIVIDER, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
 | 
			
		||||
{ mode_info[MODE_NULL].name, 0, cb_init_mode, (void *)MODE_NULL, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_SSB].name, 0, cb_init_mode, (void *)MODE_SSB, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
 | 
			
		||||
{ mode_info[MODE_WWV].name, 0, cb_init_mode, (void *)MODE_WWV, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
 | 
			
		||||
{ mode_info[MODE_ANALYSIS].name, 0, cb_init_mode, (void *)MODE_ANALYSIS, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ OPMODES_FEWER, 0, cb_opmode_show, 0, FL_MENU_INVISIBLE, FL_NORMAL_LABEL, FL_HELVETICA_ITALIC, 14, 0 },
 | 
			
		||||
{0,0,0,0,0,0,0,0,0},
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -3366,7 +3440,8 @@ Fl_Menu_Item menu_[] = {
 | 
			
		|||
{ make_icon_label(_("Colors && Fonts"), preferences_desktop_font_icon), 0, (Fl_Callback*)cb_mnuConfigFonts, 0, 0, _FL_MULTI_LABEL, 0, 14, 0},
 | 
			
		||||
{ make_icon_label(_("User Interface")), 0,  (Fl_Callback*)cb_mnuUI, 0, 0, _FL_MULTI_LABEL, 0, 14, 0},
 | 
			
		||||
{ make_icon_label(_("Waterfall"), waterfall_icon), 0,  (Fl_Callback*)cb_mnuConfigWaterfall, 0, 0, _FL_MULTI_LABEL, 0, 14, 0},
 | 
			
		||||
{ make_icon_label(_("Waterfall controls")), 0,  (Fl_Callback*)cb_mnuConfigWFcontrols, 0, FL_MENU_DIVIDER, _FL_MULTI_LABEL, 0, 14, 0},
 | 
			
		||||
{ make_icon_label(_("Waterfall controls")), 0,  (Fl_Callback*)cb_mnuConfigWFcontrols, 0, FL_MENU_DIVIDER, 
 | 
			
		||||
_FL_MULTI_LABEL, 0, 14, 0},
 | 
			
		||||
{ make_icon_label(_("Modems"), emblems_system_icon), 0, (Fl_Callback*)cb_mnuConfigModems, 0, 0, _FL_MULTI_LABEL, 0, 14, 0},
 | 
			
		||||
{ make_icon_label(RIGCONTROL_MLABEL, multimedia_player_icon), 0, (Fl_Callback*)cb_mnuConfigRigCtrl, 0, 0, _FL_MULTI_LABEL, 0, 14, 0},
 | 
			
		||||
{ make_icon_label(_("Sound Card"), audio_card_icon), 0, (Fl_Callback*)cb_mnuConfigSoundCard, 0, FL_MENU_DIVIDER, _FL_MULTI_LABEL, 0, 14, 0},
 | 
			
		||||
| 
						 | 
				
			
			@ -5348,13 +5423,15 @@ Fl_Menu_Item alt_menu_[] = {
 | 
			
		|||
{0,0,0,0,0,0,0,0,0},
 | 
			
		||||
 | 
			
		||||
{"Olivia", 0, 0, 0, FL_SUBMENU, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ "8/250", 0, cb_oliviaA, (void *)MODE_OLIVIA, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ "4/500", 0, cb_oliviaF, (void *)MODE_OLIVIA, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ "8/500", 0, cb_oliviaB, (void *)MODE_OLIVIA, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ "16/500", 0, cb_oliviaC, (void *)MODE_OLIVIA, FL_MENU_DIVIDER, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ "8/1000", 0, cb_oliviaD, (void *)MODE_OLIVIA, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ "32/1000", 0, cb_oliviaE, (void *)MODE_OLIVIA, FL_MENU_DIVIDER, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ "64/2000", 0, cb_oliviaG, (void *)MODE_OLIVIA, FL_MENU_DIVIDER, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_OLIVIA_4_250].name, 0, cb_init_mode, (void *)MODE_OLIVIA_4_250, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_OLIVIA_8_250].name, 0, cb_init_mode, (void *)MODE_OLIVIA_8_250, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_OLIVIA_4_500].name, 0, cb_init_mode, (void *)MODE_OLIVIA_4_500, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_OLIVIA_8_500].name, 0, cb_init_mode, (void *)MODE_OLIVIA_8_500, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_OLIVIA_16_500].name, 0, cb_init_mode, (void *)MODE_OLIVIA_16_500, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_OLIVIA_8_1000].name, 0, cb_init_mode, (void *)MODE_OLIVIA_8_1000, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_OLIVIA_16_1000].name, 0, cb_init_mode, (void *)MODE_OLIVIA_16_1000, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_OLIVIA_32_1000].name, 0, cb_init_mode, (void *)MODE_OLIVIA_32_1000, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_OLIVIA_64_2000].name, 0, cb_init_mode, (void *)MODE_OLIVIA_64_2000, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ _("Custom..."), 0, cb_oliviaCustom, (void *)MODE_OLIVIA, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{0,0,0,0,0,0,0,0,0},
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -5412,17 +5489,17 @@ Fl_Menu_Item alt_menu_[] = {
 | 
			
		|||
{ mode_info[MODE_WEFAX_288].name, 0,  cb_init_mode, (void *)MODE_WEFAX_288, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{0,0,0,0,0,0,0,0,0},
 | 
			
		||||
 | 
			
		||||
{"Navtex/SitorB", 0, 0, 0, FL_SUBMENU, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{"Navtex/SitorB", 0, 0, 0, FL_SUBMENU | FL_MENU_DIVIDER, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_NAVTEX].name, 0,  cb_init_mode, (void *)MODE_NAVTEX, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_SITORB].name, 0,  cb_init_mode, (void *)MODE_SITORB, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{0,0,0,0,0,0,0,0,0},
 | 
			
		||||
 | 
			
		||||
{ mode_info[MODE_WWV].name, 0, cb_init_mode, (void *)MODE_WWV, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_ANALYSIS].name, 0, cb_init_mode, (void *)MODE_ANALYSIS, FL_MENU_DIVIDER, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
 | 
			
		||||
{ mode_info[MODE_NULL].name, 0, cb_init_mode, (void *)MODE_NULL, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{ mode_info[MODE_SSB].name, 0, cb_init_mode, (void *)MODE_SSB, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
 | 
			
		||||
{ mode_info[MODE_WWV].name, 0, cb_init_mode, (void *)MODE_WWV, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
 | 
			
		||||
{ mode_info[MODE_ANALYSIS].name, 0, cb_init_mode, (void *)MODE_ANALYSIS, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{0,0,0,0,0,0,0,0,0},
 | 
			
		||||
 | 
			
		||||
{_("&Configure"), 0, 0, 0, FL_SUBMENU, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
| 
						 | 
				
			
			@ -6547,7 +6624,8 @@ void resetTHOR() {
 | 
			
		|||
	if (md == MODE_THOR4 || md == MODE_THOR5 || md == MODE_THOR8 ||
 | 
			
		||||
		md == MODE_THOR11 ||
 | 
			
		||||
		md == MODE_THOR16 || md == MODE_THOR22 ||
 | 
			
		||||
		md == MODE_THOR44 || md == MODE_THOR88 )
 | 
			
		||||
		md == MODE_THOR25x4 || md == MODE_THOR50x1 ||
 | 
			
		||||
		md == MODE_THOR50x2 || md == MODE_THOR100 )
 | 
			
		||||
		trx_start_modem(active_modem);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,10 +2,10 @@
 | 
			
		|||
//
 | 
			
		||||
// dominoex.cxx  --  DominoEX modem
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2008-2009
 | 
			
		||||
//		David Freese (w1hkj@w1hkj.com)
 | 
			
		||||
// Copyright (C) 2006
 | 
			
		||||
//		Hamish Moffatt (hamish@debian.org)
 | 
			
		||||
// Copyright (C) 2008-20012
 | 
			
		||||
//     David Freese   <w1hkj@w1hkj.com>
 | 
			
		||||
//     Hamish Moffatt <hamish@debian.org>
 | 
			
		||||
//     John Phelps    <kl4yfd@gmail.com>
 | 
			
		||||
//
 | 
			
		||||
// based on code in gmfsk
 | 
			
		||||
//
 | 
			
		||||
| 
						 | 
				
			
			@ -94,16 +94,15 @@ void dominoex::rx_init()
 | 
			
		|||
void dominoex::reset_filters()
 | 
			
		||||
{
 | 
			
		||||
// fft filter at first IF frequency
 | 
			
		||||
	fft->create_filter( 
 | 
			
		||||
		(FIRSTIF - 0.5 * progdefaults.DOMINOEX_BW * bandwidth) / samplerate,
 | 
			
		||||
		(FIRSTIF + 0.5 * progdefaults.DOMINOEX_BW * bandwidth)/ samplerate );
 | 
			
		||||
	fft->create_filter( (FIRSTIF - 0.5 * progdefaults.DOMINOEX_BW * bandwidth) / samplerate,
 | 
			
		||||
						(FIRSTIF + 0.5 * progdefaults.DOMINOEX_BW * bandwidth)/ samplerate );
 | 
			
		||||
 | 
			
		||||
	for (int i = 0; i < MAXFFTS; i++) {
 | 
			
		||||
		if (binsfft[i]) delete binsfft[i];
 | 
			
		||||
		binsfft[i] = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (slowcpu || samplerate == 22050) {
 | 
			
		||||
	if (slowcpu) {
 | 
			
		||||
		extones = 4;
 | 
			
		||||
		paths = 3;
 | 
			
		||||
	} else {
 | 
			
		||||
| 
						 | 
				
			
			@ -116,13 +115,8 @@ void dominoex::reset_filters()
 | 
			
		|||
 | 
			
		||||
	numbins = hitone - lotone;
 | 
			
		||||
 | 
			
		||||
	for (int i = 0; i < paths; i++) { //MAXFFTS; i++)
 | 
			
		||||
	for (int i = 0; i < paths; i++)//MAXFFTS; i++)
 | 
			
		||||
		binsfft[i] = new sfft (symlen, lotone, hitone);
 | 
			
		||||
		if (!binsfft[i]) {
 | 
			
		||||
			printf("Domino Arrgh %d\n", i);
 | 
			
		||||
			exit(0);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	filter_reset = false;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -138,6 +132,7 @@ void dominoex::init()
 | 
			
		|||
		MuPsk_sec2pri_init();
 | 
			
		||||
 | 
			
		||||
	modem::init();
 | 
			
		||||
//	reset_filters();
 | 
			
		||||
	rx_init();
 | 
			
		||||
 | 
			
		||||
	set_scope_mode(Digiscope::DOMDATA);
 | 
			
		||||
| 
						 | 
				
			
			@ -190,11 +185,9 @@ dominoex::~dominoex()
 | 
			
		|||
{
 | 
			
		||||
	if (hilbert) delete hilbert;
 | 
			
		||||
 | 
			
		||||
	for (int i = 0; i < MAXFFTS; i++) { //paths; i++) {//MAXFFTS; i++) {
 | 
			
		||||
		if (binsfft[i]) {
 | 
			
		||||
			delete binsfft[i];
 | 
			
		||||
			binsfft[i] = 0;
 | 
			
		||||
		}
 | 
			
		||||
	for (int i = 0; i < MAXFFTS; i++) {
 | 
			
		||||
		if (binsfft[i]) delete binsfft[i];
 | 
			
		||||
		binsfft[i] = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for (int i = 0; i < SCOPESIZE; i++) {
 | 
			
		||||
| 
						 | 
				
			
			@ -225,29 +218,16 @@ dominoex::dominoex(trx_mode md)
 | 
			
		|||
		doublespaced = 2;
 | 
			
		||||
		samplerate = 11025;
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case MODE_DOMINOEX11:
 | 
			
		||||
		symlen = 1024;
 | 
			
		||||
		doublespaced = 1;
 | 
			
		||||
		samplerate = 11025;
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case MODE_DOMINOEX22:
 | 
			
		||||
		symlen = 512;
 | 
			
		||||
		doublespaced = 1;
 | 
			
		||||
		samplerate = 11025;
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case MODE_DOMINOEX44:
 | 
			
		||||
		symlen = 250;
 | 
			
		||||
		doublespaced = 2;
 | 
			
		||||
		samplerate = 11025;
 | 
			
		||||
		break;
 | 
			
		||||
	case MODE_DOMINOEX88:
 | 
			
		||||
		symlen = 125;
 | 
			
		||||
		doublespaced = 1;
 | 
			
		||||
		samplerate = 11025;
 | 
			
		||||
		break;
 | 
			
		||||
// 8kHz modes
 | 
			
		||||
	case MODE_DOMINOEX4:
 | 
			
		||||
		symlen = 2048;
 | 
			
		||||
| 
						 | 
				
			
			@ -264,6 +244,19 @@ dominoex::dominoex(trx_mode md)
 | 
			
		|||
		doublespaced = 1;
 | 
			
		||||
		samplerate = 8000;
 | 
			
		||||
		break;
 | 
			
		||||
// experimental 
 | 
			
		||||
	case MODE_DOMINOEX44:
 | 
			
		||||
		symlen = 256;
 | 
			
		||||
		doublespaced = 2;
 | 
			
		||||
		samplerate = 11025;
 | 
			
		||||
		break;
 | 
			
		||||
	case MODE_DOMINOEX88:
 | 
			
		||||
		symlen = 128;
 | 
			
		||||
 		doublespaced = 1;
 | 
			
		||||
		samplerate = 11025;
 | 
			
		||||
 		break;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	default: // EX8
 | 
			
		||||
		symlen = 1024;
 | 
			
		||||
		doublespaced = 2;
 | 
			
		||||
| 
						 | 
				
			
			@ -278,10 +271,10 @@ dominoex::dominoex(trx_mode md)
 | 
			
		|||
	hilbert->init_hilbert(37, 1);
 | 
			
		||||
 | 
			
		||||
// fft filter at first if frequency
 | 
			
		||||
	fft = new fftfilt( 
 | 
			
		||||
			(FIRSTIF - 0.5 * progdefaults.DOMINOEX_BW * bandwidth) / samplerate,
 | 
			
		||||
			(FIRSTIF + 0.5 * progdefaults.DOMINOEX_BW * bandwidth)/ samplerate,
 | 
			
		||||
			1024 );
 | 
			
		||||
	fft = new fftfilt( (FIRSTIF - 0.5 * progdefaults.DOMINOEX_BW * bandwidth) / samplerate,
 | 
			
		||||
					   (FIRSTIF + 0.5 * progdefaults.DOMINOEX_BW * bandwidth)/ samplerate,
 | 
			
		||||
					   1024 );
 | 
			
		||||
 | 
			
		||||
	basetone = (int)floor(BASEFREQ * symlen / samplerate + 0.5);
 | 
			
		||||
 | 
			
		||||
	slowcpu = progdefaults.slowcpu;
 | 
			
		||||
| 
						 | 
				
			
			@ -315,9 +308,11 @@ dominoex::dominoex(trx_mode md)
 | 
			
		|||
	prev1symbol = prev2symbol = 0;
 | 
			
		||||
 | 
			
		||||
	MuPskEnc	= new encoder (K, POLY1, POLY2);
 | 
			
		||||
	MuPskDec	= new viterbi::impl <K, 1, 45>(POLY1, POLY2);
 | 
			
		||||
	MuPskTxinlv = new interleave (-1, INTERLEAVE_FWD);
 | 
			
		||||
	MuPskRxinlv = new interleave (-1, INTERLEAVE_REV);
 | 
			
		||||
	MuPskDec	= new viterbi (K, POLY1, POLY2);
 | 
			
		||||
	MuPskDec->settraceback (45);
 | 
			
		||||
	MuPskDec->setchunksize (1);
 | 
			
		||||
	MuPskTxinlv = new interleave (4, 4, INTERLEAVE_FWD);
 | 
			
		||||
	MuPskRxinlv = new interleave (4, 4, INTERLEAVE_REV);
 | 
			
		||||
	Mu_bitstate = 0;
 | 
			
		||||
	Mu_symbolpair[0] = Mu_symbolpair[1] = 0;
 | 
			
		||||
	Mu_datashreg = 1;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -33,21 +33,172 @@
 | 
			
		|||
#include "misc.h"
 | 
			
		||||
 | 
			
		||||
/* ---------------------------------------------------------------------- */
 | 
			
		||||
viterbi::viterbi( int poly1, int poly2, unsigned int * output, int outsize )
 | 
			
		||||
viterbi::viterbi(int k, int poly1, int poly2)
 | 
			
		||||
{
 | 
			
		||||
	int outsize = 1 << k;
 | 
			
		||||
	_traceback = PATHMEM - 1;
 | 
			
		||||
	_chunksize = 8;
 | 
			
		||||
	nstates = 1 << (k - 1);
 | 
			
		||||
	
 | 
			
		||||
	output = new int[outsize];
 | 
			
		||||
	
 | 
			
		||||
	for (int i = 0; i < outsize; i++) {
 | 
			
		||||
		output[i] = parity(poly1 & i) | (parity(poly2 & i) << 1);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	for (int i = 0; i < PATHMEM; i++) {
 | 
			
		||||
		metrics[i] = new int[nstates];
 | 
			
		||||
		history[i] = new int[nstates];
 | 
			
		||||
		sequence[i] = 0;
 | 
			
		||||
		for (int j = 0; j < nstates; j++)
 | 
			
		||||
			metrics[i][j] = history[i][j] = 0;
 | 
			
		||||
	}
 | 
			
		||||
	for (int i = 0; i < 256; i++) {
 | 
			
		||||
		mettab[0][i] = 128 - i;
 | 
			
		||||
		mettab[1][i] = i - 128;
 | 
			
		||||
	}
 | 
			
		||||
	reset();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
viterbi::~viterbi() {}
 | 
			
		||||
viterbi::~viterbi()
 | 
			
		||||
{
 | 
			
		||||
	if (output) delete [] output;
 | 
			
		||||
	for (int i = 0; i < PATHMEM; i++) {
 | 
			
		||||
		if (metrics[i]) delete [] metrics[i];
 | 
			
		||||
		if (history[i]) delete [] history[i];
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void viterbi::reset()
 | 
			
		||||
{
 | 
			
		||||
	for (int i = 0; i < PATHMEM; i++) {
 | 
			
		||||
		memset(metrics[i], 0, nstates * sizeof(int));
 | 
			
		||||
		memset(history[i], 0, nstates * sizeof(int));
 | 
			
		||||
	}
 | 
			
		||||
	ptr = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int viterbi::settraceback(int trace) {
 | 
			
		||||
	if (trace < 0 || trace > PATHMEM - 1)
 | 
			
		||||
	return -1;
 | 
			
		||||
	_traceback = trace;
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int viterbi::setchunksize(int chunk) {
 | 
			
		||||
	if (chunk < 1 || chunk > _traceback)
 | 
			
		||||
	return -1;
 | 
			
		||||
	_chunksize = chunk;
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int viterbi::traceback(int *metric)
 | 
			
		||||
{
 | 
			
		||||
	int bestmetric, beststate;
 | 
			
		||||
	unsigned int p, c = 0;
 | 
			
		||||
 | 
			
		||||
	p = (ptr - 1) % PATHMEM;
 | 
			
		||||
 | 
			
		||||
// Find the state with the best metric
 | 
			
		||||
	bestmetric = INT_MIN;
 | 
			
		||||
	beststate = 0;
 | 
			
		||||
 | 
			
		||||
	for (int i = 0; i < nstates; i++) {
 | 
			
		||||
		if (metrics[p][i] > bestmetric) {
 | 
			
		||||
			bestmetric = metrics[p][i];
 | 
			
		||||
			beststate = i;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
// Trace back 'traceback' steps, starting from the best state
 | 
			
		||||
	sequence[p] = beststate;
 | 
			
		||||
 | 
			
		||||
	for (int i = 0; i < _traceback; i++) {
 | 
			
		||||
		unsigned int prev = (p - 1) % PATHMEM;
 | 
			
		||||
 | 
			
		||||
		sequence[prev] = history[p][sequence[p]];
 | 
			
		||||
		p = prev;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (metric)
 | 
			
		||||
		*metric = metrics[p][sequence[p]];
 | 
			
		||||
 | 
			
		||||
// Decode 'chunksize' bits
 | 
			
		||||
	for (int i = 0; i < _chunksize; i++) {
 | 
			
		||||
// low bit of state is the previous input bit
 | 
			
		||||
		c = (c << 1) | (sequence[p] & 1);
 | 
			
		||||
		p = (p + 1) % PATHMEM;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (metric)
 | 
			
		||||
		*metric = metrics[p][sequence[p]] - *metric;
 | 
			
		||||
 | 
			
		||||
	return c;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int viterbi::decode(unsigned char *sym, int *metric)
 | 
			
		||||
{
 | 
			
		||||
	unsigned int currptr, prevptr;
 | 
			
		||||
	int met[4];
 | 
			
		||||
	
 | 
			
		||||
	currptr = ptr;
 | 
			
		||||
	prevptr = (currptr - 1) % PATHMEM;
 | 
			
		||||
//	if (prevptr < 0) prevptr = PATHMEM - 1;
 | 
			
		||||
 | 
			
		||||
	met[0] = mettab[0][sym[1]] + mettab[0][sym[0]];
 | 
			
		||||
	met[1] = mettab[0][sym[1]] + mettab[1][sym[0]];
 | 
			
		||||
	met[2] = mettab[1][sym[1]] + mettab[0][sym[0]];
 | 
			
		||||
	met[3] = mettab[1][sym[1]] + mettab[1][sym[0]];
 | 
			
		||||
 | 
			
		||||
//	met[0] = 256 - sym[1] - sym[0];
 | 
			
		||||
//	met[1] = sym[0] - sym[1];
 | 
			
		||||
//	met[2] = sym[1] - sym[0];
 | 
			
		||||
//	met[3] = sym[0] + sym[1] - 256;
 | 
			
		||||
 | 
			
		||||
	for (int n = 0; n < nstates; n++) {
 | 
			
		||||
		int p0, p1, s0, s1, m0, m1;
 | 
			
		||||
 | 
			
		||||
		m0 = 0;
 | 
			
		||||
		m1 = 0;
 | 
			
		||||
		s0 = n;
 | 
			
		||||
		s1 = n + nstates;
 | 
			
		||||
 | 
			
		||||
		p0 = s0 >> 1;
 | 
			
		||||
		p1 = s1 >> 1;
 | 
			
		||||
 | 
			
		||||
		m0 = metrics[prevptr][p0] + met[output[s0]];
 | 
			
		||||
		m1 = metrics[prevptr][p1] + met[output[s1]];
 | 
			
		||||
 | 
			
		||||
		if (m0 > m1) {
 | 
			
		||||
			metrics[currptr][n] = m0;
 | 
			
		||||
			history[currptr][n] = p0;
 | 
			
		||||
		} else {
 | 
			
		||||
			metrics[currptr][n] = m1;
 | 
			
		||||
			history[currptr][n] = p1;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ptr = (ptr + 1) % PATHMEM;
 | 
			
		||||
 | 
			
		||||
	if ((ptr % _chunksize) == 0)
 | 
			
		||||
		return traceback(metric);
 | 
			
		||||
 | 
			
		||||
	if (metrics[currptr][0] > INT_MAX / 2) {
 | 
			
		||||
		for (int i = 0; i < PATHMEM; i++)
 | 
			
		||||
			for (int j = 0; j < nstates; j++)
 | 
			
		||||
				metrics[i][j] -= INT_MAX / 2;
 | 
			
		||||
	}
 | 
			
		||||
	if (metrics[currptr][0] < INT_MIN / 2) {
 | 
			
		||||
		for (int i = 0; i < PATHMEM; i++)
 | 
			
		||||
			for (int j = 0; j < nstates; j++)
 | 
			
		||||
				metrics[i][j] += INT_MIN / 2;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ---------------------------------------------------------------------- */
 | 
			
		||||
#include <iostream>
 | 
			
		||||
encoder::encoder(int k, int poly1, int poly2)
 | 
			
		||||
{
 | 
			
		||||
	int size = 1 << k;	/* size of the output table */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -55,8 +55,8 @@ const struct mode_info_t mode_info[NUM_MODES] = {
 | 
			
		|||
	{ MODE_DOMINOEX11, &dominoex11_modem, "DOMX11", "DominoEX 11", "DOMINOEX11", "DOMINO", "DM11" },
 | 
			
		||||
	{ MODE_DOMINOEX16, &dominoex16_modem, "DOMX16", "DominoEX 16", "DOMINOEX16", "DOMINO", "DM16" },
 | 
			
		||||
	{ MODE_DOMINOEX22, &dominoex22_modem, "DOMX22", "DominoEX 22", "DOMINOEX22", "DOMINO", "DM22" },
 | 
			
		||||
	{ MODE_DOMINOEX44, &dominoex44_modem, "DOMX44", "DominoEX 44", "DOMINOEX44", "DOMINO", "DOM44" },
 | 
			
		||||
	{ MODE_DOMINOEX88, &dominoex88_modem, "DOMX88", "DominoEX 88", "DOMINOEX88", "DOMINO", "DOM88" },
 | 
			
		||||
	{ MODE_DOMINOEX44, &dominoex44_modem, "DOMX44", "DominoEX 44", "DOMINOEX44", "DOMINO", "DM44" },
 | 
			
		||||
	{ MODE_DOMINOEX88, &dominoex88_modem, "DOMX88", "DominoEX 88", "DOMINOEX88", "DOMINO", "DM88" },
 | 
			
		||||
 | 
			
		||||
	{ MODE_FELDHELL, &feld_modem, "FELDHELL", "Feld Hell", "", "HELL", "HELL" },
 | 
			
		||||
	{ MODE_SLOWHELL, &feld_slowmodem, "SLOWHELL", "Slow Hell", "", "HELL", "SHLL" },
 | 
			
		||||
| 
						 | 
				
			
			@ -75,6 +75,7 @@ const struct mode_info_t mode_info[NUM_MODES] = {
 | 
			
		|||
	{ MODE_MFSK22, &mfsk22_modem, "MFSK22", "MFSK-22", "MFSK22", "MFSK22", "MK22" },
 | 
			
		||||
	{ MODE_MFSK31, &mfsk31_modem, "MFSK31", "MFSK-31", "MFSK31", "MFSK31", "MK31" },
 | 
			
		||||
	{ MODE_MFSK64, &mfsk64_modem, "MFSK64", "MFSK-64", "MFSK64", "MFSK64", "MK64" },
 | 
			
		||||
	{ MODE_MFSK128, &mfsk128_modem, "MFSK128", "MFSK-128", "MFSK128", "MFSK128", "MK128" },
 | 
			
		||||
 | 
			
		||||
	{ MODE_WEFAX_576, &wefax576_modem, "WEFAX576", "WEFAX-IOC576", "WEFAXIOC576", "FAX", "FX576" },
 | 
			
		||||
	{ MODE_WEFAX_288, &wefax288_modem, "WEFAX288", "WEFAX-IOC288", "WEFAXIOC288", "FAX", "FX288" },
 | 
			
		||||
| 
						 | 
				
			
			@ -92,16 +93,30 @@ const struct mode_info_t mode_info[NUM_MODES] = {
 | 
			
		|||
	{ MODE_PSK125, &psk125_modem, "BPSK125", "BPSK-125", "PSK125", "PSK125", "P125" },
 | 
			
		||||
	{ MODE_PSK250, &psk250_modem, "BPSK250", "BPSK-250", "PSK250", "PSK250", "P250" },
 | 
			
		||||
	{ MODE_PSK500, &psk500_modem, "BPSK500", "BPSK-500", "PSK500", "PSK500", "P500" },
 | 
			
		||||
 | 
			
		||||
	{ MODE_QPSK31, &qpsk31_modem, "QPSK31", "QPSK-31", "QPSK31", "QPSK31", "Q31" },
 | 
			
		||||
	{ MODE_QPSK63, &qpsk63_modem, "QPSK63", "QPSK-63", "QPSK63", "QPSK63", "Q63" },
 | 
			
		||||
	{ MODE_QPSK125, &qpsk125_modem, "QPSK125", "QPSK-125", "QPSK125", "QPSK125", "Q125" },
 | 
			
		||||
	{ MODE_QPSK250, &qpsk250_modem, "QPSK250", "QPSK-250", "QPSK250", "QPSK250", "Q250" },
 | 
			
		||||
	{ MODE_QPSK500, &qpsk500_modem, "QPSK500", "QPSK-500", "QPSK500", "QPSK500", "Q500" },
 | 
			
		||||
 | 
			
		||||
	{ MODE_PSK125R, &psk125r_modem, "PSK125R", "PSK-125R", "PSK125R", "PSK125R", "P125R" },
 | 
			
		||||
	{ MODE_PSK250R, &psk250r_modem, "PSK250R", "PSK-250R", "PSK250R", "PSK250R", "P250R" },
 | 
			
		||||
	{ MODE_PSK500R, &psk500r_modem, "PSK500R", "PSK-500R", "PSK500R", "PSK500R", "P500R" },
 | 
			
		||||
 | 
			
		||||
	{ MODE_OLIVIA, &olivia_modem, "OLIVIA", "Olivia", "", "OLIVIA", "OL" },
 | 
			
		||||
	{ MODE_PSK1000, &psk1000_modem, "BPSK1000", "BPSK-1000", "PSK1000", "PSK1000", "P1000" },
 | 
			
		||||
	{ MODE_PSK1000R, &psk1000r_modem, "PSK1000R", "PSK-1000R", "PSK1000R", "PSK1000R", "PSK1000R" },
 | 
			
		||||
 | 
			
		||||
	{ MODE_OLIVIA, &olivia_modem, "OLIVIA", "OLIVIA", "OLIVIA", "OLIVIA", "OL" },
 | 
			
		||||
	{ MODE_OLIVIA_4_250, &olivia_4_250_modem, "Olivia-4-250", "OL 4-250", "OLIV 4/250", "OLIVIA", "OL4/250" },
 | 
			
		||||
	{ MODE_OLIVIA_8_250, &olivia_8_250_modem, "Olivia-8-250", "OL 8-250", "OLIV 8/250", "OLIVIA", "OL8/250" },
 | 
			
		||||
	{ MODE_OLIVIA_4_500, &olivia_4_500_modem, "Olivia-4-500", "OL 4-500", "OLIV 4/500", "OLIVIA", "OL4/500" },
 | 
			
		||||
	{ MODE_OLIVIA_8_500, &olivia_8_500_modem, "Olivia-8-500", "OL 8-500", "OLIV 8/500", "OLIVIA", "OL8/500" },
 | 
			
		||||
	{ MODE_OLIVIA_16_500, &olivia_16_500_modem, "Olivia-16-500", "OL 16-500", "OLIV 16/500", "OLIVIA", "OL16/500" },
 | 
			
		||||
	{ MODE_OLIVIA_8_1000, &olivia_8_1000_modem, "Olivia-8-1K", "OL 8-1K", "OLIV 8/1K", "OLIVIA", "OL8/1K" },
 | 
			
		||||
	{ MODE_OLIVIA_16_1000, &olivia_16_1000_modem, "Olivia-16-1K", "OL 16-1K", "OLIV 16/1K", "OLIVIA", "OL16/1K" },
 | 
			
		||||
	{ MODE_OLIVIA_32_1000, &olivia_32_1000_modem, "Olivia-32-1K", "OL 32-1K", "OLIV 32/1K", "OLIVIA", "OL32/1K" },
 | 
			
		||||
	{ MODE_OLIVIA_64_2000, &olivia_64_2000_modem, "Olivia-64-2K", "OL 64-2K", "OLIV 64/2K", "OLIVIA", "OL64/2K" },
 | 
			
		||||
 | 
			
		||||
	{ MODE_RTTY, &rtty_modem, "RTTY", "RTTY", "RTTY", "RTTY", "RY" },
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -111,8 +126,11 @@ const struct mode_info_t mode_info[NUM_MODES] = {
 | 
			
		|||
	{ MODE_THOR11, &thor11_modem, "THOR11", "THOR 11", "THOR11", "THOR", "TH11" },
 | 
			
		||||
	{ MODE_THOR16, &thor16_modem, "THOR16", "THOR 16", "THOR16", "THOR", "TH16" },
 | 
			
		||||
	{ MODE_THOR22, &thor22_modem, "THOR22", "THOR 22", "THOR22", "THOR", "TH22" },
 | 
			
		||||
	{ MODE_THOR44, &thor44_modem, "THOR44", "THOR 44", "THOR44", "THOR", "TH44" },
 | 
			
		||||
	{ MODE_THOR88, &thor88_modem, "THOR88", "THOR 88", "THOR88", "THOR", "TH88" },
 | 
			
		||||
	{ MODE_THOR25x4, &thor25x4_modem, "THOR25x4", "THOR 25 x4", "THOR25x4", "THOR", "TH25" },
 | 
			
		||||
	{ MODE_THOR50x1, &thor50x1_modem, "THOR50x1", "THOR 50 x1", "THOR50x1", "THOR", "TH51" },
 | 
			
		||||
	{ MODE_THOR50x2, &thor50x2_modem, "THOR50x2", "THOR 50 x2", "THOR50x2", "THOR", "TH52" },
 | 
			
		||||
	{ MODE_THOR100, &thor100_modem, "THOR100", "THOR 100", "THOR100", "THOR", "TH10" },
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	{ MODE_THROB1, &throb1_modem, "THROB1", "Throb 1", "", "THRB", "TB1" },
 | 
			
		||||
	{ MODE_THROB2, &throb2_modem, "THROB2", "Throb 2", "", "THRB", "TB2" },
 | 
			
		||||
| 
						 | 
				
			
			@ -123,9 +141,45 @@ const struct mode_info_t mode_info[NUM_MODES] = {
 | 
			
		|||
 | 
			
		||||
	{ MODE_PACKET, &pkt_modem, "PACKET", "Packet", "", "PKT", "PKT" },
 | 
			
		||||
 | 
			
		||||
	{ MODE_4X_PSK63R, &psk63r_c4_modem, "PSK63RC4", "4xPSK63R", "PSK63RC4", "PSK63RC4", "P63R4" },
 | 
			
		||||
	{ MODE_5X_PSK63R, &psk63r_c5_modem, "PSK63RC5", "5xPSK63R", "PSK63RC5", "PSK63RC5", "P63R5" },
 | 
			
		||||
	{ MODE_10X_PSK63R, &psk63r_c10_modem, "PSK63RC10", "10xPSK63R", "PSK63RC10", "PSK63RC10", "P63R10" },
 | 
			
		||||
	{ MODE_20X_PSK63R, &psk63r_c20_modem, "PSK63RC20", "20xPSK63R", "PSK63RC20", "PSK63RC20", "P63R20" },
 | 
			
		||||
	{ MODE_32X_PSK63R, &psk63r_c32_modem, "PSK63RC32", "32xPSK63R", "PSK63RC32", "PSK63RC32", "P63R32" },
 | 
			
		||||
 | 
			
		||||
	{ MODE_4X_PSK125R, &psk125r_c4_modem, "PSK125RC4", "4xPSK125R", "PSK125RC4", "PSK125RC4", "P125R4" },
 | 
			
		||||
	{ MODE_5X_PSK125R, &psk125r_c5_modem, "PSK125RC5", "5xPSK125R", "PSK125RC5", "PSK125RC5", "P125R5" },
 | 
			
		||||
	{ MODE_10X_PSK125R, &psk125r_c10_modem, "PSK125RC10", "10xPSK125R", "PSK125RC10", "PSK125RC10", "P125R10" },
 | 
			
		||||
	{ MODE_12X_PSK125, &psk125_c12_modem, "PSK125C12", "12xPSK125", "PSK125C12", "PSK125C12", "P125C12" },
 | 
			
		||||
	{ MODE_12X_PSK125R, &psk125r_c12_modem, "PSK125RC12", "12xPSK125R", "PSK125RC12", "PSK125RC12", "P125R12" },
 | 
			
		||||
	{ MODE_16X_PSK125R, &psk125r_c16_modem, "PSK125RC16", "16xPSK125R", "PSK125RC16", "PSK125RC16", "P125R16" },
 | 
			
		||||
 | 
			
		||||
	{ MODE_6X_PSK250, &psk250_c6_modem, "PSK250C6", "6xPSK250", "PSK250C6", "PSK250C6", "P2506"},
 | 
			
		||||
 | 
			
		||||
	{ MODE_2X_PSK250R, &psk250r_c2_modem, "PSK250RC2", "2xPSK250R", "PSK250RC2", "PSK250RC2", "P250R2" },
 | 
			
		||||
	{ MODE_3X_PSK250R, &psk250r_c3_modem, "PSK250RC3", "3xPSK250R", "PSK250RC3", "PSK250RC3", "P250R3" },
 | 
			
		||||
	{ MODE_5X_PSK250R, &psk250r_c5_modem, "PSK250RC5", "5xPSK250R", "PSK250RC5", "PSK250RC5", "P250R5"},
 | 
			
		||||
	{ MODE_6X_PSK250R, &psk250r_c6_modem, "PSK250RC6", "6xPSK250R", "PSK250RC6", "PSK250RC6", "P250R6"},
 | 
			
		||||
	{ MODE_7X_PSK250R, &psk250r_c7_modem, "PSK250RC7", "7xPSK250R", "PSK250RC7", "PSK250RC7", "P250R7"},
 | 
			
		||||
 | 
			
		||||
	{ MODE_2X_PSK500, &psk500_c2_modem, "PSK500C2", "2xPSK500", "PSK500C2", "PSK500C2", "2xP500" },
 | 
			
		||||
	{ MODE_4X_PSK500, &psk500_c4_modem, "PSK500C4", "4xPSK500", "PSK500C4", "PSK500C4", "4xP500" },
 | 
			
		||||
 | 
			
		||||
	{ MODE_2X_PSK500R, &psk500r_c2_modem, "PSK500RC2", "2xPSK500R", "PSK500RC2", "PSK500RC2", "P500R2" },
 | 
			
		||||
	{ MODE_3X_PSK500R, &psk500r_c3_modem, "PSK500RC3", "3xPSK500R", "PSK500RC3", "PSK500RC3", "P500R3" },
 | 
			
		||||
	{ MODE_4X_PSK500R, &psk500r_c4_modem, "PSK500RC4", "4xPSK500R", "PSK500RC4", "PSK500RC4", "P500R4"},
 | 
			
		||||
 | 
			
		||||
	{ MODE_2X_PSK800, &psk800_c2_modem, "PSK800C2", "2xPSK800", "PSK800C2", "PSK800C2", "P800RC2" },
 | 
			
		||||
 | 
			
		||||
	{ MODE_2X_PSK800R, &psk800r_c2_modem, "PSK800RC2", "2xPSK800R", "PSK800RC2", "PSK800RC2", "P800RC2" },
 | 
			
		||||
 | 
			
		||||
	{ MODE_2X_PSK1000, &psk1000_c2_modem, "PSK1000C2", "2xPSK1000", "PSK1000C2", "PSK1000C2", "P1KC2" },
 | 
			
		||||
	{ MODE_2X_PSK1000R, &psk1000r_c2_modem, "PSK1000RC2", "2xPSK1000R", "PSK1000RC2", "PSK1000RC2", "P1KRC2" },
 | 
			
		||||
 | 
			
		||||
	{ MODE_SSB, &ssb_modem, "SSB", "SSB", "", "SSB", "" },
 | 
			
		||||
	{ MODE_WWV, &wwv_modem, "WWV", "WWV", "", "", "" },
 | 
			
		||||
	{ MODE_ANALYSIS, &anal_modem, "ANALYSIS", "Freq Analysis", "", "", "" }
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
std::ostream& operator<<(std::ostream& s, const qrg_mode_t& m)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -261,11 +261,11 @@ extern Fl_Group *tabTHOR;
 | 
			
		|||
extern Fl_Input2 *txtTHORSecondary;
 | 
			
		||||
extern Fl_Check_Button *valTHOR_FILTER;
 | 
			
		||||
extern Fl_Counter2 *valTHOR_BW;
 | 
			
		||||
extern Fl_Value_Slider2 *valThorCWI;
 | 
			
		||||
extern Fl_Counter2 *valTHOR_PATHS;
 | 
			
		||||
extern Fl_Check_Button *valTHOR_PREAMBLE;
 | 
			
		||||
extern Fl_Check_Button *valTHOR_SOFTSYMBOLS;
 | 
			
		||||
extern Fl_Check_Button *valTHOR_SOFTBITS;
 | 
			
		||||
extern Fl_Value_Slider2 *valThorCWI;
 | 
			
		||||
extern Fl_Counter2 *valTHOR_PATHS;
 | 
			
		||||
extern Fl_Group *tabPacket;
 | 
			
		||||
extern Fl_Choice *selPacket_Baud;
 | 
			
		||||
extern Fl_Counter2 *valPacket_LoSig_RXGain;
 | 
			
		||||
| 
						 | 
				
			
			@ -417,6 +417,7 @@ extern Fl_Check_Button *chkRSidAutoDisable;
 | 
			
		|||
extern Fl_Check_Button *chkRSidNotifyOnly;
 | 
			
		||||
extern Fl_Button *bRSIDRxModes;
 | 
			
		||||
extern Fl_Value_Slider2 *sldrRSIDsquelch;
 | 
			
		||||
extern Fl_Value_Slider2 *sldrRSIDresolution;
 | 
			
		||||
extern Fl_Button *bRSIDTxModes;
 | 
			
		||||
extern Fl_Check_Button *btn_post_rsid;
 | 
			
		||||
extern Fl_Counter *val_pretone;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -45,12 +45,9 @@
 | 
			
		|||
#include "viterbi.h"
 | 
			
		||||
 | 
			
		||||
#define NUMTONES 18
 | 
			
		||||
//#define MAXFFTS  4
 | 
			
		||||
#define MAXFFTS  8
 | 
			
		||||
#define BASEFREQ 1000.0
 | 
			
		||||
#define FIRSTIF  1500.0
 | 
			
		||||
//#define BASEFREQ 500.0
 | 
			
		||||
//#define FIRSTIF 1000.0
 | 
			
		||||
 | 
			
		||||
#define SCOPESIZE 64
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -79,14 +79,14 @@ enum {
 | 
			
		|||
	MODE_MFSK8,
 | 
			
		||||
	MODE_MFSK16,
 | 
			
		||||
	MODE_MFSK32,
 | 
			
		||||
// experimental modes
 | 
			
		||||
	MODE_MFSK4,
 | 
			
		||||
	MODE_MFSK11,
 | 
			
		||||
	MODE_MFSK22,
 | 
			
		||||
	MODE_MFSK31,
 | 
			
		||||
	MODE_MFSK64,
 | 
			
		||||
	MODE_MFSK128,
 | 
			
		||||
	MODE_MFSK_FIRST = MODE_MFSK8,
 | 
			
		||||
	MODE_MFSK_LAST = MODE_MFSK64,
 | 
			
		||||
	MODE_MFSK_LAST = MODE_MFSK128,
 | 
			
		||||
 | 
			
		||||
	MODE_WEFAX_576,
 | 
			
		||||
	MODE_WEFAX_288,
 | 
			
		||||
| 
						 | 
				
			
			@ -115,13 +115,25 @@ enum {
 | 
			
		|||
	MODE_QPSK125,
 | 
			
		||||
	MODE_QPSK250,
 | 
			
		||||
	MODE_QPSK500,
 | 
			
		||||
 | 
			
		||||
	MODE_PSK125R,
 | 
			
		||||
	MODE_PSK250R,
 | 
			
		||||
	MODE_PSK500R,
 | 
			
		||||
	MODE_PSK1000,
 | 
			
		||||
	MODE_PSK1000R,
 | 
			
		||||
	MODE_PSK_FIRST = MODE_PSK31,
 | 
			
		||||
	MODE_PSK_LAST = MODE_PSK500R,
 | 
			
		||||
	MODE_PSK_LAST = MODE_PSK1000R,
 | 
			
		||||
 | 
			
		||||
	MODE_OLIVIA,
 | 
			
		||||
	MODE_OLIVIA_4_250,
 | 
			
		||||
	MODE_OLIVIA_8_250,
 | 
			
		||||
	MODE_OLIVIA_4_500,
 | 
			
		||||
	MODE_OLIVIA_8_500,
 | 
			
		||||
	MODE_OLIVIA_16_500,
 | 
			
		||||
	MODE_OLIVIA_8_1000,
 | 
			
		||||
	MODE_OLIVIA_16_1000,
 | 
			
		||||
	MODE_OLIVIA_32_1000,
 | 
			
		||||
	MODE_OLIVIA_64_2000,
 | 
			
		||||
 | 
			
		||||
	MODE_RTTY,
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -131,10 +143,12 @@ enum {
 | 
			
		|||
	MODE_THOR11,
 | 
			
		||||
	MODE_THOR16,
 | 
			
		||||
	MODE_THOR22,
 | 
			
		||||
	MODE_THOR44,
 | 
			
		||||
	MODE_THOR88,
 | 
			
		||||
	MODE_THOR25x4,
 | 
			
		||||
	MODE_THOR50x1,
 | 
			
		||||
	MODE_THOR50x2,
 | 
			
		||||
	MODE_THOR100,
 | 
			
		||||
	MODE_THOR_FIRST = MODE_THOR4,
 | 
			
		||||
	MODE_THOR_LAST = MODE_THOR88,
 | 
			
		||||
	MODE_THOR_LAST = MODE_THOR100,
 | 
			
		||||
 | 
			
		||||
	MODE_THROB1,
 | 
			
		||||
	MODE_THROB2,
 | 
			
		||||
| 
						 | 
				
			
			@ -146,6 +160,41 @@ enum {
 | 
			
		|||
	MODE_THROB_LAST = MODE_THROBX4,
 | 
			
		||||
 | 
			
		||||
	MODE_PACKET,
 | 
			
		||||
// high speed && multiple carrier modes
 | 
			
		||||
 | 
			
		||||
	MODE_4X_PSK63R,
 | 
			
		||||
	MODE_5X_PSK63R,
 | 
			
		||||
	MODE_10X_PSK63R,
 | 
			
		||||
	MODE_20X_PSK63R,
 | 
			
		||||
	MODE_32X_PSK63R,
 | 
			
		||||
 | 
			
		||||
	MODE_4X_PSK125R,
 | 
			
		||||
	MODE_5X_PSK125R,
 | 
			
		||||
	MODE_10X_PSK125R,
 | 
			
		||||
	MODE_12X_PSK125,
 | 
			
		||||
	MODE_12X_PSK125R,
 | 
			
		||||
	MODE_16X_PSK125R,
 | 
			
		||||
 | 
			
		||||
	MODE_6X_PSK250,
 | 
			
		||||
 | 
			
		||||
	MODE_2X_PSK250R,
 | 
			
		||||
	MODE_3X_PSK250R,
 | 
			
		||||
	MODE_5X_PSK250R,
 | 
			
		||||
	MODE_6X_PSK250R,
 | 
			
		||||
	MODE_7X_PSK250R,
 | 
			
		||||
 | 
			
		||||
	MODE_2X_PSK500,
 | 
			
		||||
	MODE_4X_PSK500,
 | 
			
		||||
 | 
			
		||||
	MODE_2X_PSK500R,
 | 
			
		||||
	MODE_3X_PSK500R,
 | 
			
		||||
	MODE_4X_PSK500R,
 | 
			
		||||
 | 
			
		||||
	MODE_2X_PSK800,
 | 
			
		||||
	MODE_2X_PSK800R,
 | 
			
		||||
 | 
			
		||||
	MODE_2X_PSK1000,
 | 
			
		||||
	MODE_2X_PSK1000R,
 | 
			
		||||
 | 
			
		||||
	MODE_SSB,
 | 
			
		||||
	MODE_WWV,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -41,7 +41,7 @@ protected:
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
	interleave(int _size, int dir);
 | 
			
		||||
	interleave(int _size, int depth, int dir);
 | 
			
		||||
	~interleave();
 | 
			
		||||
	void symbols (unsigned char *psyms);
 | 
			
		||||
	void bits (unsigned int *pbits);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -167,6 +167,9 @@ protected:
 | 
			
		|||
 | 
			
		||||
	unsigned int datashreg;
 | 
			
		||||
 | 
			
		||||
	//VK2ETA high speed modes
 | 
			
		||||
	int	preamble;
 | 
			
		||||
 | 
			
		||||
	complex currvector;
 | 
			
		||||
	complex prev1vector;
 | 
			
		||||
	complex prev2vector;
 | 
			
		||||
| 
						 | 
				
			
			@ -242,7 +245,7 @@ protected:
 | 
			
		|||
	void	eval_s2n();
 | 
			
		||||
	void 	sendsymbol(int sym);
 | 
			
		||||
	void	sendbit(int bit);
 | 
			
		||||
	void	sendchar(unsigned int c);
 | 
			
		||||
	void	sendchar(unsigned char c);
 | 
			
		||||
	void	sendidle();
 | 
			
		||||
	void	flushtx();
 | 
			
		||||
	void	clearbits();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -197,6 +197,7 @@ extern modem *mfsk11_modem;
 | 
			
		|||
extern modem *mfsk22_modem;
 | 
			
		||||
extern modem *mfsk31_modem;
 | 
			
		||||
extern modem *mfsk64_modem;
 | 
			
		||||
extern modem *mfsk128_modem;
 | 
			
		||||
 | 
			
		||||
extern modem *wefax576_modem;
 | 
			
		||||
extern modem *wefax288_modem;
 | 
			
		||||
| 
						 | 
				
			
			@ -223,6 +224,7 @@ extern modem *psk63f_modem;
 | 
			
		|||
extern modem *psk125_modem;
 | 
			
		||||
extern modem *psk250_modem;
 | 
			
		||||
extern modem *psk500_modem;
 | 
			
		||||
extern modem *psk1000_modem;
 | 
			
		||||
 | 
			
		||||
extern modem *qpsk31_modem;
 | 
			
		||||
extern modem *qpsk63_modem;
 | 
			
		||||
| 
						 | 
				
			
			@ -233,11 +235,55 @@ extern modem *qpsk500_modem;
 | 
			
		|||
extern modem *psk125r_modem;
 | 
			
		||||
extern modem *psk250r_modem;
 | 
			
		||||
extern modem *psk500r_modem;
 | 
			
		||||
extern modem *psk1000r_modem;
 | 
			
		||||
 | 
			
		||||
extern modem *psk800_c2_modem;
 | 
			
		||||
extern modem *psk800r_c2_modem;
 | 
			
		||||
 | 
			
		||||
extern modem *psk1000_c2_modem;
 | 
			
		||||
extern modem *psk1000r_c2_modem;
 | 
			
		||||
 | 
			
		||||
extern modem *psk63r_c4_modem;
 | 
			
		||||
extern modem *psk63r_c5_modem;
 | 
			
		||||
extern modem *psk63r_c10_modem;
 | 
			
		||||
extern modem *psk63r_c20_modem;
 | 
			
		||||
extern modem *psk63r_c32_modem;
 | 
			
		||||
 | 
			
		||||
extern modem *psk125r_c4_modem;
 | 
			
		||||
extern modem *psk125r_c5_modem;
 | 
			
		||||
extern modem *psk125r_c10_modem;
 | 
			
		||||
extern modem *psk125_c12_modem;
 | 
			
		||||
extern modem *psk125r_c12_modem;
 | 
			
		||||
extern modem *psk125r_c16_modem;
 | 
			
		||||
 | 
			
		||||
extern modem *psk250r_c2_modem;
 | 
			
		||||
extern modem *psk250r_c3_modem;
 | 
			
		||||
extern modem *psk250r_c5_modem;
 | 
			
		||||
extern modem *psk250_c6_modem;
 | 
			
		||||
extern modem *psk250r_c6_modem;
 | 
			
		||||
extern modem *psk250r_c7_modem;
 | 
			
		||||
 | 
			
		||||
extern modem *psk500_c2_modem;
 | 
			
		||||
extern modem *psk500_c4_modem;
 | 
			
		||||
 | 
			
		||||
extern modem *psk500r_c2_modem;
 | 
			
		||||
extern modem *psk500r_c3_modem;
 | 
			
		||||
extern modem *psk500r_c4_modem;
 | 
			
		||||
 | 
			
		||||
extern modem *rtty_modem;
 | 
			
		||||
extern modem *pkt_modem;
 | 
			
		||||
 | 
			
		||||
extern modem *olivia_modem;
 | 
			
		||||
extern modem *olivia_4_250_modem;
 | 
			
		||||
extern modem *olivia_8_250_modem;
 | 
			
		||||
extern modem *olivia_4_500_modem;
 | 
			
		||||
extern modem *olivia_8_500_modem;
 | 
			
		||||
extern modem *olivia_16_500_modem;
 | 
			
		||||
extern modem *olivia_8_1000_modem;
 | 
			
		||||
extern modem *olivia_16_1000_modem;
 | 
			
		||||
extern modem *olivia_32_1000_modem;
 | 
			
		||||
extern modem *olivia_64_2000_modem;
 | 
			
		||||
 | 
			
		||||
extern modem *contestia_modem;
 | 
			
		||||
 | 
			
		||||
extern modem *thor4_modem;
 | 
			
		||||
| 
						 | 
				
			
			@ -246,11 +292,10 @@ extern modem *thor8_modem;
 | 
			
		|||
extern modem *thor11_modem;
 | 
			
		||||
extern modem *thor16_modem;
 | 
			
		||||
extern modem *thor22_modem;
 | 
			
		||||
 | 
			
		||||
extern modem *dominoex44_modem;
 | 
			
		||||
extern modem *thor44_modem;
 | 
			
		||||
extern modem *dominoex88_modem;
 | 
			
		||||
extern modem *thor88_modem;
 | 
			
		||||
extern modem *thor25x4_modem;
 | 
			
		||||
extern modem *thor50x1_modem;
 | 
			
		||||
extern modem *thor50x2_modem;
 | 
			
		||||
extern modem *thor100_modem;
 | 
			
		||||
 | 
			
		||||
extern modem *dominoex4_modem;
 | 
			
		||||
extern modem *dominoex5_modem;
 | 
			
		||||
| 
						 | 
				
			
			@ -258,6 +303,8 @@ extern modem *dominoex8_modem;
 | 
			
		|||
extern modem *dominoex11_modem;
 | 
			
		||||
extern modem *dominoex16_modem;
 | 
			
		||||
extern modem *dominoex22_modem;
 | 
			
		||||
extern modem *dominoex44_modem;
 | 
			
		||||
extern modem *dominoex88_modem;
 | 
			
		||||
 | 
			
		||||
extern modem *throb1_modem;
 | 
			
		||||
extern modem *throb2_modem;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -76,7 +76,7 @@ private:
 | 
			
		|||
	void		send_tones();
 | 
			
		||||
	
 | 
			
		||||
public:
 | 
			
		||||
	olivia();
 | 
			
		||||
	olivia(trx_mode omode = MODE_OLIVIA);
 | 
			
		||||
	~olivia();
 | 
			
		||||
	void init();
 | 
			
		||||
	void rx_init();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -48,6 +48,8 @@
 | 
			
		|||
#define NUM_FILTERS 3
 | 
			
		||||
#define GOERTZEL 288		//96 x 2 must be an integer value
 | 
			
		||||
 | 
			
		||||
#define MAX_CARRIERS 32
 | 
			
		||||
 | 
			
		||||
//=====================================================================
 | 
			
		||||
 | 
			
		||||
class psk : public modem {
 | 
			
		||||
| 
						 | 
				
			
			@ -56,17 +58,18 @@ private:
 | 
			
		|||
	int				symbollen;
 | 
			
		||||
	bool			_qpsk;
 | 
			
		||||
	bool			_pskr;
 | 
			
		||||
	double			phaseacc;
 | 
			
		||||
	complex			prevsymbol;
 | 
			
		||||
	double			phaseacc[MAX_CARRIERS];
 | 
			
		||||
	complex			prevsymbol[MAX_CARRIERS];
 | 
			
		||||
	unsigned int		shreg;
 | 
			
		||||
	//FEC: 2nd stream
 | 
			
		||||
	unsigned int		shreg2;
 | 
			
		||||
	int			numinterleavers; //interleaver size (speed dependant)
 | 
			
		||||
	double 			numcarriers; //Number of parallel carriers for M CAR PSK and PSKR and QPSKR
 | 
			
		||||
	double 			inter_carrier; // Frequency gap betweeb carriers
 | 
			
		||||
 | 
			
		||||
// rx variables & functions
 | 
			
		||||
 | 
			
		||||
	C_FIR_filter		*fir1;
 | 
			
		||||
	C_FIR_filter		*fir2;
 | 
			
		||||
	C_FIR_filter		*fir1[MAX_CARRIERS];
 | 
			
		||||
	C_FIR_filter		*fir2[MAX_CARRIERS];
 | 
			
		||||
//	C_FIR_filter		*fir3;
 | 
			
		||||
	double			*fir1c;
 | 
			
		||||
	double			*fir2c;
 | 
			
		||||
| 
						 | 
				
			
			@ -89,7 +92,7 @@ private:
 | 
			
		|||
	interleave		*Rxinlv;
 | 
			
		||||
	interleave		*Rxinlv2;
 | 
			
		||||
	interleave		*Txinlv;
 | 
			
		||||
	unsigned int 	bitshreg;
 | 
			
		||||
	unsigned int 		bitshreg;
 | 
			
		||||
	int 			rxbitstate;
 | 
			
		||||
	//PSKR modes - Soft decoding
 | 
			
		||||
	unsigned char		symbolpair[2];
 | 
			
		||||
| 
						 | 
				
			
			@ -115,7 +118,7 @@ private:
 | 
			
		|||
	viewpsk*		pskviewer;
 | 
			
		||||
	pskeval*		evalpsk;
 | 
			
		||||
 | 
			
		||||
	void			rx_symbol(complex symbol);
 | 
			
		||||
	void			rx_symbol(complex symbol, int car);
 | 
			
		||||
	void 			rx_bit(int bit);
 | 
			
		||||
	void 			rx_bit2(int bit);
 | 
			
		||||
	void			rx_qpsk(int bits);
 | 
			
		||||
| 
						 | 
				
			
			@ -127,15 +130,20 @@ private:
 | 
			
		|||
	double			snratio, s2n, imdratio, imd;
 | 
			
		||||
	double			E1, E2, E3;
 | 
			
		||||
	double			afcmetric;
 | 
			
		||||
	
 | 
			
		||||
	//PSKR modes
 | 
			
		||||
 | 
			
		||||
//PSKR modes
 | 
			
		||||
	bool			firstbit;
 | 
			
		||||
	bool			startpreamble;
 | 
			
		||||
 | 
			
		||||
//MULTI-CARRIER
 | 
			
		||||
	double			sc_bw; // single carrier bandwidth
 | 
			
		||||
 | 
			
		||||
	
 | 
			
		||||
//	complex thirdorder;
 | 
			
		||||
// tx variables & functions
 | 
			
		||||
	int			accumulated_bits; //JD for multiple carriers
 | 
			
		||||
	int			txsymbols[MAX_CARRIERS];
 | 
			
		||||
 | 
			
		||||
	double			*tx_shape;
 | 
			
		||||
	int 			preamble;
 | 
			
		||||
	void 			tx_symbol(int sym);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -42,7 +42,7 @@ public:
 | 
			
		|||
	void	clear();
 | 
			
		||||
	void	setbw(double w) { bw = w;}
 | 
			
		||||
	void	sigdensity();
 | 
			
		||||
	double	sigpeak(int &f, int f1, int f2, int bw);
 | 
			
		||||
	double	sigpeak(int &f, int f1, int f2);
 | 
			
		||||
	double	peak(int &f, int f1, int f2, double level);
 | 
			
		||||
	double	power(int f1, int f2);
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -113,7 +113,9 @@ public:
 | 
			
		|||
                }
 | 
			
		||||
 | 
			
		||||
#ifndef NDEBUG
 | 
			
		||||
		LOG_ERROR("qrunner: thread %" PRIdPTR " fifo full!", GET_THREAD_ID());
 | 
			
		||||
//Remi's extra debugging info		LOG_ERROR("qrunner: thread %" PRIdPTR " fifo full!", GET_THREAD_ID());
 | 
			
		||||
		LOG_ERROR("qrunner: thread %" PRIdPTR " fifo full at %s!", GET_THREAD_ID(),typeid(F).name() );
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
                return false;
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -72,16 +72,29 @@ enum {
 | 
			
		|||
struct RSIDs { unsigned short rs; trx_mode mode; const char* name; };
 | 
			
		||||
 | 
			
		||||
class cRsId {
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
// note: hamming distance > 5 causes false detection on second burst
 | 
			
		||||
enum { HAMMING_HIGH = 2, HAMMING_MED = 4, HAMMING_LOW = 5 };// 6 };
 | 
			
		||||
enum { INITIAL, EXTENDED, WAIT };
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	// Table of precalculated Reed Solomon symbols
 | 
			
		||||
	unsigned char   *pCodes;
 | 
			
		||||
	unsigned char   *pCodes2;
 | 
			
		||||
 | 
			
		||||
	static const RSIDs  rsid_ids[];
 | 
			
		||||
	static const int rsid_ids_size;
 | 
			
		||||
 | 
			
		||||
	static const int Squares[];
 | 
			
		||||
	static const int indices[];
 | 
			
		||||
 | 
			
		||||
	static const RSIDs  rsid_ids2[];
 | 
			
		||||
	static const int rsid_ids_size2;
 | 
			
		||||
 | 
			
		||||
	int state;
 | 
			
		||||
 | 
			
		||||
	int hamming_resolution;
 | 
			
		||||
 | 
			
		||||
// Span of FFT bins, in which the RSID will be searched for
 | 
			
		||||
	int		nBinLow;
 | 
			
		||||
	int		nBinHigh;
 | 
			
		||||
| 
						 | 
				
			
			@ -95,13 +108,22 @@ private:
 | 
			
		|||
	unsigned char	aHashTable1[RSID_HASH_LEN];
 | 
			
		||||
	unsigned char	aHashTable2[RSID_HASH_LEN];
 | 
			
		||||
 | 
			
		||||
	bool		bPrevTimeSliceValid;
 | 
			
		||||
	unsigned char	aHashTable1_2[RSID_HASH_LEN];
 | 
			
		||||
	unsigned char	aHashTable2_2[RSID_HASH_LEN];
 | 
			
		||||
 | 
			
		||||
	bool	bPrevTimeSliceValid;
 | 
			
		||||
	int		iPrevDistance;
 | 
			
		||||
	int		iPrevBin;
 | 
			
		||||
	int		iPrevSymbol;
 | 
			
		||||
	int		iTime; // modulo RSID_NTIMES
 | 
			
		||||
	int		aBuckets[RSID_NTIMES][RSID_FFT_SIZE];
 | 
			
		||||
 | 
			
		||||
	bool	bPrevTimeSliceValid2;
 | 
			
		||||
	int		iPrevDistance2;
 | 
			
		||||
	int		iPrevBin2;
 | 
			
		||||
	int		iPrevSymbol2;
 | 
			
		||||
	int		iTime2; // modulo RSID_NTIMES
 | 
			
		||||
 | 
			
		||||
	int		DistanceOut;
 | 
			
		||||
	int		MetricsOut;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -120,14 +142,18 @@ private:
 | 
			
		|||
	int		HammingDistance(int iBucket, unsigned char *p2);
 | 
			
		||||
	void	CalculateBuckets(const double *pSpectrum, int iBegin, int iEnd);
 | 
			
		||||
	bool	search_amp( int &pSymbolOut, int &pBinOut);
 | 
			
		||||
	bool	search_amp2( int &pSymbolOut, int &pBinOut);
 | 
			
		||||
	void	search(void);
 | 
			
		||||
	void	apply (int iSymbol, int iBin);
 | 
			
		||||
	void	apply2 (int iSymbol, int iBin);
 | 
			
		||||
public:
 | 
			
		||||
	cRsId();
 | 
			
		||||
	~cRsId();
 | 
			
		||||
	void	reset();
 | 
			
		||||
	void	receive(const float* buf, size_t len);
 | 
			
		||||
	void	send(bool postidle);
 | 
			
		||||
 | 
			
		||||
friend void reset_rsid(void *who);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,8 +1,10 @@
 | 
			
		|||
// ----------------------------------------------------------------------------
 | 
			
		||||
//    thor.h  --  thor modem
 | 
			
		||||
//
 | 
			
		||||
//	Copyright (C) 2008-2009
 | 
			
		||||
//		David Freese (w1hkj@w1hkj.com)
 | 
			
		||||
// Copyright (C) 2008-2012
 | 
			
		||||
//     David Freese <w1hkj@w1hkj.com>
 | 
			
		||||
//     John Douyere <vk2eta@gmail.com>
 | 
			
		||||
//     John Phelps  <kl4yfd@gmail.com>
 | 
			
		||||
//
 | 
			
		||||
// This file is part of fldigi.
 | 
			
		||||
//
 | 
			
		||||
| 
						 | 
				
			
			@ -39,6 +41,7 @@
 | 
			
		|||
#define	THOR_POLY1	0x6d
 | 
			
		||||
#define	THOR_POLY2	0x4f
 | 
			
		||||
 | 
			
		||||
//VK2ETA high speed modes
 | 
			
		||||
// NASA Galileo coefficients for viterbi encode/decode algorithms
 | 
			
		||||
#define	GALILEO_K	15
 | 
			
		||||
#define	GALILEO_POLY1	046321
 | 
			
		||||
| 
						 | 
				
			
			@ -51,10 +54,8 @@
 | 
			
		|||
 | 
			
		||||
#define THORNUMTONES 18
 | 
			
		||||
#define THORMAXFFTS  8
 | 
			
		||||
//#define THORBASEFREQ 500.0
 | 
			
		||||
//#define THORFIRSTIF 1000.0
 | 
			
		||||
#define THORBASEFREQ 1000.0
 | 
			
		||||
#define THORFIRSTIF  1500.0
 | 
			
		||||
#define THORBASEFREQ 1500.0
 | 
			
		||||
#define THORFIRSTIF  2000.0
 | 
			
		||||
 | 
			
		||||
#define THORSCOPESIZE 64
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -129,6 +130,8 @@ protected:
 | 
			
		|||
	
 | 
			
		||||
	bool filter_reset;
 | 
			
		||||
	bool staticburst;
 | 
			
		||||
	
 | 
			
		||||
	int fec_confidence;
 | 
			
		||||
 | 
			
		||||
// tx variables
 | 
			
		||||
	int txstate;
 | 
			
		||||
| 
						 | 
				
			
			@ -144,6 +147,9 @@ protected:
 | 
			
		|||
	int			bitstate;
 | 
			
		||||
	unsigned char symbolpair[2];
 | 
			
		||||
	
 | 
			
		||||
	int flushlength;
 | 
			
		||||
 | 
			
		||||
	
 | 
			
		||||
private:
 | 
			
		||||
	complex	mixer(int n, const complex& in);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -152,6 +158,7 @@ private:
 | 
			
		|||
	void	decodesymbol();
 | 
			
		||||
	void	softdecodesymbol();
 | 
			
		||||
	int		harddecode();
 | 
			
		||||
	int		softdecode();
 | 
			
		||||
	void	update_syncscope();
 | 
			
		||||
	void	synchronize();
 | 
			
		||||
	void	reset_afc();
 | 
			
		||||
| 
						 | 
				
			
			@ -159,7 +166,6 @@ private:
 | 
			
		|||
	int		get_secondary_char();
 | 
			
		||||
	void	reset_filters();
 | 
			
		||||
	void	decodePairs(unsigned char symbol);
 | 
			
		||||
//	void	decodeEX(int c);
 | 
			
		||||
	bool	preambledetect(int c);
 | 
			
		||||
	void	softflushrx();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,181 +25,31 @@
 | 
			
		|||
#ifndef VITERBI_H
 | 
			
		||||
#define VITERBI_H
 | 
			
		||||
 | 
			
		||||
#define PATHMEM 128 // Must be a power of base 2 (32,64,128,256...)
 | 
			
		||||
#define PATHMEM 128
 | 
			
		||||
 | 
			
		||||
class viterbi  {
 | 
			
		||||
protected:
 | 
			
		||||
	int mettab[2][256];
 | 
			
		||||
	viterbi( int poly1, int poly2, unsigned int * output, int outsize );
 | 
			
		||||
public:
 | 
			
		||||
	virtual ~viterbi() ;
 | 
			
		||||
 | 
			
		||||
	/// CPU cost of this virtual is negligible compared to the rest.
 | 
			
		||||
	virtual int decode(const unsigned char * sym, int * __restrict__ metric = NULL) = 0;
 | 
			
		||||
 | 
			
		||||
	template<	int k,
 | 
			
		||||
			int _chunksize = 8,
 | 
			
		||||
			int _traceback = PATHMEM - 1 >
 | 
			
		||||
	class impl ;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Real implementation of viterbi interface.
 | 
			
		||||
template<	int k,
 | 
			
		||||
		int _chunksize,
 | 
			
		||||
		int _traceback >
 | 
			
		||||
class viterbi::impl : public viterbi {
 | 
			
		||||
	// Find the state with the best metric
 | 
			
		||||
	// We are sure that nstates is even and greater or equal than 2
 | 
			
		||||
	int best_metric(int p) const {
 | 
			
		||||
		const int *  __restrict__ metrics_p = metrics[p];
 | 
			
		||||
		int bestmetric0 = metrics_p[0];
 | 
			
		||||
		int beststate0 = 0;
 | 
			
		||||
		int bestmetric1 = metrics_p[1];
 | 
			
		||||
		int beststate1 = 1;
 | 
			
		||||
 | 
			
		||||
		/// Loop is unrolled with two tests at a time.
 | 
			
		||||
		for (int i = 2; i < nstates; i+=2) {
 | 
			
		||||
			int metrics_p_i_0 = metrics_p[i];
 | 
			
		||||
			if (metrics_p_i_0 > bestmetric0) {
 | 
			
		||||
				bestmetric0 = metrics_p_i_0;
 | 
			
		||||
				beststate0 = i;
 | 
			
		||||
			}
 | 
			
		||||
			int metrics_p_i_1 = metrics_p[i+1];
 | 
			
		||||
			if (metrics_p_i_1 > bestmetric1) {
 | 
			
		||||
				bestmetric1 = metrics_p_i_1;
 | 
			
		||||
				beststate1 = i+1;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return bestmetric0 > bestmetric1 ? beststate0 : beststate1 ;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// n is always even because k is always bigger than 1,
 | 
			
		||||
	// because the number of states must be at least equal to 2.
 | 
			
		||||
	static const int nstates = 1 << ( k - 1 );
 | 
			
		||||
	static const int outsize = 1 << k ;
 | 
			
		||||
	/// Stores values between zero and three.
 | 
			
		||||
	unsigned int output[outsize];
 | 
			
		||||
	int metrics[PATHMEM][nstates];
 | 
			
		||||
	int history[PATHMEM][nstates];
 | 
			
		||||
private:
 | 
			
		||||
	int _traceback;
 | 
			
		||||
	int _chunksize;
 | 
			
		||||
	int nstates;
 | 
			
		||||
	int *output;
 | 
			
		||||
	int *metrics[PATHMEM];
 | 
			
		||||
	int *history[PATHMEM];
 | 
			
		||||
	int sequence[PATHMEM];
 | 
			
		||||
	int mettab[2][256];
 | 
			
		||||
	unsigned int ptr;
 | 
			
		||||
 | 
			
		||||
	int traceback(int * __restrict__ metric)
 | 
			
		||||
	{
 | 
			
		||||
		unsigned int p = ptr ? ptr - 1 : PATHMEM - 1 ;
 | 
			
		||||
 | 
			
		||||
		// Trace back 'traceback' steps, starting from the best state
 | 
			
		||||
		sequence[p] = best_metric(p);
 | 
			
		||||
 | 
			
		||||
		int delta = p - _traceback ;
 | 
			
		||||
		unsigned int limit = delta > 0 ? delta : 0 ;
 | 
			
		||||
		for( ; p > limit ; --p )
 | 
			
		||||
			sequence[p-1] = history[p][sequence[p]];
 | 
			
		||||
 | 
			
		||||
		if( delta < 0 ) {
 | 
			
		||||
			sequence[PATHMEM-1] = history[0][sequence[0]];
 | 
			
		||||
			limit = PATHMEM + delta ;
 | 
			
		||||
			for( p = PATHMEM-1 ; p > limit ; --p )
 | 
			
		||||
				sequence[p-1] = history[p][sequence[p]];
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (metric)
 | 
			
		||||
			*metric = metrics[p][sequence[p]];
 | 
			
		||||
 | 
			
		||||
		// Decode 'chunksize' bits
 | 
			
		||||
		unsigned int c = 0;
 | 
			
		||||
		for (int i = 0; i < _chunksize; i++) {
 | 
			
		||||
			// low bit of state is the previous input bit
 | 
			
		||||
			c = (c << 1) | (sequence[p] & 1);
 | 
			
		||||
			p = ( p == PATHMEM - 1 ) ? 0 : p + 1 ;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (metric)
 | 
			
		||||
			*metric = metrics[p][sequence[p]] - *metric;
 | 
			
		||||
 | 
			
		||||
		return c;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	int traceback(int *metric);
 | 
			
		||||
public:
 | 
			
		||||
	impl(int poly1, int poly2 ) : viterbi( poly1, poly2, output, outsize )
 | 
			
		||||
	{
 | 
			
		||||
		/// Will be eliminated at compile-time if OK.
 | 
			
		||||
		if (_traceback > PATHMEM - 1) abort();
 | 
			
		||||
		if (_chunksize > _traceback) abort();
 | 
			
		||||
 | 
			
		||||
		memset( sequence, 0, sizeof(int) * PATHMEM );
 | 
			
		||||
		memset( metrics, 0, nstates * sizeof(int) * PATHMEM );
 | 
			
		||||
		memset( history, 0, nstates * sizeof(int) * PATHMEM );
 | 
			
		||||
		ptr = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	~impl() {}
 | 
			
		||||
 | 
			
		||||
	int decode(const unsigned char *sym, int * __restrict__ metric = NULL)
 | 
			
		||||
	{
 | 
			
		||||
		unsigned int currptr = ptr;
 | 
			
		||||
		unsigned int prevptr = currptr ? currptr - 1 : PATHMEM - 1 ;
 | 
			
		||||
 | 
			
		||||
		const int sym0 = sym[0], sym1 = sym[1];
 | 
			
		||||
		const int * __restrict__ mettab0 = viterbi::mettab[0];
 | 
			
		||||
		const int * __restrict__ mettab1 = viterbi::mettab[1] ;
 | 
			
		||||
		const int met[4] = {
 | 
			
		||||
			mettab0[sym1] + mettab0[sym0],
 | 
			
		||||
			mettab0[sym1] + mettab1[sym0],
 | 
			
		||||
			mettab1[sym1] + mettab0[sym0],
 | 
			
		||||
			mettab1[sym1] + mettab1[sym0] } ;
 | 
			
		||||
 | 
			
		||||
		const int * __restrict__ metrics_prevptr = metrics[prevptr];
 | 
			
		||||
		int * __restrict__ metrics_currptr = metrics[currptr];
 | 
			
		||||
		int * __restrict__ history_currptr = history[currptr];
 | 
			
		||||
		// n and nstates are always even.
 | 
			
		||||
		for (int n = 0; n < nstates; n+=2) {
 | 
			
		||||
			/// p0 and p1 do not change if n = n+1, because n is even.
 | 
			
		||||
			int p0 = n >> 1;
 | 
			
		||||
			/// Equal to (n + nstates)>> 1 because n and nstates are even.
 | 
			
		||||
			int p1 = p0 + ( nstates >> 1 );
 | 
			
		||||
 | 
			
		||||
			int metrics_p0 = metrics_prevptr[p0];
 | 
			
		||||
			int metrics_p1 = metrics_prevptr[p1];
 | 
			
		||||
 | 
			
		||||
			int m0 = metrics_p0 + met[output[n]];
 | 
			
		||||
			int m1 = metrics_p1 + met[output[n + nstates]];
 | 
			
		||||
 | 
			
		||||
			bool m0_gt_1 = m0 > m1 ;
 | 
			
		||||
			metrics_currptr[n] = m0_gt_1 ? m0 : m1 ;
 | 
			
		||||
			history_currptr[n] = m0_gt_1 ? p0 : p1 ;
 | 
			
		||||
 | 
			
		||||
			m0 = metrics_p0 + met[output[n + 1]];
 | 
			
		||||
			m1 = metrics_p1 + met[output[n + 1 + nstates]];
 | 
			
		||||
 | 
			
		||||
			m0_gt_1 = m0 > m1 ;
 | 
			
		||||
			metrics_currptr[n + 1] = m0_gt_1 ? m0 : m1 ;
 | 
			
		||||
			history_currptr[n + 1] = m0_gt_1 ? p0 : p1 ;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		ptr = ( ptr == PATHMEM - 1 ) ? 0 : ptr + 1 ;
 | 
			
		||||
 | 
			
		||||
		if ((ptr % _chunksize) == 0)
 | 
			
		||||
			return traceback(metric);
 | 
			
		||||
 | 
			
		||||
		if (metrics[currptr][0] > INT_MAX / 2) {
 | 
			
		||||
			for (int i = 0; i < PATHMEM; i++)
 | 
			
		||||
				for (int j = 0; j < nstates; j++)
 | 
			
		||||
					metrics[i][j] -= INT_MAX / 2;
 | 
			
		||||
		}
 | 
			
		||||
		/// This test or the previous, but not both.
 | 
			
		||||
		else if (metrics[currptr][0] < INT_MIN / 2) {
 | 
			
		||||
			for (int i = 0; i < PATHMEM; i++)
 | 
			
		||||
				for (int j = 0; j < nstates; j++)
 | 
			
		||||
					metrics[i][j] += INT_MIN / 2;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
	viterbi(int k, int poly1, int poly2);
 | 
			
		||||
	~viterbi();
 | 
			
		||||
	void reset();
 | 
			
		||||
	int settraceback(int trace);
 | 
			
		||||
	int setchunksize(int chunk);
 | 
			
		||||
	int decode(unsigned char *sym, int *metric);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class encoder {
 | 
			
		||||
private:
 | 
			
		||||
	int *output;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -31,32 +31,10 @@
 | 
			
		|||
 | 
			
		||||
// ---------------------------------------------------------------------- 
 | 
			
		||||
 | 
			
		||||
interleave::interleave (int _size, int dir)
 | 
			
		||||
interleave::interleave (int _size, int _depth, int dir)
 | 
			
		||||
{
 | 
			
		||||
	size = _size;
 | 
			
		||||
	if (size == -1) { // dominoEX interleaver
 | 
			
		||||
		size = 4;
 | 
			
		||||
		depth = 4;
 | 
			
		||||
//BPSK+FEC+interleaver. First digit is size, then number of concatenated square interleavers
 | 
			
		||||
	} else if (size == -220) { // BPSK FEC + Interleaver 2x2x20
 | 
			
		||||
		size = 2;
 | 
			
		||||
		depth = 20;
 | 
			
		||||
	} else if (size == -240) { // BPSK FEC + Interleaver 2x2x40
 | 
			
		||||
		size = 2;
 | 
			
		||||
		depth = 40;
 | 
			
		||||
	} else if (size == -280) { // BPSK FEC + Interleaver 2x2x80
 | 
			
		||||
		size = 2;
 | 
			
		||||
		depth = 80;
 | 
			
		||||
	} else if (size == -2160) { // BPSK FEC + Interleaver 2x2x160
 | 
			
		||||
		size = 2;
 | 
			
		||||
		depth = 160;
 | 
			
		||||
	} else if (size == -488) { // THOR 44/88 Interleaver 4x4x88
 | 
			
		||||
		size = 4;
 | 
			
		||||
		depth = 88;
 | 
			
		||||
	} else if (size == 5)
 | 
			
		||||
		depth = 5;
 | 
			
		||||
	else
 | 
			
		||||
		depth = 10;
 | 
			
		||||
	depth = _depth;
 | 
			
		||||
	direction = dir;
 | 
			
		||||
	table = new unsigned char [depth * size * size];
 | 
			
		||||
	memset(table, 0, depth * size * size);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -133,13 +133,26 @@ mfsk::mfsk(trx_mode mfsk_mode) : modem()
 | 
			
		|||
 | 
			
		||||
	double bw, cf, flo, fhi;
 | 
			
		||||
	mode = mfsk_mode;
 | 
			
		||||
	int depth = 10;
 | 
			
		||||
 | 
			
		||||
	//VK2ETA high speed modes
 | 
			
		||||
	preamble = 107;
 | 
			
		||||
 | 
			
		||||
	switch (mode) {
 | 
			
		||||
		
 | 
			
		||||
	case MODE_MFSK4:
 | 
			
		||||
		samplerate = 8000;
 | 
			
		||||
		symlen = 2048;
 | 
			
		||||
		symbits = 5;
 | 
			
		||||
		depth = 5;
 | 
			
		||||
		basetone = 256;
 | 
			
		||||
		numtones = 32;
 | 
			
		||||
		break;
 | 
			
		||||
	case MODE_MFSK8:
 | 
			
		||||
		samplerate = 8000;
 | 
			
		||||
		symlen =  1024;
 | 
			
		||||
		symbits =    5;
 | 
			
		||||
		depth = 5;
 | 
			
		||||
		basetone = 128;
 | 
			
		||||
		numtones = 32;
 | 
			
		||||
		break;
 | 
			
		||||
| 
						 | 
				
			
			@ -147,46 +160,55 @@ mfsk::mfsk(trx_mode mfsk_mode) : modem()
 | 
			
		|||
		samplerate = 8000;
 | 
			
		||||
		symlen =  512;
 | 
			
		||||
		symbits =   4;
 | 
			
		||||
		depth = 10;
 | 
			
		||||
		basetone = 64;
 | 
			
		||||
		numtones = 16;
 | 
			
		||||
		cap |= CAP_IMG;
 | 
			
		||||
		break;
 | 
			
		||||
	case MODE_MFSK31:
 | 
			
		||||
		samplerate = 8000;
 | 
			
		||||
		symlen =  256;
 | 
			
		||||
		symbits =   3;
 | 
			
		||||
		depth = 10;
 | 
			
		||||
		basetone = 32;
 | 
			
		||||
		numtones = 8;
 | 
			
		||||
		cap |= CAP_IMG;
 | 
			
		||||
		break;
 | 
			
		||||
	case MODE_MFSK32:
 | 
			
		||||
		samplerate = 8000;
 | 
			
		||||
		symlen =  256;
 | 
			
		||||
		symbits =   4;
 | 
			
		||||
		depth = 10;
 | 
			
		||||
		basetone = 32;
 | 
			
		||||
		numtones = 16;
 | 
			
		||||
		cap |= CAP_IMG;
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case MODE_MFSK4:
 | 
			
		||||
		samplerate = 8000;
 | 
			
		||||
		symlen = 2048;
 | 
			
		||||
		symbits = 5;
 | 
			
		||||
		basetone = 256;
 | 
			
		||||
		numtones = 32;
 | 
			
		||||
		break;
 | 
			
		||||
	case MODE_MFSK31:
 | 
			
		||||
		samplerate = 8000;
 | 
			
		||||
		symlen =  256;
 | 
			
		||||
		symbits =   3;
 | 
			
		||||
		basetone = 32;
 | 
			
		||||
		numtones = 8;
 | 
			
		||||
		cap |= CAP_IMG;
 | 
			
		||||
		break;
 | 
			
		||||
	case MODE_MFSK64:
 | 
			
		||||
		samplerate = 8000;
 | 
			
		||||
		symlen =  128;
 | 
			
		||||
		symbits =    4;
 | 
			
		||||
		depth = 10;
 | 
			
		||||
		basetone = 16;
 | 
			
		||||
		numtones = 16;
 | 
			
		||||
		preamble = 180;
 | 
			
		||||
		cap |= CAP_IMG;
 | 
			
		||||
		break;
 | 
			
		||||
	case MODE_MFSK128:
 | 
			
		||||
		samplerate = 8000;
 | 
			
		||||
		symlen =  64;
 | 
			
		||||
		symbits =   4;
 | 
			
		||||
		depth = 20;
 | 
			
		||||
		basetone = 8;
 | 
			
		||||
		numtones = 16;
 | 
			
		||||
		cap |= CAP_IMG;
 | 
			
		||||
		preamble = 214;
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case MODE_MFSK11:
 | 
			
		||||
		samplerate = 11025;
 | 
			
		||||
		symlen =  1024;
 | 
			
		||||
		symbits =   4;
 | 
			
		||||
		depth = 10;
 | 
			
		||||
		basetone = 93;
 | 
			
		||||
		numtones = 16;
 | 
			
		||||
		cap |= CAP_IMG;
 | 
			
		||||
| 
						 | 
				
			
			@ -195,15 +217,17 @@ mfsk::mfsk(trx_mode mfsk_mode) : modem()
 | 
			
		|||
		samplerate = 11025;
 | 
			
		||||
		symlen =  512;
 | 
			
		||||
		symbits =    4;
 | 
			
		||||
		depth = 10;
 | 
			
		||||
		basetone = 46;
 | 
			
		||||
		numtones = 16;
 | 
			
		||||
		cap |= CAP_IMG;
 | 
			
		||||
		break;
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
	default:
 | 
			
		||||
		samplerate = 8000;
 | 
			
		||||
		symlen =  512;
 | 
			
		||||
		symbits =   4;
 | 
			
		||||
		depth = 10;
 | 
			
		||||
		basetone = 64;
 | 
			
		||||
		numtones = 16;
 | 
			
		||||
        break;
 | 
			
		||||
| 
						 | 
				
			
			@ -224,11 +248,16 @@ mfsk::mfsk(trx_mode mfsk_mode) : modem()
 | 
			
		|||
	pipe		= new rxpipe[ 2 * symlen ];
 | 
			
		||||
 | 
			
		||||
	enc			= new encoder (K, POLY1, POLY2);
 | 
			
		||||
	dec1		= new viterbi::impl <K, 1, 45 >( POLY1, POLY2 );
 | 
			
		||||
	dec2		= new viterbi::impl <K, 1, 45 >( POLY1, POLY2 );
 | 
			
		||||
	dec1		= new viterbi (K, POLY1, POLY2);
 | 
			
		||||
	dec2		= new viterbi (K, POLY1, POLY2);
 | 
			
		||||
 | 
			
		||||
	txinlv = new interleave (symbits, INTERLEAVE_FWD);
 | 
			
		||||
	rxinlv = new interleave (symbits, INTERLEAVE_REV);
 | 
			
		||||
	dec1->settraceback (45);
 | 
			
		||||
	dec2->settraceback (45);
 | 
			
		||||
	dec1->setchunksize (1);
 | 
			
		||||
	dec2->setchunksize (1);
 | 
			
		||||
 | 
			
		||||
	txinlv = new interleave (symbits, depth, INTERLEAVE_FWD);
 | 
			
		||||
	rxinlv = new interleave (symbits, depth, INTERLEAVE_REV);
 | 
			
		||||
 | 
			
		||||
	bw = (numtones - 1) * tonespacing;
 | 
			
		||||
	cf = basefreq + bw / 2.0;
 | 
			
		||||
| 
						 | 
				
			
			@ -512,7 +541,7 @@ void mfsk::softdecode(complex *bins)
 | 
			
		|||
// shift to range 0...255
 | 
			
		||||
	for (i = 0; i < symbits; i++)
 | 
			
		||||
		if (staticburst)
 | 
			
		||||
			symbols[i] = 128;  // puncturing 128 is neither 0 nor a 1
 | 
			
		||||
			symbols[i] = 0;  // puncturing
 | 
			
		||||
		else
 | 
			
		||||
			symbols[i] = (unsigned char)clamp(128.0 + (b[i] / sum * 128.0), 0, 255);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -803,12 +832,11 @@ void mfsk::sendbit(int bit)
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void mfsk::sendchar(unsigned int c)
 | 
			
		||||
void mfsk::sendchar(unsigned char c)
 | 
			
		||||
{
 | 
			
		||||
	const char *code = varienc(c);
 | 
			
		||||
	while (*code)
 | 
			
		||||
		sendbit(*code++ - '0');
 | 
			
		||||
 | 
			
		||||
	put_echo_char(c);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -828,7 +856,8 @@ void mfsk::flushtx()
 | 
			
		|||
	sendbit(1);
 | 
			
		||||
 | 
			
		||||
// flush the convolutional encoder and interleaver
 | 
			
		||||
	for (int i = 0; i < 107; i++)
 | 
			
		||||
//VK2ETA high speed modes	for (int i = 0; i < 107; i++)
 | 
			
		||||
	for (int i = 0; i < preamble; i++)
 | 
			
		||||
		sendbit(0);
 | 
			
		||||
 | 
			
		||||
	bitstate = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -868,7 +897,8 @@ void mfsk::sendpic(unsigned char *data, int len)
 | 
			
		|||
void mfsk::clearbits()
 | 
			
		||||
{
 | 
			
		||||
	int data = enc->encode(0);
 | 
			
		||||
	for (int k = 0; k < 100; k++) {
 | 
			
		||||
//VK2ETA high speed modes	for (int k = 0; k < 100; k++) {
 | 
			
		||||
	for (int k = 0; k < preamble; k++) {
 | 
			
		||||
		for (int i = 0; i < 2; i++) {
 | 
			
		||||
			bitshreg = (bitshreg << 1) | ((data >> i) & 1);
 | 
			
		||||
			bitstate++;
 | 
			
		||||
| 
						 | 
				
			
			@ -890,7 +920,8 @@ int mfsk::tx_process()
 | 
			
		|||
	switch (txstate) {
 | 
			
		||||
		case TX_STATE_PREAMBLE:
 | 
			
		||||
			clearbits();
 | 
			
		||||
			for (int i = 0; i < 32; i++)
 | 
			
		||||
//VK2ETA high speed modes			for (int i = 0; i < 32; i++)
 | 
			
		||||
			for (int i = 0; i < preamble / 3; i++)
 | 
			
		||||
				sendbit(0);
 | 
			
		||||
			txstate = TX_STATE_START;
 | 
			
		||||
			break;
 | 
			
		||||
| 
						 | 
				
			
			@ -918,9 +949,12 @@ int mfsk::tx_process()
 | 
			
		|||
				txstate = TX_STATE_FLUSH;
 | 
			
		||||
			else if (xmtbyte == GET_TX_CHAR_NODATA)
 | 
			
		||||
				sendidle();
 | 
			
		||||
			else
 | 
			
		||||
			else {
 | 
			
		||||
				if (xmtbyte & 0x8000) // UTF-8 character send two bytes
 | 
			
		||||
					sendchar((xmtbyte >> 8) & 0xFF);
 | 
			
		||||
				sendchar(xmtbyte);
 | 
			
		||||
			break;
 | 
			
		||||
			}
 | 
			
		||||
 			break;
 | 
			
		||||
 | 
			
		||||
		case TX_STATE_FLUSH:
 | 
			
		||||
			sendchar('\r');
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -984,10 +984,23 @@ static void doMODEM(std::string s)
 | 
			
		|||
				set_contestia_tones((int)args[1]);
 | 
			
		||||
			break;
 | 
			
		||||
		case MODE_OLIVIA: // bandwidth, tones
 | 
			
		||||
			if (args.at(0) != DBL_MIN)
 | 
			
		||||
				set_olivia_bw((int)args[0]);
 | 
			
		||||
			if (args.at(1) != DBL_MIN)
 | 
			
		||||
				set_olivia_tones((int)args[1]);
 | 
			
		||||
			if (args.at(0) != DBL_MIN && args.at(1) != DBL_MIN) {
 | 
			
		||||
				int bw = (int)args[0];
 | 
			
		||||
				int tones = (int)args[1];
 | 
			
		||||
				if (bw == 250 && tones == 4) m = MODE_OLIVIA_4_250;
 | 
			
		||||
				else if (bw == 250 && tones == 8) m = MODE_OLIVIA_8_250;
 | 
			
		||||
				else if (bw == 500 && tones == 4) m = MODE_OLIVIA_4_500;
 | 
			
		||||
				else if (bw == 500 && tones == 8) m = MODE_OLIVIA_8_500;
 | 
			
		||||
				else if (bw == 500 && tones == 16) m = MODE_OLIVIA_16_500;
 | 
			
		||||
				else if (bw == 1000 && tones == 8) m = MODE_OLIVIA_8_1000;
 | 
			
		||||
				else if (bw == 1000 && tones == 16) m = MODE_OLIVIA_16_1000;
 | 
			
		||||
				else if (bw == 1000 && tones == 32) m = MODE_OLIVIA_32_1000;
 | 
			
		||||
				else if (bw == 2000 && tones == 64) m = MODE_OLIVIA_64_2000;
 | 
			
		||||
				else {
 | 
			
		||||
					set_olivia_bw(bw);
 | 
			
		||||
					set_olivia_tones(tones);
 | 
			
		||||
				}	
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			break;
 | 
			
		||||
| 
						 | 
				
			
			@ -1075,10 +1088,23 @@ static void pMODEM(std::string &s, size_t &i, size_t endbracket)
 | 
			
		|||
				set_contestia_tones((int)args[1]);
 | 
			
		||||
			break;
 | 
			
		||||
		case MODE_OLIVIA: // bandwidth, tones
 | 
			
		||||
			if (args.at(0) != DBL_MIN)
 | 
			
		||||
				set_olivia_bw((int)args[0]);
 | 
			
		||||
			if (args.at(1) != DBL_MIN)
 | 
			
		||||
				set_olivia_tones((int)args[1]);
 | 
			
		||||
			if (args.at(0) != DBL_MIN && args.at(1) != DBL_MIN) {
 | 
			
		||||
				int bw = (int)args[0];
 | 
			
		||||
				int tones = (int)args[1];
 | 
			
		||||
				if (bw == 250 && tones == 4) m = MODE_OLIVIA_4_250;
 | 
			
		||||
				else if (bw == 250 && tones == 8) m = MODE_OLIVIA_8_250;
 | 
			
		||||
				else if (bw == 500 && tones == 4) m = MODE_OLIVIA_4_500;
 | 
			
		||||
				else if (bw == 500 && tones == 8) m = MODE_OLIVIA_8_500;
 | 
			
		||||
				else if (bw == 500 && tones == 16) m = MODE_OLIVIA_16_500;
 | 
			
		||||
				else if (bw == 1000 && tones == 8) m = MODE_OLIVIA_8_1000;
 | 
			
		||||
				else if (bw == 1000 && tones == 16) m = MODE_OLIVIA_16_1000;
 | 
			
		||||
				else if (bw == 1000 && tones == 32) m = MODE_OLIVIA_32_1000;
 | 
			
		||||
				else if (bw == 2000 && tones == 64) m = MODE_OLIVIA_64_2000;
 | 
			
		||||
				else {
 | 
			
		||||
					set_olivia_bw(bw);
 | 
			
		||||
					set_olivia_tones(tones);
 | 
			
		||||
				}	
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			break;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -37,6 +37,7 @@
 | 
			
		|||
#include "confdialog.h"
 | 
			
		||||
#include "status.h"
 | 
			
		||||
#include "debug.h"
 | 
			
		||||
#include "qrunner.h"
 | 
			
		||||
 | 
			
		||||
LOG_FILE_SOURCE(debug::LOG_MODEM);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -142,8 +143,9 @@ int olivia::tx_process()
 | 
			
		|||
{
 | 
			
		||||
	int c = 0, len = 0;
 | 
			
		||||
 | 
			
		||||
	if (tones	!= progdefaults.oliviatones ||
 | 
			
		||||
		bw 		!= progdefaults.oliviabw ||
 | 
			
		||||
	if ((mode == MODE_OLIVIA && 
 | 
			
		||||
		(tones	!= progdefaults.oliviatones ||
 | 
			
		||||
		bw 		!= progdefaults.oliviabw)) ||
 | 
			
		||||
		smargin != progdefaults.oliviasmargin ||
 | 
			
		||||
		sinteg	!= progdefaults.oliviasinteg )
 | 
			
		||||
			restart();
 | 
			
		||||
| 
						 | 
				
			
			@ -212,8 +214,9 @@ int olivia::rx_process(const double *buf, int len)
 | 
			
		|||
	static char msg1[20];
 | 
			
		||||
	static char msg2[20];
 | 
			
		||||
 | 
			
		||||
	if (tones	!= progdefaults.oliviatones ||
 | 
			
		||||
		bw 		!= progdefaults.oliviabw ||
 | 
			
		||||
	if ((mode == MODE_OLIVIA && 
 | 
			
		||||
		(tones	!= progdefaults.oliviatones ||
 | 
			
		||||
		bw 		!= progdefaults.oliviabw)) ||
 | 
			
		||||
		smargin != progdefaults.oliviasmargin ||
 | 
			
		||||
		sinteg	!= progdefaults.oliviasinteg )
 | 
			
		||||
			restart();
 | 
			
		||||
| 
						 | 
				
			
			@ -270,8 +273,10 @@ int olivia::rx_process(const double *buf, int len)
 | 
			
		|||
 | 
			
		||||
void olivia::restart()
 | 
			
		||||
{
 | 
			
		||||
	tones	= progdefaults.oliviatones;
 | 
			
		||||
	bw 		= progdefaults.oliviabw;
 | 
			
		||||
	if (mode == MODE_OLIVIA) {
 | 
			
		||||
		tones	= progdefaults.oliviatones;
 | 
			
		||||
		bw 		= progdefaults.oliviabw;
 | 
			
		||||
	}
 | 
			
		||||
	smargin = progdefaults.oliviasmargin;
 | 
			
		||||
	sinteg	= progdefaults.oliviasinteg;
 | 
			
		||||
	
 | 
			
		||||
| 
						 | 
				
			
			@ -329,7 +334,11 @@ void olivia::restart()
 | 
			
		|||
	fragmentsize = 1024;
 | 
			
		||||
	set_bandwidth(Tx->Bandwidth - Tx->Bandwidth / Tx->Tones);
 | 
			
		||||
 | 
			
		||||
	put_MODEstatus("%s %" PRIuSZ "/%" PRIuSZ "", get_mode_name(), Tx->Tones, Tx->Bandwidth);
 | 
			
		||||
	if (mode == MODE_OLIVIA)
 | 
			
		||||
		put_MODEstatus("%s %" PRIuSZ "/%" PRIuSZ "", get_mode_name(), Tx->Tones, Tx->Bandwidth);
 | 
			
		||||
	else
 | 
			
		||||
		put_MODEstatus("%s", mode_info[mode].sname);//get_mode_name());
 | 
			
		||||
 | 
			
		||||
	metric = 0;
 | 
			
		||||
 | 
			
		||||
	sigpwr = 1e-10; noisepwr = 1e-8;
 | 
			
		||||
| 
						 | 
				
			
			@ -343,17 +352,71 @@ void olivia::init()
 | 
			
		|||
	set_scope_mode(Digiscope::BLANK);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
olivia::olivia()
 | 
			
		||||
olivia::olivia(trx_mode omode)
 | 
			
		||||
{
 | 
			
		||||
	mode = omode;
 | 
			
		||||
	cap |= CAP_REV;
 | 
			
		||||
 | 
			
		||||
	txfbuffer = 0;
 | 
			
		||||
	samplerate = 8000;
 | 
			
		||||
 | 
			
		||||
	switch (mode) {
 | 
			
		||||
		case MODE_OLIVIA_4_250:
 | 
			
		||||
			progdefaults.oliviatones = tones = 1;
 | 
			
		||||
			progdefaults.oliviabw = bw = 1;
 | 
			
		||||
			REQ(set_olivia_tab_widgets);
 | 
			
		||||
			break;
 | 
			
		||||
		case MODE_OLIVIA_8_250:
 | 
			
		||||
			progdefaults.oliviatones = tones = 2;
 | 
			
		||||
			progdefaults.oliviabw = bw = 1;
 | 
			
		||||
			REQ(set_olivia_tab_widgets);
 | 
			
		||||
			break;
 | 
			
		||||
		case MODE_OLIVIA_4_500:
 | 
			
		||||
			progdefaults.oliviatones = tones = 1;
 | 
			
		||||
			progdefaults.oliviabw = bw = 2;
 | 
			
		||||
			REQ(set_olivia_tab_widgets);
 | 
			
		||||
			break;
 | 
			
		||||
		case MODE_OLIVIA_8_500:
 | 
			
		||||
			progdefaults.oliviatones = tones = 2;
 | 
			
		||||
			progdefaults.oliviabw = bw = 2;
 | 
			
		||||
			REQ(set_olivia_tab_widgets);
 | 
			
		||||
			break;
 | 
			
		||||
		case MODE_OLIVIA_16_500:
 | 
			
		||||
			progdefaults.oliviatones = tones = 3;
 | 
			
		||||
			progdefaults.oliviabw = bw = 2;
 | 
			
		||||
			REQ(set_olivia_tab_widgets);
 | 
			
		||||
			break;
 | 
			
		||||
		case MODE_OLIVIA_8_1000:
 | 
			
		||||
			progdefaults.oliviatones = tones = 2;
 | 
			
		||||
			progdefaults.oliviabw = bw = 3;
 | 
			
		||||
			REQ(set_olivia_tab_widgets);
 | 
			
		||||
			break;
 | 
			
		||||
		case MODE_OLIVIA_16_1000:
 | 
			
		||||
			progdefaults.oliviatones = tones = 3;
 | 
			
		||||
			progdefaults.oliviabw = bw = 3;
 | 
			
		||||
			REQ(set_olivia_tab_widgets);
 | 
			
		||||
			break;
 | 
			
		||||
		case MODE_OLIVIA_32_1000:
 | 
			
		||||
			progdefaults.oliviatones = tones = 4;
 | 
			
		||||
			progdefaults.oliviabw = bw = 3;
 | 
			
		||||
			REQ(set_olivia_tab_widgets);
 | 
			
		||||
			break;
 | 
			
		||||
		case MODE_OLIVIA_64_2000:
 | 
			
		||||
			progdefaults.oliviatones = tones = 5;
 | 
			
		||||
			progdefaults.oliviabw = bw = 4;
 | 
			
		||||
			REQ(set_olivia_tab_widgets);
 | 
			
		||||
			break;
 | 
			
		||||
		case MODE_OLIVIA:
 | 
			
		||||
		default:
 | 
			
		||||
			tones = progdefaults.oliviatones;
 | 
			
		||||
			bw    = progdefaults.oliviabw;
 | 
			
		||||
			REQ(set_olivia_tab_widgets);
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Tx = new MFSK_Transmitter< double >;
 | 
			
		||||
	Rx = new MFSK_Receiver< double >;
 | 
			
		||||
 | 
			
		||||
	mode = MODE_OLIVIA;
 | 
			
		||||
	lastfreq = 0;
 | 
			
		||||
 | 
			
		||||
	for (int i = 0; i < SR4; i++) ampshape[i] = 1.0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										799
									
								
								src/psk/psk.cxx
								
								
								
								
							
							
						
						
									
										799
									
								
								src/psk/psk.cxx
								
								
								
								
							
										
											
												Plik diff jest za duży
												Load Diff
											
										
									
								
							| 
						 | 
				
			
			@ -77,7 +77,7 @@ void pskeval::sigdensity() {
 | 
			
		|||
	delete [] vals;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
double pskeval::sigpeak(int &f, int f1, int f2, int w)
 | 
			
		||||
double pskeval::sigpeak(int &f, int f1, int f2)
 | 
			
		||||
{
 | 
			
		||||
	double peak = 0;
 | 
			
		||||
	f1 -= bw;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -37,7 +37,8 @@
 | 
			
		|||
#include "fqueue.h"
 | 
			
		||||
#include "qrunner.h"
 | 
			
		||||
 | 
			
		||||
#define FIFO_SIZE 2048
 | 
			
		||||
//Remi's advice for FIFO full issue #define FIFO_SIZE 2048
 | 
			
		||||
#define FIFO_SIZE 8192
 | 
			
		||||
 | 
			
		||||
#ifndef __MINGW32__
 | 
			
		||||
#  define QRUNNER_EAGAIN() (errno == EAGAIN)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,10 +2,12 @@
 | 
			
		|||
//
 | 
			
		||||
//	rsid.cxx
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2008-2010
 | 
			
		||||
// Copyright (C) 2008-2012
 | 
			
		||||
//		Dave Freese, W1HKJ
 | 
			
		||||
// Copyright (C) 2009
 | 
			
		||||
// Copyright (C) 2009-2012
 | 
			
		||||
//		Stelios Bounanos, M0GLD
 | 
			
		||||
// Copyright (C) 2012
 | 
			
		||||
//		John Douyere, VK2ETA
 | 
			
		||||
//
 | 
			
		||||
// This file is part of fldigi.
 | 
			
		||||
//
 | 
			
		||||
| 
						 | 
				
			
			@ -47,203 +49,19 @@
 | 
			
		|||
 | 
			
		||||
LOG_FILE_SOURCE(debug::LOG_MODEM);
 | 
			
		||||
 | 
			
		||||
// Syntax: ELEM_(rsid_code, rsid_tag, fldigi_mode)
 | 
			
		||||
// fldigi_mode is NUM_MODES if mode is not available in fldigi,
 | 
			
		||||
// otherwise one of the tags defined in globals.h.
 | 
			
		||||
// rsid_tag is stringified and may be shown to the user.
 | 
			
		||||
#undef ELEM_
 | 
			
		||||
#define RSID_LIST                                       \
 | 
			
		||||
        ELEM_(1, BPSK31, MODE_PSK31)                    \
 | 
			
		||||
        ELEM_(110, QPSK31, MODE_QPSK31)                 \
 | 
			
		||||
        ELEM_(2, BPSK63, MODE_PSK63)                    \
 | 
			
		||||
        ELEM_(3, QPSK63, MODE_QPSK63)                   \
 | 
			
		||||
        ELEM_(4, BPSK125, MODE_PSK125)                  \
 | 
			
		||||
        ELEM_(5, QPSK125, MODE_QPSK125)                 \
 | 
			
		||||
        ELEM_(126, BPSK250, MODE_PSK250)                \
 | 
			
		||||
        ELEM_(127, QPSK250, MODE_QPSK250)               \
 | 
			
		||||
        ELEM_(173, BPSK500, MODE_PSK500)                \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(183, PSK125R, MODE_PSK125R)               \
 | 
			
		||||
        ELEM_(186, PSK250R, MODE_PSK250R)               \
 | 
			
		||||
        ELEM_(187, PSK500R, MODE_PSK500R)               \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(7, PSKFEC31, NUM_MODES)                   \
 | 
			
		||||
        ELEM_(8, PSK10, NUM_MODES)                      \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(9, MT63_500_LG, MODE_MT63_500)            \
 | 
			
		||||
        ELEM_(10, MT63_500_ST, MODE_MT63_500)           \
 | 
			
		||||
        ELEM_(11, MT63_500_VST, MODE_MT63_500)          \
 | 
			
		||||
        ELEM_(12, MT63_1000_LG, MODE_MT63_1000)         \
 | 
			
		||||
        ELEM_(13, MT63_1000_ST, MODE_MT63_1000)         \
 | 
			
		||||
        ELEM_(14, MT63_1000_VST, MODE_MT63_1000)        \
 | 
			
		||||
        ELEM_(15, MT63_2000_LG, MODE_MT63_2000)         \
 | 
			
		||||
        ELEM_(17, MT63_2000_ST, MODE_MT63_2000)         \
 | 
			
		||||
        ELEM_(18, MT63_2000_VST, MODE_MT63_2000)        \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(19, PSKAM10, NUM_MODES)                   \
 | 
			
		||||
        ELEM_(20, PSKAM31, NUM_MODES)                   \
 | 
			
		||||
        ELEM_(21, PSKAM50, NUM_MODES)                   \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(22, PSK63F, MODE_PSK63F)                  \
 | 
			
		||||
        ELEM_(23, PSK220F, NUM_MODES)                   \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(24, CHIP64, NUM_MODES)                    \
 | 
			
		||||
        ELEM_(25, CHIP128, NUM_MODES)                   \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(26, CW, MODE_CW)                          \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(27, CCW_OOK_12, NUM_MODES)                \
 | 
			
		||||
        ELEM_(28, CCW_OOK_24, NUM_MODES)                \
 | 
			
		||||
        ELEM_(29, CCW_OOK_48, NUM_MODES)                \
 | 
			
		||||
        ELEM_(30, CCW_FSK_12, NUM_MODES)                \
 | 
			
		||||
        ELEM_(31, CCW_FSK_24, NUM_MODES)                \
 | 
			
		||||
        ELEM_(33, CCW_FSK_48, NUM_MODES)                \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(34, PACTOR1_FEC, NUM_MODES)               \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(113, PACKET_110, NUM_MODES)               \
 | 
			
		||||
        ELEM_(35, PACKET_300, NUM_MODES)                \
 | 
			
		||||
        ELEM_(36, PACKET_1200, NUM_MODES)               \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(37, RTTY_ASCII_7, MODE_RTTY)              \
 | 
			
		||||
        ELEM_(38, RTTY_ASCII_8, MODE_RTTY)              \
 | 
			
		||||
        ELEM_(39, RTTY_45, MODE_RTTY)                   \
 | 
			
		||||
        ELEM_(40, RTTY_50, MODE_RTTY)                   \
 | 
			
		||||
        ELEM_(41, RTTY_75, MODE_RTTY)                   \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(42, AMTOR_FEC, NUM_MODES)                 \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(43, THROB_1, MODE_THROB1)                 \
 | 
			
		||||
        ELEM_(44, THROB_2, MODE_THROB2)                 \
 | 
			
		||||
        ELEM_(45, THROB_4, MODE_THROB4)                 \
 | 
			
		||||
        ELEM_(46, THROBX_1, MODE_THROBX1)               \
 | 
			
		||||
        ELEM_(47, THROBX_2, MODE_THROBX2)               \
 | 
			
		||||
        ELEM_(146, THROBX_4, MODE_THROBX4)              \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(204, CONTESTIA_4_125, MODE_CONTESTIA)     \
 | 
			
		||||
        ELEM_(55,  CONTESTIA_4_250, MODE_CONTESTIA)     \
 | 
			
		||||
        ELEM_(54,  CONTESTIA_4_500, MODE_CONTESTIA)     \
 | 
			
		||||
        ELEM_(255, CONTESTIA_4_1000, MODE_CONTESTIA)    \
 | 
			
		||||
        ELEM_(254, CONTESTIA_4_2000, MODE_CONTESTIA)    \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(169, CONTESTIA_8_125, MODE_CONTESTIA)     \
 | 
			
		||||
        ELEM_(49,  CONTESTIA_8_250, MODE_CONTESTIA)     \
 | 
			
		||||
        ELEM_(52,  CONTESTIA_8_500, MODE_CONTESTIA)     \
 | 
			
		||||
        ELEM_(117, CONTESTIA_8_1000, MODE_CONTESTIA)    \
 | 
			
		||||
        ELEM_(247, CONTESTIA_8_2000, MODE_CONTESTIA)    \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(50,  CONTESTIA_16_500, MODE_CONTESTIA)    \
 | 
			
		||||
        ELEM_(53,  CONTESTIA_16_1000, MODE_CONTESTIA)   \
 | 
			
		||||
        ELEM_(259, CONTESTIA_16_2000, MODE_CONTESTIA)   \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(51,  CONTESTIA_32_1000, MODE_CONTESTIA)   \
 | 
			
		||||
        ELEM_(201, CONTESTIA_32_2000, MODE_CONTESTIA)   \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(194, CONTESTIA_64_500, MODE_CONTESTIA)    \
 | 
			
		||||
        ELEM_(193, CONTESTIA_64_1000, MODE_CONTESTIA)   \
 | 
			
		||||
        ELEM_(191, CONTESTIA_64_2000, MODE_CONTESTIA)   \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(261, CONTESTIA_128_2000, MODE_CONTESTIA)  \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(56, VOICE, NUM_MODES)                     \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(60, MFSK8, MODE_MFSK8)                    \
 | 
			
		||||
        ELEM_(57, MFSK16, MODE_MFSK16)                  \
 | 
			
		||||
        ELEM_(147, MFSK32, MODE_MFSK32)                 \
 | 
			
		||||
        ELEM_(148, MFSK11, MODE_MFSK11)                 \
 | 
			
		||||
        ELEM_(152, MFSK22, MODE_MFSK22)                 \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(61, RTTYM_8_250, NUM_MODES)               \
 | 
			
		||||
        ELEM_(62, RTTYM_16_500, NUM_MODES)              \
 | 
			
		||||
        ELEM_(63, RTTYM_32_1000, NUM_MODES)             \
 | 
			
		||||
        ELEM_(65, RTTYM_8_500, NUM_MODES)               \
 | 
			
		||||
        ELEM_(66, RTTYM_16_1000, NUM_MODES)             \
 | 
			
		||||
        ELEM_(67, RTTYM_4_500, NUM_MODES)               \
 | 
			
		||||
        ELEM_(68, RTTYM_4_250, NUM_MODES)               \
 | 
			
		||||
        ELEM_(119, RTTYM_8_1000, NUM_MODES)             \
 | 
			
		||||
        ELEM_(170, RTTYM_8_125, NUM_MODES)              \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(203, OLIVIA_4_125, MODE_OLIVIA)           \
 | 
			
		||||
        ELEM_(75,  OLIVIA_4_250, MODE_OLIVIA)           \
 | 
			
		||||
        ELEM_(74,  OLIVIA_4_500, MODE_OLIVIA)           \
 | 
			
		||||
        ELEM_(229, OLIVIA_4_1000, MODE_OLIVIA)          \
 | 
			
		||||
        ELEM_(238, OLIVIA_4_2000, MODE_OLIVIA)          \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(163, OLIVIA_8_125, MODE_OLIVIA)           \
 | 
			
		||||
        ELEM_(69,  OLIVIA_8_250, MODE_OLIVIA)           \
 | 
			
		||||
        ELEM_(72,  OLIVIA_8_500, MODE_OLIVIA)           \
 | 
			
		||||
        ELEM_(116, OLIVIA_8_1000, MODE_OLIVIA)          \
 | 
			
		||||
        ELEM_(214, OLIVIA_8_2000, MODE_OLIVIA)          \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(70,  OLIVIA_16_500, MODE_OLIVIA)          \
 | 
			
		||||
        ELEM_(73,  OLIVIA_16_1000, MODE_OLIVIA)         \
 | 
			
		||||
        ELEM_(234, OLIVIA_16_2000, MODE_OLIVIA)         \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(71,  OLIVIA_32_1000, MODE_OLIVIA)         \
 | 
			
		||||
        ELEM_(221, OLIVIA_32_2000, MODE_OLIVIA)         \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(211, OLIVIA_64_2000, MODE_OLIVIA)         \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(76, PAX, NUM_MODES)                       \
 | 
			
		||||
        ELEM_(77, PAX2, NUM_MODES)                      \
 | 
			
		||||
        ELEM_(78, DOMINOF, NUM_MODES)                   \
 | 
			
		||||
        ELEM_(79, FAX, NUM_MODES)                       \
 | 
			
		||||
        ELEM_(81, SSTV, NUM_MODES)                      \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(84, DOMINOEX_4, MODE_DOMINOEX4)           \
 | 
			
		||||
        ELEM_(85, DOMINOEX_5, MODE_DOMINOEX5)           \
 | 
			
		||||
        ELEM_(86, DOMINOEX_8, MODE_DOMINOEX8)           \
 | 
			
		||||
        ELEM_(87, DOMINOEX_11, MODE_DOMINOEX11)         \
 | 
			
		||||
        ELEM_(88, DOMINOEX_16, MODE_DOMINOEX16)         \
 | 
			
		||||
        ELEM_(90, DOMINOEX_22, MODE_DOMINOEX22)         \
 | 
			
		||||
        ELEM_(92, DOMINOEX_4_FEC, MODE_DOMINOEX4)       \
 | 
			
		||||
        ELEM_(93, DOMINOEX_5_FEC, MODE_DOMINOEX5)       \
 | 
			
		||||
        ELEM_(97, DOMINOEX_8_FEC, MODE_DOMINOEX8)       \
 | 
			
		||||
        ELEM_(98, DOMINOEX_11_FEC, MODE_DOMINOEX11)     \
 | 
			
		||||
        ELEM_(99, DOMINOEX_16_FEC, MODE_DOMINOEX16)     \
 | 
			
		||||
        ELEM_(101, DOMINOEX_22_FEC, MODE_DOMINOEX22)    \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(104, FELD_HELL, MODE_FELDHELL)            \
 | 
			
		||||
        ELEM_(105, PSK_HELL, NUM_MODES)                 \
 | 
			
		||||
        ELEM_(106, HELL_80, MODE_HELL80)                \
 | 
			
		||||
        ELEM_(107, FM_HELL_105, MODE_FSKH105)           \
 | 
			
		||||
        ELEM_(108, FM_HELL_245, NUM_MODES)              \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(114, MODE_141A, NUM_MODES)                \
 | 
			
		||||
        ELEM_(123, DTMF, NUM_MODES)                     \
 | 
			
		||||
        ELEM_(125, ALE400, NUM_MODES)                   \
 | 
			
		||||
        ELEM_(131, FDMDV, NUM_MODES)                    \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(132, JT65_A, NUM_MODES)                   \
 | 
			
		||||
        ELEM_(134, JT65_B, NUM_MODES)                   \
 | 
			
		||||
        ELEM_(135, JT65_C, NUM_MODES)                   \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(136, THOR_4, MODE_THOR4)                  \
 | 
			
		||||
        ELEM_(137, THOR_8, MODE_THOR8)                  \
 | 
			
		||||
        ELEM_(138, THOR_16, MODE_THOR16)                \
 | 
			
		||||
        ELEM_(139, THOR_5, MODE_THOR5)                  \
 | 
			
		||||
        ELEM_(143, THOR_11, MODE_THOR11)                \
 | 
			
		||||
        ELEM_(145, THOR_22, MODE_THOR22)                \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(153, CALL_ID, NUM_MODES)                  \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(155, PACKET_PSK1200, NUM_MODES)           \
 | 
			
		||||
        ELEM_(156, PACKET_PSK250, NUM_MODES)            \
 | 
			
		||||
        ELEM_(159, PACKET_PSK63, NUM_MODES)             \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(172, MODE_188_110A_8N1, NUM_MODES)        \
 | 
			
		||||
                                                        \
 | 
			
		||||
        /* NONE must be the last element */             \
 | 
			
		||||
        ELEM_(0, NONE, NUM_MODES)
 | 
			
		||||
#include "rsid_defs.cxx"
 | 
			
		||||
 | 
			
		||||
#define ELEM_(code_, tag_, mode_) RSID_ ## tag_ = code_,
 | 
			
		||||
enum { RSID_LIST };
 | 
			
		||||
#undef ELEM_
 | 
			
		||||
void reset_rsid(void *who) {
 | 
			
		||||
	cRsId *me = (cRsId *)who;
 | 
			
		||||
	LOG_INFO("%s", "RxID detector reset");
 | 
			
		||||
	me->state = cRsId::INITIAL;
 | 
			
		||||
	me->reset();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define ELEM_(code_, tag_, mode_) { RSID_ ## tag_, mode_, #tag_ },
 | 
			
		||||
const RSIDs cRsId::rsid_ids[] = { RSID_LIST };
 | 
			
		||||
#undef ELEM_
 | 
			
		||||
const int cRsId::rsid_ids_size = sizeof(rsid_ids)/sizeof(*rsid_ids) - 1;
 | 
			
		||||
void reset_rsid_detector(void *me) {
 | 
			
		||||
	Fl::remove_timeout(reset_rsid);
 | 
			
		||||
	Fl::add_timeout(3*15*RSID_SYMLEN, reset_rsid, me);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const int cRsId::Squares[] = {
 | 
			
		||||
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 | 
			
		||||
| 
						 | 
				
			
			@ -285,14 +103,14 @@ cRsId::cRsId()
 | 
			
		|||
	memset(aHashTable1, 255, sizeof(aHashTable1));
 | 
			
		||||
	memset(aHashTable2, 255, sizeof(aHashTable2));
 | 
			
		||||
	memset(fftwindow, 0, RSID_ARRAY_SIZE * sizeof(double));
 | 
			
		||||
//	BlackmanWindow(fftwindow, RSID_FFT_SIZE);
 | 
			
		||||
//	HammingWindow(fftwindow, RSID_FFT_SIZE);
 | 
			
		||||
//	HanningWindow(fftwindow, RSID_FFT_SIZE);
 | 
			
		||||
	RectWindow(fftwindow, RSID_FFT_SIZE);
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	pCodes = new unsigned char[rsid_ids_size * RSID_NSYMBOLS];
 | 
			
		||||
	memset(pCodes, 0, rsid_ids_size * RSID_NSYMBOLS);
 | 
			
		||||
 | 
			
		||||
	pCodes2 = new unsigned char[rsid_ids_size2 * RSID_NSYMBOLS];
 | 
			
		||||
	memset(pCodes, 0, rsid_ids_size2 * RSID_NSYMBOLS);
 | 
			
		||||
 | 
			
		||||
	// Initialization  of assigned mode/submode IDs.
 | 
			
		||||
	// HashTable is used for finding a code with lowest Hamming distance.
 | 
			
		||||
	unsigned char* c;
 | 
			
		||||
| 
						 | 
				
			
			@ -306,17 +124,33 @@ cRsId::cRsId()
 | 
			
		|||
		aHashTable2[hash2] = i;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for (int i = 0; i < rsid_ids_size2; i++) {
 | 
			
		||||
		c = pCodes2 + i * RSID_NSYMBOLS;
 | 
			
		||||
		Encode(rsid_ids2[i].rs, c);
 | 
			
		||||
		hash1 = c[11] | (c[12] << 4);
 | 
			
		||||
		hash2 = c[13] | (c[14] << 4);
 | 
			
		||||
		aHashTable1_2[hash1] = i;
 | 
			
		||||
		aHashTable2_2[hash2] = i;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	nBinLow = RSID_RESOL + 1;
 | 
			
		||||
	nBinHigh = RSID_FFT_SIZE - 32;
 | 
			
		||||
 | 
			
		||||
	outbuf = 0;
 | 
			
		||||
	symlen = 0;
 | 
			
		||||
 | 
			
		||||
	hamming_resolution = progdefaults.rsid_resolution;
 | 
			
		||||
 | 
			
		||||
	state = INITIAL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cRsId::~cRsId()
 | 
			
		||||
{
 | 
			
		||||
	delete [] pCodes;
 | 
			
		||||
	delete [] pCodes2;
 | 
			
		||||
 | 
			
		||||
	delete [] outbuf;
 | 
			
		||||
	delete rsfft;
 | 
			
		||||
	src_delete(src_state);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -324,7 +158,9 @@ void cRsId::reset()
 | 
			
		|||
{
 | 
			
		||||
	iPrevDistance = 99;
 | 
			
		||||
	bPrevTimeSliceValid = false;
 | 
			
		||||
	bPrevTimeSliceValid2 = false;
 | 
			
		||||
	iTime = 0;
 | 
			
		||||
	iTime2 = 0;
 | 
			
		||||
	memset(aInputSamples, 0, sizeof(aInputSamples));
 | 
			
		||||
	memset(aFFTReal, 0, sizeof(aFFTReal));
 | 
			
		||||
	memset(aFFTAmpl, 0, sizeof(aFFTAmpl));
 | 
			
		||||
| 
						 | 
				
			
			@ -351,7 +187,6 @@ void cRsId::Encode(int code, unsigned char *rsid)
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void cRsId::CalculateBuckets(const double *pSpectrum, int iBegin, int iEnd)
 | 
			
		||||
{
 | 
			
		||||
	double Amp = 0.0, AmpMax = 0.0;
 | 
			
		||||
| 
						 | 
				
			
			@ -435,9 +270,7 @@ void cRsId::search(void)
 | 
			
		|||
	else {
 | 
			
		||||
		double centerfreq = active_modem->get_freq();
 | 
			
		||||
		nBinLow = (int)((centerfreq  - 100.0 * RSID_RESOL) * 2048.0 / RSID_SAMPLE_RATE);
 | 
			
		||||
		if (nBinLow < RSID_RESOL + 1) nBinLow = RSID_RESOL + 1;
 | 
			
		||||
		nBinHigh = (int)((centerfreq  + 100.0 * RSID_RESOL) * 2048.0 / RSID_SAMPLE_RATE);
 | 
			
		||||
		if (nBinHigh > RSID_FFT_SIZE -32) nBinHigh = RSID_FFT_SIZE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bool bReverse = !(wf->Reverse() ^ wf->USB());
 | 
			
		||||
| 
						 | 
				
			
			@ -475,10 +308,29 @@ void cRsId::search(void)
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	int SymbolOut = -1, BinOut = -1;
 | 
			
		||||
	if (search_amp(SymbolOut, BinOut)) {
 | 
			
		||||
	if (state == INITIAL && search_amp(SymbolOut, BinOut)) {
 | 
			
		||||
		LOG_INFO("Rsid_code detected: %d", SymbolOut);
 | 
			
		||||
		if (SymbolOut == RSID_ESCAPE) {
 | 
			
		||||
			state = EXTENDED;
 | 
			
		||||
			reset();
 | 
			
		||||
			REQ(reset_rsid_detector, this);  // reset after fixed time interval
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		if (bReverse)
 | 
			
		||||
			BinOut = 1024 - BinOut - 31;
 | 
			
		||||
		apply(SymbolOut, BinOut);
 | 
			
		||||
		Fl::remove_timeout(reset_rsid);
 | 
			
		||||
		state = INITIAL;
 | 
			
		||||
		reset();
 | 
			
		||||
	} else if (state == EXTENDED && search_amp(SymbolOut, BinOut)) {
 | 
			
		||||
		LOG_INFO("Ext' rsid_code detected: %d", SymbolOut);
 | 
			
		||||
		if (bReverse)
 | 
			
		||||
			BinOut = 1024 - BinOut - 31;
 | 
			
		||||
		if (SymbolOut != RSID_ESCAPE2)
 | 
			
		||||
			apply2(SymbolOut, BinOut);
 | 
			
		||||
		Fl::remove_timeout(reset_rsid);
 | 
			
		||||
		state = INITIAL;
 | 
			
		||||
		reset();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -729,11 +581,6 @@ void cRsId::apply(int iSymbol, int iBin)
 | 
			
		|||
		progdefaults.contestiabw = 4;
 | 
			
		||||
		REQ(&set_contestia_tab_widgets);
 | 
			
		||||
		break;
 | 
			
		||||
	case RSID_CONTESTIA_128_2000:
 | 
			
		||||
		progdefaults.contestiatones = 6;
 | 
			
		||||
		progdefaults.contestiabw = 4;
 | 
			
		||||
		REQ(&set_contestia_tab_widgets);
 | 
			
		||||
		break;
 | 
			
		||||
	// mt63
 | 
			
		||||
	case RSID_MT63_500_LG: case RSID_MT63_1000_LG: case RSID_MT63_2000_LG:
 | 
			
		||||
		progdefaults.mt63_interleave = 64;
 | 
			
		||||
| 
						 | 
				
			
			@ -764,6 +611,54 @@ void cRsId::apply(int iSymbol, int iBin)
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cRsId::apply2(int iSymbol, int iBin)
 | 
			
		||||
{
 | 
			
		||||
	ENSURE_THREAD(TRX_TID);
 | 
			
		||||
 | 
			
		||||
	double freq = (iBin + (RSID_NSYMBOLS - 1) * RSID_RESOL / 2) * RSID_SAMPLE_RATE / 2048.0;
 | 
			
		||||
 | 
			
		||||
	int n, mbin = NUM_MODES;
 | 
			
		||||
	for (n = 0; n < rsid_ids_size2; n++) {
 | 
			
		||||
		if (rsid_ids2[n].rs == iSymbol) {
 | 
			
		||||
			mbin = rsid_ids2[n].mode;
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if (mbin == NUM_MODES) {
 | 
			
		||||
		char msg[50];
 | 
			
		||||
		if (n < rsid_ids_size2) // RSID known but unimplemented
 | 
			
		||||
			snprintf(msg, sizeof(msg), "RSID-2: %s unimplemented", rsid_ids2[n].name);
 | 
			
		||||
		else // RSID unknown; shouldn't  happen
 | 
			
		||||
			snprintf(msg, sizeof(msg), "RSID-2: code %d unknown", iSymbol);
 | 
			
		||||
		put_status(msg, 4.0);
 | 
			
		||||
		LOG_VERBOSE("%s", msg);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	else if (!progdefaults.rsid_rx_modes.test(mbin)) {
 | 
			
		||||
		LOG_DEBUG("Ignoring RSID: %s @ %0.0f Hz", rsid_ids2[n].name, freq);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
		LOG_INFO("RSID: %s @ %0.0f Hz", rsid_ids2[n].name, freq);
 | 
			
		||||
 | 
			
		||||
	if (!progdefaults.rsid_notify_only && progdefaults.rsid_auto_disable)
 | 
			
		||||
		REQ(toggleRSID);
 | 
			
		||||
 | 
			
		||||
	if (mailclient || mailserver)
 | 
			
		||||
		REQ(pskmail_notify_rsid, mbin);
 | 
			
		||||
 | 
			
		||||
	if (progdefaults.rsid_mark && !progdefaults.rsid_notify_only) // mark current modem & freq
 | 
			
		||||
		REQ(note_qrg, false, "\nBefore RSID: ", "\n",
 | 
			
		||||
		    active_modem->get_mode(), 0LL, active_modem->get_freq());
 | 
			
		||||
	REQ(notify_rsid, mbin, freq);
 | 
			
		||||
	if (!progdefaults.rsid_notify_only) {
 | 
			
		||||
		if (progdefaults.rsid_squelch)
 | 
			
		||||
			REQ(init_modem_squelch, mbin, freq);
 | 
			
		||||
		else
 | 
			
		||||
			REQ(init_modem, mbin, freq);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//=============================================================================
 | 
			
		||||
// search_amp routine #1
 | 
			
		||||
//=============================================================================
 | 
			
		||||
| 
						 | 
				
			
			@ -776,7 +671,8 @@ int cRsId::HammingDistance(int iBucket, unsigned char *p2)
 | 
			
		|||
		j += RSID_NTIMES;
 | 
			
		||||
	for (int i = 0; i < RSID_NSYMBOLS; i++) {
 | 
			
		||||
		if (aBuckets[j][iBucket] != p2[i])//*p2++)
 | 
			
		||||
			if (++dist == 2)
 | 
			
		||||
//VK2ETA For ARQ modes, allow more bit corrections (4 in 6)
 | 
			
		||||
			if (++dist == hamming_resolution)
 | 
			
		||||
				return dist;
 | 
			
		||||
		j += RSID_RESOL;//2;
 | 
			
		||||
		if (j >= RSID_NTIMES)
 | 
			
		||||
| 
						 | 
				
			
			@ -816,9 +712,10 @@ bool cRsId::search_amp( int &SymbolOut,	int &BinOut)
 | 
			
		|||
 | 
			
		||||
	for (i = nBinLow; i < iEnd; ++ i) {
 | 
			
		||||
		j = aHashTable1[aBuckets[i1][i] | (aBuckets[i2][i] << 4)];
 | 
			
		||||
		if (j < rsid_ids_size)  { //!= 255) {
 | 
			
		||||
		if (j < rsid_ids_size)  {
 | 
			
		||||
			iDistance = HammingDistance(i, pCodes + j * RSID_NSYMBOLS);
 | 
			
		||||
			if (iDistance < 2 && iDistance < iDistanceMin) {
 | 
			
		||||
//VK2ETA For ARQ modes, allow more bit corrections (4 in 6)
 | 
			
		||||
			if (iDistance < hamming_resolution && iDistance < iDistanceMin) {
 | 
			
		||||
				iDistanceMin = iDistance;
 | 
			
		||||
				iSymbol  	 = rsid_ids[j].rs;
 | 
			
		||||
				iBin		 = i;
 | 
			
		||||
| 
						 | 
				
			
			@ -827,7 +724,8 @@ bool cRsId::search_amp( int &SymbolOut,	int &BinOut)
 | 
			
		|||
		j = aHashTable2[aBuckets[i3][i] | (aBuckets[iTime][i] << 4)];
 | 
			
		||||
		if (j < rsid_ids_size)  { //!= 255) {
 | 
			
		||||
			iDistance = HammingDistance (i, pCodes + j * RSID_NSYMBOLS);
 | 
			
		||||
			if (iDistance < 2 && iDistance < iDistanceMin) {
 | 
			
		||||
//VK2ETA For ARQ modes, allow more bit corrections (4 in 6)
 | 
			
		||||
			if (iDistance < hamming_resolution && iDistance < iDistanceMin) {
 | 
			
		||||
				iDistanceMin = iDistance;
 | 
			
		||||
				iSymbol		 = rsid_ids[j].rs;
 | 
			
		||||
				iBin		 = i;
 | 
			
		||||
| 
						 | 
				
			
			@ -859,6 +757,82 @@ bool cRsId::search_amp( int &SymbolOut,	int &BinOut)
 | 
			
		|||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cRsId::search_amp2( int &SymbolOut,	int &BinOut)
 | 
			
		||||
{
 | 
			
		||||
	int i, j;
 | 
			
		||||
	int iDistanceMin = 99;  // infinity
 | 
			
		||||
	int iDistance;
 | 
			
		||||
	int iBin		 = -1;
 | 
			
		||||
	int iSymbol		 = -1;
 | 
			
		||||
	int iEnd		 = nBinHigh - RSID_NTIMES;//30;
 | 
			
		||||
	int i1, i2, i3;
 | 
			
		||||
 | 
			
		||||
	if (++iTime2 == RSID_NTIMES)
 | 
			
		||||
		iTime2 = 0;
 | 
			
		||||
 | 
			
		||||
	i1 = iTime2 - 3 * RSID_RESOL;//6;
 | 
			
		||||
	i2 = i1 + RSID_RESOL;//2;
 | 
			
		||||
	i3 = i2 + RSID_RESOL;//2;
 | 
			
		||||
 | 
			
		||||
	if (i1 < 0) {
 | 
			
		||||
		i1 += RSID_NTIMES;
 | 
			
		||||
		if (i2 < 0) {
 | 
			
		||||
			i2 += RSID_NTIMES;
 | 
			
		||||
			if (i3 < 0)
 | 
			
		||||
				i3 += RSID_NTIMES;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	CalculateBuckets ( aFFTAmpl, nBinLow,     iEnd);//nBinHigh - 30);
 | 
			
		||||
	CalculateBuckets ( aFFTAmpl, nBinLow + 1, iEnd);//nBinHigh - 30);
 | 
			
		||||
 | 
			
		||||
	for (i = nBinLow; i < iEnd; ++ i) {
 | 
			
		||||
		j = aHashTable1_2[aBuckets[i1][i] | (aBuckets[i2][i] << 4)];
 | 
			
		||||
		if (j < rsid_ids_size2)  {
 | 
			
		||||
			iDistance = HammingDistance(i, pCodes2 + j * RSID_NSYMBOLS);
 | 
			
		||||
//VK2ETA For ARQ modes, allow more bit corrections (4 in 6)
 | 
			
		||||
			if (iDistance < hamming_resolution && iDistance < iDistanceMin) {
 | 
			
		||||
				iDistanceMin	= iDistance;
 | 
			
		||||
				iSymbol  		= rsid_ids2[j].rs;
 | 
			
		||||
				iBin			= i;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		j = aHashTable2_2[aBuckets[i3][i] | (aBuckets[iTime2][i] << 4)];
 | 
			
		||||
		if (j < rsid_ids_size2)  {
 | 
			
		||||
			iDistance = HammingDistance (i, pCodes2 + j * RSID_NSYMBOLS);
 | 
			
		||||
//VK2ETA For ARQ modes, allow more bit corrections (4 in 6)
 | 
			
		||||
			if (iDistance < hamming_resolution && iDistance < iDistanceMin) {
 | 
			
		||||
				iDistanceMin	= iDistance;
 | 
			
		||||
				iSymbol			= rsid_ids2[j].rs;
 | 
			
		||||
				iBin			= i;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (iSymbol == -1) {
 | 
			
		||||
		// No RSID found in this time slice.
 | 
			
		||||
		// If there is a code stored from the previous time slice, return it.
 | 
			
		||||
		if (bPrevTimeSliceValid2) {
 | 
			
		||||
			SymbolOut			= iPrevSymbol2;
 | 
			
		||||
			BinOut				= iPrevBin2;
 | 
			
		||||
			DistanceOut	    	= iPrevDistance2;
 | 
			
		||||
			MetricsOut			= 0;
 | 
			
		||||
			bPrevTimeSliceValid = false;
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (! bPrevTimeSliceValid2 ||
 | 
			
		||||
		iDistanceMin <= iPrevDistance2) {
 | 
			
		||||
		iPrevSymbol2	= iSymbol;
 | 
			
		||||
		iPrevBin2		= iBin;
 | 
			
		||||
		iPrevDistance2	= iDistanceMin;
 | 
			
		||||
	}
 | 
			
		||||
	bPrevTimeSliceValid2 = true;
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//=============================================================================
 | 
			
		||||
// transmit rsid code for current mode
 | 
			
		||||
//=============================================================================
 | 
			
		||||
| 
						 | 
				
			
			@ -876,6 +850,7 @@ void cRsId::send(bool preRSID)
 | 
			
		|||
		return;
 | 
			
		||||
 | 
			
		||||
	unsigned short rmode = RSID_NONE;
 | 
			
		||||
	unsigned short rmode2 = RSID_NONE;
 | 
			
		||||
 | 
			
		||||
	switch (mode) {
 | 
			
		||||
	case MODE_RTTY :
 | 
			
		||||
| 
						 | 
				
			
			@ -894,7 +869,15 @@ void cRsId::send(bool preRSID)
 | 
			
		|||
		break;
 | 
			
		||||
 | 
			
		||||
	case MODE_OLIVIA:
 | 
			
		||||
 | 
			
		||||
	case MODE_OLIVIA_4_250:
 | 
			
		||||
	case MODE_OLIVIA_8_250:
 | 
			
		||||
	case MODE_OLIVIA_4_500:
 | 
			
		||||
	case MODE_OLIVIA_8_500:
 | 
			
		||||
	case MODE_OLIVIA_16_500:
 | 
			
		||||
	case MODE_OLIVIA_8_1000:
 | 
			
		||||
	case MODE_OLIVIA_16_1000:
 | 
			
		||||
	case MODE_OLIVIA_32_1000:
 | 
			
		||||
	case MODE_OLIVIA_64_2000:
 | 
			
		||||
		if (progdefaults.oliviatones == 1 && progdefaults.oliviabw == 0)
 | 
			
		||||
			rmode = RSID_OLIVIA_4_125;
 | 
			
		||||
		else if (progdefaults.oliviatones == 1 && progdefaults.oliviabw == 1)
 | 
			
		||||
| 
						 | 
				
			
			@ -979,9 +962,6 @@ void cRsId::send(bool preRSID)
 | 
			
		|||
		else if (progdefaults.contestiatones == 5 && progdefaults.contestiabw == 4)
 | 
			
		||||
			rmode = RSID_CONTESTIA_64_2000;
 | 
			
		||||
 | 
			
		||||
		else if (progdefaults.contestiatones == 6 && progdefaults.contestiabw == 4)
 | 
			
		||||
			rmode = RSID_CONTESTIA_128_2000;
 | 
			
		||||
 | 
			
		||||
		else
 | 
			
		||||
			return;
 | 
			
		||||
		break;
 | 
			
		||||
| 
						 | 
				
			
			@ -1025,49 +1005,60 @@ void cRsId::send(bool preRSID)
 | 
			
		|||
		break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// if rmode is still unset, look it up
 | 
			
		||||
// if rmode is still unset, look it up
 | 
			
		||||
// Try secondary table first
 | 
			
		||||
	if (rmode == RSID_NONE) {
 | 
			
		||||
		for (size_t i = 0; i < sizeof(rsid_ids)/sizeof(*rsid_ids); i++) {
 | 
			
		||||
			if (mode == rsid_ids[i].mode) {
 | 
			
		||||
				rmode = rsid_ids[i].rs;
 | 
			
		||||
		for (size_t i = 0; i < sizeof(rsid_ids2)/sizeof(*rsid_ids2); i++) {
 | 
			
		||||
			if (mode == rsid_ids2[i].mode) {
 | 
			
		||||
				rmode2 = rsid_ids2[i].rs;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (rmode2 == RSID_NONE2) {
 | 
			
		||||
			for (size_t i = 0; i < sizeof(rsid_ids)/sizeof(*rsid_ids); i++) {
 | 
			
		||||
				if (mode == rsid_ids[i].mode) {
 | 
			
		||||
					rmode = rsid_ids[i].rs;
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		} else
 | 
			
		||||
			rmode = RSID_ESCAPE;
 | 
			
		||||
	}
 | 
			
		||||
	if (rmode == RSID_NONE)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	unsigned char rsid[RSID_NSYMBOLS];
 | 
			
		||||
	double sr;
 | 
			
		||||
	size_t len;
 | 
			
		||||
	int iTone;
 | 
			
		||||
	double freq, phaseincr;
 | 
			
		||||
	double fr;
 | 
			
		||||
	double phase;
 | 
			
		||||
 | 
			
		||||
	Encode(rmode, rsid);
 | 
			
		||||
 | 
			
		||||
	double sr = active_modem->get_samplerate();
 | 
			
		||||
	size_t len = (size_t)floor(RSID_SYMLEN * sr);
 | 
			
		||||
	sr = active_modem->get_samplerate();
 | 
			
		||||
	len = (size_t)floor(RSID_SYMLEN * sr);
 | 
			
		||||
	if (unlikely(len != symlen)) {
 | 
			
		||||
		symlen = len;
 | 
			
		||||
		delete [] outbuf;
 | 
			
		||||
		outbuf = new double[symlen];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	// transmit 3 symbol periods of silence at end of transmission
 | 
			
		||||
// transmit 3 symbol periods of silence at end of transmission
 | 
			
		||||
	if (!preRSID) {
 | 
			
		||||
		memset(outbuf, 0, symlen * sizeof(*outbuf));
 | 
			
		||||
		for (int i = 0; i < 3; i++)
 | 
			
		||||
			active_modem->ModulateXmtr(outbuf, symlen);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// transmit sequence of 15 symbols (tones)
 | 
			
		||||
	int iTone;
 | 
			
		||||
	double freq, phaseincr;
 | 
			
		||||
	double fr = 1.0 * active_modem->get_txfreq() - (RSID_SAMPLE_RATE * 7 / 1024);
 | 
			
		||||
	double phase = 0.0;
 | 
			
		||||
 | 
			
		||||
// transmit sequence of 15 symbols (tones)
 | 
			
		||||
	fr = 1.0 * active_modem->get_txfreq() - (RSID_SAMPLE_RATE * 7 / 1024);
 | 
			
		||||
	phase = 0.0;
 | 
			
		||||
 | 
			
		||||
	for (int i = 0; i < 15; i++) {
 | 
			
		||||
		iTone = rsid[i];
 | 
			
		||||
		if (active_modem->get_reverse())
 | 
			
		||||
			iTone = 15 - iTone;
 | 
			
		||||
		iTone = 15 - iTone;
 | 
			
		||||
		freq = fr + iTone * RSID_SAMPLE_RATE / 1024;
 | 
			
		||||
		phaseincr = 2.0 * M_PI * freq / sr;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1077,8 +1068,42 @@ void cRsId::send(bool preRSID)
 | 
			
		|||
			outbuf[j] = sin(phase);
 | 
			
		||||
		}
 | 
			
		||||
		active_modem->ModulateXmtr(outbuf, symlen);
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (rmode == RSID_ESCAPE && rmode2 != RSID_NONE2) {
 | 
			
		||||
// transmit 3 symbol periods between rsid bursts
 | 
			
		||||
		memset(outbuf, 0, symlen * sizeof(*outbuf));
 | 
			
		||||
		for (int i = 0; i < 3; i++)
 | 
			
		||||
			active_modem->ModulateXmtr(outbuf, symlen);
 | 
			
		||||
 | 
			
		||||
		Encode(rmode2, rsid);
 | 
			
		||||
		sr = active_modem->get_samplerate();
 | 
			
		||||
		len = (size_t)floor(RSID_SYMLEN * sr);
 | 
			
		||||
		if (unlikely(len != symlen)) {
 | 
			
		||||
			symlen = len;
 | 
			
		||||
			delete [] outbuf;
 | 
			
		||||
			outbuf = new double[symlen];
 | 
			
		||||
		}
 | 
			
		||||
// transmit sequence of 15 symbols (tones)
 | 
			
		||||
		fr = 1.0 * active_modem->get_txfreq() - (RSID_SAMPLE_RATE * 7 / 1024);
 | 
			
		||||
		phase = 0.0;
 | 
			
		||||
 | 
			
		||||
		for (int i = 0; i < 15; i++) {
 | 
			
		||||
			iTone = rsid[i];
 | 
			
		||||
			if (active_modem->get_reverse())
 | 
			
		||||
			iTone = 15 - iTone;
 | 
			
		||||
			freq = fr + iTone * RSID_SAMPLE_RATE / 1024;
 | 
			
		||||
			phaseincr = 2.0 * M_PI * freq / sr;
 | 
			
		||||
 | 
			
		||||
			for (size_t j = 0; j < symlen; j++) {
 | 
			
		||||
				phase += phaseincr;
 | 
			
		||||
				if (phase > 2.0 * M_PI) phase -= 2.0 * M_PI;
 | 
			
		||||
				outbuf[j] = sin(phase);
 | 
			
		||||
			}
 | 
			
		||||
			active_modem->ModulateXmtr(outbuf, symlen);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
// one symbol period of silence
 | 
			
		||||
	memset(outbuf, 0, symlen * sizeof(*outbuf));
 | 
			
		||||
	active_modem->ModulateXmtr(outbuf, symlen);
 | 
			
		||||
| 
						 | 
				
			
			@ -1090,5 +1115,6 @@ void cRsId::send(bool preRSID)
 | 
			
		|||
			active_modem->ModulateXmtr(outbuf, symlen);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,262 @@
 | 
			
		|||
// Syntax: ELEM_(rsid_code, rsid_tag, fldigi_mode)
 | 
			
		||||
// fldigi_mode is NUM_MODES if mode is not available in fldigi,
 | 
			
		||||
// otherwise one of the tags defined in globals.h.
 | 
			
		||||
// rsid_tag is stringified and may be shown to the user.
 | 
			
		||||
#undef ELEM_
 | 
			
		||||
#define RSID_LIST                                       \
 | 
			
		||||
        ELEM_(1, BPSK31, MODE_PSK31)                    \
 | 
			
		||||
        ELEM_(110, QPSK31, MODE_QPSK31)                 \
 | 
			
		||||
        ELEM_(2, BPSK63, MODE_PSK63)                    \
 | 
			
		||||
        ELEM_(3, QPSK63, MODE_QPSK63)                   \
 | 
			
		||||
        ELEM_(4, BPSK125, MODE_PSK125)                  \
 | 
			
		||||
        ELEM_(5, QPSK125, MODE_QPSK125)                 \
 | 
			
		||||
        ELEM_(126, BPSK250, MODE_PSK250)                \
 | 
			
		||||
        ELEM_(127, QPSK250, MODE_QPSK250)               \
 | 
			
		||||
        ELEM_(173, BPSK500, MODE_PSK500)                \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(183, PSK125R, MODE_PSK125R)               \
 | 
			
		||||
        ELEM_(186, PSK250R, MODE_PSK250R)               \
 | 
			
		||||
        ELEM_(187, PSK500R, MODE_PSK500R)               \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(7, PSKFEC31, NUM_MODES)                   \
 | 
			
		||||
        ELEM_(8, PSK10, NUM_MODES)                      \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(9, MT63_500_LG, MODE_MT63_500)            \
 | 
			
		||||
        ELEM_(10, MT63_500_ST, MODE_MT63_500)           \
 | 
			
		||||
        ELEM_(11, MT63_500_VST, MODE_MT63_500)          \
 | 
			
		||||
        ELEM_(12, MT63_1000_LG, MODE_MT63_1000)         \
 | 
			
		||||
        ELEM_(13, MT63_1000_ST, MODE_MT63_1000)         \
 | 
			
		||||
        ELEM_(14, MT63_1000_VST, MODE_MT63_1000)        \
 | 
			
		||||
        ELEM_(15, MT63_2000_LG, MODE_MT63_2000)         \
 | 
			
		||||
        ELEM_(17, MT63_2000_ST, MODE_MT63_2000)         \
 | 
			
		||||
        ELEM_(18, MT63_2000_VST, MODE_MT63_2000)        \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(19, PSKAM10, NUM_MODES)                   \
 | 
			
		||||
        ELEM_(20, PSKAM31, NUM_MODES)                   \
 | 
			
		||||
        ELEM_(21, PSKAM50, NUM_MODES)                   \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(22, PSK63F, MODE_PSK63F)                  \
 | 
			
		||||
        ELEM_(23, PSK220F, NUM_MODES)                   \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(24, CHIP64, NUM_MODES)                    \
 | 
			
		||||
        ELEM_(25, CHIP128, NUM_MODES)                   \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(26, CW, MODE_CW)                          \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(27, CCW_OOK_12, NUM_MODES)                \
 | 
			
		||||
        ELEM_(28, CCW_OOK_24, NUM_MODES)                \
 | 
			
		||||
        ELEM_(29, CCW_OOK_48, NUM_MODES)                \
 | 
			
		||||
        ELEM_(30, CCW_FSK_12, NUM_MODES)                \
 | 
			
		||||
        ELEM_(31, CCW_FSK_24, NUM_MODES)                \
 | 
			
		||||
        ELEM_(33, CCW_FSK_48, NUM_MODES)                \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(34, PACTOR1_FEC, NUM_MODES)               \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(113, PACKET_110, NUM_MODES)               \
 | 
			
		||||
        ELEM_(35, PACKET_300, NUM_MODES)                \
 | 
			
		||||
        ELEM_(36, PACKET_1200, NUM_MODES)               \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(37, RTTY_ASCII_7, MODE_RTTY)              \
 | 
			
		||||
        ELEM_(38, RTTY_ASCII_8, MODE_RTTY)              \
 | 
			
		||||
        ELEM_(39, RTTY_45, MODE_RTTY)                   \
 | 
			
		||||
        ELEM_(40, RTTY_50, MODE_RTTY)                   \
 | 
			
		||||
        ELEM_(41, RTTY_75, MODE_RTTY)                   \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(42, AMTOR_FEC, NUM_MODES)                 \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(43, THROB_1, MODE_THROB1)                 \
 | 
			
		||||
        ELEM_(44, THROB_2, MODE_THROB2)                 \
 | 
			
		||||
        ELEM_(45, THROB_4, MODE_THROB4)                 \
 | 
			
		||||
        ELEM_(46, THROBX_1, MODE_THROBX1)               \
 | 
			
		||||
        ELEM_(47, THROBX_2, MODE_THROBX2)               \
 | 
			
		||||
        ELEM_(146, THROBX_4, MODE_THROBX4)              \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(204, CONTESTIA_4_125, MODE_CONTESTIA)     \
 | 
			
		||||
        ELEM_(55,  CONTESTIA_4_250, MODE_CONTESTIA)     \
 | 
			
		||||
        ELEM_(54,  CONTESTIA_4_500, MODE_CONTESTIA)     \
 | 
			
		||||
        ELEM_(255, CONTESTIA_4_1000, MODE_CONTESTIA)    \
 | 
			
		||||
        ELEM_(254, CONTESTIA_4_2000, MODE_CONTESTIA)    \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(169, CONTESTIA_8_125, MODE_CONTESTIA)     \
 | 
			
		||||
        ELEM_(49,  CONTESTIA_8_250, MODE_CONTESTIA)     \
 | 
			
		||||
        ELEM_(52,  CONTESTIA_8_500, MODE_CONTESTIA)     \
 | 
			
		||||
        ELEM_(117, CONTESTIA_8_1000, MODE_CONTESTIA)    \
 | 
			
		||||
        ELEM_(247, CONTESTIA_8_2000, MODE_CONTESTIA)    \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(50,  CONTESTIA_16_500, MODE_CONTESTIA)    \
 | 
			
		||||
        ELEM_(53,  CONTESTIA_16_1000, MODE_CONTESTIA)   \
 | 
			
		||||
        ELEM_(259, CONTESTIA_16_2000, MODE_CONTESTIA)   \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(51,  CONTESTIA_32_1000, MODE_CONTESTIA)   \
 | 
			
		||||
        ELEM_(201, CONTESTIA_32_2000, MODE_CONTESTIA)   \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(194, CONTESTIA_64_500, MODE_CONTESTIA)    \
 | 
			
		||||
        ELEM_(193, CONTESTIA_64_1000, MODE_CONTESTIA)   \
 | 
			
		||||
        ELEM_(191, CONTESTIA_64_2000, MODE_CONTESTIA)   \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(56, VOICE, NUM_MODES)                     \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(60, MFSK8, MODE_MFSK8)                    \
 | 
			
		||||
        ELEM_(57, MFSK16, MODE_MFSK16)                  \
 | 
			
		||||
        ELEM_(147, MFSK32, MODE_MFSK32)                 \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(148, MFSK11, MODE_MFSK11)                 \
 | 
			
		||||
        ELEM_(152, MFSK22, MODE_MFSK22)                 \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(61, RTTYM_8_250, NUM_MODES)               \
 | 
			
		||||
        ELEM_(62, RTTYM_16_500, NUM_MODES)              \
 | 
			
		||||
        ELEM_(63, RTTYM_32_1000, NUM_MODES)             \
 | 
			
		||||
        ELEM_(65, RTTYM_8_500, NUM_MODES)               \
 | 
			
		||||
        ELEM_(66, RTTYM_16_1000, NUM_MODES)             \
 | 
			
		||||
        ELEM_(67, RTTYM_4_500, NUM_MODES)               \
 | 
			
		||||
        ELEM_(68, RTTYM_4_250, NUM_MODES)               \
 | 
			
		||||
        ELEM_(119, RTTYM_8_1000, NUM_MODES)             \
 | 
			
		||||
        ELEM_(170, RTTYM_8_125, NUM_MODES)              \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(203, OLIVIA_4_125, MODE_OLIVIA)           \
 | 
			
		||||
        ELEM_(75,  OLIVIA_4_250, MODE_OLIVIA_4_250)     \
 | 
			
		||||
        ELEM_(74,  OLIVIA_4_500, MODE_OLIVIA_4_500)     \
 | 
			
		||||
        ELEM_(229, OLIVIA_4_1000, MODE_OLIVIA)          \
 | 
			
		||||
        ELEM_(238, OLIVIA_4_2000, MODE_OLIVIA)          \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(163, OLIVIA_8_125, MODE_OLIVIA)           \
 | 
			
		||||
        ELEM_(69,  OLIVIA_8_250, MODE_OLIVIA_8_250)     \
 | 
			
		||||
        ELEM_(72,  OLIVIA_8_500, MODE_OLIVIA_8_500)     \
 | 
			
		||||
        ELEM_(116, OLIVIA_8_1000, MODE_OLIVIA_8_1000)   \
 | 
			
		||||
        ELEM_(214, OLIVIA_8_2000, MODE_OLIVIA)          \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(70,  OLIVIA_16_500, MODE_OLIVIA_16_500)   \
 | 
			
		||||
        ELEM_(73,  OLIVIA_16_1000, MODE_OLIVIA)         \
 | 
			
		||||
        ELEM_(234, OLIVIA_16_2000, MODE_OLIVIA)         \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(71,  OLIVIA_32_1000, MODE_OLIVIA_32_1000) \
 | 
			
		||||
        ELEM_(221, OLIVIA_32_2000, MODE_OLIVIA)         \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(211, OLIVIA_64_2000, MODE_OLIVIA_64_2000) \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(76, PAX, NUM_MODES)                       \
 | 
			
		||||
        ELEM_(77, PAX2, NUM_MODES)                      \
 | 
			
		||||
        ELEM_(78, DOMINOF, NUM_MODES)                   \
 | 
			
		||||
        ELEM_(79, FAX, NUM_MODES)                       \
 | 
			
		||||
        ELEM_(81, SSTV, NUM_MODES)                      \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(84, DOMINOEX_4, MODE_DOMINOEX4)           \
 | 
			
		||||
        ELEM_(85, DOMINOEX_5, MODE_DOMINOEX5)           \
 | 
			
		||||
        ELEM_(86, DOMINOEX_8, MODE_DOMINOEX8)           \
 | 
			
		||||
        ELEM_(87, DOMINOEX_11, MODE_DOMINOEX11)         \
 | 
			
		||||
        ELEM_(88, DOMINOEX_16, MODE_DOMINOEX16)         \
 | 
			
		||||
        ELEM_(90, DOMINOEX_22, MODE_DOMINOEX22)         \
 | 
			
		||||
        ELEM_(92, DOMINOEX_4_FEC, MODE_DOMINOEX4)       \
 | 
			
		||||
        ELEM_(93, DOMINOEX_5_FEC, MODE_DOMINOEX5)       \
 | 
			
		||||
        ELEM_(97, DOMINOEX_8_FEC, MODE_DOMINOEX8)       \
 | 
			
		||||
        ELEM_(98, DOMINOEX_11_FEC, MODE_DOMINOEX11)     \
 | 
			
		||||
        ELEM_(99, DOMINOEX_16_FEC, MODE_DOMINOEX16)     \
 | 
			
		||||
        ELEM_(101, DOMINOEX_22_FEC, MODE_DOMINOEX22)    \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(104, FELD_HELL, MODE_FELDHELL)            \
 | 
			
		||||
        ELEM_(105, PSK_HELL, NUM_MODES)                 \
 | 
			
		||||
        ELEM_(106, HELL_80, MODE_HELL80)                \
 | 
			
		||||
        ELEM_(107, FM_HELL_105, MODE_FSKH105)           \
 | 
			
		||||
        ELEM_(108, FM_HELL_245, NUM_MODES)              \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(114, MODE_141A, NUM_MODES)                \
 | 
			
		||||
        ELEM_(123, DTMF, NUM_MODES)                     \
 | 
			
		||||
        ELEM_(125, ALE400, NUM_MODES)                   \
 | 
			
		||||
        ELEM_(131, FDMDV, NUM_MODES)                    \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(132, JT65_A, NUM_MODES)                   \
 | 
			
		||||
        ELEM_(134, JT65_B, NUM_MODES)                   \
 | 
			
		||||
        ELEM_(135, JT65_C, NUM_MODES)                   \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(136, THOR_4, MODE_THOR4)                  \
 | 
			
		||||
        ELEM_(137, THOR_8, MODE_THOR8)                  \
 | 
			
		||||
        ELEM_(138, THOR_16, MODE_THOR16)                \
 | 
			
		||||
        ELEM_(139, THOR_5, MODE_THOR5)                  \
 | 
			
		||||
        ELEM_(143, THOR_11, MODE_THOR11)                \
 | 
			
		||||
        ELEM_(145, THOR_22, MODE_THOR22)                \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(153, CALL_ID, NUM_MODES)                  \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(155, PACKET_PSK1200, NUM_MODES)           \
 | 
			
		||||
        ELEM_(156, PACKET_PSK250, NUM_MODES)            \
 | 
			
		||||
        ELEM_(159, PACKET_PSK63, NUM_MODES)             \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(172, MODE_188_110A_8N1, NUM_MODES)        \
 | 
			
		||||
                                                        \
 | 
			
		||||
/* ESCAPE used to transition to 2nd RSID set */         \
 | 
			
		||||
        ELEM_(263, ESCAPE, NUM_MODES)                   \
 | 
			
		||||
        /* NONE must be the last element */             \
 | 
			
		||||
        ELEM_(0, NONE, NUM_MODES)
 | 
			
		||||
 | 
			
		||||
#define ELEM_(code_, tag_, mode_) RSID_ ## tag_ = code_,
 | 
			
		||||
enum { RSID_LIST };
 | 
			
		||||
#undef ELEM_
 | 
			
		||||
 | 
			
		||||
#define ELEM_(code_, tag_, mode_) { RSID_ ## tag_, mode_, #tag_ },
 | 
			
		||||
const RSIDs cRsId::rsid_ids[] = { RSID_LIST };
 | 
			
		||||
#undef ELEM_
 | 
			
		||||
 | 
			
		||||
const int cRsId::rsid_ids_size = sizeof(rsid_ids)/sizeof(*rsid_ids) - 1;
 | 
			
		||||
 | 
			
		||||
//======================================================================
 | 
			
		||||
 | 
			
		||||
#define RSID_LIST2                                      \
 | 
			
		||||
        ELEM_(263, ESCAPE2, NUM_MODES)                  \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(1, PSK63RX4, MODE_4X_PSK63R)              \
 | 
			
		||||
        ELEM_(2, PSK63RX5, MODE_5X_PSK63R)              \
 | 
			
		||||
        ELEM_(3, PSK63RX10, MODE_10X_PSK63R)            \
 | 
			
		||||
        ELEM_(4, PSK63RX20, MODE_20X_PSK63R)            \
 | 
			
		||||
        ELEM_(5, PSK63RX32, MODE_32X_PSK63R)            \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(10, PSK125RX4, MODE_4X_PSK125R)           \
 | 
			
		||||
        ELEM_(11, PSK125RX5, MODE_5X_PSK125R)           \
 | 
			
		||||
        ELEM_(12, PSK125RX10, MODE_10X_PSK125R)         \
 | 
			
		||||
        ELEM_(61, PSK125X12, MODE_12X_PSK125)           \
 | 
			
		||||
        ELEM_(62, PSK125RX12, MODE_12X_PSK125R)         \
 | 
			
		||||
        ELEM_(13, PSK125RX16, MODE_16X_PSK125R)         \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(20, PSK250RX2, MODE_2X_PSK250R)           \
 | 
			
		||||
        ELEM_(21, PSK250RX3, MODE_3X_PSK250R)           \
 | 
			
		||||
        ELEM_(22, PSK250RX5, MODE_5X_PSK250R)           \
 | 
			
		||||
        ELEM_(63, PSK250X6, MODE_6X_PSK250)             \
 | 
			
		||||
        ELEM_(65, PSK250RX6, MODE_6X_PSK250R)           \
 | 
			
		||||
        ELEM_(23, PSK250RX7, MODE_7X_PSK250R)           \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(24, PSK500RX2, MODE_2X_PSK500R)           \
 | 
			
		||||
        ELEM_(25, PSK500RX3, MODE_3X_PSK500R)           \
 | 
			
		||||
        ELEM_(26, PSK500RX4, MODE_4X_PSK500R)           \
 | 
			
		||||
        ELEM_(27, PSK500X2, MODE_2X_PSK500)             \
 | 
			
		||||
        ELEM_(28, PSK500X4, MODE_4X_PSK500)             \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(30, MFSK64, MODE_MFSK64)                  \
 | 
			
		||||
        ELEM_(31, MFSK128, MODE_MFSK128)                \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(40, THOR25x4, MODE_THOR25x4)              \
 | 
			
		||||
        ELEM_(41, THOR50x1, MODE_THOR50x1)              \
 | 
			
		||||
        ELEM_(42, THOR50x2, MODE_THOR50x2)              \
 | 
			
		||||
        ELEM_(43, THOR100, MODE_THOR100)                \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(45, DOMINOEX_44, MODE_DOMINOEX44)         \
 | 
			
		||||
        ELEM_(46, DOMINOEX_88, MODE_DOMINOEX88)         \
 | 
			
		||||
                                                        \
 | 
			
		||||
        ELEM_(50, PSK1000, MODE_PSK1000)                \
 | 
			
		||||
        ELEM_(51, PSK1000R, MODE_PSK1000R)              \
 | 
			
		||||
        ELEM_(52, PSK1000X2, MODE_2X_PSK1000)           \
 | 
			
		||||
        ELEM_(53, PSK1000RX2, MODE_2X_PSK1000R)         \
 | 
			
		||||
        ELEM_(54, PSK800RX2, MODE_2X_PSK800R)           \
 | 
			
		||||
        ELEM_(57, PSK800X2, MODE_2X_PSK800)             \
 | 
			
		||||
                                                        \
 | 
			
		||||
        /* NONE2 must be the last element */            \
 | 
			
		||||
        ELEM_(0, NONE2, NUM_MODES)
 | 
			
		||||
 | 
			
		||||
#define ELEM_(code_, tag_, mode_) RSID_ ## tag_ = code_,
 | 
			
		||||
enum { RSID_LIST2 };
 | 
			
		||||
#undef ELEM_
 | 
			
		||||
 | 
			
		||||
#define ELEM_(code_, tag_, mode_) { RSID_ ## tag_, mode_, #tag_ },
 | 
			
		||||
const RSIDs cRsId::rsid_ids2[] = { RSID_LIST2 };
 | 
			
		||||
#undef ELEM_
 | 
			
		||||
 | 
			
		||||
const int cRsId::rsid_ids_size2 = sizeof(rsid_ids2)/sizeof(*rsid_ids2) - 1;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1,8 +1,10 @@
 | 
			
		|||
// ----------------------------------------------------------------------------
 | 
			
		||||
// thor.cxx  --  thor modem
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2008, 2009
 | 
			
		||||
//   David Freese <w1hkj@w1hkj.com>
 | 
			
		||||
// Copyright (C) 2008-2012
 | 
			
		||||
//     David Freese <w1hkj@w1hkj.com>
 | 
			
		||||
//     John Douyere <vk2eta@gmail.com>
 | 
			
		||||
//     John Phelps  <kl4yfd@gmail.com>
 | 
			
		||||
//
 | 
			
		||||
// This file is part of fldigi.
 | 
			
		||||
//
 | 
			
		||||
| 
						 | 
				
			
			@ -40,13 +42,15 @@
 | 
			
		|||
 | 
			
		||||
#include "ascii.h"
 | 
			
		||||
#include "main.h"
 | 
			
		||||
#include "debug.h"
 | 
			
		||||
 | 
			
		||||
// Enable to enable profiling output for the soft-decision decoder
 | 
			
		||||
#define SOFTPROFILE false
 | 
			
		||||
#define SOFTPROFILE true
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
 | 
			
		||||
char thormsg[80];
 | 
			
		||||
char confidence[80];
 | 
			
		||||
 | 
			
		||||
void thor::tx_init(SoundBase *sc)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -87,38 +91,33 @@ void thor::rx_init()
 | 
			
		|||
void thor::reset_filters()
 | 
			
		||||
{
 | 
			
		||||
// fft filter at first IF frequency
 | 
			
		||||
	fft->create_filter( 
 | 
			
		||||
		(THORFIRSTIF - 0.5 * progdefaults.THOR_BW * bandwidth) / samplerate,
 | 
			
		||||
		(THORFIRSTIF + 0.5 * progdefaults.THOR_BW * bandwidth)/ samplerate );
 | 
			
		||||
	fft->create_filter( (THORFIRSTIF - 0.5 * progdefaults.THOR_BW * bandwidth) / samplerate,
 | 
			
		||||
	                    (THORFIRSTIF + 0.5 * progdefaults.THOR_BW * bandwidth)/ samplerate );
 | 
			
		||||
 | 
			
		||||
	for (int i = 0; i < THORMAXFFTS; i++)
 | 
			
		||||
		if (binsfft[i]) {
 | 
			
		||||
			delete binsfft[i];
 | 
			
		||||
			binsfft[i] = 0;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
	if (slowcpu || samplerate == 22050) {
 | 
			
		||||
 | 
			
		||||
	if (slowcpu) {
 | 
			
		||||
		extones = 4;
 | 
			
		||||
		paths = THORSLOWPATHS;
 | 
			
		||||
	} else {
 | 
			
		||||
		extones = THORNUMTONES / 2;
 | 
			
		||||
		paths = THORFASTPATHS;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	lotone = basetone - extones * doublespaced;
 | 
			
		||||
	if (lotone < 1) lotone = 1;
 | 
			
		||||
	hitone = basetone + THORNUMTONES * doublespaced + extones * doublespaced;
 | 
			
		||||
 | 
			
		||||
	numbins = hitone - lotone;
 | 
			
		||||
 | 
			
		||||
	for (int i = 0; i < paths; i++) {
 | 
			
		||||
	for (int i = 0; i < paths; i++)
 | 
			
		||||
		binsfft[i] = new sfft (symlen, lotone, hitone);
 | 
			
		||||
		if (!binsfft[i]) {
 | 
			
		||||
			printf("Thor Arrgh %d\n", i);
 | 
			
		||||
			exit(0);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	filter_reset = false;               
 | 
			
		||||
 | 
			
		||||
	filter_reset = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void thor::restart()
 | 
			
		||||
| 
						 | 
				
			
			@ -138,7 +137,7 @@ void thor::init()
 | 
			
		|||
thor::~thor()
 | 
			
		||||
{
 | 
			
		||||
	if (hilbert) delete hilbert;
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	for (int i = 0; i < THORMAXFFTS; i++) {
 | 
			
		||||
		if (binsfft[i]) delete binsfft[i];
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -147,15 +146,15 @@ thor::~thor()
 | 
			
		|||
		if (vidfilter[i]) delete vidfilter[i];
 | 
			
		||||
	}
 | 
			
		||||
	if (syncfilter) delete syncfilter;
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	if (pipe) delete [] pipe;
 | 
			
		||||
	if (fft) delete fft;
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	if (Rxinlv) delete Rxinlv;
 | 
			
		||||
	if (Txinlv) delete Txinlv;
 | 
			
		||||
	if (Dec) delete Dec;
 | 
			
		||||
	if (Enc) delete Enc;
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
thor::thor(trx_mode md)
 | 
			
		||||
| 
						 | 
				
			
			@ -164,6 +163,10 @@ thor::thor(trx_mode md)
 | 
			
		|||
 | 
			
		||||
	mode = md;
 | 
			
		||||
 | 
			
		||||
	int isize = 4;
 | 
			
		||||
	int idepth = 10;
 | 
			
		||||
	flushlength = 4;
 | 
			
		||||
 | 
			
		||||
	switch (mode) {
 | 
			
		||||
// 11.025 kHz modes
 | 
			
		||||
	case MODE_THOR5:
 | 
			
		||||
| 
						 | 
				
			
			@ -177,27 +180,13 @@ thor::thor(trx_mode md)
 | 
			
		|||
		doublespaced = 1;
 | 
			
		||||
		samplerate = 11025;
 | 
			
		||||
		break;
 | 
			
		||||
//	case MODE_TSOR11:
 | 
			
		||||
//		symlen = 1024;
 | 
			
		||||
//		doublespaced = 2;
 | 
			
		||||
//		samplerate = 11025;
 | 
			
		||||
//		break;
 | 
			
		||||
 | 
			
		||||
	case MODE_THOR22:
 | 
			
		||||
		symlen = 512;
 | 
			
		||||
		doublespaced = 1;
 | 
			
		||||
		samplerate = 11025;
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case MODE_THOR44:
 | 
			
		||||
		symlen = 250;
 | 
			
		||||
		doublespaced = 2;
 | 
			
		||||
		samplerate = 11025;
 | 
			
		||||
		break;
 | 
			
		||||
	case MODE_THOR88:
 | 
			
		||||
		symlen = 125;
 | 
			
		||||
		doublespaced = 1;
 | 
			
		||||
		samplerate = 11025;
 | 
			
		||||
		break;
 | 
			
		||||
// 8kHz modes
 | 
			
		||||
	case MODE_THOR4:
 | 
			
		||||
		symlen = 2048;
 | 
			
		||||
| 
						 | 
				
			
			@ -210,6 +199,39 @@ thor::thor(trx_mode md)
 | 
			
		|||
		doublespaced = 2;
 | 
			
		||||
		samplerate = 8000;
 | 
			
		||||
		break;
 | 
			
		||||
		
 | 
			
		||||
	case MODE_THOR25x4:
 | 
			
		||||
		symlen = 320;
 | 
			
		||||
		doublespaced = 4;
 | 
			
		||||
		samplerate = 8000;
 | 
			
		||||
		idepth = 50; // 2 sec interleave
 | 
			
		||||
		flushlength = 40;
 | 
			
		||||
		break;
 | 
			
		||||
		
 | 
			
		||||
	case MODE_THOR50x1:
 | 
			
		||||
		symlen = 160;
 | 
			
		||||
		doublespaced = 1;
 | 
			
		||||
		samplerate = 8000;
 | 
			
		||||
		idepth = 50; // 1 sec interleave
 | 
			
		||||
		flushlength = 40;
 | 
			
		||||
		break;
 | 
			
		||||
		
 | 
			
		||||
	case MODE_THOR50x2:
 | 
			
		||||
		symlen = 160;
 | 
			
		||||
		doublespaced = 2;
 | 
			
		||||
		samplerate = 8000;
 | 
			
		||||
		idepth = 50; // 1 sec interleave
 | 
			
		||||
		flushlength = 40;
 | 
			
		||||
		break;
 | 
			
		||||
		
 | 
			
		||||
	case MODE_THOR100:
 | 
			
		||||
		symlen = 80;
 | 
			
		||||
		doublespaced = 1;
 | 
			
		||||
		samplerate = 8000;
 | 
			
		||||
		idepth = 50; // 0.5 sec interleave
 | 
			
		||||
		flushlength = 40;
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case MODE_THOR16:
 | 
			
		||||
	default:
 | 
			
		||||
		symlen = 512;
 | 
			
		||||
| 
						 | 
				
			
			@ -225,32 +247,32 @@ thor::thor(trx_mode md)
 | 
			
		|||
	hilbert->init_hilbert(37, 1);
 | 
			
		||||
 | 
			
		||||
// fft filter at first if frequency
 | 
			
		||||
	fft = new fftfilt(
 | 
			
		||||
			(THORFIRSTIF - 0.5 * progdefaults.THOR_BW * bandwidth) / samplerate,
 | 
			
		||||
			(THORFIRSTIF + 0.5 * progdefaults.THOR_BW * bandwidth)/ samplerate,
 | 
			
		||||
			1024 );
 | 
			
		||||
	fft = new fftfilt( (THORFIRSTIF - 0.5 * progdefaults.THOR_BW * bandwidth) / samplerate,
 | 
			
		||||
	                   (THORFIRSTIF + 0.5 * progdefaults.THOR_BW * bandwidth)/ samplerate,
 | 
			
		||||
	                   1024 );
 | 
			
		||||
 | 
			
		||||
	basetone = (int)floor(THORBASEFREQ * symlen / samplerate + 0.5);
 | 
			
		||||
 | 
			
		||||
	slowcpu = progdefaults.slowcpu;
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	for (int i = 0; i < THORMAXFFTS; i++)
 | 
			
		||||
		binsfft[i] = 0;
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
	reset_filters();
 | 
			
		||||
 | 
			
		||||
	for (int i = 0; i < THORSCOPESIZE; i++)
 | 
			
		||||
		vidfilter[i] = new Cmovavg(16);
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
	syncfilter = new Cmovavg(8);
 | 
			
		||||
 | 
			
		||||
	twosym = 2 * symlen;
 | 
			
		||||
	pipe = new THORrxpipe[twosym];
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	scopedata.alloc(THORSCOPESIZE);
 | 
			
		||||
	videodata.alloc(THORMAXFFTS * numbins );
 | 
			
		||||
 | 
			
		||||
	pipeptr = 0;
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	symcounter = 0;
 | 
			
		||||
	metric = 0.0;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -260,26 +282,25 @@ thor::thor(trx_mode md)
 | 
			
		|||
 | 
			
		||||
	prev1symbol = prev2symbol = 0;
 | 
			
		||||
 | 
			
		||||
	static const int longtraceback = 127 ;
 | 
			
		||||
	static const int traceback = 45 ;
 | 
			
		||||
	static const int chunksize = 1 ;
 | 
			
		||||
	prev1symbol = prev2symbol = 0;
 | 
			
		||||
 | 
			
		||||
	if ( mode == MODE_THOR88 || mode == MODE_THOR44) {
 | 
			
		||||
	if ( mode == MODE_THOR100 || mode == MODE_THOR50x1 || mode == MODE_THOR50x2 || mode == MODE_THOR25x4 ) {
 | 
			
		||||
		Enc = new encoder (GALILEO_K, GALILEO_POLY1, GALILEO_POLY2);
 | 
			
		||||
		Dec = new viterbi::impl <GALILEO_K, chunksize, longtraceback >( GALILEO_POLY1, GALILEO_POLY2 );
 | 
			
		||||
		Txinlv = new interleave (-488, INTERLEAVE_FWD); // 4x4x88
 | 
			
		||||
		Rxinlv = new interleave (-488, INTERLEAVE_REV); // 4x4x88
 | 
			
		||||
		Dec = new viterbi (GALILEO_K, GALILEO_POLY1, GALILEO_POLY2);
 | 
			
		||||
		Dec->settraceback (PATHMEM-1); // Long constraint length codes require longer traceback
 | 
			
		||||
	} else {
 | 
			
		||||
		Enc = new encoder (THOR_K, THOR_POLY1, THOR_POLY2);
 | 
			
		||||
		Dec = new viterbi::impl <THOR_K, chunksize, traceback >( THOR_POLY1, THOR_POLY2 );
 | 
			
		||||
		Txinlv = new interleave (4, INTERLEAVE_FWD); // 4x4x10
 | 
			
		||||
		Rxinlv = new interleave (4, INTERLEAVE_REV); // 4x4x10
 | 
			
		||||
		Dec = new viterbi (THOR_K, THOR_POLY1, THOR_POLY2);
 | 
			
		||||
		Dec->settraceback (45);
 | 
			
		||||
	}
 | 
			
		||||
	Txinlv = new interleave (isize, idepth, INTERLEAVE_FWD);
 | 
			
		||||
	Rxinlv = new interleave (isize, idepth, INTERLEAVE_REV);
 | 
			
		||||
	Dec->setchunksize (1);
 | 
			
		||||
	
 | 
			
		||||
	bitstate = 0;
 | 
			
		||||
	symbolpair[0] = symbolpair[1] = 0;
 | 
			
		||||
	datashreg = 1;
 | 
			
		||||
 | 
			
		||||
//	init();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//=====================================================================
 | 
			
		||||
| 
						 | 
				
			
			@ -345,68 +366,79 @@ void thor::recvchar(int c)
 | 
			
		|||
 | 
			
		||||
void thor::decodePairs(unsigned char symbol)
 | 
			
		||||
{
 | 
			
		||||
	int c, ch, met;
 | 
			
		||||
 | 
			
		||||
	symbolpair[0] = symbolpair[1];
 | 
			
		||||
	symbolpair[1] = symbol;
 | 
			
		||||
 | 
			
		||||
	symcounter = symcounter ? 0 : 1;
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	if (symcounter) return;
 | 
			
		||||
 | 
			
		||||
	int c = Dec->decode (symbolpair);
 | 
			
		||||
	c = Dec->decode (symbolpair, &met);
 | 
			
		||||
 | 
			
		||||
	if (c == -1)
 | 
			
		||||
		return;
 | 
			
		||||
	
 | 
			
		||||
	if(met < 255 / 2) fec_confidence -=  2 + fec_confidence / 2;
 | 
			
		||||
	else fec_confidence += 2;
 | 
			
		||||
	if (fec_confidence < 0) fec_confidence = 0;
 | 
			
		||||
	if (fec_confidence > 100) fec_confidence = 100;
 | 
			
		||||
 | 
			
		||||
	if (progStatus.sqlonoff && metric < progStatus.sldrSquelchValue)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	datashreg = (datashreg << 1) | !!c;
 | 
			
		||||
	if ((datashreg & 7) == 1) {
 | 
			
		||||
		int ch = thorvaridec(datashreg >> 1);
 | 
			
		||||
		ch = thorvaridec(datashreg >> 1);
 | 
			
		||||
		recvchar(ch);
 | 
			
		||||
		datashreg = 1;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void thor::decodesymbol()
 | 
			
		||||
{
 | 
			
		||||
	int c;
 | 
			
		||||
	double fdiff;//, softmag;
 | 
			
		||||
	unsigned char symbols[4];
 | 
			
		||||
	bool outofrange = false;
 | 
			
		||||
 | 
			
		||||
// Decode the IFK+ sequence, which results in a single nibble
 | 
			
		||||
 | 
			
		||||
	double fdiff = currsymbol - prev1symbol;
 | 
			
		||||
		
 | 
			
		||||
	fdiff = currsymbol - prev1symbol;
 | 
			
		||||
 | 
			
		||||
	if (reverse) fdiff = -fdiff;
 | 
			
		||||
	fdiff /= paths;
 | 
			
		||||
	fdiff /= doublespaced;
 | 
			
		||||
 | 
			
		||||
	if (fabs(fdiff) > 17) outofrange = true;
 | 
			
		||||
 | 
			
		||||
	int c = (int)floor(fdiff + .5); {
 | 
			
		||||
	c = (int)floor(fdiff + .5); {
 | 
			
		||||
	 	if (progdefaults.THOR_PREAMBLE) {
 | 
			
		||||
			if ( preambledetect(c) ) {
 | 
			
		||||
				softflushrx(); // Flush the soft rx pipeline with punctures (interleaver & viterbi decoder)
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
		} 
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	c -= 2;
 | 
			
		||||
	if (c < 0) c += THORNUMTONES;
 | 
			
		||||
 | 
			
		||||
	if (staticburst == true || outofrange == true) // puncture the code
 | 
			
		||||
		symbols[3] = symbols[2] = symbols[1] = symbols[0] = 128;	
 | 
			
		||||
		symbols[3] = symbols[2] = symbols[1] = symbols[0] = 128;
 | 
			
		||||
	else {
 | 
			
		||||
		symbols[3] = (c & 1) == 1 ? 255 : 0; c /= 2;
 | 
			
		||||
		symbols[2] = (c & 1) == 1 ? 255 : 0; c /= 2;
 | 
			
		||||
		symbols[1] = (c & 1) == 1 ? 255 : 0; c /= 2;
 | 
			
		||||
		symbols[0] = (c & 1) == 1 ? 255 : 0; c /= 2;
 | 
			
		||||
	} 
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Rxinlv->symbols(symbols);
 | 
			
		||||
 | 
			
		||||
	for (int i = 0; i < 4; i++) decodePairs(symbols[i]);
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void thor::softdecodesymbol()
 | 
			
		||||
| 
						 | 
				
			
			@ -421,7 +453,7 @@ void thor::softdecodesymbol()
 | 
			
		|||
	if (reverse) fdiff = -fdiff;
 | 
			
		||||
	fdiff /= paths;
 | 
			
		||||
	fdiff /= doublespaced;
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	c = (int)floor(fdiff + .5); {
 | 
			
		||||
		if (c < -16 || 0 == c || 1 == c || c > 17) outofrange = true; // Out of the range of the function thor::sendsymbol()
 | 
			
		||||
		if (progdefaults.THOR_PREAMBLE) {
 | 
			
		||||
| 
						 | 
				
			
			@ -432,30 +464,40 @@ void thor::softdecodesymbol()
 | 
			
		|||
			}
 | 
			
		||||
		}
 | 
			
		||||
#if SOFTPROFILE
 | 
			
		||||
		printf("\nSymbol: %3d",currsymbol);
 | 
			
		||||
		if (c >= 0) printf(" \tDELTAf: +%2d",c);
 | 
			
		||||
		else printf(" \tDELTAf: %3d",c);
 | 
			
		||||
		LOG_DEBUG("\nSymbol: %3d; DELTAf: +%3d",currsymbol, c);
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
	c -= 2;
 | 
			
		||||
	if (c < 0) c += THORNUMTONES;	
 | 
			
		||||
	
 | 
			
		||||
	// Since the THOR modem is differential, when an outofrange error occurs there are 2 possibilities:
 | 
			
		||||
	// either previous (reference) symbol or current. 50% probability of each being the culprit.
 | 
			
		||||
	// either way, the current symbol is lost, puncture it. Also 50% probability next symbol will have an error
 | 
			
		||||
	if (c < 0) c += THORNUMTONES;
 | 
			
		||||
 | 
			
		||||
// Since the THOR modem is differential, when an outofrange error occurs
 | 
			
		||||
// there are 2 possibilities:
 | 
			
		||||
//   . either previous (reference) symbol or current with a 50%
 | 
			
		||||
//     probability of each being the culprit.
 | 
			
		||||
// Either way, the current symbol is lost, puncture it. There is also a
 | 
			
		||||
// 50% probability the next symbol will have an error
 | 
			
		||||
	if (outofrange){
 | 
			
		||||
		lastmag /= 2;
 | 
			
		||||
		nowmag = 0;
 | 
			
		||||
		nextmag /= 2;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// O is puncture/null-symbol from softdecode
 | 
			
		||||
	if (0 == currsymbol) {
 | 
			
		||||
	  	nowmag = 0;
 | 
			
		||||
		nextmag = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// puncture while squelched
 | 
			
		||||
	if (progStatus.sqlonoff && metric < progStatus.sldrSquelchValue) nowmag = 0;
 | 
			
		||||
 | 
			
		||||
	// One in 16 chance the correct reference tone chosen in staticburst
 | 
			
		||||
	if (staticburst){
 | 
			
		||||
		nowmag /= 16;
 | 
			
		||||
		nextmag /= 16;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	if (lastmag <= 0) { // puncture 
 | 
			
		||||
 | 
			
		||||
	if (lastmag <= 0) { // puncture
 | 
			
		||||
		one = 128;
 | 
			
		||||
		zero = 128;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -468,28 +510,27 @@ void thor::softdecodesymbol()
 | 
			
		|||
		zero = static_cast<unsigned char>( 127-lastmag ); // never < 0
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#if SOFTPROFILE 
 | 
			
		||||
	printf("   \t-->%.3d|%.3d|%.3d = ",nextmag, nowmag, lastmag);
 | 
			
		||||
	printf("%.3d|%.3d",zero,one);
 | 
			
		||||
	if (outofrange) printf(" (outofrange)");
 | 
			
		||||
	if (staticburst) printf("  (staticburst)");
 | 
			
		||||
#if SOFTPROFILE
 | 
			
		||||
	LOG_DEBUG("next mag %.3d | now mag %.3d | last mag %.3d",nextmag, nowmag, lastmag);
 | 
			
		||||
	if (outofrange) LOG_DEBUG("%s","outofrange");
 | 
			
		||||
	if (staticburst) LOG_DEBUG("%s","staticburst");
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	lastsymbols[3] = (lastc & 1) == 1 ? one : zero ; lastc /= 2;
 | 
			
		||||
	lastsymbols[2] = (lastc & 1) == 1 ? one : zero ; lastc /= 2;
 | 
			
		||||
	lastsymbols[1] = (lastc & 1) == 1 ? one : zero ; lastc /= 2;
 | 
			
		||||
	lastsymbols[0] = (lastc & 1) == 1 ? one : zero ; lastc /= 2;
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	Rxinlv->symbols(lastsymbols);
 | 
			
		||||
	for (int i = 0; i < 4; i++) decodePairs(lastsymbols[i]);
 | 
			
		||||
 | 
			
		||||
	// Since modem is differential, wait until next symbol (to detect errors) then decode.
 | 
			
		||||
// Since modem is differential, wait until next symbol (to detect errors)
 | 
			
		||||
// then decode.
 | 
			
		||||
	lastc = c;
 | 
			
		||||
	lastmag = nowmag;
 | 
			
		||||
	nowmag = nextmag;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int thor::harddecode()
 | 
			
		||||
{
 | 
			
		||||
	double x, max = 0.0;
 | 
			
		||||
| 
						 | 
				
			
			@ -501,9 +542,9 @@ int thor::harddecode()
 | 
			
		|||
	for (int i = 0; i < paths * numbins; i++)
 | 
			
		||||
		avg += pipe[pipeptr].vector[i].mag();
 | 
			
		||||
	avg /= (paths * numbins);
 | 
			
		||||
			
 | 
			
		||||
 | 
			
		||||
	if (avg < 1e-10) avg = 1e-10;
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	int numtests = 10;
 | 
			
		||||
	int count = 0;
 | 
			
		||||
	for (int i = 0; i < paths * numbins; i++) {
 | 
			
		||||
| 
						 | 
				
			
			@ -515,9 +556,9 @@ int thor::harddecode()
 | 
			
		|||
			cwmag = (pipe[j].vector[i].mag())/numtests;
 | 
			
		||||
			if (cwmag >= 50.0 * (1.0 - progdefaults.ThorCWI) * avg) count++;
 | 
			
		||||
		}
 | 
			
		||||
		cwi[i] = (count == numtests); 
 | 
			
		||||
		cwi[i] = (count == numtests);
 | 
			
		||||
	}
 | 
			
		||||
					
 | 
			
		||||
 | 
			
		||||
	for (int i = 0; i <  paths * numbins ; i++) {
 | 
			
		||||
		if (cwi[i] == false) {
 | 
			
		||||
			x = pipe[pipeptr].vector[i].mag();
 | 
			
		||||
| 
						 | 
				
			
			@ -533,6 +574,77 @@ int thor::harddecode()
 | 
			
		|||
	return symbol;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int thor::softdecode()
 | 
			
		||||
{
 | 
			
		||||
	static const int SoftBailout=6; // Max number of attempts to get a valid symbol
 | 
			
		||||
 | 
			
		||||
	double x, max = 0.0, avg = 0.0;
 | 
			
		||||
	int symbol = 0;
 | 
			
		||||
	int avgcount = 0;
 | 
			
		||||
	int soft_symbol_trycount=0;
 | 
			
		||||
 | 
			
		||||
	static bool lastCWI[1024] = {false};
 | 
			
		||||
	bool nextCWI[paths * numbins];
 | 
			
		||||
 | 
			
		||||
	int lowest_tone = 0;
 | 
			
		||||
	int highest_tone = paths * numbins;
 | 
			
		||||
 | 
			
		||||
	// Clear nextCWI  bool array for this run
 | 
			
		||||
	for (int i = lowest_tone; i < highest_tone; i++) nextCWI[i] = false;
 | 
			
		||||
 | 
			
		||||
	// Allow for case where symbol == prev2symbol  (before calculating signal average...)
 | 
			
		||||
	lastCWI[prev2symbol-1] =  lastCWI[prev2symbol] = lastCWI[prev2symbol+1] = false;
 | 
			
		||||
 | 
			
		||||
	// Constrict the tone set further so CWI detect & set does not go out of intended range
 | 
			
		||||
	lowest_tone += 1;
 | 
			
		||||
	highest_tone -= 1;
 | 
			
		||||
 | 
			
		||||
	// Calculate signal average, ignoring CWI signals
 | 
			
		||||
	for (int i = lowest_tone; i < highest_tone; i++)
 | 
			
		||||
	{
 | 
			
		||||
		if ( !lastCWI[i]  ) {
 | 
			
		||||
			avg += pipe[pipeptr].vector[i].mag();
 | 
			
		||||
			avgcount++;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	avg /= avgcount;
 | 
			
		||||
	if (avg < 1e-10) avg = 1e-10;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	// Run symbol-decoder until a non-CWI && non-Repeated symbol is selected
 | 
			
		||||
	do {
 | 
			
		||||
		soft_symbol_trycount++;
 | 
			
		||||
		max = 0.0;
 | 
			
		||||
 | 
			
		||||
		for (int i = lowest_tone; i < highest_tone; i++) {
 | 
			
		||||
		  	x = pipe[pipeptr].vector[i].mag();
 | 
			
		||||
			if ( x > max && !nextCWI[i-1] && !nextCWI[i] && !nextCWI[i+1] ) {
 | 
			
		||||
				max = x;
 | 
			
		||||
				symbol = i;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// detect repeated symbols (an invalid pattern for IFK+ modems)
 | 
			
		||||
		if ( abs(prev1symbol - symbol) < paths ) {
 | 
			
		||||
			nextCWI[symbol-1] = nextCWI[symbol] = nextCWI[symbol+1] = true;
 | 
			
		||||
		}
 | 
			
		||||
		// Update the next CWI mask if the tone from last-run persists
 | 
			
		||||
		else if ( lastCWI[symbol-1] || lastCWI[symbol] || lastCWI[symbol+1] ) {
 | 
			
		||||
			nextCWI[symbol-1] = nextCWI[symbol] = nextCWI[symbol+1] = true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	} while ( nextCWI[symbol] && soft_symbol_trycount < SoftBailout ); // Run while the detected symbol has been identified as CWI (alt: bailout after 6 trys)
 | 
			
		||||
 | 
			
		||||
	// Copy the newly-detected CWI mask to the static lastCWI array for use on next function call
 | 
			
		||||
	for (int i = lowest_tone-1; i < highest_tone+1; i++) lastCWI[i] = nextCWI[i];
 | 
			
		||||
 | 
			
		||||
	staticburst = (max / avg < 1.2);
 | 
			
		||||
 | 
			
		||||
	// Return a NULL / Puncture symbol if a bailout occured
 | 
			
		||||
	if (soft_symbol_trycount >= SoftBailout) return 0;
 | 
			
		||||
	else return symbol;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool thor::preambledetect(int c)
 | 
			
		||||
{
 | 
			
		||||
	static int preamblecheck=0, twocount=0;
 | 
			
		||||
| 
						 | 
				
			
			@ -541,19 +653,21 @@ bool thor::preambledetect(int c)
 | 
			
		|||
	if (twocount > 14 ) twocount = 0;
 | 
			
		||||
 | 
			
		||||
	if (-16 == c && twocount > 2 ) neg16seen = true;
 | 
			
		||||
	else if (2 != c) neg16seen = false; // 2 does not reset the neg16seen bool
 | 
			
		||||
// 2 does not reset the neg16seen bool
 | 
			
		||||
	else if (2 != c) neg16seen = false;
 | 
			
		||||
	else if (2 == c) twocount ++;
 | 
			
		||||
	
 | 
			
		||||
	if (-16 != c && 2 != c) // -16 does not reset the twos counter
 | 
			
		||||
		if (twocount > 1) twocount -= 2; 
 | 
			
		||||
#if SOFTPROFILE
 | 
			
		||||
	printf(" [%d:%d]",twocount, preamblecheck);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// -16 does not reset the twos counter
 | 
			
		||||
	if (-16 != c && 2 != c)
 | 
			
		||||
		if (twocount > 1) twocount -= 2;
 | 
			
		||||
//#if SOFTPROFILE
 | 
			
		||||
//	LOG_DEBUG("[2count:pcheck] [%d:%d]",twocount, preamblecheck);
 | 
			
		||||
//#endif
 | 
			
		||||
	if ( twocount > 4 && neg16seen ){
 | 
			
		||||
		if ( ++preamblecheck > 4 ) return true;
 | 
			
		||||
	}
 | 
			
		||||
	else preamblecheck = 0; 
 | 
			
		||||
	  
 | 
			
		||||
	else preamblecheck = 0;
 | 
			
		||||
 | 
			
		||||
	return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -563,11 +677,13 @@ void thor::softflushrx()
 | 
			
		|||
	unsigned char puncture[2], flushsymbols[4];
 | 
			
		||||
	puncture[0]=128;
 | 
			
		||||
	puncture[1]=128;
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	for (int i = 0; i < 4; i++) flushsymbols[i] = 128;
 | 
			
		||||
	
 | 
			
		||||
	for(int i=0; i<90; i++) Rxinlv->symbols(flushsymbols); // flush interleaver with punctured symbols
 | 
			
		||||
	for (int j = 0; j < 128; j++) Dec->decode (puncture, NULL); // flush viterbi with puncture soft-bits
 | 
			
		||||
 | 
			
		||||
// flush interleaver with punctured symbols
 | 
			
		||||
	for(int i = 0; i < 90; i++) Rxinlv->symbols(flushsymbols);
 | 
			
		||||
// flush viterbi with puncture soft-bits
 | 
			
		||||
	for (int j = 0; j < 128; j++) Dec->decode (puncture, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void thor::update_syncscope()
 | 
			
		||||
| 
						 | 
				
			
			@ -614,7 +730,7 @@ void thor::synchronize()
 | 
			
		|||
	double val, max = 0.0;
 | 
			
		||||
 | 
			
		||||
	if (staticburst == true) return;
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	if (currsymbol == prev1symbol)
 | 
			
		||||
		return;
 | 
			
		||||
	if (prev1symbol == prev2symbol)
 | 
			
		||||
| 
						 | 
				
			
			@ -628,7 +744,7 @@ void thor::synchronize()
 | 
			
		|||
		}
 | 
			
		||||
		j = (j + 1) % twosym;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	syn = syncfilter->run(syn);
 | 
			
		||||
 | 
			
		||||
	synccounter += (int) floor(1.0 * (syn - symlen) / THORNUMTONES + 0.5);
 | 
			
		||||
| 
						 | 
				
			
			@ -651,7 +767,7 @@ void thor::eval_s2n()
 | 
			
		|||
	else
 | 
			
		||||
		s2n = 0;
 | 
			
		||||
	// To partially offset the increase of noise by (THORNUMTONES -1)
 | 
			
		||||
	// in the noise calculation above, 
 | 
			
		||||
	// in the noise calculation above,
 | 
			
		||||
	// add 15*log10(THORNUMTONES -1) = 18.4, and multiply by 6
 | 
			
		||||
	metric = 6 * (s2n + 18.4);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -667,6 +783,18 @@ void thor::eval_s2n()
 | 
			
		|||
 | 
			
		||||
	snprintf(thormsg, sizeof(thormsg), "s/n %3.0f dB", s2n );
 | 
			
		||||
	put_Status1(thormsg);
 | 
			
		||||
	
 | 
			
		||||
	// Scale FEC indicatior to reduce erratic / jumpy / unreadable display in GUI
 | 
			
		||||
	int scalefec;
 | 
			
		||||
	if (fec_confidence++ > 90) scalefec = 100;
 | 
			
		||||
	else if (fec_confidence++ > 60) scalefec = 75;
 | 
			
		||||
	else if (fec_confidence++ > 40) scalefec = 50;
 | 
			
		||||
	else if (fec_confidence++ >= 20) scalefec = 25;
 | 
			
		||||
	else if ( fec_confidence > 9) scalefec = 10;
 | 
			
		||||
	else scalefec = 0; // Else just round to 0.
 | 
			
		||||
 | 
			
		||||
	snprintf(confidence, sizeof(confidence), "FEC: %3.1d%%", scalefec);
 | 
			
		||||
	put_Status2(confidence);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int thor::rx_process(const double *buf, int len)
 | 
			
		||||
| 
						 | 
				
			
			@ -681,7 +809,7 @@ int thor::rx_process(const double *buf, int len)
 | 
			
		|||
		slowcpu = progdefaults.slowcpu;
 | 
			
		||||
		reset_filters();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	while (len) {
 | 
			
		||||
// create analytic signal at first IF
 | 
			
		||||
		zref.re = zref.im = *buf++;
 | 
			
		||||
| 
						 | 
				
			
			@ -696,7 +824,7 @@ int thor::rx_process(const double *buf, int len)
 | 
			
		|||
			zp = zarray;
 | 
			
		||||
			n = 1;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
		if (n) {
 | 
			
		||||
			for (int i = 0; i < n; i++) {
 | 
			
		||||
				complex * pipe_pipeptr_vector = pipe[pipeptr].vector ;
 | 
			
		||||
| 
						 | 
				
			
			@ -711,14 +839,20 @@ int thor::rx_process(const double *buf, int len)
 | 
			
		|||
				}
 | 
			
		||||
				if (--synccounter <= 0) {
 | 
			
		||||
					synccounter = symlen;
 | 
			
		||||
					//if (progdefaults.THOR_SOFTSYMBOLS)
 | 
			
		||||
					currsymbol = harddecode();
 | 
			
		||||
					
 | 
			
		||||
					if (progdefaults.THOR_SOFTSYMBOLS) 
 | 
			
		||||
						currsymbol = softdecode();
 | 
			
		||||
					else 
 | 
			
		||||
						currsymbol = harddecode();
 | 
			
		||||
					
 | 
			
		||||
					currmag = pipe_pipeptr_vector[currsymbol].mag();
 | 
			
		||||
					eval_s2n();
 | 
			
		||||
        		    
 | 
			
		||||
					if (progdefaults.THOR_SOFTBITS) softdecodesymbol();
 | 
			
		||||
					else decodesymbol();
 | 
			
		||||
				
 | 
			
		||||
 | 
			
		||||
					if (progdefaults.THOR_SOFTBITS)
 | 
			
		||||
						softdecodesymbol();
 | 
			
		||||
					else
 | 
			
		||||
						decodesymbol();
 | 
			
		||||
 | 
			
		||||
					synchronize();
 | 
			
		||||
					prev2symbol = prev1symbol;
 | 
			
		||||
					prev1symbol = currsymbol;
 | 
			
		||||
| 
						 | 
				
			
			@ -732,7 +866,7 @@ int thor::rx_process(const double *buf, int len)
 | 
			
		|||
		}
 | 
			
		||||
		--len;
 | 
			
		||||
	}
 | 
			
		||||
			
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -771,7 +905,7 @@ void thor::sendsymbol(int sym)
 | 
			
		|||
{
 | 
			
		||||
	complex z;
 | 
			
		||||
    int tone;
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	tone = (txprevtone + 2 + sym) % THORNUMTONES;
 | 
			
		||||
    txprevtone = tone;
 | 
			
		||||
	if (reverse)
 | 
			
		||||
| 
						 | 
				
			
			@ -786,7 +920,7 @@ void thor::sendchar(unsigned char c, int secondary)
 | 
			
		|||
	const char *code;
 | 
			
		||||
 | 
			
		||||
	code = thorvarienc(c, secondary);
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	while (*code) {
 | 
			
		||||
		int data = Enc->encode(*code++ - '0');
 | 
			
		||||
		for (int i = 0; i < 2; i++) {
 | 
			
		||||
| 
						 | 
				
			
			@ -835,30 +969,22 @@ void thor::flushtx()
 | 
			
		|||
{
 | 
			
		||||
// flush the varicode decoder at the other end
 | 
			
		||||
// flush the convolutional encoder and interleaver
 | 
			
		||||
  if ( mode == MODE_THOR88 || mode == MODE_THOR44) for (int i=0; i<57; i++) sendidle();
 | 
			
		||||
  else {
 | 
			
		||||
    for (int i = 0; i < 4; i++)
 | 
			
		||||
  	    sendidle();
 | 
			
		||||
	bitstate = 0;
 | 
			
		||||
  }
 | 
			
		||||
  for (int i = 0; i < flushlength; i++) sendidle();
 | 
			
		||||
 | 
			
		||||
  bitstate = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int thor::tx_process()
 | 
			
		||||
{
 | 
			
		||||
	int i;
 | 
			
		||||
	int i = 0;
 | 
			
		||||
 | 
			
		||||
	switch (txstate) {
 | 
			
		||||
	case TX_STATE_PREAMBLE:
 | 
			
		||||
		Clearbits();
 | 
			
		||||
		for (int j = 0; j < 16; j++) sendsymbol(0);
 | 
			
		||||
//		sendtone(THORNUMTONES/2, 4);
 | 
			
		||||
//		for (int k = 0; k < 3; k++) {
 | 
			
		||||
//			sendtone(THORNUMTONES, 3);
 | 
			
		||||
//			sendtone(0, 3);
 | 
			
		||||
//		}
 | 
			
		||||
//		sendtone(THORNUMTONES/2, 4);
 | 
			
		||||
 | 
			
		||||
        sendidle();
 | 
			
		||||
		for (int j = 0; j < 16; j++) sendsymbol(0);
 | 
			
		||||
		
 | 
			
		||||
	sendidle();
 | 
			
		||||
		txstate = TX_STATE_START;
 | 
			
		||||
		break;
 | 
			
		||||
	case TX_STATE_START:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -54,6 +54,7 @@ modem *mfsk11_modem = 0;
 | 
			
		|||
modem *mfsk22_modem = 0;
 | 
			
		||||
modem *mfsk31_modem = 0;
 | 
			
		||||
modem *mfsk64_modem = 0;
 | 
			
		||||
modem *mfsk128_modem = 0;
 | 
			
		||||
 | 
			
		||||
modem *wefax576_modem = 0;
 | 
			
		||||
modem *wefax288_modem = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -80,6 +81,7 @@ modem *psk63f_modem = 0;
 | 
			
		|||
modem *psk125_modem = 0;
 | 
			
		||||
modem *psk250_modem = 0;
 | 
			
		||||
modem *psk500_modem = 0;
 | 
			
		||||
modem *psk1000_modem = 0;
 | 
			
		||||
 | 
			
		||||
modem *qpsk31_modem = 0;
 | 
			
		||||
modem *qpsk63_modem = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -90,8 +92,51 @@ modem *qpsk500_modem = 0;
 | 
			
		|||
modem *psk125r_modem = 0;
 | 
			
		||||
modem *psk250r_modem = 0;
 | 
			
		||||
modem *psk500r_modem = 0;
 | 
			
		||||
modem *psk1000r_modem = 0;
 | 
			
		||||
 | 
			
		||||
modem *psk800_c2_modem = 0;
 | 
			
		||||
modem *psk800r_c2_modem = 0;
 | 
			
		||||
modem *psk1000_c2_modem = 0;
 | 
			
		||||
modem *psk1000r_c2_modem = 0;
 | 
			
		||||
 | 
			
		||||
modem *psk63r_c4_modem = 0;
 | 
			
		||||
modem *psk63r_c5_modem = 0;
 | 
			
		||||
modem *psk63r_c10_modem = 0;
 | 
			
		||||
modem *psk63r_c20_modem = 0;
 | 
			
		||||
modem *psk63r_c32_modem = 0;
 | 
			
		||||
 | 
			
		||||
modem *psk125r_c4_modem = 0;
 | 
			
		||||
modem *psk125r_c5_modem = 0;
 | 
			
		||||
modem *psk125r_c10_modem = 0;
 | 
			
		||||
modem *psk125_c12_modem = 0;
 | 
			
		||||
modem *psk125r_c12_modem = 0;
 | 
			
		||||
modem *psk125r_c16_modem = 0;
 | 
			
		||||
 | 
			
		||||
modem *psk250r_c2_modem = 0;
 | 
			
		||||
modem *psk250r_c3_modem = 0;
 | 
			
		||||
modem *psk250r_c5_modem = 0;
 | 
			
		||||
modem *psk250_c6_modem = 0;
 | 
			
		||||
modem *psk250r_c6_modem = 0;
 | 
			
		||||
modem *psk250r_c7_modem = 0;
 | 
			
		||||
 | 
			
		||||
modem *psk500_c2_modem = 0;
 | 
			
		||||
modem *psk500_c4_modem = 0;
 | 
			
		||||
 | 
			
		||||
modem *psk500r_c2_modem = 0;
 | 
			
		||||
modem *psk500r_c3_modem = 0;
 | 
			
		||||
modem *psk500r_c4_modem = 0;
 | 
			
		||||
 | 
			
		||||
modem *olivia_modem = 0;
 | 
			
		||||
modem *olivia_4_250_modem = 0;
 | 
			
		||||
modem *olivia_8_250_modem = 0;
 | 
			
		||||
modem *olivia_4_500_modem = 0;
 | 
			
		||||
modem *olivia_8_500_modem = 0;
 | 
			
		||||
modem *olivia_16_500_modem = 0;
 | 
			
		||||
modem *olivia_8_1000_modem = 0;
 | 
			
		||||
modem *olivia_16_1000_modem = 0;
 | 
			
		||||
modem *olivia_32_1000_modem = 0;
 | 
			
		||||
modem *olivia_64_2000_modem = 0;
 | 
			
		||||
 | 
			
		||||
modem *contestia_modem = 0;
 | 
			
		||||
 | 
			
		||||
modem *rtty_modem = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -103,8 +148,10 @@ modem *thor8_modem = 0;
 | 
			
		|||
modem *thor11_modem = 0;
 | 
			
		||||
modem *thor16_modem = 0;
 | 
			
		||||
modem *thor22_modem = 0;
 | 
			
		||||
modem *thor44_modem = 0;
 | 
			
		||||
modem *thor88_modem = 0;
 | 
			
		||||
modem *thor25x4_modem = 0;
 | 
			
		||||
modem *thor50x1_modem = 0;
 | 
			
		||||
modem *thor50x2_modem = 0;
 | 
			
		||||
modem *thor100_modem = 0;
 | 
			
		||||
 | 
			
		||||
modem *dominoex4_modem = 0;
 | 
			
		||||
modem *dominoex5_modem = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -665,7 +712,6 @@ void modem::wfid_send(int numchars)
 | 
			
		|||
 | 
			
		||||
void modem::wfid_sendchars(string s)
 | 
			
		||||
{
 | 
			
		||||
	long long int symbol;
 | 
			
		||||
	int len = s.length();
 | 
			
		||||
	int  n[len];
 | 
			
		||||
	int  c;
 | 
			
		||||
| 
						 | 
				
			
			@ -682,7 +728,6 @@ void modem::wfid_sendchars(string s)
 | 
			
		|||
	}
 | 
			
		||||
// send rows from bottom to top so they appear to scroll down the waterfall correctly
 | 
			
		||||
	for (int row = 0; row < NUMROWS; row++) {
 | 
			
		||||
		symbol = 0;
 | 
			
		||||
		for (int i = 0; i < len; i++) {
 | 
			
		||||
			if (useIDSMALL)
 | 
			
		||||
				symbols[i] = idch1[n[i]].byte[NUMROWS - 1 - row];
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Ładowanie…
	
		Reference in New Issue