kopia lustrzana https://github.com/jamescoxon/dl-fldigi
CW decoder update
* Cooperative programming effort, W1HKJ and AG1LE * Added matched filter implementation using FFT convolution filter * Added Self Organizing Map decoding. * Added adjustable upper/lower detection levels * Added level indicators on CW digiscope * combined new fft-convolution filter, SOM decoder & FIR filter * added configure controls for filter selection * modified CW digiscope display to show 9 dot intervals independent if WPM setting * increased CW_FIR length to 512pull/2/head
rodzic
92279e7a8d
commit
c7f11f471a
Plik diff jest za duży
Load Diff
|
@ -1101,6 +1101,49 @@ static void cb_sldrCWbandwidth(Fl_Value_Slider2* o, void*) {
|
|||
progdefaults.changed = true;
|
||||
}
|
||||
|
||||
Fl_Value_Output *valCWrcvWPM=(Fl_Value_Output *)0;
|
||||
|
||||
static void cb_valCWrcvWPM(Fl_Value_Output*, void*) {
|
||||
progdefaults.changed = true;
|
||||
}
|
||||
|
||||
Fl_Progress *prgsCWrcvWPM=(Fl_Progress *)0;
|
||||
|
||||
Fl_Check_Button *btnCWuseSOMdecoding=(Fl_Check_Button *)0;
|
||||
|
||||
static void cb_btnCWuseSOMdecoding(Fl_Check_Button* o, void*) {
|
||||
progdefaults.CWuseSOMdecoding = o->value();
|
||||
progdefaults.changed = true;
|
||||
}
|
||||
|
||||
Fl_Counter2 *cntLower=(Fl_Counter2 *)0;
|
||||
|
||||
static void cb_cntLower(Fl_Counter2* o, void*) {
|
||||
progdefaults.CWlower = o->value();
|
||||
progdefaults.changed = true;
|
||||
}
|
||||
|
||||
Fl_Counter2 *cntUpper=(Fl_Counter2 *)0;
|
||||
|
||||
static void cb_cntUpper(Fl_Counter2* o, void*) {
|
||||
progdefaults.CWupper = o->value();
|
||||
progdefaults.changed = true;
|
||||
}
|
||||
|
||||
Fl_Check_Button *btnCWmfilt=(Fl_Check_Button *)0;
|
||||
|
||||
static void cb_btnCWmfilt(Fl_Check_Button* o, void*) {
|
||||
progdefaults.CWmfilt = o->value();
|
||||
progdefaults.changed = true;
|
||||
}
|
||||
|
||||
Fl_Check_Button *btnCWuseFFTfilter=(Fl_Check_Button *)0;
|
||||
|
||||
static void cb_btnCWuseFFTfilter(Fl_Check_Button* o, void*) {
|
||||
progdefaults.CWuse_fft_filter = o->value();
|
||||
progdefaults.changed = true;
|
||||
}
|
||||
|
||||
Fl_Check_Button *btnCWrcvTrack=(Fl_Check_Button *)0;
|
||||
|
||||
static void cb_btnCWrcvTrack(Fl_Check_Button* o, void*) {
|
||||
|
@ -1115,14 +1158,6 @@ static void cb_cntCWrange(Fl_Counter2* o, void*) {
|
|||
progdefaults.changed = true;
|
||||
}
|
||||
|
||||
Fl_Value_Output *valCWrcvWPM=(Fl_Value_Output *)0;
|
||||
|
||||
static void cb_valCWrcvWPM(Fl_Value_Output*, void*) {
|
||||
progdefaults.changed = true;
|
||||
}
|
||||
|
||||
Fl_Progress *prgsCWrcvWPM=(Fl_Progress *)0;
|
||||
|
||||
Fl_Value_Slider2 *sldrCWxmtWPM=(Fl_Value_Slider2 *)0;
|
||||
|
||||
static void cb_sldrCWxmtWPM(Fl_Value_Slider2* o, void*) {
|
||||
|
@ -3396,7 +3431,7 @@ Fl_Double_Window* ConfigureDialog() {
|
|||
o->selection_color((Fl_Color)51);
|
||||
o->labelsize(18);
|
||||
o->align(Fl_Align(FL_ALIGN_CLIP|FL_ALIGN_INSIDE));
|
||||
{ tabsConfigure = new Fl_Tabs(-5, 0, 545, 372);
|
||||
{ tabsConfigure = new Fl_Tabs(-5, 0, 553, 372);
|
||||
tabsConfigure->color(FL_LIGHT1);
|
||||
tabsConfigure->selection_color(FL_LIGHT1);
|
||||
{ tabOperator = new Fl_Group(0, 25, 500, 345, _("Operator"));
|
||||
|
@ -3509,7 +3544,7 @@ Fl_Double_Window* ConfigureDialog() {
|
|||
} // Fl_Group* grpNoise
|
||||
tabOperator->end();
|
||||
} // Fl_Group* tabOperator
|
||||
{ tabUI = new Fl_Group(0, 25, 506, 346, _("UI"));
|
||||
{ tabUI = new Fl_Group(0, 25, 500, 346, _("UI"));
|
||||
tabUI->hide();
|
||||
{ tabsUI = new Fl_Tabs(0, 25, 506, 346);
|
||||
tabsUI->selection_color(FL_LIGHT1);
|
||||
|
@ -4169,13 +4204,12 @@ ab and newline are automatically included."));
|
|||
} // Fl_Tabs* tabsUI
|
||||
tabUI->end();
|
||||
} // Fl_Group* tabUI
|
||||
{ tabWaterfall = new Fl_Group(-2, 25, 501, 347, _("Waterfall"));
|
||||
{ tabWaterfall = new Fl_Group(0, 25, 500, 347, _("Waterfall"));
|
||||
tabWaterfall->hide();
|
||||
{ tabsWaterfall = new Fl_Tabs(-2, 25, 501, 347);
|
||||
tabsWaterfall->color(FL_LIGHT1);
|
||||
tabsWaterfall->selection_color(FL_LIGHT1);
|
||||
{ Fl_Group* o = new Fl_Group(-2, 50, 501, 320, _("Display"));
|
||||
o->hide();
|
||||
{ Fl_Group* o = new Fl_Group(0, 50, 500, 320, _("Display"));
|
||||
{ Fl_Group* o = new Fl_Group(3, 56, 496, 190, _("Colors and cursors"));
|
||||
o->box(FL_ENGRAVED_FRAME);
|
||||
o->align(Fl_Align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE));
|
||||
|
@ -4370,7 +4404,8 @@ ab and newline are automatically included."));
|
|||
} // Fl_Group* o
|
||||
o->end();
|
||||
} // Fl_Group* o
|
||||
{ Fl_Group* o = new Fl_Group(-2, 50, 500, 320, _("FFT Processing"));
|
||||
{ Fl_Group* o = new Fl_Group(0, 50, 500, 320, _("FFT Processing"));
|
||||
o->hide();
|
||||
{ Fl_Group* o = new Fl_Group(3, 62, 490, 135);
|
||||
o->box(FL_ENGRAVED_FRAME);
|
||||
{ Fl_Counter2* o = cntLowFreqCutoff = new Fl_Counter2(48, 72, 70, 20, _("Lower limit"));
|
||||
|
@ -4480,7 +4515,7 @@ an merging"));
|
|||
} // Fl_Group* o
|
||||
o->end();
|
||||
} // Fl_Group* o
|
||||
{ Fl_Group* o = new Fl_Group(-2, 50, 500, 320, _("Mouse"));
|
||||
{ Fl_Group* o = new Fl_Group(0, 50, 500, 320, _("Mouse"));
|
||||
o->hide();
|
||||
{ Fl_Group* o = new Fl_Group(3, 62, 490, 170);
|
||||
o->box(FL_ENGRAVED_FRAME);
|
||||
|
@ -4529,20 +4564,20 @@ an merging"));
|
|||
} // Fl_Tabs* tabsWaterfall
|
||||
tabWaterfall->end();
|
||||
} // Fl_Group* tabWaterfall
|
||||
{ tabModems = new Fl_Group(-5, 25, 545, 347, _("Modems"));
|
||||
{ tabModems = new Fl_Group(0, 25, 500, 347, _("Modems"));
|
||||
tabModems->hide();
|
||||
{ tabsModems = new Fl_Tabs(-5, 25, 545, 347);
|
||||
{ tabsModems = new Fl_Tabs(0, 25, 500, 347);
|
||||
tabsModems->selection_color(FL_LIGHT1);
|
||||
tabsModems->align(Fl_Align(FL_ALIGN_TOP_RIGHT));
|
||||
{ tabCW = new Fl_Group(0, 50, 504, 320, _("CW"));
|
||||
{ tabsCW = new Fl_Tabs(0, 50, 504, 320);
|
||||
{ tabCW = new Fl_Group(0, 50, 500, 320, _("CW"));
|
||||
{ tabsCW = new Fl_Tabs(0, 50, 500, 320);
|
||||
tabsCW->selection_color(FL_LIGHT1);
|
||||
{ Fl_Group* o = new Fl_Group(0, 75, 500, 295, _("General"));
|
||||
o->align(Fl_Align(FL_ALIGN_TOP_LEFT));
|
||||
{ Fl_Group* o = new Fl_Group(5, 85, 490, 130, _("Receive"));
|
||||
o->box(FL_ENGRAVED_FRAME);
|
||||
o->align(Fl_Align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE));
|
||||
{ Fl_Value_Slider2* o = sldrCWbandwidth = new Fl_Value_Slider2(40, 115, 290, 20, _("Filter bandwidth"));
|
||||
{ Fl_Value_Slider2* o = sldrCWbandwidth = new Fl_Value_Slider2(20, 149, 300, 20, _("Filter bandwidth"));
|
||||
sldrCWbandwidth->tooltip(_("CW dsp filter bandwidth"));
|
||||
sldrCWbandwidth->type(1);
|
||||
sldrCWbandwidth->box(FL_DOWN_BOX);
|
||||
|
@ -4553,24 +4588,96 @@ an merging"));
|
|||
sldrCWbandwidth->labelsize(14);
|
||||
sldrCWbandwidth->labelcolor(FL_FOREGROUND_COLOR);
|
||||
sldrCWbandwidth->minimum(10);
|
||||
sldrCWbandwidth->maximum(500);
|
||||
sldrCWbandwidth->step(10);
|
||||
sldrCWbandwidth->value(150);
|
||||
sldrCWbandwidth->maximum(400);
|
||||
sldrCWbandwidth->step(1);
|
||||
sldrCWbandwidth->value(66);
|
||||
sldrCWbandwidth->textsize(14);
|
||||
sldrCWbandwidth->callback((Fl_Callback*)cb_sldrCWbandwidth);
|
||||
sldrCWbandwidth->align(Fl_Align(FL_ALIGN_RIGHT));
|
||||
sldrCWbandwidth->align(Fl_Align(FL_ALIGN_TOP_LEFT));
|
||||
sldrCWbandwidth->when(FL_WHEN_CHANGED);
|
||||
o->value(progdefaults.CWbandwidth);
|
||||
o->labelsize(FL_NORMAL_SIZE); o->textsize(FL_NORMAL_SIZE);
|
||||
} // Fl_Value_Slider2* sldrCWbandwidth
|
||||
{ Fl_Check_Button* o = btnCWrcvTrack = new Fl_Check_Button(40, 150, 80, 20, _("Tracking"));
|
||||
{ valCWrcvWPM = new Fl_Value_Output(20, 188, 35, 20, _("Rx WPM"));
|
||||
valCWrcvWPM->color(FL_BACKGROUND2_COLOR);
|
||||
valCWrcvWPM->callback((Fl_Callback*)cb_valCWrcvWPM);
|
||||
valCWrcvWPM->align(Fl_Align(FL_ALIGN_TOP_LEFT));
|
||||
} // Fl_Value_Output* valCWrcvWPM
|
||||
{ prgsCWrcvWPM = new Fl_Progress(56, 188, 264, 20);
|
||||
prgsCWrcvWPM->tooltip(_("Tracked CW speed in WPM"));
|
||||
prgsCWrcvWPM->color(FL_BACKGROUND_COLOR);
|
||||
prgsCWrcvWPM->selection_color(FL_SELECTION_COLOR);
|
||||
prgsCWrcvWPM->align(Fl_Align(FL_ALIGN_CENTER));
|
||||
} // Fl_Progress* prgsCWrcvWPM
|
||||
{ Fl_Check_Button* o = btnCWuseSOMdecoding = new Fl_Check_Button(16, 108, 125, 20, _("SOM decoding"));
|
||||
btnCWuseSOMdecoding->tooltip(_("Self Organizing Mapping"));
|
||||
btnCWuseSOMdecoding->down_box(FL_DOWN_BOX);
|
||||
btnCWuseSOMdecoding->value(1);
|
||||
btnCWuseSOMdecoding->callback((Fl_Callback*)cb_btnCWuseSOMdecoding);
|
||||
o->value(progdefaults.CWuseSOMdecoding);
|
||||
} // Fl_Check_Button* btnCWuseSOMdecoding
|
||||
{ Fl_Counter2* o = cntLower = new Fl_Counter2(162, 108, 65, 20, _("Lower"));
|
||||
cntLower->tooltip(_("Detector low threshold"));
|
||||
cntLower->type(1);
|
||||
cntLower->box(FL_UP_BOX);
|
||||
cntLower->color(FL_BACKGROUND_COLOR);
|
||||
cntLower->selection_color(FL_INACTIVE_COLOR);
|
||||
cntLower->labeltype(FL_NORMAL_LABEL);
|
||||
cntLower->labelfont(0);
|
||||
cntLower->labelsize(14);
|
||||
cntLower->labelcolor(FL_FOREGROUND_COLOR);
|
||||
cntLower->minimum(0.01);
|
||||
cntLower->maximum(0.99);
|
||||
cntLower->step(0.01);
|
||||
cntLower->value(0.45);
|
||||
cntLower->callback((Fl_Callback*)cb_cntLower);
|
||||
cntLower->align(Fl_Align(FL_ALIGN_TOP));
|
||||
cntLower->when(FL_WHEN_CHANGED);
|
||||
o->value(progdefaults.CWlower);
|
||||
o->labelsize(FL_NORMAL_SIZE);
|
||||
} // Fl_Counter2* cntLower
|
||||
{ Fl_Counter2* o = cntUpper = new Fl_Counter2(255, 108, 65, 20, _("Upper"));
|
||||
cntUpper->tooltip(_("Detector high threshold"));
|
||||
cntUpper->type(1);
|
||||
cntUpper->box(FL_UP_BOX);
|
||||
cntUpper->color(FL_BACKGROUND_COLOR);
|
||||
cntUpper->selection_color(FL_INACTIVE_COLOR);
|
||||
cntUpper->labeltype(FL_NORMAL_LABEL);
|
||||
cntUpper->labelfont(0);
|
||||
cntUpper->labelsize(14);
|
||||
cntUpper->labelcolor(FL_FOREGROUND_COLOR);
|
||||
cntUpper->minimum(0.01);
|
||||
cntUpper->maximum(0.99);
|
||||
cntUpper->step(0.01);
|
||||
cntUpper->value(0.55);
|
||||
cntUpper->callback((Fl_Callback*)cb_cntUpper);
|
||||
cntUpper->align(Fl_Align(FL_ALIGN_TOP));
|
||||
cntUpper->when(FL_WHEN_CHANGED);
|
||||
o->value(progdefaults.CWupper);
|
||||
o->labelsize(FL_NORMAL_SIZE);
|
||||
} // Fl_Counter2* cntUpper
|
||||
{ Fl_Check_Button* o = btnCWmfilt = new Fl_Check_Button(330, 108, 80, 20, _("Matched Filter"));
|
||||
btnCWmfilt->tooltip(_("Matched Filter bandwidth"));
|
||||
btnCWmfilt->down_box(FL_DOWN_BOX);
|
||||
btnCWmfilt->value(1);
|
||||
btnCWmfilt->callback((Fl_Callback*)cb_btnCWmfilt);
|
||||
o->value(progdefaults.CWmfilt);
|
||||
} // Fl_Check_Button* btnCWmfilt
|
||||
{ Fl_Check_Button* o = btnCWuseFFTfilter = new Fl_Check_Button(330, 134, 125, 20, _("FFT filter"));
|
||||
btnCWuseFFTfilter->tooltip(_("FFT / FIR filter"));
|
||||
btnCWuseFFTfilter->down_box(FL_DOWN_BOX);
|
||||
btnCWuseFFTfilter->value(1);
|
||||
btnCWuseFFTfilter->callback((Fl_Callback*)cb_btnCWuseFFTfilter);
|
||||
o->value(progdefaults.CWuse_fft_filter);
|
||||
} // Fl_Check_Button* btnCWuseFFTfilter
|
||||
{ Fl_Check_Button* o = btnCWrcvTrack = new Fl_Check_Button(330, 160, 80, 20, _("Tracking"));
|
||||
btnCWrcvTrack->tooltip(_("Automatic Rx speed tracking"));
|
||||
btnCWrcvTrack->down_box(FL_DOWN_BOX);
|
||||
btnCWrcvTrack->value(1);
|
||||
btnCWrcvTrack->callback((Fl_Callback*)cb_btnCWrcvTrack);
|
||||
o->value(progdefaults.CWtrack);
|
||||
} // Fl_Check_Button* btnCWrcvTrack
|
||||
{ Fl_Counter2* o = cntCWrange = new Fl_Counter2(225, 150, 65, 20, _("Tracking range (WPM)"));
|
||||
{ Fl_Counter2* o = cntCWrange = new Fl_Counter2(330, 187, 65, 20, _("Range, WPM"));
|
||||
cntCWrange->tooltip(_("Range +/- wpm"));
|
||||
cntCWrange->type(1);
|
||||
cntCWrange->box(FL_UP_BOX);
|
||||
|
@ -4590,19 +4697,6 @@ an merging"));
|
|||
o->value(progdefaults.CWrange);
|
||||
o->labelsize(FL_NORMAL_SIZE);
|
||||
} // Fl_Counter2* cntCWrange
|
||||
{ valCWrcvWPM = new Fl_Value_Output(70, 185, 35, 20);
|
||||
valCWrcvWPM->color(FL_BACKGROUND2_COLOR);
|
||||
valCWrcvWPM->callback((Fl_Callback*)cb_valCWrcvWPM);
|
||||
} // Fl_Value_Output* valCWrcvWPM
|
||||
{ prgsCWrcvWPM = new Fl_Progress(105, 185, 250, 20);
|
||||
prgsCWrcvWPM->tooltip(_("Tracked CW speed in WPM"));
|
||||
prgsCWrcvWPM->color(FL_BACKGROUND_COLOR);
|
||||
prgsCWrcvWPM->selection_color(FL_SELECTION_COLOR);
|
||||
prgsCWrcvWPM->align(Fl_Align(FL_ALIGN_CENTER));
|
||||
} // Fl_Progress* prgsCWrcvWPM
|
||||
{ Fl_Box* o = new Fl_Box(360, 185, 70, 20, _("RX WPM"));
|
||||
o->align(Fl_Align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE));
|
||||
} // Fl_Box* o
|
||||
o->end();
|
||||
} // Fl_Group* o
|
||||
{ Fl_Group* o = new Fl_Group(5, 215, 490, 150, _("Transmit"));
|
||||
|
@ -5319,7 +5413,7 @@ an merging"));
|
|||
} // Fl_Group* o
|
||||
tabContestia->end();
|
||||
} // Fl_Group* tabContestia
|
||||
{ tabPSK = new Fl_Group(-4, 50, 521, 322, _("PSK"));
|
||||
{ tabPSK = new Fl_Group(0, 50, 500, 322, _("PSK"));
|
||||
tabPSK->hide();
|
||||
{ tabsPSK = new Fl_Tabs(-4, 50, 521, 322);
|
||||
tabsPSK->selection_color(FL_LIGHT1);
|
||||
|
|
|
@ -132,7 +132,7 @@ static const char szProsigns[] = "~|%|&|+|=|{|}|<|>|[|]| ";} {}
|
|||
xywh {729 57 500 400} type Double color 45 selection_color 51 labelsize 18 align 80 non_modal visible
|
||||
} {
|
||||
Fl_Tabs tabsConfigure {open
|
||||
xywh {-5 0 545 372} color 50 selection_color 50
|
||||
xywh {-5 0 553 372} color 50 selection_color 50
|
||||
} {
|
||||
Fl_Group tabOperator {
|
||||
label Operator
|
||||
|
@ -217,7 +217,7 @@ progdefaults.changed = true;}
|
|||
}
|
||||
Fl_Group tabUI {
|
||||
label UI open
|
||||
xywh {0 25 506 346} hide
|
||||
xywh {0 25 500 346} hide
|
||||
} {
|
||||
Fl_Tabs tabsUI {open
|
||||
xywh {0 25 506 346} selection_color 50
|
||||
|
@ -1019,14 +1019,14 @@ WF_UI();}
|
|||
}
|
||||
Fl_Group tabWaterfall {
|
||||
label Waterfall open
|
||||
xywh {-2 25 501 347} hide
|
||||
xywh {0 25 500 347} hide
|
||||
} {
|
||||
Fl_Tabs tabsWaterfall {open
|
||||
xywh {-2 25 501 347} color 50 selection_color 50
|
||||
} {
|
||||
Fl_Group {} {
|
||||
label Display open
|
||||
xywh {-2 50 501 320} hide
|
||||
xywh {0 50 500 320}
|
||||
} {
|
||||
Fl_Group {} {
|
||||
label {Colors and cursors} open
|
||||
|
@ -1267,7 +1267,7 @@ progdefaults.changed = true;}
|
|||
}
|
||||
Fl_Group {} {
|
||||
label {FFT Processing} open
|
||||
xywh {-2 50 500 320}
|
||||
xywh {0 50 500 320} hide
|
||||
} {
|
||||
Fl_Group {} {open
|
||||
xywh {3 62 490 135} box ENGRAVED_FRAME
|
||||
|
@ -1337,7 +1337,7 @@ progdefaults.changed = true;}
|
|||
}
|
||||
Fl_Group {} {
|
||||
label Mouse open
|
||||
xywh {-2 50 500 320} hide
|
||||
xywh {0 50 500 320} hide
|
||||
} {
|
||||
Fl_Group {} {open
|
||||
xywh {3 62 490 170} box ENGRAVED_FRAME
|
||||
|
@ -1388,17 +1388,17 @@ behaves inside the waterfall} xywh {13 196 150 22} down_box BORDER_BOX align 8
|
|||
}
|
||||
Fl_Group tabModems {
|
||||
label Modems open
|
||||
xywh {-5 25 545 347} hide
|
||||
xywh {0 25 500 347} hide
|
||||
} {
|
||||
Fl_Tabs tabsModems {open
|
||||
xywh {-5 25 545 347} selection_color 50 align 9
|
||||
xywh {0 25 500 347} selection_color 50 align 9
|
||||
} {
|
||||
Fl_Group tabCW {
|
||||
label CW open
|
||||
xywh {0 50 504 320}
|
||||
xywh {0 50 500 320}
|
||||
} {
|
||||
Fl_Tabs tabsCW {open
|
||||
xywh {0 50 504 320} selection_color 50
|
||||
xywh {0 50 500 320} selection_color 50
|
||||
} {
|
||||
Fl_Group {} {
|
||||
label General open
|
||||
|
@ -1412,38 +1412,74 @@ behaves inside the waterfall} xywh {13 196 150 22} down_box BORDER_BOX align 8
|
|||
label {Filter bandwidth}
|
||||
callback {progdefaults.CWbandwidth = (int)o->value();
|
||||
progdefaults.changed = true;}
|
||||
tooltip {CW dsp filter bandwidth} xywh {40 115 290 20} type Horizontal align 8 minimum 10 maximum 500 step 10 value 150 textsize 14
|
||||
tooltip {CW dsp filter bandwidth} xywh {20 149 300 20} type Horizontal align 5 minimum 10 maximum 400 step 1 value 66 textsize 14
|
||||
code0 {o->value(progdefaults.CWbandwidth);}
|
||||
code1 {o->labelsize(FL_NORMAL_SIZE); o->textsize(FL_NORMAL_SIZE);}
|
||||
class Fl_Value_Slider2
|
||||
}
|
||||
Fl_Value_Output valCWrcvWPM {
|
||||
label {Rx WPM}
|
||||
callback {progdefaults.changed = true;}
|
||||
xywh {20 188 35 20} color 7 align 5
|
||||
}
|
||||
Fl_Progress prgsCWrcvWPM {
|
||||
tooltip {Tracked CW speed in WPM} xywh {56 188 264 20} color 49 selection_color 15 align 0
|
||||
}
|
||||
Fl_Check_Button btnCWuseSOMdecoding {
|
||||
label {SOM decoding}
|
||||
callback {progdefaults.CWuseSOMdecoding = o->value();
|
||||
progdefaults.changed = true;}
|
||||
tooltip {Self Organizing Mapping} xywh {16 108 125 20} down_box DOWN_BOX value 1
|
||||
code0 {o->value(progdefaults.CWuseSOMdecoding);}
|
||||
}
|
||||
Fl_Counter cntLower {
|
||||
label Lower
|
||||
callback {progdefaults.CWlower = o->value();
|
||||
progdefaults.changed = true;}
|
||||
tooltip {Detector low threshold} xywh {162 108 65 20} type Simple align 1 minimum 0.01 maximum 0.99 step 0.01 value 0.45
|
||||
code0 {o->value(progdefaults.CWlower);}
|
||||
code1 {o->labelsize(FL_NORMAL_SIZE);}
|
||||
class Fl_Counter2
|
||||
}
|
||||
Fl_Counter cntUpper {
|
||||
label Upper
|
||||
callback {progdefaults.CWupper = o->value();
|
||||
progdefaults.changed = true;}
|
||||
tooltip {Detector high threshold} xywh {255 108 65 20} type Simple align 1 minimum 0.01 maximum 0.99 step 0.01 value 0.55
|
||||
code0 {o->value(progdefaults.CWupper);}
|
||||
code1 {o->labelsize(FL_NORMAL_SIZE);}
|
||||
class Fl_Counter2
|
||||
}
|
||||
Fl_Check_Button btnCWmfilt {
|
||||
label {Matched Filter}
|
||||
callback {progdefaults.CWmfilt = o->value();
|
||||
progdefaults.changed = true;}
|
||||
tooltip {Matched Filter bandwidth} xywh {330 108 80 20} down_box DOWN_BOX value 1
|
||||
code0 {o->value(progdefaults.CWmfilt);}
|
||||
}
|
||||
Fl_Check_Button btnCWuseFFTfilter {
|
||||
label {FFT filter}
|
||||
callback {progdefaults.CWuse_fft_filter = o->value();
|
||||
progdefaults.changed = true;}
|
||||
tooltip {FFT / FIR filter} xywh {330 134 125 20} down_box DOWN_BOX value 1
|
||||
code0 {o->value(progdefaults.CWuse_fft_filter);}
|
||||
}
|
||||
Fl_Check_Button btnCWrcvTrack {
|
||||
label Tracking
|
||||
callback {progdefaults.CWtrack = o->value();
|
||||
progdefaults.changed = true;}
|
||||
tooltip {Automatic Rx speed tracking} xywh {40 150 80 20} down_box DOWN_BOX value 1
|
||||
tooltip {Automatic Rx speed tracking} xywh {330 160 80 20} down_box DOWN_BOX value 1
|
||||
code0 {o->value(progdefaults.CWtrack);}
|
||||
}
|
||||
Fl_Counter cntCWrange {
|
||||
label {Tracking range (WPM)}
|
||||
label {Range, WPM}
|
||||
callback {progdefaults.CWrange = (int)o->value();
|
||||
progdefaults.changed = true;}
|
||||
tooltip {Range +/- wpm} xywh {225 150 65 20} type Simple align 8 minimum 5 maximum 25 step 1 value 10
|
||||
tooltip {Range +/- wpm} xywh {330 187 65 20} type Simple align 8 minimum 5 maximum 25 step 1 value 10
|
||||
code0 {o->value(progdefaults.CWrange);}
|
||||
code1 {o->labelsize(FL_NORMAL_SIZE);}
|
||||
class Fl_Counter2
|
||||
}
|
||||
Fl_Value_Output valCWrcvWPM {
|
||||
callback {progdefaults.changed = true;}
|
||||
xywh {70 185 35 20} color 7
|
||||
}
|
||||
Fl_Progress prgsCWrcvWPM {
|
||||
tooltip {Tracked CW speed in WPM} xywh {105 185 250 20} color 49 selection_color 15 align 0
|
||||
}
|
||||
Fl_Box {} {
|
||||
label {RX WPM}
|
||||
xywh {360 185 70 20} align 20
|
||||
}
|
||||
}
|
||||
Fl_Group {} {
|
||||
label Transmit open
|
||||
|
@ -2123,7 +2159,7 @@ progdefaults.changed = true;}
|
|||
}
|
||||
Fl_Group tabPSK {
|
||||
label PSK open
|
||||
xywh {-4 50 521 322} hide
|
||||
xywh {0 50 500 322} hide
|
||||
} {
|
||||
Fl_Tabs tabsPSK {open
|
||||
xywh {-4 50 521 322} selection_color 50
|
||||
|
|
|
@ -5522,6 +5522,48 @@ void set_zdata(complex *zarray, int len)
|
|||
wf->wfscope->zdata(zarray, len);
|
||||
}
|
||||
|
||||
void set_scope_xaxis_1(double y1)
|
||||
{
|
||||
if (digiscope)
|
||||
digiscope->xaxis_1(y1);
|
||||
wf->wfscope->xaxis_1(y1);
|
||||
}
|
||||
|
||||
void set_scope_xaxis_2(double y2)
|
||||
{
|
||||
if (digiscope)
|
||||
digiscope->xaxis_2(y2);
|
||||
wf->wfscope->xaxis_2(y2);
|
||||
}
|
||||
|
||||
void set_scope_yaxis_1(double x1)
|
||||
{
|
||||
if (digiscope)
|
||||
digiscope->yaxis_1(x1);
|
||||
wf->wfscope->yaxis_1(x1);
|
||||
}
|
||||
|
||||
void set_scope_yaxis_2(double x2)
|
||||
{
|
||||
if (digiscope)
|
||||
digiscope->yaxis_2(x2);
|
||||
wf->wfscope->yaxis_2(x2);
|
||||
}
|
||||
|
||||
void set_scope_clear_axis()
|
||||
{
|
||||
if (digiscope) {
|
||||
digiscope->xaxis_1(0);
|
||||
digiscope->xaxis_2(0);
|
||||
digiscope->yaxis_1(0);
|
||||
digiscope->yaxis_2(0);
|
||||
}
|
||||
wf->wfscope->xaxis_1(0);
|
||||
wf->wfscope->xaxis_2(0);
|
||||
wf->wfscope->yaxis_1(0);
|
||||
wf->wfscope->yaxis_2(0);
|
||||
}
|
||||
|
||||
// raw buffer functions can ONLY be called by FLMAIN_TID
|
||||
|
||||
//======================================================================
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include <config.h>
|
||||
#include <memory.h>
|
||||
|
||||
#include <cmath>
|
||||
#include "misc.h"
|
||||
|
@ -52,10 +53,31 @@ fftfilt::fftfilt(double f1, double f2, int len)
|
|||
ovlbuf[i].re = ovlbuf[i].im = 0.0;
|
||||
|
||||
inptr = 0;
|
||||
|
||||
|
||||
create_filter(f1, f2);
|
||||
}
|
||||
|
||||
fftfilt::fftfilt(double f, int len)
|
||||
{
|
||||
filterlen = len;
|
||||
fft = new Cfft(filterlen);
|
||||
ift = new Cfft(filterlen);
|
||||
|
||||
ovlbuf = new complex[filterlen/2];
|
||||
filter = new complex[filterlen];
|
||||
filtdata = new complex[filterlen];
|
||||
|
||||
for (int i = 0; i < filterlen; i++)
|
||||
filter[i].re = filter[i].im =
|
||||
filtdata[i].re = filtdata[i].im = 0.0;
|
||||
for (int i = 0; i < filterlen/2; i++)
|
||||
ovlbuf[i].re = ovlbuf[i].im = 0.0;
|
||||
|
||||
inptr = 0;
|
||||
|
||||
create_lpf(f);
|
||||
}
|
||||
|
||||
fftfilt::~fftfilt()
|
||||
{
|
||||
if (fft) delete fft;
|
||||
|
@ -75,7 +97,7 @@ void fftfilt::create_filter(double f1, double f2)
|
|||
|
||||
// initialize the filter to zero
|
||||
for (int i = 0; i < filterlen; i++)
|
||||
filter[i].re = filter[i].im = 0.0;
|
||||
filter[i].re = filter[i].im = 0.0;
|
||||
|
||||
// create the filter shape coefficients by fft
|
||||
// filter values initialized to the impulse response h(t)
|
||||
|
@ -99,20 +121,52 @@ void fftfilt::create_filter(double f1, double f2)
|
|||
}
|
||||
|
||||
|
||||
void fftfilt::create_lpf(double f)
|
||||
{
|
||||
int len = filterlen / 2 + 1;
|
||||
double t, h, x, it;
|
||||
Cfft *tmpfft;
|
||||
tmpfft = new Cfft(filterlen);
|
||||
|
||||
// initialize the filter to zero
|
||||
for (int i = 0; i < filterlen; i++)
|
||||
filter[i].re = filter[i].im = 0.0;
|
||||
|
||||
// create the filter shape coefficients by fft
|
||||
// filter values initialized to the impulse response h(t)
|
||||
for (int i = 0; i < len; i++) {
|
||||
it = (double) i;
|
||||
t = it - (len - 1) / 2.0;
|
||||
h = it / (len - 1);
|
||||
|
||||
x = f * sinc(2 * f * t);
|
||||
x *= blackman(h); // windowed by Blackman function
|
||||
x *= filterlen; // scaled for unity in passband
|
||||
filter[i].re = x;
|
||||
}
|
||||
// perform the complex forward fft to obtain H(w)
|
||||
tmpfft->cdft(filter);
|
||||
// start outputs after 2 full passes are complete
|
||||
pass = 2;
|
||||
delete tmpfft;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Filter with fast convolution (overlap-add algorithm).
|
||||
*/
|
||||
int fftfilt::run(const complex& in, complex **out)
|
||||
{
|
||||
// collect filterlen/2 input samples
|
||||
const int filterlen_div2 = filterlen / 2 ;
|
||||
filtdata[inptr++] = in;
|
||||
|
||||
if (inptr < filterlen / 2)
|
||||
if (inptr < filterlen_div2)
|
||||
return 0;
|
||||
if (pass) --pass; // filter output is not stable until 2 passes
|
||||
|
||||
// zero the rest of the input data
|
||||
for (int i = filterlen / 2 ; i < filterlen; i++)
|
||||
for (int i = filterlen_div2 ; i < filterlen; i++)
|
||||
filtdata[i].re = filtdata[i].im = 0.0;
|
||||
|
||||
// FFT transpose to the frequency domain
|
||||
|
@ -127,15 +181,15 @@ int fftfilt::run(const complex& in, complex **out)
|
|||
ift->icdft(filtdata);
|
||||
|
||||
// overlap and add
|
||||
for (int i = 0; i < filterlen / 2; i++) {
|
||||
filtdata[i].re += ovlbuf[i].re;
|
||||
filtdata[i].im += ovlbuf[i].im;
|
||||
for (int i = 0; i < filterlen_div2; i++) {
|
||||
filtdata[i] += ovlbuf[i];
|
||||
}
|
||||
*out = filtdata;
|
||||
|
||||
// save the second half for overlapping
|
||||
for (int i = 0; i < filterlen / 2; i++)
|
||||
ovlbuf[i] = filtdata[i + filterlen / 2];
|
||||
// Memcpy is allowed because complex are POD objects.
|
||||
memcpy( ovlbuf, filtdata + filterlen_div2, sizeof( ovlbuf[0] ) * filterlen_div2 );
|
||||
|
||||
|
||||
// clear inbuf pointer
|
||||
inptr = 0;
|
||||
|
@ -143,5 +197,5 @@ int fftfilt::run(const complex& in, complex **out)
|
|||
// signal the caller there is filterlen/2 samples ready
|
||||
if (pass) return 0;
|
||||
|
||||
return filterlen / 2;
|
||||
return filterlen_div2;
|
||||
}
|
||||
|
|
|
@ -161,12 +161,17 @@ extern Fl_Tabs *tabsModems;
|
|||
extern Fl_Group *tabCW;
|
||||
extern Fl_Tabs *tabsCW;
|
||||
extern Fl_Value_Slider2 *sldrCWbandwidth;
|
||||
extern Fl_Check_Button *btnCWrcvTrack;
|
||||
extern Fl_Counter2 *cntCWrange;
|
||||
#include <FL/Fl_Value_Output.H>
|
||||
extern Fl_Value_Output *valCWrcvWPM;
|
||||
#include <FL/Fl_Progress.H>
|
||||
extern Fl_Progress *prgsCWrcvWPM;
|
||||
extern Fl_Check_Button *btnCWuseSOMdecoding;
|
||||
extern Fl_Counter2 *cntLower;
|
||||
extern Fl_Counter2 *cntUpper;
|
||||
extern Fl_Check_Button *btnCWmfilt;
|
||||
extern Fl_Check_Button *btnCWuseFFTfilter;
|
||||
extern Fl_Check_Button *btnCWrcvTrack;
|
||||
extern Fl_Counter2 *cntCWrange;
|
||||
extern Fl_Value_Slider2 *sldrCWxmtWPM;
|
||||
extern Fl_Counter2 *cntCWdefWPM;
|
||||
#include <FL/Fl_Counter.H>
|
||||
|
|
|
@ -166,6 +166,9 @@
|
|||
ELEM_(bool, StartAtSweetSpot, "STARTATSWEETSPOT", \
|
||||
"Always start new modems at sweet spot frequencies", \
|
||||
false) \
|
||||
ELEM_(bool, CWOffset, "CWOFFSET", \
|
||||
"Select if waterfall should compensate for BFO offset in CW", \
|
||||
false) \
|
||||
ELEM_(bool, CWIsLSB, "CWISLSB", \
|
||||
"Select if BFO is injected as LSB instead of USB", \
|
||||
false) \
|
||||
|
@ -324,9 +327,27 @@
|
|||
ELEM_(int, CWbandwidth, "CWBANDWIDTH", \
|
||||
"Filter bandwidth (Hz)", \
|
||||
150) \
|
||||
ELEM_(double, CWlower, "CWLOWER", \
|
||||
"Detector hysterisis, lower threshold", \
|
||||
0.4) \
|
||||
ELEM_(double, CWupper, "CWUPPER", \
|
||||
"Detector hysterisis, upper threshold", \
|
||||
0.6) \
|
||||
ELEM_(int, CWmfiltlen, "CWMFILTLEN", \
|
||||
"Matched Filter length", \
|
||||
100) \
|
||||
ELEM_(bool, CWtrack, "CWTRACK", \
|
||||
"Automatic receive speed tracking", \
|
||||
true) \
|
||||
ELEM_(bool, CWmfilt, "CWMFILT", \
|
||||
"Matched Filter in use", \
|
||||
false) \
|
||||
ELEM_(bool, CWuse_fft_filter, "CWUSEFFTFILTER", \
|
||||
"Use FFT overlap and add convolution filter", \
|
||||
false) \
|
||||
ELEM_(bool, CWuseSOMdecoding, "CWUSESOMDECODING", \
|
||||
"Self Organizing Map decoding", \
|
||||
false) \
|
||||
ELEM_(int, CWrange, "CWRANGE", \
|
||||
"Tracking range for CWTRACK (WPM)", \
|
||||
10) \
|
||||
|
@ -457,6 +478,57 @@
|
|||
ELEM_(double, ThorCWI, "THORCWI", \
|
||||
"CWI threshold (CWI detection and suppression)", \
|
||||
0.0) \
|
||||
ELEM_(bool, THOR_PREAMBLE, "THORPREAMBLE", \
|
||||
"Detect THOR preamble (and flush Rx pipeline)", \
|
||||
true) \
|
||||
ELEM_(bool, THOR_SOFTSYMBOLS, "THORSOFTSYMBOLS", \
|
||||
"Enable Soft-symbol decoding", \
|
||||
true) \
|
||||
ELEM_(bool, THOR_SOFTBITS, "THORSOFTBITS", \
|
||||
"Enable Soft-bit decoding", \
|
||||
true) \
|
||||
/* PACKET */ \
|
||||
ELEM_(int, PKT_BAUD_SELECT, "PKTBAUDSELECT", \
|
||||
"Packet baud rate. Values are as follows:\n" \
|
||||
" 0: 1200 (V/UHF); 1: 300 (HF); 2: 2400 (V/UHF)", \
|
||||
0) /* 1200 baud (V/UHF) default. */ \
|
||||
ELEM_(double, PKT_LOSIG_RXGAIN, "LOSIGRXGAIN", \
|
||||
"Signal gain for lower frequency (Mark) tone (in dB)", \
|
||||
0.0) \
|
||||
ELEM_(double, PKT_HISIG_RXGAIN, "HISIGRXGAIN", \
|
||||
"Signal gain for higher frequency (Space) tone (in dB)", \
|
||||
0.0) \
|
||||
ELEM_(double, PKT_LOSIG_TXGAIN, "LOSIGTXGAIN", \
|
||||
"Signal gain for Mark (lower frequency) tone (in dB)", \
|
||||
0.0) \
|
||||
ELEM_(double, PKT_HISIG_TXGAIN, "HISIGTXGAIN", \
|
||||
"Signal gain for Space (higher frequency) tone (in dB)", \
|
||||
0.0) \
|
||||
ELEM_(bool, PKT_PreferXhairScope, "PKTPREFERXHAIRSCOPE", \
|
||||
"Default to syncscope (detected symbol scope)", \
|
||||
false) ELEM_(bool, PKT_AudioBoost, "PKTAUDIOBOOST", \
|
||||
"No extra input gain (similar to Mic Boost) by default", \
|
||||
false) \
|
||||
\
|
||||
ELEM_(bool, PKT_RXTimestamp, "PKTRXTIMESTAMP", \
|
||||
"No timestamps on RX packets by default", \
|
||||
false) \
|
||||
\
|
||||
ELEM_(bool, PKT_expandMicE, "PKTEXPANDMICE", \
|
||||
"decode received Mic-E data", \
|
||||
false) \
|
||||
ELEM_(bool, PKT_expandPHG, "PKTEXPANDPHG", \
|
||||
"decode received PHG data", \
|
||||
false) \
|
||||
ELEM_(bool, PKT_expandCmp, "PKTEXPANDCMP", \
|
||||
"decode received Compressed Position data", \
|
||||
false) \
|
||||
ELEM_(bool, PKT_unitsSI, "PKTUNITSSI", \
|
||||
"display decoded data in SI units", \
|
||||
false) \
|
||||
ELEM_(bool, PKT_unitsEnglish, "PKTUNITSENGLISH", \
|
||||
"display decoded data in English units", \
|
||||
false) \
|
||||
/* DOMINOEX */ \
|
||||
ELEM_(double, DOMINOEX_BW, "DOMINOEXBW", \
|
||||
"Filter bandwidth factor (bandwidth relative to signal width)", \
|
||||
|
@ -546,7 +618,7 @@
|
|||
{255, 255, 255, 255}) \
|
||||
ELEM_(RGBI, rttymarkRGBI, "RTTYMARKRGBI", \
|
||||
"Color of RTTY MARK freq marker (RGBI)", \
|
||||
{255, 128, 0, 255}) \
|
||||
{255, 120, 0, 255}) \
|
||||
ELEM_(int, feldfontnbr, "FELDFONTNBR", \
|
||||
"Index of raster font used for transmission", \
|
||||
4) \
|
||||
|
@ -1301,9 +1373,29 @@
|
|||
ELEM_(int, wefax_filter, "WEFAXFILTER", \
|
||||
"Input filter for image reception", \
|
||||
0) \
|
||||
/* NAVTEX configuration items */ \
|
||||
ELEM_(bool, NVTX_AdifLog, "NAVTEXADIFLOG", \
|
||||
"Logs Navtex messages in Adig log file", \
|
||||
ELEM_(bool, WEFAX_EmbeddedGui, "WEFAXEMBEDDEDGUI", \
|
||||
"Embedded GUI", \
|
||||
true) \
|
||||
ELEM_(bool, WEFAX_HideTx, "WEFAXHIDETX", \
|
||||
"Hide transmission window", \
|
||||
true) \
|
||||
ELEM_(int, WEFAX_Shift, "WEFAXSHIFT", \
|
||||
"Shift (Standard 800Hz)", \
|
||||
800 ) \
|
||||
ELEM_(int, WEFAX_MaxRows, "WEFAXMAXROWS", \
|
||||
"Received fax maximum number of rows", \
|
||||
2900 ) \
|
||||
ELEM_(int, WEFAX_NoiseMargin, "WEFAXNOISEMARGIN", \
|
||||
"Pixel margin for noise removal", \
|
||||
1 ) \
|
||||
ELEM_(int, WEFAX_NoiseThreshold, "WEFAXNOISETHRESHOLD", \
|
||||
"Threshold level for noise detection and removal", \
|
||||
5 ) \
|
||||
ELEM_(int, WEFAX_SaveMonochrome, "WEFAXSAVEMONOCHROME", \
|
||||
"Save fax image as monochrome", \
|
||||
true ) \
|
||||
ELEM_(bool, WEFAX_AdifLog, "WEFAXADIFLOG", \
|
||||
"Logs wefax file names in Adif log file", \
|
||||
false) \
|
||||
/* WX fetch from NOAA */ \
|
||||
ELEM_(std::string, wx_sta, "WX_STA", \
|
||||
|
|
111
src/include/cw.h
111
src/include/cw.h
|
@ -28,18 +28,24 @@
|
|||
#ifndef _CW_H
|
||||
#define _CW_H
|
||||
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
#include "modem.h"
|
||||
#include "filters.h"
|
||||
#include "fftfilt.h"
|
||||
//#include "mfilt.h" //AG1LE: added this
|
||||
#include "mbuffer.h"
|
||||
|
||||
|
||||
#define CWSampleRate 8000
|
||||
#define CWMaxSymLen 4096
|
||||
#define KNUM 128
|
||||
#define CWMaxSymLen 4096 // AG1LE: - was 4096
|
||||
#define KNUM 122
|
||||
|
||||
// decimation ratio for the receiver
|
||||
//#define DEC_RATIO 8
|
||||
//#define CW_FIRLEN 32
|
||||
//#define CW_FIRLEN 128
|
||||
//#define CW_FIRLEN 122
|
||||
//#define CW_FIRLEN 256
|
||||
//#define CW_FIRLEN 512
|
||||
// Limits on values of CW send and timing parameters
|
||||
|
@ -47,8 +53,8 @@
|
|||
//#define CW_MAX_SPEED 100 // Highest WPM allowed
|
||||
|
||||
// CW function return status codes.
|
||||
#define CW_SUCCESS 0
|
||||
#define CW_ERROR -1
|
||||
#define CW_SUCCESS 0
|
||||
#define CW_ERROR -1
|
||||
|
||||
#define ASC_NUL '\0' // End of string
|
||||
#define ASC_SPACE ' ' // ASCII space char
|
||||
|
@ -70,6 +76,8 @@
|
|||
|
||||
#define TRACKING_FILTER_SIZE 16
|
||||
|
||||
#define MAX_PIPE_SIZE (22 * CWSampleRate * 12 / 800)
|
||||
|
||||
enum CW_RX_STATE {
|
||||
RS_IDLE = 0,
|
||||
RS_IN_TONE,
|
||||
|
@ -84,16 +92,43 @@ enum CW_EVENT {
|
|||
};
|
||||
|
||||
class cw : public modem {
|
||||
protected:
|
||||
int symbollen; // length of a dot in sound samples (tx)
|
||||
int fsymlen; // length of extra interelement space (farnsworth)
|
||||
double phaseacc; // used by NCO for rx/tx tones
|
||||
unsigned int smpl_ctr; // sample counter for timing cw rx
|
||||
double agc_peak; // threshold for tone detection
|
||||
|
||||
C_FIR_filter *cwfilter;
|
||||
Cmovavg *bitfilter;
|
||||
Cmovavg *trackingfilter;
|
||||
#define CLRCOUNT 16
|
||||
#define DEC_RATIO 16
|
||||
#define CW_FIRLEN 512
|
||||
// Maximum number of signs (dit or dah) in a Morse char.
|
||||
#define WGT_SIZE 7
|
||||
|
||||
struct SOM_TABLE {
|
||||
char chr; /* The character(s) represented */
|
||||
const char *prt; /* The printable representation of the character */
|
||||
float wgt[WGT_SIZE]; /* Dot-dash weight vector */
|
||||
};
|
||||
|
||||
protected:
|
||||
int symbollen; // length of a dot in sound samples (tx)
|
||||
int fsymlen; // length of extra interelement space (farnsworth)
|
||||
double phaseacc; // used by NCO for rx/tx tones
|
||||
double FFTphase;
|
||||
double FIRphase;
|
||||
double FFTvalue;
|
||||
double FIRvalue;
|
||||
unsigned int smpl_ctr; // sample counter for timing cw rx
|
||||
double agc_peak; // threshold for tone detection
|
||||
|
||||
int FilterFFTLen;
|
||||
bool use_matched_filter;
|
||||
bool use_fft_filter;
|
||||
|
||||
double upper_threshold;
|
||||
double lower_threshold;
|
||||
|
||||
C_FIR_filter *hilbert; // Hilbert filter precedes sinc filter
|
||||
fftfilt *cw_FFT_filter; // sinc / matched filter
|
||||
C_FIR_filter *cw_FIR_filter; // linear phase finite impulse response filter
|
||||
|
||||
Cmovavg *bitfilter;
|
||||
Cmovavg *trackingfilter;
|
||||
|
||||
int bitfilterlen;
|
||||
|
||||
|
@ -101,8 +136,9 @@ protected:
|
|||
CW_RX_STATE old_cw_receive_state;
|
||||
CW_EVENT cw_event; // functions used by cw process routine
|
||||
|
||||
double pipe[CWMaxSymLen]; // storage for sync scope data
|
||||
mbuffer<double, CWMaxSymLen, 2> scopedata;
|
||||
double pipe[MAX_PIPE_SIZE+1]; // storage for sync scope data
|
||||
double clearpipe[MAX_PIPE_SIZE+1];
|
||||
mbuffer<double, MAX_PIPE_SIZE + 1, 4> scopedata;
|
||||
int pipeptr;
|
||||
int pipesize;
|
||||
bool scope_clear;
|
||||
|
@ -112,23 +148,23 @@ protected:
|
|||
int cw_bandwidth;
|
||||
int cw_squelch;
|
||||
int cw_send_speed; // Initially 18 WPM
|
||||
int cw_receive_speed; // Initially 18 WPM
|
||||
int cw_receive_speed; // Initially 18 WPM
|
||||
bool usedefaultWPM; // use default WPM
|
||||
|
||||
int cw_upper_limit;
|
||||
int cw_lower_limit;
|
||||
|
||||
long int cw_noise_spike_threshold; // Initially ignore any tone < 10mS
|
||||
long int cw_noise_spike_threshold; // Initially ignore any tone < 10mS
|
||||
int cw_in_sync; // Synchronization flag
|
||||
|
||||
// Sending parameters:
|
||||
long int cw_send_dot_length; // Length of a send Dot, in Usec
|
||||
long int cw_send_dash_length; // Length of a send Dash, in Usec
|
||||
long int cw_send_dot_length; // Length of a send Dot, in Usec
|
||||
long int cw_send_dash_length; // Length of a send Dash, in Usec
|
||||
int lastsym; // last symbol sent
|
||||
double risetime; // leading/trailing edge rise time (msec)
|
||||
int knum; // number of samples on edges
|
||||
int QSKshape; // leading/trailing edge shape factor
|
||||
double qskbuf[OUTBUFSIZE]; // signal array for qsk drive
|
||||
double risetime; // leading/trailing edge rise time (msec)
|
||||
int knum; // number of samples on edges
|
||||
int QSKshape; // leading/trailing edge shape factor
|
||||
double qskbuf[OUTBUFSIZE]; // signal array for qsk drive
|
||||
double qskphase; //
|
||||
bool firstelement;
|
||||
|
||||
|
@ -142,10 +178,11 @@ protected:
|
|||
#define RECEIVE_CAPACITY 256 // Way longer than any representation
|
||||
char rx_rep_buf[RECEIVE_CAPACITY];
|
||||
int cw_rr_current; // Receive buffer current location
|
||||
unsigned int cw_rr_start_timestamp; // Tone start timestamp
|
||||
unsigned int cw_rr_end_timestamp; // Tone end timestamp
|
||||
unsigned int cw_rr_start_timestamp; // Tone start timestamp
|
||||
unsigned int cw_rr_end_timestamp; // Tone end timestamp
|
||||
|
||||
long int cw_adaptive_receive_threshold; // 2-dot threshold for adaptive speed
|
||||
long int cw_adaptive_receive_threshold; // 2-dot threshold for adaptive speed
|
||||
int in_replay; //AG1LE: if we have replay even, set to 1 otherwise = 0 ;
|
||||
|
||||
// Receive adaptive speed tracking.
|
||||
double dot_tracking;
|
||||
|
@ -157,6 +194,7 @@ protected:
|
|||
void clear_syncscope();
|
||||
void update_Status();
|
||||
void sync_parameters();
|
||||
void reset_rx_filter();
|
||||
int handle_event(int cw_event, const char **c);
|
||||
int usec_diff(unsigned int earlier, unsigned int later);
|
||||
void send_symbol(int symbol, int len);
|
||||
|
@ -166,7 +204,16 @@ protected:
|
|||
void update_tracking(int dot, int dash);
|
||||
|
||||
void makeshape();
|
||||
|
||||
complex mixer(complex in);
|
||||
|
||||
static const SOM_TABLE som_table[];
|
||||
float cw_buffer[512];
|
||||
int cw_ptr;
|
||||
int clrcount;
|
||||
|
||||
bool use_paren;
|
||||
std::string prosigns;
|
||||
|
||||
public:
|
||||
cw();
|
||||
~cw();
|
||||
|
@ -174,12 +221,20 @@ public:
|
|||
void rx_init();
|
||||
void tx_init(SoundBase *sc);
|
||||
void restart() {};
|
||||
|
||||
int rx_process(const double *buf, int len);
|
||||
void rx_FFTprocess(const double *buf, int len);
|
||||
void rx_FIRprocess(const double *buf, int len);
|
||||
void decode_stream(double);
|
||||
|
||||
int tx_process();
|
||||
void incWPM();
|
||||
void decWPM();
|
||||
void toggleWPM();
|
||||
|
||||
int normalize(float *v, int n, int twodots);
|
||||
const char *find_winner (float *inbuf, int twodots);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -67,6 +67,7 @@ private:
|
|||
double _phase;
|
||||
double _quality;
|
||||
double _flo, _fhi, _amp;
|
||||
double _x1, _x2, _y1, _y2;
|
||||
bool _highlight;
|
||||
scope_mode phase_mode;
|
||||
|
||||
|
@ -89,6 +90,11 @@ public:
|
|||
void rtty(double flo, double fhi, double amp);
|
||||
void mode(scope_mode md);
|
||||
scope_mode mode() { return _mode;};
|
||||
void xaxis_1(double y1) { _y1 = y1; }
|
||||
void xaxis_2(double y2) { _y2 = y2; }
|
||||
void yaxis_1(double x1) { _x1 = x1; }
|
||||
void yaxis_2(double x2) { _x2 = x2; }
|
||||
void clear_axis() { _x1 = _x2 = _y1 = _y2 = 0; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -22,8 +22,10 @@ protected:
|
|||
int pass;
|
||||
public:
|
||||
fftfilt(double f1, double f2, int len);
|
||||
fftfilt(double f, int len);
|
||||
~fftfilt();
|
||||
void create_filter(double f1, double f2);
|
||||
void create_lpf(double f);
|
||||
int run(const complex& in, complex **out);
|
||||
};
|
||||
|
||||
|
|
|
@ -179,6 +179,12 @@ extern void set_rtty(double, double, double);
|
|||
extern void set_video(double *, int, bool = true);
|
||||
extern void set_zdata(complex *, int);
|
||||
|
||||
extern void set_scope_xaxis_1(double y1);
|
||||
extern void set_scope_xaxis_2(double y2);
|
||||
extern void set_scope_yaxis_1(double x1);
|
||||
extern void set_scope_yaxis_2(double x2);
|
||||
extern void set_scope_clear_axis();
|
||||
|
||||
extern void set_CWwpm();
|
||||
extern void put_rx_char(unsigned int data, int style = FTextBase::RECV);
|
||||
extern void put_sec_char( char chr );
|
||||
|
|
|
@ -139,6 +139,7 @@ public:
|
|||
virtual void decWPM() {};
|
||||
virtual void toggleWPM() {};
|
||||
virtual void sync_parameters() {};
|
||||
virtual void reset_rx_filter(bool) {};
|
||||
virtual void update_Status() {};
|
||||
|
||||
// for waterfall id transmission
|
||||
|
@ -200,6 +201,9 @@ extern modem *mfsk64_modem;
|
|||
extern modem *wefax576_modem;
|
||||
extern modem *wefax288_modem;
|
||||
|
||||
extern modem *navtex_modem;
|
||||
extern modem *sitorb_modem;
|
||||
|
||||
extern modem *mt63_500_modem;
|
||||
extern modem *mt63_1000_modem;
|
||||
extern modem *mt63_2000_modem;
|
||||
|
@ -231,6 +235,7 @@ extern modem *psk250r_modem;
|
|||
extern modem *psk500r_modem;
|
||||
|
||||
extern modem *rtty_modem;
|
||||
extern modem *pkt_modem;
|
||||
|
||||
extern modem *olivia_modem;
|
||||
extern modem *contestia_modem;
|
||||
|
@ -239,10 +244,14 @@ extern modem *thor4_modem;
|
|||
extern modem *thor5_modem;
|
||||
extern modem *thor8_modem;
|
||||
extern modem *thor11_modem;
|
||||
//extern modem *tsor11_modem;
|
||||
extern modem *thor16_modem;
|
||||
extern modem *thor22_modem;
|
||||
|
||||
extern modem *dominoex44_modem;
|
||||
extern modem *thor44_modem;
|
||||
extern modem *dominoex88_modem;
|
||||
extern modem *thor88_modem;
|
||||
|
||||
extern modem *dominoex4_modem;
|
||||
extern modem *dominoex5_modem;
|
||||
extern modem *dominoex8_modem;
|
||||
|
|
|
@ -52,6 +52,7 @@ Digiscope::Digiscope (int X, int Y, int W, int H) :
|
|||
_highlight = false;
|
||||
_len = MAX_LEN;
|
||||
_zptr = 0;
|
||||
_x1 = _x2 = _y1 = _y2;
|
||||
phase_mode = PHASE1;
|
||||
}
|
||||
|
||||
|
@ -138,11 +139,9 @@ void Digiscope::data(double *data, int len, bool scale)
|
|||
max = MAX(max, _buf[i]);
|
||||
min = MIN(min, _buf[i]);
|
||||
}
|
||||
if (max == min) max *= 1.001;
|
||||
for (int i = 0; i < _len; i++)
|
||||
if (_buf[i] > 0.001) // threshold
|
||||
_buf[i] = (_buf[i] - min) / (max - min);
|
||||
else
|
||||
_buf[i] = 0.0;
|
||||
_buf[i] = (_buf[i] - min) / (max - min);
|
||||
}
|
||||
REQ_DROP(&Digiscope::redraw, this);
|
||||
FL_UNLOCK_D();
|
||||
|
@ -336,10 +335,42 @@ void Digiscope::draw_scope()
|
|||
for (int i = 0; i < npts; i++)
|
||||
fl_vertex( (double)i / npts, _buf[i * _len / npts] );
|
||||
fl_end_line();
|
||||
|
||||
// x & y axis'
|
||||
if (_x1) {
|
||||
fl_color(FL_WHITE);
|
||||
fl_begin_line();
|
||||
fl_vertex(_x1, 0.0);
|
||||
fl_vertex(_x1, 1.0);
|
||||
fl_end_line();
|
||||
}
|
||||
if (_x2) {
|
||||
fl_color(FL_YELLOW);
|
||||
fl_begin_line();
|
||||
fl_vertex(_x2, 0.0);
|
||||
fl_vertex(_x2, 1.0);
|
||||
fl_end_line();
|
||||
}
|
||||
if (_y1) {
|
||||
fl_color(FL_WHITE);
|
||||
fl_begin_line();
|
||||
fl_vertex(0.0, _y1);
|
||||
fl_vertex(1.0, _y1);
|
||||
fl_end_line();
|
||||
}
|
||||
if (_y2) {
|
||||
fl_color(FL_YELLOW);
|
||||
fl_begin_line();
|
||||
fl_vertex(0.0, _y2);
|
||||
fl_vertex(1.0, _y2);
|
||||
fl_end_line();
|
||||
}
|
||||
|
||||
fl_pop_matrix();
|
||||
fl_pop_clip();
|
||||
}
|
||||
|
||||
|
||||
void Digiscope::draw_xy()
|
||||
{
|
||||
fl_clip(x()+2,y()+2,w()-4,h()-4);
|
||||
|
|
Ładowanie…
Reference in New Issue