kopia lustrzana https://github.com/jamescoxon/dl-fldigi
				
				
				
			Upstream version 3.0pre1
							rodzic
							
								
									92ebc3e93f
								
							
						
					
					
						commit
						f379ad5eab
					
				| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
Change Log:
 | 
			
		||||
 | 
			
		||||
2.11  1) Added EXEC macro
 | 
			
		||||
3.0   1) Added EXEC macro
 | 
			
		||||
      2) Added mousewheel over Macro buttons to move between macro button sets.
 | 
			
		||||
      3) Fixed bug in Olivia signal level display.
 | 
			
		||||
      4) Ported to Windows (win32) and OS-X
 | 
			
		||||
| 
						 | 
				
			
			@ -88,6 +88,9 @@ Change Log:
 | 
			
		|||
     40) Fixed bug in waterfall update method that could cause a seg fault 
 | 
			
		||||
         under certain conditions.
 | 
			
		||||
     41) Change to PortAudio samplerate probing.
 | 
			
		||||
     42) Increased average power level in MT-63 mode.
 | 
			
		||||
     43) Significantly decreased cpu usage with changes to qrunner and complex 
 | 
			
		||||
         classes.
 | 
			
		||||
 | 
			
		||||
2.10.3)
 | 
			
		||||
      1) Corrected memory leak bug.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,9 +7,9 @@ AC_PREREQ(2.61)
 | 
			
		|||
 | 
			
		||||
dnl major and minor must be integers; patch may
 | 
			
		||||
dnl contain other characters or be empty
 | 
			
		||||
m4_define(FLDIGI_MAJOR, [2])
 | 
			
		||||
m4_define(FLDIGI_MINOR, [11])
 | 
			
		||||
m4_define(FLDIGI_PATCH, [AU])
 | 
			
		||||
m4_define(FLDIGI_MAJOR, [3])
 | 
			
		||||
m4_define(FLDIGI_MINOR, [0])
 | 
			
		||||
m4_define(FLDIGI_PATCH, [pre])
 | 
			
		||||
 | 
			
		||||
AC_INIT([fldigi], FLDIGI_MAJOR.FLDIGI_MINOR[FLDIGI_PATCH], [w1hkj AT w1hkj DOT com])
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -120,6 +120,7 @@ fldigi_SOURCES += \
 | 
			
		|||
	dialogs/fl_digi.cxx \
 | 
			
		||||
	dialogs/font_browser.cxx \
 | 
			
		||||
	dialogs/Viewer.cxx \
 | 
			
		||||
	dialogs/htmlstrings.cxx \
 | 
			
		||||
	thor/thor.cxx \
 | 
			
		||||
	thor/thorvaricode.cxx \
 | 
			
		||||
	dominoex/dominoex.cxx \
 | 
			
		||||
| 
						 | 
				
			
			@ -134,6 +135,7 @@ fldigi_SOURCES += \
 | 
			
		|||
	filters/filters.cxx \
 | 
			
		||||
	filters/viterbi.cxx \
 | 
			
		||||
	globals/globals.cxx \
 | 
			
		||||
	include/htmlstrings.h \
 | 
			
		||||
	include/Combo_Box.h \
 | 
			
		||||
	include/Combo_List.h \
 | 
			
		||||
	include/confdialog.h \
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -80,7 +80,6 @@ void rtty::init()
 | 
			
		|||
rtty::~rtty()
 | 
			
		||||
{
 | 
			
		||||
	if (hilbert) delete hilbert;
 | 
			
		||||
//	if (wfid) delete wfid;
 | 
			
		||||
	if (bitfilt) delete bitfilt;
 | 
			
		||||
	if (bpfilt) delete bpfilt;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1056,6 +1056,13 @@ static void cb_btnFeldHellIdle(Fl_Check_Button* o, void*) {
 | 
			
		|||
progdefaults.changed = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Fl_Spinner *valHellXmtWidth=(Fl_Spinner *)0;
 | 
			
		||||
 | 
			
		||||
static void cb_valHellXmtWidth(Fl_Spinner* o, void*) {
 | 
			
		||||
  progdefaults.HellXmtWidth=(int)o->value();
 | 
			
		||||
progdefaults.changed = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Fl_Group *tabOlivia=(Fl_Group *)0;
 | 
			
		||||
 | 
			
		||||
Fl_Choice *mnuOlivia_Tones=(Fl_Choice *)0;
 | 
			
		||||
| 
						 | 
				
			
			@ -1949,6 +1956,7 @@ l with your sound hardware.");
 | 
			
		|||
      { tabMisc = new Fl_Group(0, 25, 400, 195, "Misc");
 | 
			
		||||
        tabMisc->color((Fl_Color)51);
 | 
			
		||||
        tabMisc->selection_color((Fl_Color)51);
 | 
			
		||||
        tabMisc->hide();
 | 
			
		||||
        { Fl_Group* o = new Fl_Group(5, 35, 390, 90, "Sweet Spot");
 | 
			
		||||
          o->box(FL_ENGRAVED_FRAME);
 | 
			
		||||
          o->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE);
 | 
			
		||||
| 
						 | 
				
			
			@ -2010,7 +2018,6 @@ l with your sound hardware.");
 | 
			
		|||
      { tabModems = new Fl_Group(0, 25, 401, 195, "Modem");
 | 
			
		||||
        tabModems->color((Fl_Color)51);
 | 
			
		||||
        tabModems->selection_color((Fl_Color)51);
 | 
			
		||||
        tabModems->hide();
 | 
			
		||||
        { tabsModems = new Fl_Tabs(0, 25, 401, 195);
 | 
			
		||||
          tabsModems->color((Fl_Color)51);
 | 
			
		||||
          tabsModems->selection_color((Fl_Color)10);
 | 
			
		||||
| 
						 | 
				
			
			@ -2209,6 +2216,7 @@ l with your sound hardware.");
 | 
			
		|||
          { tabDomEX = new Fl_Group(0, 50, 400, 170, "Dom");
 | 
			
		||||
            tabDomEX->color((Fl_Color)51);
 | 
			
		||||
            tabDomEX->selection_color((Fl_Color)51);
 | 
			
		||||
            tabDomEX->hide();
 | 
			
		||||
            { txtSecondary = new Fl_Input(20, 75, 360, 44, "Secondary Text");
 | 
			
		||||
              txtSecondary->type(4);
 | 
			
		||||
              txtSecondary->callback((Fl_Callback*)cb_txtSecondary);
 | 
			
		||||
| 
						 | 
				
			
			@ -2250,8 +2258,7 @@ l with your sound hardware.");
 | 
			
		|||
          { tabFeld = new Fl_Group(0, 50, 400, 170, "Feld");
 | 
			
		||||
            tabFeld->color((Fl_Color)51);
 | 
			
		||||
            tabFeld->selection_color((Fl_Color)51);
 | 
			
		||||
            tabFeld->hide();
 | 
			
		||||
            { Fl_Choice* o = selHellFont = new Fl_Choice(175, 62, 122, 20, "Feld Hell Font:");
 | 
			
		||||
            { Fl_Choice* o = selHellFont = new Fl_Choice(260, 62, 122, 20, "Feld Hell Font:");
 | 
			
		||||
              selHellFont->down_box(FL_BORDER_BOX);
 | 
			
		||||
              selHellFont->labelfont(4);
 | 
			
		||||
              selHellFont->textfont(4);
 | 
			
		||||
| 
						 | 
				
			
			@ -2271,9 +2278,10 @@ l with your sound hardware.");
 | 
			
		|||
              sldrHellBW->align(FL_ALIGN_TOP_LEFT);
 | 
			
		||||
              o->value(progdefaults.HELL_BW);
 | 
			
		||||
            } // Fl_Value_Slider* sldrHellBW
 | 
			
		||||
            { Fl_Check_Button* o = btnHellXmtWidth = new Fl_Check_Button(40, 93, 113, 15, "2x Xmt Width");
 | 
			
		||||
            { Fl_Check_Button* o = btnHellXmtWidth = new Fl_Check_Button(175, 175, 113, 15, "2x Xmt Width");
 | 
			
		||||
              btnHellXmtWidth->down_box(FL_DOWN_BOX);
 | 
			
		||||
              btnHellXmtWidth->callback((Fl_Callback*)cb_btnHellXmtWidth);
 | 
			
		||||
              btnHellXmtWidth->hide();
 | 
			
		||||
              o->value(progdefaults.HellXmtWidth);
 | 
			
		||||
            } // Fl_Check_Button* btnHellXmtWidth
 | 
			
		||||
            { Fl_Check_Button* o = btnHellRcvWidth = new Fl_Check_Button(40, 113, 130, 15, "1/2 x Rcv Width");
 | 
			
		||||
| 
						 | 
				
			
			@ -2286,15 +2294,15 @@ l with your sound hardware.");
 | 
			
		|||
              btnBlackboard->callback((Fl_Callback*)cb_btnBlackboard);
 | 
			
		||||
              o->value(progdefaults.HellBlackboard);
 | 
			
		||||
            } // Fl_Check_Button* btnBlackboard
 | 
			
		||||
            { Fl_Group* o = new Fl_Group(175, 90, 195, 85, "Pulse Shape");
 | 
			
		||||
            { Fl_Group* o = new Fl_Group(189, 90, 195, 85, "Pulse Shape");
 | 
			
		||||
              o->box(FL_ENGRAVED_FRAME);
 | 
			
		||||
              o->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE);
 | 
			
		||||
              { Fl_Check_Button* o = btnHellFastAttack = new Fl_Check_Button(185, 110, 169, 15, "Fast Attack (2 msec)");
 | 
			
		||||
              { Fl_Check_Button* o = btnHellFastAttack = new Fl_Check_Button(199, 110, 169, 15, "Fast Attack (2 msec)");
 | 
			
		||||
                btnHellFastAttack->down_box(FL_DOWN_BOX);
 | 
			
		||||
                btnHellFastAttack->callback((Fl_Callback*)cb_btnHellFastAttack);
 | 
			
		||||
                o->value(progdefaults.HellPulseFast);
 | 
			
		||||
              } // Fl_Check_Button* btnHellFastAttack
 | 
			
		||||
              { Fl_Check_Button* o = btnHellSlowAttack = new Fl_Check_Button(185, 131, 70, 15, "Slow Attack (4 msec)");
 | 
			
		||||
              { Fl_Check_Button* o = btnHellSlowAttack = new Fl_Check_Button(199, 131, 70, 15, "Slow Attack (4 msec)");
 | 
			
		||||
                btnHellSlowAttack->down_box(FL_DOWN_BOX);
 | 
			
		||||
                btnHellSlowAttack->value(1);
 | 
			
		||||
                btnHellSlowAttack->callback((Fl_Callback*)cb_btnHellSlowAttack);
 | 
			
		||||
| 
						 | 
				
			
			@ -2308,6 +2316,13 @@ l with your sound hardware.");
 | 
			
		|||
              btnFeldHellIdle->callback((Fl_Callback*)cb_btnFeldHellIdle);
 | 
			
		||||
              o->value(progdefaults.HellXmtIdle);
 | 
			
		||||
            } // Fl_Check_Button* btnFeldHellIdle
 | 
			
		||||
            { Fl_Spinner* o = valHellXmtWidth = new Fl_Spinner(40, 80, 40, 25, "Xmt Width");
 | 
			
		||||
              valHellXmtWidth->maximum(3);
 | 
			
		||||
              valHellXmtWidth->value(1);
 | 
			
		||||
              valHellXmtWidth->callback((Fl_Callback*)cb_valHellXmtWidth);
 | 
			
		||||
              valHellXmtWidth->align(FL_ALIGN_RIGHT);
 | 
			
		||||
              o->value(progdefaults.HellXmtWidth);
 | 
			
		||||
            } // Fl_Spinner* valHellXmtWidth
 | 
			
		||||
            tabFeld->end();
 | 
			
		||||
          } // Fl_Group* tabFeld
 | 
			
		||||
          { tabOlivia = new Fl_Group(0, 50, 400, 170, "Olivia");
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -898,7 +898,7 @@ progdefaults.changed = true;}
 | 
			
		|||
      }
 | 
			
		||||
      Fl_Group tabMisc {
 | 
			
		||||
        label Misc open
 | 
			
		||||
        xywh {0 25 400 195} color 51 selection_color 51
 | 
			
		||||
        xywh {0 25 400 195} color 51 selection_color 51 hide
 | 
			
		||||
      } {
 | 
			
		||||
        Fl_Group {} {
 | 
			
		||||
          label {Sweet Spot} open
 | 
			
		||||
| 
						 | 
				
			
			@ -952,7 +952,7 @@ progdefaults.changed = true;}
 | 
			
		|||
          Fl_Check_Button chkSlowCpu {
 | 
			
		||||
            label {Slow cpu}
 | 
			
		||||
            callback {progdefaults.slowcpu = o->value();
 | 
			
		||||
progdefaults.changed = true;} selected
 | 
			
		||||
progdefaults.changed = true;}
 | 
			
		||||
            xywh {110 190 89 15} down_box DOWN_BOX
 | 
			
		||||
            code0 {o->value(progdefaults.slowcpu);}
 | 
			
		||||
          }
 | 
			
		||||
| 
						 | 
				
			
			@ -960,7 +960,7 @@ progdefaults.changed = true;} selected
 | 
			
		|||
      }
 | 
			
		||||
      Fl_Group tabModems {
 | 
			
		||||
        label Modem open
 | 
			
		||||
        xywh {0 25 401 195} color 51 selection_color 51 hide
 | 
			
		||||
        xywh {0 25 401 195} color 51 selection_color 51
 | 
			
		||||
      } {
 | 
			
		||||
        Fl_Tabs tabsModems {open
 | 
			
		||||
          xywh {0 25 401 195} color 51 selection_color 10 align 9
 | 
			
		||||
| 
						 | 
				
			
			@ -1133,7 +1133,7 @@ progdefaults.changed = true;}
 | 
			
		|||
          }
 | 
			
		||||
          Fl_Group tabDomEX {
 | 
			
		||||
            label Dom open
 | 
			
		||||
            xywh {0 50 400 170} color 51 selection_color 51
 | 
			
		||||
            xywh {0 50 400 170} color 51 selection_color 51 hide
 | 
			
		||||
          } {
 | 
			
		||||
            Fl_Input txtSecondary {
 | 
			
		||||
              label {Secondary Text}
 | 
			
		||||
| 
						 | 
				
			
			@ -1174,13 +1174,13 @@ progdefaults.changed = true;}
 | 
			
		|||
          }
 | 
			
		||||
          Fl_Group tabFeld {
 | 
			
		||||
            label Feld open
 | 
			
		||||
            xywh {0 50 400 170} color 51 selection_color 51 hide
 | 
			
		||||
            xywh {0 50 400 170} color 51 selection_color 51
 | 
			
		||||
          } {
 | 
			
		||||
            Fl_Choice selHellFont {
 | 
			
		||||
              label {Feld Hell Font:}
 | 
			
		||||
              callback {progdefaults.feldfontnbr=o->value();
 | 
			
		||||
progdefaults.changed = true;} open
 | 
			
		||||
              xywh {175 62 122 20} down_box BORDER_BOX labelfont 4 textfont 4
 | 
			
		||||
              xywh {260 62 122 20} down_box BORDER_BOX labelfont 4 textfont 4
 | 
			
		||||
              code0 {\#include "fontdef.h"}
 | 
			
		||||
              code1 {o->add(szFeldFonts);}
 | 
			
		||||
              code2 {o->value(progdefaults.feldfontnbr);}
 | 
			
		||||
| 
						 | 
				
			
			@ -1195,7 +1195,7 @@ progdefaults.changed = true;} open
 | 
			
		|||
              label {2x Xmt Width}
 | 
			
		||||
              callback {progdefaults.HellXmtWidth=o->value();
 | 
			
		||||
progdefaults.changed = true;}
 | 
			
		||||
              xywh {40 93 113 15} down_box DOWN_BOX
 | 
			
		||||
              xywh {175 175 113 15} down_box DOWN_BOX hide
 | 
			
		||||
              code0 {o->value(progdefaults.HellXmtWidth);}
 | 
			
		||||
            }
 | 
			
		||||
            Fl_Check_Button btnHellRcvWidth {
 | 
			
		||||
| 
						 | 
				
			
			@ -1214,7 +1214,7 @@ progdefaults.changed = true;}
 | 
			
		|||
            }
 | 
			
		||||
            Fl_Group {} {
 | 
			
		||||
              label {Pulse Shape} open
 | 
			
		||||
              xywh {175 90 195 85} box ENGRAVED_FRAME align 21
 | 
			
		||||
              xywh {189 90 195 85} box ENGRAVED_FRAME align 21
 | 
			
		||||
            } {
 | 
			
		||||
              Fl_Check_Button btnHellFastAttack {
 | 
			
		||||
                label {Fast Attack (2 msec)}
 | 
			
		||||
| 
						 | 
				
			
			@ -1226,7 +1226,7 @@ btnHellSlowAttack->value(1);
 | 
			
		|||
progdefaults.HellPulseFast = false;
 | 
			
		||||
}
 | 
			
		||||
progdefaults.changed = true;}
 | 
			
		||||
                xywh {185 110 169 15} down_box DOWN_BOX
 | 
			
		||||
                xywh {199 110 169 15} down_box DOWN_BOX
 | 
			
		||||
                code0 {o->value(progdefaults.HellPulseFast);}
 | 
			
		||||
              }
 | 
			
		||||
              Fl_Check_Button btnHellSlowAttack {
 | 
			
		||||
| 
						 | 
				
			
			@ -1239,7 +1239,7 @@ btnHellFastAttack->value(1);
 | 
			
		|||
progdefaults.HellPulseFast = true;
 | 
			
		||||
}
 | 
			
		||||
progdefaults.changed = true;}
 | 
			
		||||
                xywh {185 131 70 15} down_box DOWN_BOX value 1
 | 
			
		||||
                xywh {199 131 70 15} down_box DOWN_BOX value 1
 | 
			
		||||
                code0 {o->value(!progdefaults.HellPulseFast);}
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -1250,6 +1250,13 @@ progdefaults.changed = true;}
 | 
			
		|||
              xywh {40 155 70 15} down_box DOWN_BOX value 1
 | 
			
		||||
              code0 {o->value(progdefaults.HellXmtIdle);}
 | 
			
		||||
            }
 | 
			
		||||
            Fl_Spinner valHellXmtWidth {
 | 
			
		||||
              label {Xmt Width}
 | 
			
		||||
              callback {progdefaults.HellXmtWidth=(int)o->value();
 | 
			
		||||
progdefaults.changed = true;} selected
 | 
			
		||||
              xywh {40 80 40 25} align 8 maximum 3 value 1
 | 
			
		||||
              code0 {o->value(progdefaults.HellXmtWidth);}
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
          Fl_Group tabOlivia {
 | 
			
		||||
            label Olivia open
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -100,6 +100,8 @@
 | 
			
		|||
#include "Viewer.h"
 | 
			
		||||
#include "soundconf.h"
 | 
			
		||||
 | 
			
		||||
#include "htmlstrings.h"
 | 
			
		||||
 | 
			
		||||
Fl_Double_Window	*fl_digi_main=(Fl_Double_Window *)0;
 | 
			
		||||
Fl_Help_Dialog 		*help_dialog = (Fl_Help_Dialog *)0;
 | 
			
		||||
Fl_Double_Window	*scopeview = (Fl_Double_Window *)0;
 | 
			
		||||
| 
						 | 
				
			
			@ -753,6 +755,25 @@ void html_help( const string &Html)
 | 
			
		|||
		help_dialog = new Fl_Help_Dialog;
 | 
			
		||||
	help_dialog->value(Html.c_str());
 | 
			
		||||
	help_dialog->show();
 | 
			
		||||
	restoreFocus();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cb_mnuBeginnersURL(Fl_Widget*, void*)
 | 
			
		||||
{
 | 
			
		||||
	if (!help_dialog)
 | 
			
		||||
		help_dialog = new Fl_Help_Dialog;
 | 
			
		||||
	help_dialog->value(szBeginner);
 | 
			
		||||
	help_dialog->show();
 | 
			
		||||
	restoreFocus();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cb_mnuAboutURL(Fl_Widget*, void*)
 | 
			
		||||
{
 | 
			
		||||
	if (!help_dialog)
 | 
			
		||||
		help_dialog = new Fl_Help_Dialog;
 | 
			
		||||
	help_dialog->value(szAbout);
 | 
			
		||||
	help_dialog->show();
 | 
			
		||||
	restoreFocus();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void fldigi_help(const string& theHelp)
 | 
			
		||||
| 
						 | 
				
			
			@ -1189,12 +1210,13 @@ Fl_Menu_Item menu_[] = {
 | 
			
		|||
// settle the gmfsk vs fldigi argument once and for all
 | 
			
		||||
{"@-1circle  Create sunspots", 0, cb_mnuFun, 0, FL_MENU_DIVIDER, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
#endif
 | 
			
		||||
{"Beginners Help", 0, cb_mnuBeginnersURL, 0, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{"Online documentation", 0, cb_mnuVisitURL, (void *)PACKAGE_DOCS, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{"Home page", 0, cb_mnuVisitURL, (void *)PACKAGE_HOME, FL_MENU_DIVIDER, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{"Command line options", 0, cb_mnuCmdLineHelp, 0, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{"Audio device info", 0, cb_mnuAudioInfo, 0, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{"Build info", 0, cb_mnuBuildInfo, 0, FL_MENU_DIVIDER, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{"About", 0, cb_mnuAbout, 0, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{"About", 0, cb_mnuAboutURL, 0, 0, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
{0,0,0,0,0,0,0,0,0},
 | 
			
		||||
	
 | 
			
		||||
{"  ", 0, 0, 0, FL_MENU_INACTIVE, FL_NORMAL_LABEL, 0, 14, 0},
 | 
			
		||||
| 
						 | 
				
			
			@ -1346,7 +1368,7 @@ void create_fl_digi_main() {
 | 
			
		|||
 | 
			
		||||
	if (twoscopes) 	WNOM -= 2*DEFAULT_SW;
 | 
			
		||||
	
 | 
			
		||||
	fl_digi_main = new Fl_Double_Window(WNOM, HNOM, "fldigi");
 | 
			
		||||
	fl_digi_main = new Fl_Double_Window(WNOM, HNOM, PACKAGE_NAME" "PACKAGE_VERSION);//"fldigi");
 | 
			
		||||
			mnu = new Fl_Menu_Bar(0, 0, WNOM - 142, Hmenu);
 | 
			
		||||
			// FL_NORMAL_SIZE may have changed; update the menu items
 | 
			
		||||
			for (size_t i = 0; i < sizeof(menu_)/sizeof(menu_[0]); i++)
 | 
			
		||||
| 
						 | 
				
			
			@ -2225,3 +2247,4 @@ void start_tx()
 | 
			
		|||
	fl_unlock(&trx_mutex);
 | 
			
		||||
	wf->set_XmtRcvBtn(true);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,568 @@
 | 
			
		|||
// ----------------------------------------------------------------------------
 | 
			
		||||
//
 | 
			
		||||
//	htmlstrings.cxx
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2008
 | 
			
		||||
//		Dave Freese, W1HKJ
 | 
			
		||||
//
 | 
			
		||||
// This file is part of fldigi.
 | 
			
		||||
//
 | 
			
		||||
// fldigi is free software; you can redistribute it and/or modify
 | 
			
		||||
// it under the terms of the GNU General Public License as published by
 | 
			
		||||
// the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
// (at your option) any later version.
 | 
			
		||||
//
 | 
			
		||||
// fldigi is distributed in the hope that it will be useful,
 | 
			
		||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
// GNU General Public License for more details.
 | 
			
		||||
//
 | 
			
		||||
// You should have received a copy of the GNU General Public License
 | 
			
		||||
// along with fldigi; if not, write to the Free Software
 | 
			
		||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
// ----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
char szBeginner[] = "\
 | 
			
		||||
<HTML>\
 | 
			
		||||
<HEAD>\
 | 
			
		||||
<TITLE>Beginners' Guide to FLDIGI</TITLE>\
 | 
			
		||||
</HEAD>\
 | 
			
		||||
<BODY BG=FFFFFF TEXT=404040 LINK=CC0088 VLINK=995544>\
 | 
			
		||||
<font size=\"0\" face=\"Verdana, Arial, Helvetica\">\
 | 
			
		||||
<CENTER>\
 | 
			
		||||
<H1>Beginners' Guide to FLDIGI</H1>\
 | 
			
		||||
<P>\
 | 
			
		||||
<A HREF=\"#Wotuneed\">Requirements</A> \
 | 
			
		||||
<A HREF=\"#Install\">Installation</A> \
 | 
			
		||||
<A HREF=\"#Start\">Getting Started</A> \
 | 
			
		||||
<A HREF=\"#Oper\">Operating</A> \
 | 
			
		||||
<A HREF=\"#Keys\">Special Keys</A> \
 | 
			
		||||
\
 | 
			
		||||
<HR>\
 | 
			
		||||
</CENTER>\
 | 
			
		||||
<H2>Beginners' Questions Answered</H2>\
 | 
			
		||||
<H3><I>What is FLDIGI?</I></H3>\
 | 
			
		||||
<BLOCKQUOTE>\
 | 
			
		||||
FLDIGI is a computer program intended for Amateur Radio Digital Modes operation using a PC (Personal Computer).\
 | 
			
		||||
FLDIGI operates (as does most similar software) in conjunction with a conventional HF SSB radio transceiver,\
 | 
			
		||||
and uses the\
 | 
			
		||||
PC sound card as the main means of input from the radio, and output to the radio. These are audio-frequency\
 | 
			
		||||
signals. The software also controls the radio by means of another connection, typically a serial port.\
 | 
			
		||||
<P>\
 | 
			
		||||
FLDIGI is multi-mode, which means that it is able to operate many popular digital modes without switching\
 | 
			
		||||
programs, so you only have one program to learn. FLDIGI includes all the popular modes, such as DominoEX, MFSK16,\
 | 
			
		||||
PSK31, and RTTY.\
 | 
			
		||||
<P>\
 | 
			
		||||
Unusually, FLDIGI is available for multiple computer operating systems; Linux, Free-BSD; OS-X and Windows(XP).\
 | 
			
		||||
</BLOCKQUOTE>\
 | 
			
		||||
<H3><I>What is a Digital Mode?</I></H3>\
 | 
			
		||||
<BLOCKQUOTE>\
 | 
			
		||||
Digital Modes are a means of operating Amateur radio from the computer keyboard. The computer acts as 'modem' (modulator - demodulator),\
 | 
			
		||||
as well as allowing you to type, and see what the other person types. It also controls the transmitter, changes modes as required,\
 | 
			
		||||
and provides various convenient features such as easy tuning of signals and prearranged messages.\
 | 
			
		||||
<P>\
 | 
			
		||||
In this context, we are talking\
 | 
			
		||||
about modes used on the HF (high frequency) bands, specifically 'chat' modes, those used to have a regular\
 | 
			
		||||
conversation in a similar way to voice or Morse, where one operator 'talks' for a minute or two, then another\
 | 
			
		||||
does the same. These chat modes allow multiple operators to take part in a 'net'.\
 | 
			
		||||
<P>\
 | 
			
		||||
Because of sophisticated digital signal processing which takes place inside the computer, digital modes can\
 | 
			
		||||
offer performance that cannot be achieved using voice (and in some cases even Morse), through reduced\
 | 
			
		||||
bandwidth, improved signal-to-noise performance and reduced transmitter power requirement. Some modes also\
 | 
			
		||||
offer built-in automatic error correction.\
 | 
			
		||||
<P>\
 | 
			
		||||
Digital Mode operating procedure is not unlike Morse operation, and many of the same abbreviations are used.\
 | 
			
		||||
Software such as FLDIGI makes this very simple as most of the procedural business is set up for you using\
 | 
			
		||||
the Function Keys at the top of the keyboard. These are easy to learn.\
 | 
			
		||||
</BLOCKQUOTE>\
 | 
			
		||||
<H3><I>Why all the different modes?</I></H3>\
 | 
			
		||||
<BLOCKQUOTE>\
 | 
			
		||||
HF propagation is very dependent on the ionosphere, which reflects the signals back to earth. There are strong\
 | 
			
		||||
interactions between different signals arriving from different paths. Experience has shown that particular\
 | 
			
		||||
modulation systems, speeds and bandwidths suit different operating conditions.\
 | 
			
		||||
<P>\
 | 
			
		||||
Other factors such as available band space, operating speed and convenience, noise level, signal level and\
 | 
			
		||||
available power also affect the choice of mode. While in many cases several different modes might be suitable,\
 | 
			
		||||
having a choice adds to the operating pleasure. It is diffcult to advise which mode is best for each particular\
 | 
			
		||||
occasion, and experience plays an important role. \
 | 
			
		||||
<P>\
 | 
			
		||||
You might consider purchasing '<I>Digital Modes for All Occasions</I>'\
 | 
			
		||||
(ISBN 1-872309-82-8) by Murray Greenman ZL1BPU, published by the <A HREF=\"http://www.rsgbshop.org/\">RSGB</A>,\
 | 
			
		||||
as this gives a good insight into each mode\
 | 
			
		||||
and its capabilities. The book is also available from FUNKAMATEUR and CQ Communications.\
 | 
			
		||||
<P>\
 | 
			
		||||
</BLOCKQUOTE>\
 | 
			
		||||
<H3><I>How do I recognise and tune in the signals?</I></H3>\
 | 
			
		||||
<BLOCKQUOTE>\
 | 
			
		||||
Recognising the different modes comes with experience. It is a matter of listening to the signal, and observing\
 | 
			
		||||
the appearance of the signal on the tuning display. You can also practice transmitting with the transceiver\
 | 
			
		||||
disconnected, listening to the sound of the signals coming from the computer. There is also (see later paragraph)\
 | 
			
		||||
an automatic tuning option which can recognise and tune in most modes for you.\
 | 
			
		||||
<P>\
 | 
			
		||||
The software provides a tuning display which shows the radio signals that are receivable within the transceiver\
 | 
			
		||||
passband. Using a 'point and click' technique with the mouse, you can click on the centre of a signal to select it,\
 | 
			
		||||
and the software will tune it in for you. Some modes require more care than others, and of course you need to have\
 | 
			
		||||
the software set for the correct mode first - not always so easy!\
 | 
			
		||||
<P>\
 | 
			
		||||
The 'RSID' (automatic mode detection and tuning) feature uses a special sequence of tones transmitted at the beginning of each transmission to identify\
 | 
			
		||||
and tune in the signals received. For this feature to work, not only do you need to enable the feature in the receiver,\
 | 
			
		||||
but in addition the stations you are wishing to tune in need to have this feature enabled on transmission. Other\
 | 
			
		||||
programs also offer this RSID feature as an option.\
 | 
			
		||||
</BLOCKQUOTE>\
 | 
			
		||||
<H3><I>Where can I find detailed instructions for FLDIGI?</I></H3>\
 | 
			
		||||
<BLOCKQUOTE>\
 | 
			
		||||
Of necessity, this Beginner's Guide contains only as much as you need to know to get started. You can always read the\
 | 
			
		||||
details and learn how to make best use of the program by reading the <A HREF=\"http://www.w1hkj.com/FldigiHelp/index.html\">Online Documentation</A>. You can also access it from within the FLDIGI program from the HELP Menu item. \
 | 
			
		||||
</BLOCKQUOTE>\
 | 
			
		||||
<A NAME=\"Wotuneed\">\
 | 
			
		||||
<HR>\
 | 
			
		||||
<H2>Requirements</H2>\
 | 
			
		||||
<BLOCKQUOTE>\
 | 
			
		||||
<DL>\
 | 
			
		||||
<DT><B>Computer</B></DT>\
 | 
			
		||||
<DD>Pentium™ 3 or 4, Celeron™, or equivalent, 750MHz or better, 256MB RAM or more. Faster computers can give\
 | 
			
		||||
better performance.</DD>\
 | 
			
		||||
<DT><B>Operating System</B></DT>\
 | 
			
		||||
<DD>Windows XP SP2 (Home or Pro), LINUX distributions such as Debian, Ubuntu, Kubuntu, Mandriva, Mandrake,\
 | 
			
		||||
SuSE, Puppy Linux, or FreeBSD. FLDIGI can be home compiled for other distributions. FLDIGI does not support\
 | 
			
		||||
Windows 98 or older, and may not work with Windows VISTA.</DD>\
 | 
			
		||||
<DT><B>Other Requirements</B></DT>\
 | 
			
		||||
<DD><LI>Computer serial port (or USB serial port) for rig control\
 | 
			
		||||
<LI>Optional serial CAT (Computer Aided Tuning) computer control\
 | 
			
		||||
<LI>About 5MB of drive space is required for program files\
 | 
			
		||||
<LI>Internet connection will allow direct connection to the online help files and your online callsign server subscription.\
 | 
			
		||||
<LI>A radio interface to the sound card and serial port, such as the RigBlaster™ or similar. You can make one yourself.\
 | 
			
		||||
<LI>A modern HF SSB transceiver, with or without CAT control. For some modes, frequency stability is very important\
 | 
			
		||||
(preferably less than 1Hz drift per over), and the difference between transmit and receive frequencies should also\
 | 
			
		||||
be low (less than 1Hz). Tuning steps should be 100Hz or less. Most commercial synthesized transceivers made in the last\
 | 
			
		||||
20 years will meet these requirements.\
 | 
			
		||||
</DD></DL>\
 | 
			
		||||
</BLOCKQUOTE>\
 | 
			
		||||
<A NAME=\"Install\">\
 | 
			
		||||
<HR>\
 | 
			
		||||
<H2>Installation</H2>\
 | 
			
		||||
<H3><I>Installing</I></H3>\
 | 
			
		||||
<BLOCKQUOTE>\
 | 
			
		||||
<UL><LI>Locate and download the correct archive for your operating system from the <A HREF=\"http://www.w1hkj.com/Fldigi.html\">\
 | 
			
		||||
FLDIGI web site</A>.\
 | 
			
		||||
<LI>Create a suitable folder on your hard drive (for example Programs/FLDIGI) and unzip the archive into this folder.\
 | 
			
		||||
<LI>Right-click on the executable <B>fldigi.exe</B>, select 'Create Shortcut', and drag the resulting shortcut either to\
 | 
			
		||||
the desktop or to a suitable place in the menu structure.\
 | 
			
		||||
<LI>Double-click on this new shortcut to start the program. You're in business!\
 | 
			
		||||
</BLOCKQUOTE>\
 | 
			
		||||
<H3><I>Updating the Program</I></H3>\
 | 
			
		||||
<BLOCKQUOTE>\
 | 
			
		||||
<UL><LI>Delete the shortcut you made during installation\
 | 
			
		||||
<LI>Repeat the installation process described above, using the same folder. The new program will over-write the old.\
 | 
			
		||||
<LI>Make a new shortcut as described above.\
 | 
			
		||||
</UL>\
 | 
			
		||||
</BLOCKQUOTE>\
 | 
			
		||||
<H3><I>Removing the Program</I></H3>\
 | 
			
		||||
<BLOCKQUOTE>\
 | 
			
		||||
<UL><LI>Delete the shortcut you made during installation\
 | 
			
		||||
<LI>Locate the program folder you made during installation, delete the contents, and then delete the folder.\
 | 
			
		||||
</UL>\
 | 
			
		||||
</BLOCKQUOTE>\
 | 
			
		||||
<H3><I>Setting Up</I></H3>\
 | 
			
		||||
<BLOCKQUOTE>\
 | 
			
		||||
<UL><LI>Use the menu <B>Configure/Defaults/Sound Card Audio Devices</B> tab to select the sound card you wish to use.\
 | 
			
		||||
You can ignore the other tabs for now.\
 | 
			
		||||
<LI>Use the menu <B>Configure/Defaults/Operator</B> item to set the user name, callsign, location and so on.\
 | 
			
		||||
<LI>Use the menu <B>Configure/Defaults/Rig Ctrl</B> item to set how you will control the rig. Set 'Ptt' to 'TTY'.\
 | 
			
		||||
If you will control the rig via a serial port, select the COM port you will use, and select which line controls PTT.\
 | 
			
		||||
If in doubt, check both RTS and DTR. You MUST then press the <B>Initialize</B> button.\
 | 
			
		||||
<LI>If you plan to use CAT control of the rig via the COM port, check 'userigCAT'. If in addition you wish to use\
 | 
			
		||||
PTT control via CAT, also then check 'rigCAT PTT'. You MUST then press the <B>Initialize</B> button.\
 | 
			
		||||
<LI>Use the menu <B>Configure/Defaults/Misc</B> item to set whether you wish to transmit RSID data at the start of each\
 | 
			
		||||
over (this is for the benefit of others, this setting does not affect RSID reception), and whether you have a slow computer (under 1000MHz)\
 | 
			
		||||
or not. The receiver decoding strategy uses less processor power in 'Slow cpu' mode. If you plan to regularly\
 | 
			
		||||
use the RSID feature on receive, you must leave the 'Start New Modem at Sweet Spot' item unchecked.\
 | 
			
		||||
<LI>Each of the modems can be individually set up from the <B>Configure/Modems</B> multi-tabbed dialog.\
 | 
			
		||||
You need not change anything here to start with, although it might be a good idea to set the 'secondary text' for DominoEX\
 | 
			
		||||
('Dom' tab) and THOR ('Thor' tab) to something useful, such as your call and locator. (Secondary text is transmitted when the text\
 | 
			
		||||
you type does not keep up with the typing speed of the mode - this handy text appears in a small window at the very bottom of the screen).\
 | 
			
		||||
Note that this set of tabs is also where you set the RTTY modem speed and shift, although the default values should be fine\
 | 
			
		||||
for normal operation.\
 | 
			
		||||
<LI>Use the menu <B>Configure/Save Config</B> item to save the new configuration.\
 | 
			
		||||
<LI>Use your sound card 'Master Volume' applet to select the sound card, the Wave output and set the transmit audio level.\
 | 
			
		||||
You can check the level using the <B>TUNE</B> button, top right, beyond the Menu.\
 | 
			
		||||
<LI>The 'Volume' applet can usually be opened by <B>START/Run...</B> and enter '<B>sndvol32'</B>, or from the Control Panel.\
 | 
			
		||||
<LI>Use your sound card 'Recording Control' applet to select the sound card, the line or mic input and set the receiver audio level.\
 | 
			
		||||
Watch the waterfall display for receiver noise when setting the level. If you see any dark blue noise, you have the right input\
 | 
			
		||||
and about the right level. The actual setting is not very important, provided you see blue noise. If the audio level is too high,\
 | 
			
		||||
the little diamond shaped indicator (bottom right) will show <B><FONT COLOR=RED>red</FONT></B>. The waterfall may also show red bands.\
 | 
			
		||||
Performance will be degraded if the level is too high.\
 | 
			
		||||
<LI>The 'Record' applet can usually be opened by <B>START/Run...</B> and enter '<B>sndvol32 /r</B>', or from the Control Panel.\
 | 
			
		||||
If opened from the Control Panel, you'll end up with the Master Volume applet, and need to switch using Options/Properties, and selecting\
 | 
			
		||||
the 'Recording' radio button.\
 | 
			
		||||
</UL>\
 | 
			
		||||
</BLOCKQUOTE>\
 | 
			
		||||
<A NAME=\"Start\">\
 | 
			
		||||
<HR>\
 | 
			
		||||
<H2>Getting Started</H2>\
 | 
			
		||||
<H3><I>Guided Tour</I></H3>\
 | 
			
		||||
<BLOCKQUOTE>\
 | 
			
		||||
Double-click on the FLDIGI shortcut to start the program. A window with three main panes will appear.\
 | 
			
		||||
Study it carefully as you read these notes. From top to bottom, these are the <B>RECEIVE</B> pane\
 | 
			
		||||
(<B><FONT COLOR=EECC44>orange</FONT></B>), the <B>TRANSMIT</B> pane (<B><FONT COLOR=cyan>light blue</FONT></B>), and the <B>WATERFALL</B> pane (<B><FONT COLOR=black>black</FONT></B>). At the top is\
 | 
			
		||||
the collection of entry items which form the <B>LOG DATA</B>, and at the very top, a\
 | 
			
		||||
conventional drop-down <B>MENU</B> system, with entries for <U>F</U>iles, Op <U>M</U>ode, Configure, View and Help.\
 | 
			
		||||
<P>\
 | 
			
		||||
Between the RECEIVE and TRANSMIT panes is a line of boxes (buttons), which represent the Function Keys F1 - F12.\
 | 
			
		||||
We call this the <B>FUNCTIONS</B> group.\
 | 
			
		||||
Below the WATERFALL pane is another line of boxes (buttons), which provide various control features. We call this the\
 | 
			
		||||
<B>CONTROLS</B> group. The program and various buttons can mostly be operated using the mouse or the keyboard, and users\
 | 
			
		||||
generally find it convenient\
 | 
			
		||||
to use the mouse while tuning around, and the keyboard and function keys during a QSO.\
 | 
			
		||||
</BLOCKQUOTE>\
 | 
			
		||||
<H3><I>RECEIVE Pane</I></H3>\
 | 
			
		||||
<BLOCKQUOTE>\
 | 
			
		||||
This is where the text from decoded incoming signals is displayed, in <B><FONT COLOR=black>black</FONT></B> text.\
 | 
			
		||||
When you transmit, the transmitted text is also displayed here, but in <B><FONT COLOR=red>red</FONT></B>, so\
 | 
			
		||||
the RECEIVE pane becomes a complete record of the QSO. The information in this pane can also be logged to a file.\
 | 
			
		||||
<P>\
 | 
			
		||||
The line at the bottom of this pane can be dragged up and down with the mouse. You might prefer to drag it down a bit\
 | 
			
		||||
to enlarge the RECEIVE pane and reduce the size of the TRANSMIT pane.\
 | 
			
		||||
</BLOCKQUOTE>\
 | 
			
		||||
<H3><I>TRANSMIT Pane</I></H3>\
 | 
			
		||||
<BLOCKQUOTE>\
 | 
			
		||||
This is where you type what you want to transmit. The mouse must click in here before you type (to obtain 'focus') otherwise\
 | 
			
		||||
your text will go nowhere. You can type in here while you are receiving, and when you start transmitting, the text already typed\
 | 
			
		||||
will be sent first. This trick is a cool way to impress others with your typing speed! As the text is transmitted, the text colour\
 | 
			
		||||
changes from <B><FONT COLOR=black>black</FONT></B> to <B><FONT COLOR=red>red</FONT></B>. At the end of the over, all the transmitted\
 | 
			
		||||
text (and any as yet not transmitted) will be deleted.\
 | 
			
		||||
</BLOCKQUOTE>\
 | 
			
		||||
<H3><I>WATERFALL Pane</I></H3>\
 | 
			
		||||
<BLOCKQUOTE>\
 | 
			
		||||
This is the main tuning facility. There are two modes, 'Waterfall' and 'FFT', selected by a button in the CONTROL group. For now,\
 | 
			
		||||
leave it in 'Waterfall' mode, as this is the easiest to tune with, and gives the best identification of the signal.\
 | 
			
		||||
<UL><LI>'Waterfall' is a spectrogram display, of signal strength versus frequency, over passing time. The receiver passband\
 | 
			
		||||
is analysed and displayed with lower frequencies to the left, higher to the right. Weak signals and background noise\
 | 
			
		||||
are dark while stronger signals show as brighter colours. As time passes (over a few seconds), the historic signals move downwards like a waterfall.\
 | 
			
		||||
<LI>'FFT' is a spectrum display, simply the mean signal strength versus frequency. Again frequency is displayed from left to right,\
 | 
			
		||||
but now the vertical direction shows signal strength and there is no brightness or historic onformation.</UL>\
 | 
			
		||||
<P>\
 | 
			
		||||
At the top of the pane is a scale of frequency in Hz, which corresponds to the frequency displayed immediately below it. This\
 | 
			
		||||
scale can be moved around and zoomed using buttons in the CONTROL group.\
 | 
			
		||||
<P>\
 | 
			
		||||
As you move the mouse around in this pane you will see a <B><FONT COLOR=CCCC00>yellow</FONT></B> group of tuning marks following the mouse pointer.\
 | 
			
		||||
Tuning is achieved by left-clicking on a signal displayed by the waterfall in this pane. Use these yellow marks to\
 | 
			
		||||
exactly straddle the signal and then left-click on the centre of the signal. The tuning marks change to\
 | 
			
		||||
<B><FONT COLOR=red>red</FONT></B>. The <B><FONT COLOR=red>red</FONT></B> vertical lines will show the approximate\
 | 
			
		||||
width of the active signal area (the expected signal bandwidth), while a <B><FONT COLOR=red>red</FONT></B>\
 | 
			
		||||
horizontal bar above will indicate the receiver software's active decoding range. When you left-click, the red\
 | 
			
		||||
marks move to where you clicked, and will attempt to auto-track the signal from there.\
 | 
			
		||||
<P>\
 | 
			
		||||
You can temporarily 'monitor' a different signal by right-clicking on it. As long as you hold the mouse button down, the signal under\
 | 
			
		||||
it will be decoded; as soon as you release the mouse, decoding will revert to the previously tuned spot (where the red marks are).\
 | 
			
		||||
</BLOCKQUOTE>\
 | 
			
		||||
<H3><I>LOG Data</I></H3>\
 | 
			
		||||
<BLOCKQUOTE>\
 | 
			
		||||
Using this group of entry boxes, you can keep a log of your QSOs. At the left are two '<B>Frequency</B>' boxes.\
 | 
			
		||||
If you use CAT control to operate your transceiver, the dial frequency is recorded automatically in the lower box;\
 | 
			
		||||
otherwise you can type it manually or select (botton to the right) from a list of common frequencies. The audio frequency from the waterfall\
 | 
			
		||||
is added to this value and displayed in the upper box - assuming your rig is calibrated correctly, this is the true\
 | 
			
		||||
centre frequency of the station you are in QSO with. You can't type in the upper box.\
 | 
			
		||||
<P>\
 | 
			
		||||
The program is able to switch sidebands (the '<B>U</B>' or '<B>L</B>' button under the '<B>Time</B>' display),\
 | 
			
		||||
so if your rig is in LSB mode, the signals are inverted for you, and when you\
 | 
			
		||||
add the frequency to the log information, the audio frequency is subtracted rather than added, so again the true transmit\
 | 
			
		||||
frequency is displayed and logged.\
 | 
			
		||||
<P>\
 | 
			
		||||
The '<B>Time</B>' box can be typed in, or you can push the adjacent button to insert the current time. All times are in UTC,\
 | 
			
		||||
and the computer knows how to calculate this from the PC local civil time, time zone and summer-time setting. Clever stuff!\
 | 
			
		||||
<P>\
 | 
			
		||||
You can type the other station's callsign and name in the '<B>Call</B>' and '<B>Namel</B>' boxes, or right-click\
 | 
			
		||||
on the appropriate word in the RECEIVE pane to insert them automatically. The same applies to the '<B>QTH</B>',\
 | 
			
		||||
'<B>LOC</B>' (locator) and received signal report '<B>RST In</B>'. The other entries must be added manually.\
 | 
			
		||||
If you have access to an appropriate Callbook on-line subscription or CD, pressing the '<B>QRZ</B>' button will fetch\
 | 
			
		||||
this information for you automatically.\
 | 
			
		||||
<P>\
 | 
			
		||||
The '<B>Clear</B>' button clears all the log data; the '<B>Save</B>' button sends the logged information to the log file.\
 | 
			
		||||
</BLOCKQUOTE>\
 | 
			
		||||
<H3><I>MENU</I></H3>\
 | 
			
		||||
<BLOCKQUOTE>\
 | 
			
		||||
At the very top of the program window is a conventional drop-down menu. If you click on any of the items, a list of optional\
 | 
			
		||||
functions will appear. Keyboard menu selection is also provided.\
 | 
			
		||||
Where <U>underscored</U> characters are shown in the menu, you can select these menu items from the keyboard\
 | 
			
		||||
using the marked character and <<B>Alt</B>> at the same time, then moving around with the up/down/left/right keys.\
 | 
			
		||||
Use <<B>Esc</B>> to quit from the menu with no change.\
 | 
			
		||||
These menu functions are:\
 | 
			
		||||
</BLOCKQUOTE>\
 | 
			
		||||
<DL><DT><B><U>F</U>iles</B></DT>\
 | 
			
		||||
<DD>Allows you to open or save Macros (we won't get into that here), turn on/off logging to file, record/play audio samples, and exit the program. You can also exit the program by clicking on the 'X' in the tope right corner of the window, in the usual manner.</DD>\
 | 
			
		||||
<DT><B>Op <U>M</U>ode</B></DT>\
 | 
			
		||||
<DD>This is where you select the operating modem used for transmission and reception. Some modes only have one option. Where more are\
 | 
			
		||||
offered, drag the mouse down the list and sideways following the arrow to a secondary list, before releasing it. When you start the\
 | 
			
		||||
program next time, it will remember the last mode you used.\
 | 
			
		||||
<P>\
 | 
			
		||||
Not all the modes are widely used, so choose a mode which (a) maximizes your chance of a QSO, and (b) is appropriate for\
 | 
			
		||||
the band, conditions, bandwidth requirements and permissions relevant to your operating licence.\
 | 
			
		||||
<P>\
 | 
			
		||||
At the bottom of the list are two 'modes' which aren't modes at all, and do not transmit (see\
 | 
			
		||||
<A HREF=\"http://www.w1hkj.com/FldigiHelp/index.html\">Online Documentation</A> for details). <B>WWV</B> mode allows you to receive a standard time\
 | 
			
		||||
signal so the beeps it transmits can be used for sound card calibration. <B>Freq Analysis</B> provides just a waterfall display with a very narrow cursor, and a frequency meter\
 | 
			
		||||
which indicates the received frequency in Hz to two decimal places. This is useful for on-air frequency measurement.</DD>\
 | 
			
		||||
<DT><B>Configure</B></DT>\
 | 
			
		||||
<DD>This is where you set up the program to suit your computer, yourself and your operating preferences. <B>Defaults</B>\
 | 
			
		||||
will allow you to change the operating settings of the program. This is where you enter your personal information,\
 | 
			
		||||
or define your computer sound card, for example.\
 | 
			
		||||
<B>Modems</B> can be individually changed, each having\
 | 
			
		||||
different adjustments. The <B>Modems</B> dialog has multiple tabs, so you can edit any one of them. Don't fool with\
 | 
			
		||||
the settings until you know what you are doing! The final item, <B>Save Config</B> allows you to save the altered configuration\
 | 
			
		||||
for next time you start the program (otherwise changes are temporary).\
 | 
			
		||||
<DT><B>View</B></DT>\
 | 
			
		||||
<DD>This menu item allows you to open extra windows. Most will be greyed out, but two that are available are the <B>Digiscope</B>,\
 | 
			
		||||
and the <B>PSK Browser</B>. The <B>Digiscope</B> provides a mode-specific graphical analysis of the received signal, and\
 | 
			
		||||
can have more than one view (left click in the new window to change the view), or maybe none at all. The <B>PSK Browser</B>\
 | 
			
		||||
is a rather cool tool that allows you to monitor several PSK31 signals all at the same time! These windows can be resized to suit.</DD>\
 | 
			
		||||
<DT><B>Help</B></DT>\
 | 
			
		||||
<DD>Brings up the <A HREF=\"http://www.w1hkj.com/FldigiHelp/index.html\">Online Documentation</A>, the FLDIGI\
 | 
			
		||||
<A HREF=\"http://www.w1hkj.com/Fldigi.html\">Home Page</A>, and various information about the program.</DD>\
 | 
			
		||||
</DL>\
 | 
			
		||||
<H3><I>FUNCTIONS</I></H3>\
 | 
			
		||||
<BLOCKQUOTE>\
 | 
			
		||||
This line of buttons provides user-editable QSO features. For example, the first button on the left sends CQ for you. Both the\
 | 
			
		||||
function of these buttons (we call them <B><I>MACROS</I></B>) and the label on each button, can be changed. Select each button\
 | 
			
		||||
to use it by pressing the corresponding Function Key (F1 - F12, you'll notice the buttons are grouped in patterns four to a group,\
 | 
			
		||||
just as the Function Keys are). You can also select them with a left-click of the mouse. If you right-click on the button, you\
 | 
			
		||||
are able to edit the buttons label and its function. A handy dialog pops up to allow this to be done. There are many standard\
 | 
			
		||||
shortcuts, such as <MYCALL> which you can use within the Macros. Notice that the buttons also turn the transmitter on\
 | 
			
		||||
and off as necessary.\
 | 
			
		||||
<P>\
 | 
			
		||||
You can just about hold a complete QSO using these buttons from left to right (but please don't!). Notice that at the right are\
 | 
			
		||||
two spare buttons you can set as you wish, and then a button labelled '1'. Yes, this is the first set of FOUR sets of Macros,\
 | 
			
		||||
and you can access the others using this button, which changes to read '2', '3', '4' then '1' again (right-click to go backwards),\
 | 
			
		||||
or by pressing <<B>Alt</B>> and the corresponding number (1-4, not F1-F4) at the same time.\
 | 
			
		||||
<P>\
 | 
			
		||||
If you REALLY mess up the Macros and can't see how to fix them, just close the program without saving them, and reopen it.\
 | 
			
		||||
</BLOCKQUOTE>\
 | 
			
		||||
<H3><I>CONTROLS</I></H3>\
 | 
			
		||||
<BLOCKQUOTE>\
 | 
			
		||||
The line of buttons under the waterfall is used to control the program (as opposed to the QSO). If you hover the mouse over\
 | 
			
		||||
these buttons, you'll see a little yellow hint box appear which tells you what each button does.\
 | 
			
		||||
<P>\
 | 
			
		||||
The <B>Id?</B> button turns on the receive\
 | 
			
		||||
RSID (automatic mode detection and tuning) feature. When in use, the button turns yellow and no text reception is possible until\
 | 
			
		||||
a signal is identified, or the feature is turned off again. If you plan to use the RSID feature on receive,\
 | 
			
		||||
you must leave the 'Start New Modem at Sweet Spot' item in the Menu Configure/Defaults/Mics tab unchecked.\
 | 
			
		||||
<P>\
 | 
			
		||||
The next three buttons control waterfall behaviour. The first switches between Waterfall and FFT modes; the next sets the scale\
 | 
			
		||||
zoom factor (visible display width, x1, x2 or x4); the third selects the waterfall speed. NORM or SLOW setting is best unless\
 | 
			
		||||
you have a very fast computer.\
 | 
			
		||||
<P>\
 | 
			
		||||
The next three buttons move the waterfall left and right, followed by two (either side of a number, the audio frequency in Hz)\
 | 
			
		||||
which control the receiving frequency (they move the red cursor lines).\
 | 
			
		||||
<P>\
 | 
			
		||||
You can also adjust the signal level over which the waterfall works. The default range is from 0dB downwards 70dB (i.e. to -70dB).\
 | 
			
		||||
Both of these values can be adjusted to suit your sound card and receiver audio level.\
 | 
			
		||||
<P>\
 | 
			
		||||
The <B>M</B> button allows you to store or recall the current frequency (see the <A HREF=\"http://www.w1hkj.com/FldigiHelp/index.html\">Online Documentation</A> for details). The <B>Lk</B> button locks the transmit frequency (fixes the red cursors), and the <B>Rv</B> button turns\
 | 
			
		||||
the signal decoding upside down (some modes are sideband sensitive, and if they are the wrong way up, can't be received\
 | 
			
		||||
correctly). Remember to turn this one off when you're done, or you won't receive anything! If every signal you hear is upside\
 | 
			
		||||
down, check your transceiver sideband setting.\
 | 
			
		||||
<P>\
 | 
			
		||||
The <B>T/R</B> button forces the transmitter on or off - use this with care, as it will stop transmission immediately,\
 | 
			
		||||
losing whatever is in the buffer (what you have typed in the Transmit pane), or start it immediately, even if nothing is ready to transmit.\
 | 
			
		||||
<P>\
 | 
			
		||||
There are two further controls in the bottom right corner of the program, to the right of the Status line:\
 | 
			
		||||
</BLOCKQUOTE>\
 | 
			
		||||
<DL><DT><B>Afc</B> - The AFC control</DT>\
 | 
			
		||||
<DD>When this button is pressed, an indicator on the button turns yellow, and the program will automatically retune to drifting signals.\
 | 
			
		||||
When the button is again pressed, AFC is off, and the tuning will stay where you leave it.</DD>\
 | 
			
		||||
<DT><B>Sql</B> - The Squelch control</DT>\
 | 
			
		||||
<DD>When off (no coloured indicator on the button, the receiver displays all 'text' received, even if there is no signal present,\
 | 
			
		||||
and the receiver is simply attempting to decode noise. When activated by pressing the button, the indicator turns yellow.\
 | 
			
		||||
If the incoming signal strength exceeds that set by the adjacent slider control (above the <B>Sql</B> button), the indicator\
 | 
			
		||||
turns green and the incoming signal is decoded and printed. The signal strength is indicated on the green bar beside the\
 | 
			
		||||
Squelch level slider. If nothing seems to be printing, the first thing to do is check the Squelch!</DD>\
 | 
			
		||||
</DL>\
 | 
			
		||||
</BLOCKQUOTE>\
 | 
			
		||||
<H3><I>STATUS Line</I></H3>\
 | 
			
		||||
<BLOCKQUOTE>\
 | 
			
		||||
At the very bottom line of the FLDIGI window is a row of useful information. At the left is the current operating mode. Next (some modes)\
 | 
			
		||||
is the measured signal-to-noise ratio at the receiver, and (in some modes) the measured signal intermodulation level (IMD).\
 | 
			
		||||
<P>\
 | 
			
		||||
The larger central box shows (in DominoEX and THOR modes) the received 'Secondary Text'. This is information (such as\
 | 
			
		||||
station identification) which is transmitted automatically whenever the transmitter has completed all user text that is\
 | 
			
		||||
available to send. It is transmitted using special characters, and is automatically directed to this special window. Secondary text\
 | 
			
		||||
you transmit is also shown here. This box changes size when you enlarge the program window.\
 | 
			
		||||
</BLOCKQUOTE>\
 | 
			
		||||
<A NAME=\"Oper\">\
 | 
			
		||||
<HR>\
 | 
			
		||||
<H2>Operating</H2>\
 | 
			
		||||
<H3><I>Procedure</I></H3>\
 | 
			
		||||
<BLOCKQUOTE>\
 | 
			
		||||
Operating procedure for digital modes is similar to that for Morse. Some of the same abbreviations are used. For example, at the beginning\
 | 
			
		||||
of an over, you might send 'VK3XYZ de WB8ABC' or just 'RR Jack' and so on. At the end of an over, it is usual to send 'ZL1ABC de AA3AR K',\
 | 
			
		||||
and at the end of a QSO '73 F3XYZ de 3D2ZZ SK'. When operating in a group or net it is usual to sign 'AA3AE es gp de ZK8WW K'.\
 | 
			
		||||
<P>\
 | 
			
		||||
It is also considered a courtesy to send a blank line or two (press <<B>Enter</B>>)\
 | 
			
		||||
before any text at the start of an over, and following the last text at the end of an over. You can also place these in the macros.\
 | 
			
		||||
The purpose is to separate your text from the previous text, and especially from any rubbish that was printed between overs.\
 | 
			
		||||
<P>\
 | 
			
		||||
FLDIGI does all of this for you. The Function Keys are set up to provide these start and end of over facilities, and can be edited\
 | 
			
		||||
to suit your preferences. In\
 | 
			
		||||
order that the other station's callsign can appear when these keys are used, you need to set the other station's callsign in the log\
 | 
			
		||||
data - it does not matter if you use the log facility or not.\
 | 
			
		||||
<DL>\
 | 
			
		||||
<DT><B>Hint:</B> Some Function Key Macro buttons have graphic symbols on them which imply the following:<BR>\
 | 
			
		||||
<DD><B>>></B>  The transmitter comes on and stays on when you use this button/macro.\
 | 
			
		||||
<DD><B>||</B>   The transmitter goes off when the text from this button/macro has been sent.\
 | 
			
		||||
<DD><B>>|</B>  The transmitter comes on, sends the text from this button/macro, and goes off when the text from this button/macro has been sent.\
 | 
			
		||||
</DL>\
 | 
			
		||||
\
 | 
			
		||||
The Macros are set up to control the transmitter as necessary, but you can also switch the transmitter on at the start of an over with <<B>Ctrl</B>>\
 | 
			
		||||
and <B>T</B> or the <B>TX</B> macro button, and off again with <<B>Ctrl</B>> and <B>R</B> or the <B>RX</B> macro button. If you\
 | 
			
		||||
have Macros copied into or text already typed in the Transmit pane when you start the transmitter, this is sent first.\
 | 
			
		||||
<P>\
 | 
			
		||||
Calling another station you have tuned in is as simple as pushing a button. Put his callsign into the log data (right click, select Call)\
 | 
			
		||||
and press the <B>ANS</B> Macro button (or <B>F2</B>) when you are ready. If he replies, you are in business! Then press <B>QSO</B> (<B>F3</B>)\
 | 
			
		||||
to start each over, and <B>BTU</B> (<B>F4</B>) to end it, and <B>SK</B> (<B>F5</B>) to sign off.\
 | 
			
		||||
<DL>\
 | 
			
		||||
<DT><B>Hint:</B> When typing text, the correct use of upper and lower case is important:<BR>\
 | 
			
		||||
<DD><LI>Modes such as RTTY and THROB have no lower case capability.\
 | 
			
		||||
<DD><LI>In most other modes, excessive use of upper case is considered impolite, like SHOUTING!\
 | 
			
		||||
<DD><LI>Modes such as PSK31, MFSK16, DominoEX and THOR use character sets which are optimized for lower case.\
 | 
			
		||||
You should use lower case as much as possible in these modes to achieve maximum text speed. In these modes upper case\
 | 
			
		||||
characters are noticeably slower to send and also slightly more prone to errors.\
 | 
			
		||||
</DL>\
 | 
			
		||||
</BLOCKQUOTE>\
 | 
			
		||||
<H3><I>Adjustment</I></H3>\
 | 
			
		||||
<BLOCKQUOTE>\
 | 
			
		||||
Most digital modes do not require much transmitter power, as the receiver software is very sensitive. Many modes (PSK31, THROB,\
 | 
			
		||||
MT63) also require very high transmitter linearity, which is another reason to keep transmitter power below 30% of maximum.\
 | 
			
		||||
Some modes (Hellschreiber, Morse) have high peak power output, which may not indicate well on the conventional power meter,\
 | 
			
		||||
another reason to keep the average transmitted power low to prevent a very broad signal being transmitted.\
 | 
			
		||||
<P>\
 | 
			
		||||
Adjust the transmitter output power using the <B>TUNE</B> button, top right, beyond the Menu. The output will be the same as the peak\
 | 
			
		||||
power in other modes. Adjust the master Volume applet Wave Out and Master Volume controls to achieve the appropriate power.\
 | 
			
		||||
Use of excessive drive will result in distortion (signal difficult to tune in, and often poorer reception) and a very broad signal.\
 | 
			
		||||
<P>Some multi-carrier modes (MT63 for example) may require individual adjustment as the average power may be rather low.\
 | 
			
		||||
<DL>\
 | 
			
		||||
<DT><B>Hint:</B> Where possible, use the area above 1200Hz on the waterfall.\
 | 
			
		||||
<DD><LI>Below 1200Hz the second harmonic of the transmitted audio will pass through the transmitter filters.\
 | 
			
		||||
<DD><LI>When using lower frequency tones, adjust the transmitter and audio level with great\
 | 
			
		||||
care, as the second (and even third) harmonic will appear in the transmitter passband, causing excessive signal width.\
 | 
			
		||||
<DD><LI>A narrow (CW) filter in the rig is no help in this regard, as it is only used on receive. When you do use a narrow filter, this will restrict the area over which the receiver and transmitter will operate (without retuning of course). Try adjusting the passband tuning (if available).\
 | 
			
		||||
<DD><LI>Keep the sound card audio level to a minimum and set the transmitter gain to a similar level used for SSB.\
 | 
			
		||||
</DL>\
 | 
			
		||||
</BLOCKQUOTE>\
 | 
			
		||||
<H3><I>Waterfall Tuning</I></H3>\
 | 
			
		||||
<BLOCKQUOTE>\
 | 
			
		||||
When using this program, as with most other digital modes programs, tuning is generally accomplished by leaving the\
 | 
			
		||||
transceiver VFO at a popular spot (for example 14.070MHz, USB), and performing all the 'tuning' by moving around within\
 | 
			
		||||
the software.\
 | 
			
		||||
<P>\
 | 
			
		||||
The FLDIGI software has a second 'VFO' which is tuned by clicking on the waterfall. On a busy band, you\
 | 
			
		||||
may see many signals at the same time (especially with PSK31 or Morse), and so you can click with the mouse on\
 | 
			
		||||
any one of these signals to tune it in, receive it, and if the opportunity allows, reply to the station.\
 | 
			
		||||
<P>\
 | 
			
		||||
The software 'VFO' operates in a transceive mode, so the transmitter signal is automatically and exactly tuned to the\
 | 
			
		||||
received frequency. If you click correctly on the signal, your reply will always be in tune with the other station.\
 | 
			
		||||
<DL>\
 | 
			
		||||
<DT><B>Hint:</B> You <B>MUST NOT</B> use RIT (Clarifier) when using digital modes.\
 | 
			
		||||
<DD><LI>With RIT on, you will probably have to retune after every over.\
 | 
			
		||||
<DD><LI>Use of the RIT will also cause the other station to change frequency, and you will chase each other\
 | 
			
		||||
across the band.\
 | 
			
		||||
<DD><LI>Older transceivers without digital synthesis may have an unwanted offset (frequency difference)\
 | 
			
		||||
between transmit and receive frequencies. Such rigs should not be used for digital modes.\
 | 
			
		||||
</DL>\
 | 
			
		||||
Wider digital modes (MT63, Olivia) can be tuned using the rig if necessary, as tuning is not at all critical.\
 | 
			
		||||
The software tuning still operates, but because the signal is so wide, there is limited ability to move\
 | 
			
		||||
around in the waterfall tuning.\
 | 
			
		||||
</BLOCKQUOTE>\
 | 
			
		||||
<A NAME=\"Keys\">\
 | 
			
		||||
<H3><I>Special Keys</I></H3>\
 | 
			
		||||
<BLOCKQUOTE>\
 | 
			
		||||
Several special keyboard controls are provided to make operating easier.\
 | 
			
		||||
</BLOCKQUOTE>\
 | 
			
		||||
<DL><DT><B>Pause Transmission</B></DT>\
 | 
			
		||||
<DD>\
 | 
			
		||||
Press <<B>Pause/Break</B>> while in receive, and the program will switch to transmit mode. It will continue\
 | 
			
		||||
with the text in the transmit buffer (the Transmit pane text) from the current point, i.e. where the red (previously sent) text ends and\
 | 
			
		||||
the black (yet to be sent) text begins. If the buffer only contains unsent text, then it will begin at the first\
 | 
			
		||||
character in the buffer.  If the buffer is empty, the program will switch to transmit mode, and depending on the\
 | 
			
		||||
mode of operation, will send idle characters or nothing at all until characters are entered into the buffer. \
 | 
			
		||||
<P>\
 | 
			
		||||
If you press <<B>Pause/Break</B>> while in transmit mode, the program will return to receive mode. There\
 | 
			
		||||
may be a slight delay for some modes like MFSK, PSK and others, that requires the transmitter to send a postamble\
 | 
			
		||||
at the end of a transmission.  The transmit text buffer stays intact, ready for the <<B>Pause/Break</B>>\
 | 
			
		||||
key to return you to the transmit mode .\
 | 
			
		||||
<P>\
 | 
			
		||||
Pressing <<B>Alt/Meta</B>> and <B>R</B> has the same effect as <<B>Pause/Break</B>>.\
 | 
			
		||||
You could think of the <<B>Pause/Break</B>> key as a software break-in capability.</DD>\
 | 
			
		||||
<P>\
 | 
			
		||||
<DT><B>ESCAPE</B></DT>\
 | 
			
		||||
<DD>\
 | 
			
		||||
Pressing <<B>Esc</B>> while transmitting will abort the transmission. Transmission stops as soon as possible,\
 | 
			
		||||
(any necessary postamble is sent), and the program returns to receive. Any unsent text in the transmit\
 | 
			
		||||
buffer will be lost.\
 | 
			
		||||
<P>\
 | 
			
		||||
If you press <<B>Esc</B>> <<B>Esc</B>> (i.e. twice in quick succession),\
 | 
			
		||||
transmission stops immediately, (without sending any postamble), and the program returns to receive. Any unsent\
 | 
			
		||||
text in the transmit buffer will be lost. Use this feature as an <FONT COLOR=RED><B>EMERGENCY STOP</B></FONT>.\
 | 
			
		||||
<P>\
 | 
			
		||||
<DT><B>RETURN to Receive</B></DT>\
 | 
			
		||||
<DD>Press <<B>Ctrl</B>> and <B>R</B> to insert the <B>^r</B> command in the transmit buffer at the current typing\
 | 
			
		||||
point. When transmission reaches this point, transmission will stop. The transmission does not stop immediately.\
 | 
			
		||||
<P>\
 | 
			
		||||
<DT><B>START Transmission</B></DT>\
 | 
			
		||||
<DD>Press <<B>Ctrl</B>> and <B>T</B> to start transmission if there is text ready in the transmit buffer.\
 | 
			
		||||
</DD><P>\
 | 
			
		||||
<P>\
 | 
			
		||||
<DT><B>MOVE Typing Cursor</B></DT>\
 | 
			
		||||
<DD>Press <<B>Tab</B>> to move the cursor (typing insertion point) to the end of the transmit buffer.\
 | 
			
		||||
This will also pause transmission. A <<B>Tab</B>> press at that position moves the cursor back to the\
 | 
			
		||||
character following the last one transmitted. Morse operation is slightly different. See the on-line help for\
 | 
			
		||||
<A HREF=\"http://www.w1hkj.com/FldigiHelp/CW.html\">CW</A>. \
 | 
			
		||||
</DD><P>\
 | 
			
		||||
<P>\
 | 
			
		||||
<DT><B>SEND any ASCII character</B></DT>\
 | 
			
		||||
<DD>Press <<B>Ctl</B>> and (at the same time) any three-digit number (on the numeric keypad) to\
 | 
			
		||||
insert the ASCII character designated by that entry value into the transmit buffer. For example,\
 | 
			
		||||
<<B>Ctl</B>><B>177</B> is '±' and <<B>Ctl</B>><B>176</B> is '°' (degree).\
 | 
			
		||||
</DL>\
 | 
			
		||||
<HR>\
 | 
			
		||||
<SMALL><CENTER><b>Copyright © M. Greenman</a> 2008</b.</SMALL>\
 | 
			
		||||
</CENTER>\
 | 
			
		||||
\
 | 
			
		||||
</BODY>\
 | 
			
		||||
</HTML>\
 | 
			
		||||
<html><body></body></html>\
 | 
			
		||||
";
 | 
			
		||||
 | 
			
		||||
char szAbout[] =
 | 
			
		||||
"<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\
 | 
			
		||||
<html>\
 | 
			
		||||
<head>\
 | 
			
		||||
  <title>about</title>\
 | 
			
		||||
</head>\
 | 
			
		||||
<BODY BGCOLOR=FFFFCO TEXT=101010>\
 | 
			
		||||
<font size=\"0\" face=\"Verdana, Arial, Helvetica\">\
 | 
			
		||||
<CENTER>\
 | 
			
		||||
<H1><I>Fldigi</I></H1>\
 | 
			
		||||
<br>\
 | 
			
		||||
</CENTER>\
 | 
			
		||||
<H4>Digital modem program for</H4><br>\
 | 
			
		||||
<P>\
 | 
			
		||||
     Linux<br>\
 | 
			
		||||
     Free-BSD<br>\
 | 
			
		||||
     OS-X<br>\
 | 
			
		||||
     Windows (XP)<br>\
 | 
			
		||||
<br>\
 | 
			
		||||
<H4>Authors:</H4><br>\
 | 
			
		||||
<P>\
 | 
			
		||||
     Dave Freese, W1HKJ<br>\
 | 
			
		||||
     Stelios Buonanos, M0GLD<br>\
 | 
			
		||||
     Leigh Klotz, WA5ZNU<br>\
 | 
			
		||||
<br>\
 | 
			
		||||
<H4>Beginners Help:</H4><br>\
 | 
			
		||||
<P>\
 | 
			
		||||
     M. Greenman, ZL1BPU<br>\
 | 
			
		||||
</big>\
 | 
			
		||||
</body>\
 | 
			
		||||
</html>\
 | 
			
		||||
";
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -467,7 +467,7 @@ int feld::tx_process()
 | 
			
		|||
	int c;
 | 
			
		||||
	bool hdkey;
 | 
			
		||||
 | 
			
		||||
	dxmode = 1 + progdefaults.HellXmtWidth;
 | 
			
		||||
	dxmode = progdefaults.HellXmtWidth;
 | 
			
		||||
	hdkey = progdefaults.HellPulseFast;
 | 
			
		||||
 | 
			
		||||
	fntnbr = progdefaults.feldfontnbr;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -85,7 +85,7 @@ void fftfilt::create_filter(double f1, double f2)
 | 
			
		|||
/*
 | 
			
		||||
 * Filter with fast convolution (overlap-add algorithm).
 | 
			
		||||
 */
 | 
			
		||||
int fftfilt::run(complex in, complex **out)
 | 
			
		||||
int fftfilt::run(const complex& in, complex **out)
 | 
			
		||||
{
 | 
			
		||||
// collect filterlen/2 input samples
 | 
			
		||||
	filtdata[inptr++] = in;
 | 
			
		||||
| 
						 | 
				
			
			@ -103,7 +103,7 @@ int fftfilt::run(complex in, complex **out)
 | 
			
		|||
 | 
			
		||||
// multiply with the filter shape
 | 
			
		||||
	for (int i = 0; i < filterlen; i++)
 | 
			
		||||
		filtdata[i] = filtdata[i] * filter[i];
 | 
			
		||||
		filtdata[i] *= filter[i];
 | 
			
		||||
 | 
			
		||||
// IFFT transpose back to the time domain
 | 
			
		||||
	ift->icdft(filtdata);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -432,7 +432,7 @@ sfft::~sfft()
 | 
			
		|||
// Values are not stable until more than "len" samples have been processed.
 | 
			
		||||
// returns address of first component in array
 | 
			
		||||
 | 
			
		||||
complex *sfft::run(complex input)
 | 
			
		||||
complex *sfft::run(const complex& input)
 | 
			
		||||
{
 | 
			
		||||
	complex z;
 | 
			
		||||
	complex y;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -330,6 +330,9 @@ protected:
 | 
			
		|||
	int			txpos;
 | 
			
		||||
	static int		*ptxpos;
 | 
			
		||||
	int			bkspaces;
 | 
			
		||||
	char		ascii_cnt;
 | 
			
		||||
	unsigned	ascii_chr;
 | 
			
		||||
	
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,56 +11,66 @@ class complex {
 | 
			
		|||
public:
 | 
			
		||||
	double re;
 | 
			
		||||
	double im;
 | 
			
		||||
	complex(double r = 0.0, double i = 0.0) {
 | 
			
		||||
		re = r;
 | 
			
		||||
		im = i;
 | 
			
		||||
	}
 | 
			
		||||
	~complex() {};
 | 
			
		||||
	complex(double r = 0.0, double i = 0.0)
 | 
			
		||||
	    : re(r), im(i) { }
 | 
			
		||||
 | 
			
		||||
	double real() { return re; };
 | 
			
		||||
	void real(double R) {re = R;};
 | 
			
		||||
	double imag() { return im; };
 | 
			
		||||
	void imag(double I) {im = I;};
 | 
			
		||||
 | 
			
		||||
// Z = X * Y
 | 
			
		||||
	complex operator* (complex y) {
 | 
			
		||||
		complex z;
 | 
			
		||||
		z.re = re * y.re - im * y.im;
 | 
			
		||||
		z.im = re * y.im + im * y.re;
 | 
			
		||||
		return z;
 | 
			
		||||
	complex& operator*=(const complex& y) {
 | 
			
		||||
		re = re * y.re - im * y.im;
 | 
			
		||||
		im = re * y.im + im * y.re;
 | 
			
		||||
		return *this;
 | 
			
		||||
	}
 | 
			
		||||
	complex operator*(const complex& y) const {
 | 
			
		||||
		return complex(re * y.re - im * y.im,  re * y.im + im * y.re);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
// Z = X * y
 | 
			
		||||
	complex operator* (double y) {
 | 
			
		||||
		complex z;
 | 
			
		||||
		z.re = y * z.re;
 | 
			
		||||
		z.im = y * z.im;
 | 
			
		||||
		return z;
 | 
			
		||||
	complex& operator*=(double y) {
 | 
			
		||||
		re *= y;
 | 
			
		||||
		im *= y;
 | 
			
		||||
		return *this;
 | 
			
		||||
	}
 | 
			
		||||
	complex operator*(double y) const {
 | 
			
		||||
		return complex(re * y, im * y);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
// Z = X + Y
 | 
			
		||||
	complex operator+ (complex y) {
 | 
			
		||||
		complex z;
 | 
			
		||||
		z.re = re + y.re;
 | 
			
		||||
		z.im = im + y.im;
 | 
			
		||||
		return z;
 | 
			
		||||
	complex& operator+=(const complex& y) {
 | 
			
		||||
		re += y.re;
 | 
			
		||||
		im += y.im;
 | 
			
		||||
		return *this;
 | 
			
		||||
        }
 | 
			
		||||
	complex operator+(const complex& y) const {
 | 
			
		||||
		return complex(re + y.re,  im + y.im);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
// Z = X - Y
 | 
			
		||||
	complex operator- (complex y) {
 | 
			
		||||
		complex z;
 | 
			
		||||
		z.re = re - y.re;
 | 
			
		||||
		z.im = im - y.im;
 | 
			
		||||
		return z;
 | 
			
		||||
	complex& operator-=(const complex& y) {
 | 
			
		||||
		re -= y.re;
 | 
			
		||||
		im -= y.im;
 | 
			
		||||
		return *this;
 | 
			
		||||
	}
 | 
			
		||||
	complex operator-(const complex& y) const {
 | 
			
		||||
		return complex(re - y.re,  im - y.im);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
// Z = X / Y
 | 
			
		||||
	complex operator/ (complex y) {
 | 
			
		||||
	complex& operator/=(const complex& y) {
 | 
			
		||||
		double denom = y.re*y.re + y.im*y.im;
 | 
			
		||||
		if (denom == 0.0) denom = 1e-10;
 | 
			
		||||
		complex z;
 | 
			
		||||
		z.re = (re * y.re + im * y.im) / denom;
 | 
			
		||||
		z.im = (im * y.re - re * y.im) / denom;
 | 
			
		||||
		return z;
 | 
			
		||||
		re = (re * y.re + im * y.im) / denom;
 | 
			
		||||
		im = (im * y.re - re * y.im) / denom;
 | 
			
		||||
		return *this;
 | 
			
		||||
	}
 | 
			
		||||
	complex operator/(const complex& y) const {
 | 
			
		||||
		double denom = y.re*y.re + y.im*y.im;
 | 
			
		||||
		if (denom == 0.0) denom = 1e-10;
 | 
			
		||||
		return complex((re * y.re + im * y.im) / denom,  (im * y.re - re * y.im) / denom);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
// Z = (complex conjugate of X) * Y
 | 
			
		||||
| 
						 | 
				
			
			@ -68,7 +78,12 @@ public:
 | 
			
		|||
// Z2 = x2 + jy2, or Z2 = |Z2|exp(jP2)
 | 
			
		||||
// Z = (x1 - jy1) * (x2 + jy2)
 | 
			
		||||
// or Z = |Z1|*|Z2| exp (j (P2 - P1))
 | 
			
		||||
	complex operator% (complex y) {
 | 
			
		||||
	complex& operator%=(const complex& y) {
 | 
			
		||||
		re = re * y.re + im * y.im;
 | 
			
		||||
		im = re * y.im - im * y.re;
 | 
			
		||||
		return *this;
 | 
			
		||||
	}
 | 
			
		||||
	complex operator%(const complex& y) const {
 | 
			
		||||
		complex z;
 | 
			
		||||
		z.re = re * y.re + im * y.im;
 | 
			
		||||
		z.im = re * y.im - im * y.re;
 | 
			
		||||
| 
						 | 
				
			
			@ -76,29 +91,29 @@ public:
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
// n = |Z| * |Z| 	
 | 
			
		||||
	double norm() {
 | 
			
		||||
	double norm() const {
 | 
			
		||||
		return (re * re + im * im);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
// n = |Z|
 | 
			
		||||
	double mag() {
 | 
			
		||||
	double mag() const {
 | 
			
		||||
		return sqrt(norm());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
// Z = x + jy
 | 
			
		||||
// Z = |Z|exp(jP)
 | 
			
		||||
// arg returns P
 | 
			
		||||
	double arg() {
 | 
			
		||||
	double arg() const {
 | 
			
		||||
		return atan2(im, re);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
inline 	complex cmac (complex *a, complex *b, int ptr, int len) {
 | 
			
		||||
inline 	complex cmac (const complex *a, const complex *b, int ptr, int len) {
 | 
			
		||||
		complex z;
 | 
			
		||||
		ptr = ptr % len;
 | 
			
		||||
		ptr %= len;
 | 
			
		||||
		for (int i = 0; i < len; i++) {
 | 
			
		||||
			z = z + a[i] * b[ptr];
 | 
			
		||||
			z += a[i] * b[ptr];
 | 
			
		||||
			ptr = (ptr + 1) % len;
 | 
			
		||||
		}
 | 
			
		||||
		return z;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -162,6 +162,7 @@ extern Fl_Check_Button *btnBlackboard;
 | 
			
		|||
extern Fl_Check_Button *btnHellFastAttack;
 | 
			
		||||
extern Fl_Check_Button *btnHellSlowAttack;
 | 
			
		||||
extern Fl_Check_Button *btnFeldHellIdle;
 | 
			
		||||
extern Fl_Spinner *valHellXmtWidth;
 | 
			
		||||
extern Fl_Group *tabOlivia;
 | 
			
		||||
extern Fl_Choice *mnuOlivia_Tones;
 | 
			
		||||
extern Fl_Choice *mnuOlivia_Bandwidth;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -73,7 +73,7 @@ struct configuration {
 | 
			
		|||
	double		HELL_BW;
 | 
			
		||||
	bool		HellRcvWidth;
 | 
			
		||||
	bool		HellBlackboard;
 | 
			
		||||
	bool		HellXmtWidth;
 | 
			
		||||
	int			HellXmtWidth;
 | 
			
		||||
	bool		HellXmtIdle;
 | 
			
		||||
	bool		HellPulseFast;
 | 
			
		||||
// OLIVIA
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,7 +25,7 @@ public:
 | 
			
		|||
	fftfilt(double f1, double f2, int len);
 | 
			
		||||
	~fftfilt();
 | 
			
		||||
	void create_filter(double f1, double f2);
 | 
			
		||||
	int run(complex in, complex **out);
 | 
			
		||||
	int run(const complex& in, complex **out);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -131,7 +131,7 @@ private:
 | 
			
		|||
public:
 | 
			
		||||
	sfft(int len, int first, int last);
 | 
			
		||||
	~sfft();
 | 
			
		||||
	complex *run(complex input);
 | 
			
		||||
	complex *run(const complex& input);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,31 @@
 | 
			
		|||
// ----------------------------------------------------------------------------
 | 
			
		||||
//
 | 
			
		||||
//	htmlstrings.h
 | 
			
		||||
//
 | 
			
		||||
// Copyright (C) 2008
 | 
			
		||||
//		Dave Freese, W1HKJ
 | 
			
		||||
//
 | 
			
		||||
// This file is part of fldigi.
 | 
			
		||||
//
 | 
			
		||||
// fldigi is free software; you can redistribute it and/or modify
 | 
			
		||||
// it under the terms of the GNU General Public License as published by
 | 
			
		||||
// the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
// (at your option) any later version.
 | 
			
		||||
//
 | 
			
		||||
// fldigi is distributed in the hope that it will be useful,
 | 
			
		||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
// GNU General Public License for more details.
 | 
			
		||||
//
 | 
			
		||||
// You should have received a copy of the GNU General Public License
 | 
			
		||||
// along with fldigi; if not, write to the Free Software
 | 
			
		||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
// ----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
#ifndef HTMLSTRINGS_H
 | 
			
		||||
#define HTMLSTRINGS_H
 | 
			
		||||
 | 
			
		||||
extern char szBeginner[];
 | 
			
		||||
extern char szAbout[];
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -87,16 +87,16 @@ struct nop
 | 
			
		|||
class qrunner
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
        qrunner(size_t npri_ = 1);
 | 
			
		||||
        qrunner();
 | 
			
		||||
        ~qrunner();
 | 
			
		||||
 | 
			
		||||
        void attach(void);
 | 
			
		||||
        void detach(void);
 | 
			
		||||
 | 
			
		||||
        template <typename F>
 | 
			
		||||
        bool request(const F &f, size_t pri = 0)
 | 
			
		||||
        bool request(const F& f)
 | 
			
		||||
        {
 | 
			
		||||
                if (fifo->push(f, pri)) {
 | 
			
		||||
                if (fifo->push(f)) {
 | 
			
		||||
#ifdef NDEBUG
 | 
			
		||||
                        if (unlikely(write(pfd[1], "", 1) != 1))
 | 
			
		||||
                                throw qexception(errno);
 | 
			
		||||
| 
						 | 
				
			
			@ -113,13 +113,13 @@ public:
 | 
			
		|||
        }
 | 
			
		||||
 | 
			
		||||
        template <typename F>
 | 
			
		||||
        bool request_sync(const F &f, size_t pri = 0)
 | 
			
		||||
        bool request_sync(const F& f)
 | 
			
		||||
        {
 | 
			
		||||
                if (!attached)
 | 
			
		||||
                        return request(f, pri);
 | 
			
		||||
                        return request(f);
 | 
			
		||||
 | 
			
		||||
                for (;;) {
 | 
			
		||||
                        if (request(f, pri))
 | 
			
		||||
                        if (request(f))
 | 
			
		||||
                                break;
 | 
			
		||||
                        sched_yield();
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			@ -128,7 +128,7 @@ public:
 | 
			
		|||
                fsignal s(&m, &c);
 | 
			
		||||
                fl_lock(&m);
 | 
			
		||||
                for (;;) {
 | 
			
		||||
                        if (request(s, pri))
 | 
			
		||||
                        if (request(s))
 | 
			
		||||
                                break;
 | 
			
		||||
                        sched_yield();
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			@ -141,14 +141,12 @@ public:
 | 
			
		|||
        static void execute(int fd, void *arg);
 | 
			
		||||
        void flush(void);
 | 
			
		||||
 | 
			
		||||
        size_t nprio(void) { return fifo->queues(); }
 | 
			
		||||
        void drop(size_t pri) { fifo->drop(pri); }
 | 
			
		||||
        size_t size(size_t pri) { return fifo->size(pri); }
 | 
			
		||||
        void drop(void) { fifo->drop(); }
 | 
			
		||||
        size_t size(void) { return fifo->size(); }
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
        fqueue *fifo;
 | 
			
		||||
        int pfd[2];
 | 
			
		||||
        size_t npri;
 | 
			
		||||
        bool attached;
 | 
			
		||||
public:
 | 
			
		||||
	bool drop_flag;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -137,7 +137,7 @@ protected:
 | 
			
		|||
	unsigned char symbolpair[2];
 | 
			
		||||
	
 | 
			
		||||
private:
 | 
			
		||||
	complex	mixer(int n, complex in);
 | 
			
		||||
	complex	mixer(int n, const complex& in);
 | 
			
		||||
 | 
			
		||||
// Rx
 | 
			
		||||
	void	recvchar(int c);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -135,7 +135,7 @@ int main(int argc, char ** argv)
 | 
			
		|||
	SET_THREAD_ID(FLMAIN_TID);
 | 
			
		||||
 | 
			
		||||
	for (int i = 0; i < NUM_QRUNNER_THREADS; i++) {
 | 
			
		||||
		cbq[i] = new qrunner(1);
 | 
			
		||||
		cbq[i] = new qrunner;
 | 
			
		||||
		cbq[i]->attach();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -78,7 +78,7 @@ configuration progdefaults = {
 | 
			
		|||
	150.0,			// double	HELL_BW;
 | 
			
		||||
	false,			// bool		HellRcvWidth;
 | 
			
		||||
	false,			// bool		HellBlackboard;
 | 
			
		||||
	false,			// bool		HellXmtWidth;
 | 
			
		||||
	1,				// bool		HellXmtWidth;
 | 
			
		||||
	true,			// bool		HellXmtIdle;
 | 
			
		||||
	false,			// bool		HellPulseFast;
 | 
			
		||||
// OLIVIA
 | 
			
		||||
| 
						 | 
				
			
			@ -420,7 +420,7 @@ void configuration::writeDefaultsXML()
 | 
			
		|||
	
 | 
			
		||||
	writeXMLint(f, "FELDFONTNBR", feldfontnbr);
 | 
			
		||||
	writeXMLbool(f, "HELLRCVWIDTH", HellRcvWidth);
 | 
			
		||||
	writeXMLbool(f, "HELLXMTWIDTH", HellXmtWidth);
 | 
			
		||||
	writeXMLint(f, "HELLXMTWIDTH", HellXmtWidth);
 | 
			
		||||
	writeXMLbool(f, "HELLBLACKBOARD", HellBlackboard);
 | 
			
		||||
	writeXMLbool(f, "HELLPULSEFAST", HellPulseFast);
 | 
			
		||||
	writeXMLbool(f, "HELLXMTIDLE", HellXmtIdle);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -53,6 +53,8 @@ void mt63::rx_init()
 | 
			
		|||
	escape = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
double peak = 0.0;
 | 
			
		||||
 | 
			
		||||
int mt63::tx_process()
 | 
			
		||||
{
 | 
			
		||||
	int c;
 | 
			
		||||
| 
						 | 
				
			
			@ -69,6 +71,8 @@ int mt63::tx_process()
 | 
			
		|||
	if (stopflag && flush-- == 0) {
 | 
			
		||||
		stopflag = false;
 | 
			
		||||
		Tx->SendJam();
 | 
			
		||||
		for (int i = 0; i < Tx->Comb.Output.Len; i++)
 | 
			
		||||
			Tx->Comb.Output.Data[i] /= 0.8;
 | 
			
		||||
		ModulateXmtr((Tx->Comb.Output.Data), Tx->Comb.Output.Len);
 | 
			
		||||
		cwid();
 | 
			
		||||
		return -1;	/* we're done */
 | 
			
		||||
| 
						 | 
				
			
			@ -82,10 +86,14 @@ int mt63::tx_process()
 | 
			
		|||
	if (c > 127) {
 | 
			
		||||
		c &= 127;
 | 
			
		||||
		Tx->SendChar(127);
 | 
			
		||||
		for (int i = 0; i < Tx->Comb.Output.Len; i++)
 | 
			
		||||
			Tx->Comb.Output.Data[i] /= 0.8;
 | 
			
		||||
		ModulateXmtr((Tx->Comb.Output.Data), Tx->Comb.Output.Len);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Tx->SendChar(c);
 | 
			
		||||
		for (int i = 0; i < Tx->Comb.Output.Len; i++)
 | 
			
		||||
			Tx->Comb.Output.Data[i] /= 0.8;
 | 
			
		||||
	ModulateXmtr((Tx->Comb.Output.Data), Tx->Comb.Output.Len);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -255,7 +255,7 @@ int olivia::rx_process(const double *buf, int len)
 | 
			
		|||
	
 | 
			
		||||
	double s2n = 20.0 * log10(snr < 0.1 ? 0.1 : snr);
 | 
			
		||||
 | 
			
		||||
	snprintf(msg1, sizeof(msg1), "s/n %4.1f", s2n);//Rx->SignalToNoiseRatio()); 
 | 
			
		||||
	snprintf(msg1, sizeof(msg1), "s/n %4.1f dB", s2n);
 | 
			
		||||
	put_Status1(msg1);
 | 
			
		||||
	snprintf(msg2, sizeof(msg2), "Freq: %+4.1f", Rx->FrequencyOffset());
 | 
			
		||||
	put_Status2(msg2);
 | 
			
		||||
| 
						 | 
				
			
			@ -272,11 +272,10 @@ void olivia::restart()
 | 
			
		|||
	tones	= progdefaults.oliviatones;
 | 
			
		||||
	bw 		= progdefaults.oliviabw;
 | 
			
		||||
	samplerate = 8000;
 | 
			
		||||
//	samplerate = 11025;
 | 
			
		||||
	
 | 
			
		||||
	Tx->Tones = 2 * (1 << tones);
 | 
			
		||||
	Tx->Bandwidth = 125 * (1 << bw);
 | 
			
		||||
	Tx->SampleRate = samplerate; //8000.0; //samplerate;
 | 
			
		||||
	Tx->SampleRate = samplerate;
 | 
			
		||||
	Tx->OutputSampleRate = samplerate;
 | 
			
		||||
    txbasefreq = get_txfreq_woffset();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -300,8 +299,8 @@ void olivia::restart()
 | 
			
		|||
	if (txfbuffer) delete [] txfbuffer;
 | 
			
		||||
	txfbuffer = new double[txbufferlen];
 | 
			
		||||
 | 
			
		||||
	rxbufferlen = 0; //SCBLOCKSIZE;
 | 
			
		||||
	rxbuffer = 0; //new short int[rxbufferlen];
 | 
			
		||||
	rxbufferlen = 0;
 | 
			
		||||
	rxbuffer = 0;
 | 
			
		||||
	
 | 
			
		||||
	Rx->Tones = Tx->Tones;
 | 
			
		||||
	Rx->Bandwidth = Tx->Bandwidth;
 | 
			
		||||
| 
						 | 
				
			
			@ -309,7 +308,7 @@ void olivia::restart()
 | 
			
		|||
	Rx->SyncIntegLen = sinteg;
 | 
			
		||||
	Rx->SyncThreshold = progStatus.sqlonoff ? progStatus.sldrSquelchValue : 0.0;
 | 
			
		||||
 | 
			
		||||
	Rx->SampleRate = samplerate; // 8000.0;//samplerate;
 | 
			
		||||
	Rx->SampleRate = samplerate;
 | 
			
		||||
	Rx->InputSampleRate = samplerate;
 | 
			
		||||
 | 
			
		||||
	if (reverse) { 
 | 
			
		||||
| 
						 | 
				
			
			@ -326,8 +325,6 @@ void olivia::restart()
 | 
			
		|||
	}
 | 
			
		||||
	fragmentsize = 1024;
 | 
			
		||||
	set_bandwidth(Tx->Bandwidth);
 | 
			
		||||
	
 | 
			
		||||
//	Rx->PrintParameters();
 | 
			
		||||
 | 
			
		||||
	put_MODEstatus(mode);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -344,7 +341,6 @@ olivia::olivia()
 | 
			
		|||
	txbuffer = 0;
 | 
			
		||||
	txfbuffer = 0;
 | 
			
		||||
	rxbuffer = 0;
 | 
			
		||||
//	samplerate = 11025;
 | 
			
		||||
	samplerate = 8000;
 | 
			
		||||
 | 
			
		||||
	FL_LOCK();
 | 
			
		||||
| 
						 | 
				
			
			@ -353,7 +349,6 @@ olivia::olivia()
 | 
			
		|||
	FL_UNLOCK();
 | 
			
		||||
 | 
			
		||||
	mode = MODE_OLIVIA;
 | 
			
		||||
//	wfid = new id(this);
 | 
			
		||||
	smargin = progdefaults.oliviasmargin;
 | 
			
		||||
	sinteg = progdefaults.oliviasinteg;
 | 
			
		||||
	lastfreq = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -367,6 +362,5 @@ olivia::~olivia()
 | 
			
		|||
	if (txbuffer) delete [] txbuffer;
 | 
			
		||||
	if (txfbuffer) delete [] txfbuffer;
 | 
			
		||||
	if (rxbuffer) delete [] rxbuffer;
 | 
			
		||||
//	if (wfid) delete wfid;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -58,113 +58,61 @@ class fqueue
 | 
			
		|||
        typedef ringbuffer<char> fqueue_ringbuffer_t;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
        fqueue(size_t count = 2048, size_t nqueues_ = 1, size_t blocksize_ = 128)
 | 
			
		||||
                : nqueues(nqueues_), blocksize(blocksize_)
 | 
			
		||||
        fqueue(size_t count = 2048, size_t blocksize_ = 128)
 | 
			
		||||
                : blocksize(blocksize_)
 | 
			
		||||
        {
 | 
			
		||||
                rb = new fqueue_ringbuffer_t*[nqueues];
 | 
			
		||||
                for (size_t i = 0; i < nqueues; i++)
 | 
			
		||||
                        rb[i] = new fqueue_ringbuffer_t(blocksize * count);
 | 
			
		||||
		rb = new fqueue_ringbuffer_t(blocksize * count);
 | 
			
		||||
        }
 | 
			
		||||
        ~fqueue()
 | 
			
		||||
        {
 | 
			
		||||
                for (size_t i = 0; i < nqueues; i++) {
 | 
			
		||||
                        drop(i);
 | 
			
		||||
                        delete rb[i];
 | 
			
		||||
                }
 | 
			
		||||
                delete [] rb;
 | 
			
		||||
		drop();
 | 
			
		||||
		delete rb;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        bool empty(size_t q)
 | 
			
		||||
        {
 | 
			
		||||
                if (q != nqueues)
 | 
			
		||||
                        return rb[q]->read_space() == 0;
 | 
			
		||||
 | 
			
		||||
                for (size_t i = 0; i < nqueues; i++)
 | 
			
		||||
                        if (rb[i]->read_space() > 0)
 | 
			
		||||
                                return false;
 | 
			
		||||
                return true;
 | 
			
		||||
        }
 | 
			
		||||
        bool empty(void) { return empty(nqueues); }
 | 
			
		||||
 | 
			
		||||
        bool full(size_t q)
 | 
			
		||||
        {
 | 
			
		||||
                if (q != nqueues)
 | 
			
		||||
                        return rb[q]->write_space() == 0;
 | 
			
		||||
 | 
			
		||||
                for (size_t i = 0; i < nqueues; i++)
 | 
			
		||||
                        if (rb[i]->write_space() > 0)
 | 
			
		||||
                                return false;
 | 
			
		||||
                return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        size_t size(size_t q)
 | 
			
		||||
        {
 | 
			
		||||
                if (q != nqueues)
 | 
			
		||||
                        return rb[q]->read_space() / blocksize;
 | 
			
		||||
 | 
			
		||||
                size_t n = 0;
 | 
			
		||||
                for (size_t i = 0; i < nqueues; i++)
 | 
			
		||||
                        n += rb[i]->read_space() / blocksize;
 | 
			
		||||
                return n;
 | 
			
		||||
        }
 | 
			
		||||
        size_t size(void) { return size(nqueues); }
 | 
			
		||||
 | 
			
		||||
        size_t queues(void) { return nqueues; }
 | 
			
		||||
        bool empty(void) { return rb->read_space() == 0; }
 | 
			
		||||
        bool full(void)  { return rb->write_space() == 0; }
 | 
			
		||||
        size_t size(void) { return rb->read_space() / blocksize; }
 | 
			
		||||
 | 
			
		||||
        template <class T>
 | 
			
		||||
        bool push(const T &t, size_t q)
 | 
			
		||||
        bool push(const T& t)
 | 
			
		||||
        {
 | 
			
		||||
                // If we have any space left at all, it will be at least
 | 
			
		||||
                // a blocksize. It will not wrap around the end of the rb.
 | 
			
		||||
                rb[q]->get_wv(wvec);
 | 
			
		||||
                if (unlikely(wvec[0].len < blocksize))
 | 
			
		||||
                if (unlikely(rb->get_wv(wvec, blocksize) < blocksize))
 | 
			
		||||
                        return false;
 | 
			
		||||
 | 
			
		||||
                assert(blocksize >= sizeof(func_wrap<T>));
 | 
			
		||||
                // we assume a no-throw ctor!
 | 
			
		||||
                new (wvec[0].buf) func_wrap<T>(t);
 | 
			
		||||
                rb[q]->write_advance(blocksize);
 | 
			
		||||
                rb->write_advance(blocksize);
 | 
			
		||||
 | 
			
		||||
                return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        bool pop(size_t q, bool exec = false)
 | 
			
		||||
        bool pop(bool exec = false)
 | 
			
		||||
        {
 | 
			
		||||
                size_t start, end;
 | 
			
		||||
                if (q != nqueues) // pull from named queue
 | 
			
		||||
                        start = end = q;
 | 
			
		||||
                else { // pull first available element
 | 
			
		||||
                        start = 0;
 | 
			
		||||
                        end = nqueues - 1;
 | 
			
		||||
                }
 | 
			
		||||
		if (rb->get_rv(rvec, blocksize) < blocksize)
 | 
			
		||||
			return false;
 | 
			
		||||
		reinterpret_cast<func_base *>(rvec[0].buf)->destroy(exec);
 | 
			
		||||
		rb->read_advance(blocksize);
 | 
			
		||||
 | 
			
		||||
                for (size_t i = start; i <= end; i++) {
 | 
			
		||||
                        rb[i]->get_rv(rvec);
 | 
			
		||||
                        if (rvec[0].len < blocksize)
 | 
			
		||||
                                continue;
 | 
			
		||||
                        reinterpret_cast<func_base *>(rvec[0].buf)->destroy(exec);
 | 
			
		||||
                        rb[i]->read_advance(blocksize);
 | 
			
		||||
 | 
			
		||||
                        return true;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                return false;
 | 
			
		||||
		return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        bool execute(void) { return pop(nqueues, true); }
 | 
			
		||||
        bool execute(void) { return pop(true); }
 | 
			
		||||
 | 
			
		||||
        size_t drop(size_t q)
 | 
			
		||||
        size_t drop(void)
 | 
			
		||||
        {
 | 
			
		||||
                size_t n = 0;
 | 
			
		||||
                while (pop(q, false))
 | 
			
		||||
                while (pop(false))
 | 
			
		||||
                        ++n;
 | 
			
		||||
                return n;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
        fqueue_ringbuffer_t **rb;
 | 
			
		||||
        fqueue_ringbuffer_t* rb;
 | 
			
		||||
        fqueue_ringbuffer_t::vector_type rvec[2], wvec[2];
 | 
			
		||||
        size_t nqueues, blocksize;
 | 
			
		||||
        size_t blocksize;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // FQUEUE_H_
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,10 +34,10 @@
 | 
			
		|||
#include "fqueue.h"
 | 
			
		||||
#include "qrunner.h"
 | 
			
		||||
 | 
			
		||||
qrunner::qrunner(size_t npri_)
 | 
			
		||||
        : npri(npri_), attached(false), drop_flag(false)
 | 
			
		||||
qrunner::qrunner()
 | 
			
		||||
        : attached(false), drop_flag(false)
 | 
			
		||||
{
 | 
			
		||||
        fifo = new fqueue(2048, npri);
 | 
			
		||||
        fifo = new fqueue(2048);
 | 
			
		||||
#ifndef __CYGWIN__
 | 
			
		||||
        if (pipe(pfd) == -1)
 | 
			
		||||
#else
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -245,7 +245,7 @@ thor::thor(trx_mode md)
 | 
			
		|||
//=====================================================================
 | 
			
		||||
// rx modules
 | 
			
		||||
 | 
			
		||||
complex thor::mixer(int n, complex in)
 | 
			
		||||
complex thor::mixer(int n, const complex& in)
 | 
			
		||||
{
 | 
			
		||||
	complex z;
 | 
			
		||||
	double f;
 | 
			
		||||
| 
						 | 
				
			
			@ -258,7 +258,7 @@ complex thor::mixer(int n, complex in)
 | 
			
		|||
		f = THORFIRSTIF - THORBASEFREQ - bandwidth/2 + (samplerate / symlen) * (1.0 * n / paths);
 | 
			
		||||
	z.re = cos(phase[n]);
 | 
			
		||||
	z.im = sin(phase[n]);
 | 
			
		||||
	z = z * in;
 | 
			
		||||
	z *= in;
 | 
			
		||||
	phase[n] -= twopi * f / samplerate;
 | 
			
		||||
	if (phase[n] > M_PI)
 | 
			
		||||
		phase[n] -= twopi;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -77,7 +77,6 @@ throb::~throb()
 | 
			
		|||
	if (outbuf) delete[] outbuf;
 | 
			
		||||
	for (int i = 0; i < num_tones; i++)
 | 
			
		||||
		if (rxtone[i]) delete [] rxtone[i];
 | 
			
		||||
//	if (wfid) delete wfid;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void throb::flip_syms() //call this whenever a space or idle is sent or received
 | 
			
		||||
| 
						 | 
				
			
			@ -231,7 +230,6 @@ throb::throb(trx_mode throb_mode) : modem()
 | 
			
		|||
	syncpos = 0.5;
 | 
			
		||||
 | 
			
		||||
	scope_data	= new double [SCOPE_DATA_LEN];
 | 
			
		||||
//	wfid = new id(this);
 | 
			
		||||
	
 | 
			
		||||
	phaseacc = 0.0;
 | 
			
		||||
	metric = 0.0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -626,7 +626,8 @@ void WFdisp::update_waterfall() {
 | 
			
		|||
	RGBI *p3, *p4;
 | 
			
		||||
	p1 = tmp_fft_db + offset;
 | 
			
		||||
	p3 = fft_img;
 | 
			
		||||
	
 | 
			
		||||
	short* limit = tmp_fft_db + image_area - step + 1;
 | 
			
		||||
 | 
			
		||||
	for (int row = 0; row < image_height; row++) {
 | 
			
		||||
		p2 = p1;
 | 
			
		||||
		p4 = p3;
 | 
			
		||||
| 
						 | 
				
			
			@ -635,38 +636,38 @@ void WFdisp::update_waterfall() {
 | 
			
		|||
				for (int col = 0; col < disp_width; col++) {
 | 
			
		||||
					*(p4++) = mag2RGBI[ (*p2+ *(p2+1)+ *(p2+2)+ *(p2+3))/4 ];
 | 
			
		||||
					p2 += step;
 | 
			
		||||
					if (p2 > tmp_fft_db + image_area - step + 1) break;
 | 
			
		||||
					if (p2 > limit) break;
 | 
			
		||||
				}
 | 
			
		||||
			else if (step == 2)
 | 
			
		||||
				for (int col = 0; col < disp_width; col++) {
 | 
			
		||||
					*(p4++) = mag2RGBI[ (*p2  + *(p2+1))/2 ];
 | 
			
		||||
					p2 += step;
 | 
			
		||||
					if (p2 > tmp_fft_db + image_area - step + 1) break;
 | 
			
		||||
					if (p2 > limit) break;
 | 
			
		||||
				}
 | 
			
		||||
			else 
 | 
			
		||||
				for (int col = 0; col < disp_width; col++) {
 | 
			
		||||
					*(p4++) = mag2RGBI[ *p2 ];
 | 
			
		||||
					p2 += step;
 | 
			
		||||
					if (p2 > tmp_fft_db + image_area - step + 1) break;
 | 
			
		||||
					if (p2 > limit) break;
 | 
			
		||||
				}
 | 
			
		||||
		} else {
 | 
			
		||||
			if (step == 4)
 | 
			
		||||
				for (int col = 0; col < disp_width; col++) {
 | 
			
		||||
					*(p4++) = mag2RGBI[ MAX( MAX ( MAX ( *p2, *(p2+1) ), *(p2+2) ), *(p2+3) ) ];
 | 
			
		||||
					p2 += step;
 | 
			
		||||
					if (p2 > tmp_fft_db + image_area - step + 1) break;
 | 
			
		||||
					if (p2 > limit) break;
 | 
			
		||||
				}
 | 
			
		||||
			else if (step == 2)
 | 
			
		||||
				for (int col = 0; col < disp_width; col++) {
 | 
			
		||||
					*(p4++) = mag2RGBI[ MAX( *p2, *(p2+1) ) ];
 | 
			
		||||
					p2 += step;
 | 
			
		||||
					if (p2 > tmp_fft_db + image_area - step + 1) break;
 | 
			
		||||
					if (p2 > limit) break;
 | 
			
		||||
				}
 | 
			
		||||
			else 
 | 
			
		||||
				for (int col = 0; col < disp_width; col++) {
 | 
			
		||||
					*(p4++) = mag2RGBI[ *p2 ];
 | 
			
		||||
					p2 += step;
 | 
			
		||||
					if (p2 > tmp_fft_db + image_area - step + 1) break;
 | 
			
		||||
					if (p2 > limit) break;
 | 
			
		||||
				}
 | 
			
		||||
		}
 | 
			
		||||
		p1 += IMAGE_WIDTH;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -642,6 +642,8 @@ FTextEdit::FTextEdit(int x, int y, int w, int h, const char *l)
 | 
			
		|||
 | 
			
		||||
	context_menu = edit_menu;
 | 
			
		||||
	change_keybindings();
 | 
			
		||||
	ascii_cnt = 0;
 | 
			
		||||
	ascii_chr = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Handles fltk events for this widget.
 | 
			
		||||
| 
						 | 
				
			
			@ -908,12 +910,13 @@ int FTextEdit::handle_key(int key)
 | 
			
		|||
        if (key >= FL_F && key <= FL_F_Last && insert_position() >= txpos)
 | 
			
		||||
            return handle_key_macro(key);
 | 
			
		||||
 | 
			
		||||
        // read A/M-ddd, where d is a digit, as ascii characters (in base 10)
 | 
			
		||||
        // and insert verbatim; e.g. M-001 inserts a <soh>
 | 
			
		||||
        if (Fl::event_state() & FL_CTRL && isdigit(key) &&
 | 
			
		||||
        // read ctl-ddd, where d is a digit, as ascii characters (in base 10)
 | 
			
		||||
        // and insert verbatim; e.g. ctl-001 inserts a <soh>
 | 
			
		||||
        if (Fl::event_state() & FL_CTRL && (key >= FL_KP + '0') && (key <= FL_KP + '9') &&
 | 
			
		||||
            insert_position() >= txpos)
 | 
			
		||||
            return handle_key_ascii(key);
 | 
			
		||||
 | 
			
		||||
		ascii_cnt = 0; // restart the numeric keypad entries.
 | 
			
		||||
		ascii_chr = 0;
 | 
			
		||||
        // do not insert printable characters in the transmitted text
 | 
			
		||||
        if (insert_position() < txpos) {
 | 
			
		||||
            int d;
 | 
			
		||||
| 
						 | 
				
			
			@ -953,16 +956,13 @@ int FTextEdit::handle_key_macro(int key)
 | 
			
		|||
///
 | 
			
		||||
int FTextEdit::handle_key_ascii(int key)
 | 
			
		||||
{
 | 
			
		||||
	static char ascii_cnt = 0;
 | 
			
		||||
	static unsigned ascii_chr = 0;
 | 
			
		||||
 | 
			
		||||
	key -= '0';
 | 
			
		||||
	key -= (FL_KP + '0');
 | 
			
		||||
	ascii_cnt++;
 | 
			
		||||
	for (int i = 0; i < 3 - ascii_cnt; i++)
 | 
			
		||||
		key *= 10;
 | 
			
		||||
	ascii_chr += key;
 | 
			
		||||
	if (ascii_cnt == 3) {
 | 
			
		||||
		if (ascii_chr <= 0x7F)
 | 
			
		||||
		if (ascii_chr < 0x100) //0x7F)
 | 
			
		||||
			add(ascii_chr, (iscntrl(ascii_chr) ? CTRL : RECV));
 | 
			
		||||
		ascii_cnt = ascii_chr = 0;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Ładowanie…
	
		Reference in New Issue