From e37ebe13a4dbce3e7e4204d6d18cd6729dcc27f5 Mon Sep 17 00:00:00 2001 From: Stelios Bounanos Date: Fri, 22 Jun 2007 23:19:01 +0100 Subject: [PATCH] Upstream version 1.35J --- ChangeLog | 9 + src/cw_rtty/cw.cxx | 114 +++++++++--- src/cw_rtty/rtty.cxx | 57 ++++-- src/dialogs/Config.cxx | 109 +++++++++-- src/dialogs/Config.fl | 79 ++++++-- src/dialogs/Config.h | 140 ++++++++++++++ src/dialogs/TextView.cxx | 245 ++++++++++--------------- src/dialogs/fl_digi.cxx | 77 ++++---- src/dialogs/font_browser.cxx | 2 +- src/dialogs/{ => oldcode}/ConfigCW.fl | 0 src/dialogs/{ => oldcode}/ConfigTTY.fl | 0 src/dominoex/dominoex.cxx | 78 ++++---- src/feld/feld.cxx | 6 +- src/ider/id.cxx | 2 +- src/include/Config.h | 8 +- src/include/TextView.h | 25 +-- src/include/complex.h | 112 ++++++----- src/include/configuration.h | 6 + src/include/cw.h | 5 + src/include/font_browser.h | 2 +- src/include/main.h | 25 +++ src/include/modem.h | 4 +- src/include/rtty.h | 6 +- src/include/sound.h | 1 + src/include/status.h | 11 +- src/include/version.h | 2 +- src/main.cxx | 11 +- src/mfsk/mfsk.cxx | 6 +- src/misc/configuration.cxx | 49 ++++- src/misc/pskmail.cxx | 2 +- src/misc/status.cxx | 76 ++++++-- src/olivia/olivia.cxx | 4 +- src/psk/psk.cxx | 13 +- src/soundcard/sound.cxx | 128 ++++++++++--- src/throb/throb.cxx | 4 +- src/trx/modem.cxx | 19 ++ src/trx/trx.cxx | 6 +- 37 files changed, 973 insertions(+), 470 deletions(-) create mode 100644 src/dialogs/Config.h rename src/dialogs/{ => oldcode}/ConfigCW.fl (100%) rename src/dialogs/{ => oldcode}/ConfigTTY.fl (100%) diff --git a/ChangeLog b/ChangeLog index c7930cd4..fee1a037 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,14 @@ Change Log: +1.35 1) Increased TxPPM to +/- 50000 to match the RxPPM range + 2) Changed all audio i/o to separate 2 channel control (stereo) + 3) Added right channel CW QRQ signal + 4) Added right channel pseudo FSK signal + 5) Added position and size of main dialog to state memory + 6) Added status and position of rig control dialog to state memory + 7) Added PSKmail tab and control to allow disabling the automatic + return to the PSK sweet spot if running a mail server + 8) Added "Save To" menu item on received text popup menu. 1.34 1) Cleaned up unused code segments 2) Modified CW decoder to allow setting upper and lower limits on Tx WPM diff --git a/src/cw_rtty/cw.cxx b/src/cw_rtty/cw.cxx index 5c38e7fd..921ee019 100644 --- a/src/cw_rtty/cw.cxx +++ b/src/cw_rtty/cw.cxx @@ -43,6 +43,7 @@ void cw::tx_init(cSound *sc) scard = sc; phaseacc = 0; lastsym = 0; + qrqphase = 0; } void cw::rx_init() @@ -62,6 +63,8 @@ void cw::init() trackingfilter->reset(); cw_adaptive_receive_threshold = (long int)trackingfilter->run(2 * cw_send_dot_length); put_cwRcvWPM(cw_send_speed); + for (int i = 0; i < OUTBUFSIZE; i++) + outbuf[i] = qrqbuf[i] = 0.0; rx_init(); } @@ -83,8 +86,8 @@ cw::cw() : morse(), modem() mode = MODE_CW; freqlock = false; - frequency = 800; - tx_frequency = 800; + frequency = progdefaults.CWsweetspot; + tx_frequency = get_txfreq_woffset(); risetime = progdefaults.CWrisetime; // keyshape = new double[KNUM]; @@ -518,28 +521,51 @@ inline double cw::nco(double freq) return sin(phaseacc); } +inline double cw::qrqnco() +{ + qrqphase += 2.0 * M_PI * 1600.0 / samplerate; + + if (qrqphase > M_PI) + qrqphase -= 2.0 * M_PI; + + return sin(qrqphase); +} + //===================================================================== // send_symbol() // Sends a part of a morse character (one dot duration) of either // sound at the correct freq or silence. Rise and fall time is controlled // with a raised cosine shape. +// +// Left channel contains the shaped A2 CW waveform +// Right channel contains a square wave burst of 1600 Hz that is used +// to trigger a QRQ switch. Right channel has pre and post timings for +// proper switching of the QRQ switch before and after the A2 element. +// If the Pre + Post timing exceeds the interelement spacing then the +// Pre and / or Post is only applied at the beginning and end of the +// character. //======================================================================= - -void cw::send_symbol(int currsym) +void cw::send_symbol(int bits) { double freq; int sample = 0, i; int delta = 0; int keydown; int keyup; + int kpre; + int kpost; int duration = 0; int symlen = 0; double dsymlen = 0.0; + int currsym = bits & 1; + + freq = get_txfreq_woffset(); - freq = tx_frequency; - - if ((currsym == 1) && (lastsym == 0)) phaseacc = 0.0; + if ((currsym == 1) && (lastsym == 0)) { + phaseacc = 0.0; +// qrqphase = 0.0; + } if ((currsym == 1 && lastsym == 0) || (currsym == 0 && lastsym == 1)) delta = (int) (symbollen * (progdefaults.CWweight - 50) / 100.0); @@ -559,34 +585,78 @@ void cw::send_symbol(int currsym) keydown = symlen - knum + delta; keyup = symlen - knum - delta; - - if (currsym == 1) { + + kpre = (int)(progdefaults.CWpre * 8); + kpost = (int)(progdefaults.CWpost * 8); + + if ( (kpre + kpost) > keyup) { + kpre = keyup / 2; + kpost = keyup - kpre; + } + if (bits == 4) { + kpost = (int)(progdefaults.CWpost * 8); + if (kpost > keyup) + kpost = keyup; + } + if (firstelement) { + kpre = (int)(progdefaults.CWpre * 8); + kpost = 0; + if (kpre > keydown) + kpre = keydown; + } + + if (currsym == 1) { // keydown for (i = 0; i < knum; i++, sample++) { if (lastsym == 0) outbuf[sample] = nco(freq) * keyshape[i]; else outbuf[sample] = nco(freq); + qrqbuf[sample] = qrqnco(); } for (i = 0; i < keydown; i++, sample++) { outbuf[sample] = nco(freq); + qrqbuf[sample] = qrqnco(); } duration = knum + keydown; - } else { + } + else { // keyup for (i = knum - 1; i >= 0; i--, sample++) { - if (lastsym == 1) + if (lastsym == 1) { outbuf[sample] = nco(freq) * keyshape[i]; - else + } else { outbuf[sample] = 0.0; + } } for (i = 0; i < keyup; i++, sample++) { outbuf[sample] = 0.0; } + + sample -= (knum + keyup); + + for (i = 0; i < knum + kpost ; i++, sample++) { + if (bits > 2 && lastsym == 1) + qrqbuf[sample] = qrqnco(); + else + qrqbuf[sample] = 0.0; + } + for (i = 0; i < (keyup - kpre - kpost); i++, sample++) + qrqbuf[sample] = 0.0; + for (i = 0; i < kpre; i++, sample++) + if (bits > 4) + qrqbuf[sample] = qrqnco(); + else + qrqbuf[sample] = 0.0; + duration = knum + keyup; } - ModulateXmtr(outbuf, duration); + if (progdefaults.QSK) + ModulateStereo(outbuf, qrqbuf, duration); + else + ModulateXmtr(outbuf, duration); lastsym = currsym; + firstelement = false; } //===================================================================== @@ -603,32 +673,32 @@ void cw::send_ch(int ch) // last char already had 2 elements of inter-character spacing if ((ch == ' ') || (ch == '\n')) { -// cout << " "; + firstelement = false; send_symbol(0); send_symbol(0); send_symbol(0); send_symbol(0); send_symbol(0); put_echo_char(ch); -// cout << endl; cout.flush(); return; } // convert character code to a morse representation - if ((ch < 256) && (ch >= 0)) + if ((ch < 256) && (ch >= 0)) { code = tx_lookup(ch); //cw_tx_lookup(ch); - else + firstelement = true; + } else { code = 0x04; // two extra dot spaces + firstelement = false; + } + // loop sending out binary bits of cw character - -// cout << (char) ch << " " << progdefaults.CWdash2dot << " === "; - while (code > 1) { - send_symbol(code & 1); + send_symbol(code);// & 1); code = code >> 1; Fl::awake(); } -// cout << endl; cout.flush(); + if (ch != 0) put_echo_char(ch); } diff --git a/src/cw_rtty/rtty.cxx b/src/cw_rtty/rtty.cxx index 4e747091..b698ab53 100644 --- a/src/cw_rtty/rtty.cxx +++ b/src/cw_rtty/rtty.cxx @@ -64,6 +64,7 @@ void rtty::rx_init() rxstate = RTTY_RX_STATE_IDLE; rxmode = LETTERS; phaseacc = 0; + FSKphaseacc = 0; for (int i = 0; i < RTTYMaxSymLen; i++ ) { bbfilter[i] = 0.0; } @@ -117,12 +118,10 @@ void rtty::restart() case 4 : rtty_parity = PARITY_ONE; break; default : rtty_parity = PARITY_NONE; break; } - msb = progdefaults.rtty_msbfirst; rtty_stop = progdefaults.rtty_stop; txmode = LETTERS; rxmode = LETTERS; - msb = chkMsbFirst->value(); symbollen = (int) (samplerate / rtty_baud + 0.5); set_bandwidth(shift); @@ -273,9 +272,6 @@ int rtty::decode_char() data = rxdata & ((1 << nbits) - 1); - if (msb) - data = bitreverse(data, nbits); - if (nbits == 5) return baudot_dec(data); @@ -543,14 +539,23 @@ double rtty::nco(double freq) { phaseacc += twopi * freq / samplerate; -// if (freq == 0.0) -// return 0.0; if (phaseacc > M_PI) phaseacc -= twopi; return cos(phaseacc); } +double rtty::FSKnco() +{ + FSKphaseacc += twopi * 1600 / samplerate; + + if (FSKphaseacc > M_PI) + FSKphaseacc -= twopi; + + return sin(FSKphaseacc); + +} + void rtty::send_symbol(int symbol) { double freq; @@ -561,13 +566,21 @@ void rtty::send_symbol(int symbol) symbol = !symbol; if (symbol) - freq = tx_frequency + shift / 2.0; + freq = get_txfreq_woffset() + shift / 2.0; else - freq = tx_frequency - shift / 2.0; - for (int i = 0; i < symbollen; i++) + freq = get_txfreq_woffset() - shift / 2.0; + for (int i = 0; i < symbollen; i++) { outbuf[i] = nco(freq); + if (symbol) + FSKbuf[i] = FSKnco(); + else + FSKbuf[i] = 0.0; + } - ModulateXmtr(outbuf, symbollen); + if (progdefaults.PseudoFSK) + ModulateStereo(outbuf, FSKbuf, symbollen); + else + ModulateXmtr(outbuf, symbollen); } void rtty::send_stop() @@ -578,19 +591,26 @@ void rtty::send_stop() invert = !invert; if (invert) - freq = tx_frequency - shift / 2.0; + freq = get_txfreq_woffset() - shift / 2.0; else - freq = tx_frequency + shift / 2.0; + freq = get_txfreq_woffset() + shift / 2.0; - for (int i = 0; i < stoplen; i++) + for (int i = 0; i < stoplen; i++) { outbuf[i] = nco(freq); - - ModulateXmtr(outbuf, stoplen); + if (invert) + FSKbuf[i] = FSKnco(); + else + FSKbuf[i] = 0.0; + } + if (progdefaults.PseudoFSK) + ModulateStereo(outbuf, FSKbuf, stoplen); + else + ModulateXmtr(outbuf, stoplen); } void rtty::send_char(int c) { - int i, j; + int i; if (nbits == 5) { if (c == LETTERS) @@ -602,8 +622,7 @@ void rtty::send_char(int c) send_symbol(0); // data bits for (i = 0; i < nbits; i++) { - j = (msb) ? (nbits - 1 - i) : i; - send_symbol((c >> j) & 1); + send_symbol((c >> i) & 1); } // parity bit if (rtty_parity != PARITY_NONE) diff --git a/src/dialogs/Config.cxx b/src/dialogs/Config.cxx index be832fc8..d10a47bf 100644 --- a/src/dialogs/Config.cxx +++ b/src/dialogs/Config.cxx @@ -469,6 +469,13 @@ static void cb_cntTxRateCorr(Fl_Spinner* o, void*) { progdefaults.changed = true; } +Fl_Spinner *cntTxOffset=(Fl_Spinner *)0; + +static void cb_cntTxOffset(Fl_Spinner* o, void*) { + progdefaults.TxOffset = (int)o->value(); +progdefaults.changed = true; +} + Fl_Value_Input *valCWsweetspot=(Fl_Value_Input *)0; static void cb_valCWsweetspot(Fl_Value_Input* o, void*) { @@ -543,6 +550,8 @@ Fl_Value_Slider *sldrCWxmtWPM=(Fl_Value_Slider *)0; static void cb_sldrCWxmtWPM(Fl_Value_Slider* o, void*) { progdefaults.CWspeed = (int)o->value(); +cntPreTiming->maximum((int)(2400/o->value())/2.0); +cntPostTiming->maximum((int)(2400/o->value())/2.0); progdefaults.changed = true; } @@ -596,6 +605,29 @@ static void cb_cntCWdefWPM(Fl_Counter* o, void*) { progdefaults.changed = true; } +Fl_Group *tabCWQSK=(Fl_Group *)0; + +Fl_Check_Button *btnQSK=(Fl_Check_Button *)0; + +static void cb_btnQSK(Fl_Check_Button* o, void*) { + progdefaults.QSK=o->value(); +progdefaults.changed = true; +} + +Fl_Counter *cntPreTiming=(Fl_Counter *)0; + +static void cb_cntPreTiming(Fl_Counter* o, void*) { + progdefaults.CWpre=o->value(); +progdefaults.changed = true; +} + +Fl_Counter *cntPostTiming=(Fl_Counter *)0; + +static void cb_cntPostTiming(Fl_Counter* o, void*) { + progdefaults.CWpost=o->value(); +progdefaults.changed = true; +} + Fl_Group *tabDomEX=(Fl_Group *)0; Fl_Input *txtSecondary=(Fl_Input *)0; @@ -702,6 +734,12 @@ resetOLIVIA(); progdefaults.changed = true; } +Fl_Check_Button *btnPSKmailSweetSpot=(Fl_Check_Button *)0; + +static void cb_btnPSKmailSweetSpot(Fl_Check_Button* o, void*) { + progdefaults.PSKmailSweetSpot = o->value(); +} + Fl_Group *tabRTTY=(Fl_Group *)0; Fl_Choice *selShift=(Fl_Choice *)0; @@ -734,10 +772,11 @@ static void cb_selStopBits(Fl_Choice*, void*) { progdefaults.changed = true; } -Fl_Check_Button *chkMsbFirst=(Fl_Check_Button *)0; +Fl_Check_Button *chkPseudoFSK=(Fl_Check_Button *)0; -static void cb_chkMsbFirst(Fl_Check_Button*, void*) { - progdefaults.changed = true; +static void cb_chkPseudoFSK(Fl_Check_Button* o, void*) { + progdefaults.PseudoFSK = o->value(); +progdefaults.changed = true; } Fl_Button *btnRestartRtty=(Fl_Button *)0; @@ -1109,7 +1148,6 @@ static char *szBaudRates = "300|600|1200|2400|4800|9600|19200|38400|57600|115200 { Fl_Group* o = tabSoundCard = new Fl_Group(0, 25, 400, 195, "SndCrd"); o->color((Fl_Color)51); o->selection_color((Fl_Color)51); - o->hide(); { Fl_Group* o = new Fl_Group(0, 27, 400, 190); o->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE); { Fl_Group* o = new Fl_Group(5, 35, 395, 115, "Mixer"); @@ -1160,11 +1198,18 @@ static char *szBaudRates = "300|600|1200|2400|4800|9600|19200|38400|57600|115200 { Fl_Spinner* o = cntTxRateCorr = new Fl_Spinner(294, 185, 75, 24, "TX ppm:"); o->callback((Fl_Callback*)cb_cntTxRateCorr); o->step(1); - o->minimum(-5000); - o->maximum(5000); + o->minimum(-50000); + o->maximum(50000); } o->end(); } + { Fl_Spinner* o = cntTxOffset = new Fl_Spinner(172, 185, 45, 24, "Tx offset:"); + o->callback((Fl_Callback*)cb_cntTxOffset); + o->value(progdefaults.TxOffset); + o->step(1); + o->minimum(-50); + o->maximum(50); + } o->end(); } { Fl_Group* o = new Fl_Group(0, 25, 400, 195, "Misc"); @@ -1215,6 +1260,7 @@ static char *szBaudRates = "300|600|1200|2400|4800|9600|19200|38400|57600|115200 { Fl_Group* o = tabModems = new Fl_Group(0, 25, 401, 195, "Modems"); o->color((Fl_Color)51); o->selection_color((Fl_Color)51); + o->hide(); { Fl_Tabs* o = tabsModems = new Fl_Tabs(0, 25, 401, 195); o->color((Fl_Color)51); o->selection_color((Fl_Color)10); @@ -1222,6 +1268,7 @@ static char *szBaudRates = "300|600|1200|2400|4800|9600|19200|38400|57600|115200 { Fl_Group* o = tabCW = new Fl_Group(0, 50, 400, 170, "CW"); o->color((Fl_Color)51); o->selection_color((Fl_Color)51); + o->hide(); { Fl_Group* o = new Fl_Group(1, 60, 398, 155); o->box(FL_ENGRAVED_FRAME); { Fl_Value_Slider* o = sldrCWbandwidth = new Fl_Value_Slider(65, 65, 325, 20, "BW"); @@ -1338,6 +1385,35 @@ static char *szBaudRates = "300|600|1200|2400|4800|9600|19200|38400|57600|115200 } o->end(); } + { Fl_Group* o = tabCWQSK = new Fl_Group(0, 50, 400, 170, "QSK"); + o->hide(); + { Fl_Check_Button* o = btnQSK = new Fl_Check_Button(35, 75, 175, 15, "QSK on right channel"); + o->down_box(FL_DOWN_BOX); + o->callback((Fl_Callback*)cb_btnQSK); + o->value(progdefaults.QSK); + } + { Fl_Counter* o = cntPreTiming = new Fl_Counter(25, 109, 64, 21, "Pre Timing"); + o->type(1); + o->minimum(0); + o->maximum(50); + o->step(0.5); + o->value(4); + o->callback((Fl_Callback*)cb_cntPreTiming); + o->value(progdefaults.CWpre); + o->maximum((int)(2400/progdefaults.CWspeed)/2.0); + } + { Fl_Counter* o = cntPostTiming = new Fl_Counter(125, 109, 64, 21, "Post Timing"); + o->type(1); + o->minimum(0); + o->maximum(50); + o->step(0.5); + o->value(4); + o->callback((Fl_Callback*)cb_cntPostTiming); + o->value(progdefaults.CWpre); + o->maximum((int)(2400/progdefaults.CWspeed)/2.0); + } + o->end(); + } { Fl_Group* o = tabDomEX = new Fl_Group(0, 50, 401, 170, "DomEX"); o->color((Fl_Color)51); o->selection_color((Fl_Color)51); @@ -1441,6 +1517,15 @@ static char *szBaudRates = "300|600|1200|2400|4800|9600|19200|38400|57600|115200 } o->end(); } + { Fl_Group* o = new Fl_Group(0, 50, 400, 170, "PSKmail"); + { Fl_Check_Button* o = btnPSKmailSweetSpot = new Fl_Check_Button(25, 75, 155, 15, "use PSK sweetspot"); + o->down_box(FL_DOWN_BOX); + o->value(1); + o->callback((Fl_Callback*)cb_btnPSKmailSweetSpot); + o->value(progdefaults.PSKmailSweetSpot); + } + o->end(); + } { Fl_Group* o = tabRTTY = new Fl_Group(0, 50, 400, 170, "RTTY"); o->color((Fl_Color)51); o->selection_color((Fl_Color)51); @@ -1470,24 +1555,24 @@ static char *szBaudRates = "300|600|1200|2400|4800|9600|19200|38400|57600|115200 o->callback((Fl_Callback*)cb_selStopBits); o->add(szStopBits); } - { Fl_Check_Button* o = chkMsbFirst = new Fl_Check_Button(15, 126, 120, 24, "Send msb first"); + { Fl_Check_Button* o = chkPseudoFSK = new Fl_Check_Button(15, 126, 120, 24, "PseudoFSK"); o->down_box(FL_DOWN_BOX); - o->callback((Fl_Callback*)cb_chkMsbFirst); - o->hide(); + o->callback((Fl_Callback*)cb_chkPseudoFSK); + o->value(progdefaults.PseudoFSK); } { Fl_Button* o = btnRestartRtty = new Fl_Button(300, 180, 79, 28, "Restart"); o->callback((Fl_Callback*)cb_btnRestartRtty); } - { Fl_Check_Button* o = btnCRCRLF = new Fl_Check_Button(16, 155, 115, 15, "CR-CR-LF"); + { Fl_Check_Button* o = btnCRCRLF = new Fl_Check_Button(15, 155, 115, 15, "CR-CR-LF"); o->down_box(FL_DOWN_BOX); o->callback((Fl_Callback*)cb_btnCRCRLF); o->when(FL_WHEN_RELEASE_ALWAYS); } - { Fl_Check_Button* o = btnAUTOCRLF = new Fl_Check_Button(16, 184, 125, 15, "AutoCRLF"); + { Fl_Check_Button* o = btnAUTOCRLF = new Fl_Check_Button(15, 184, 125, 15, "AutoCRLF"); o->down_box(FL_DOWN_BOX); o->callback((Fl_Callback*)cb_btnAUTOCRLF); } - { Fl_Counter* o = cntrAUTOCRLF = new Fl_Counter(142, 181, 65, 20, "after:"); + { Fl_Counter* o = cntrAUTOCRLF = new Fl_Counter(150, 181, 65, 20, "after:"); o->type(1); o->minimum(68); o->maximum(80); diff --git a/src/dialogs/Config.fl b/src/dialogs/Config.fl index 60e16152..191d9e75 100644 --- a/src/dialogs/Config.fl +++ b/src/dialogs/Config.fl @@ -461,7 +461,7 @@ progdefaults.changed = true;} } Fl_Group tabSoundCard { label SndCrd open - xywh {0 25 400 195} color 51 selection_color 51 hide + xywh {0 25 400 195} color 51 selection_color 51 } { Fl_Group {} {open xywh {0 27 400 190} align 21 @@ -549,10 +549,20 @@ progdefaults.changed = true;} progdefaults.changed = true;} xywh {294 185 75 24} code0 {o->step(1);} - code1 {o->minimum(-5000);} - code2 {o->maximum(5000);} + code1 {o->minimum(-50000);} + code2 {o->maximum(50000);} } } + Fl_Spinner cntTxOffset { + label {Tx offset:} + callback {progdefaults.TxOffset = (int)o->value(); +progdefaults.changed = true;} selected + xywh {172 185 45 24} + code0 {o->value(progdefaults.TxOffset);} + code1 {o->step(1);} + code2 {o->minimum(-50);} + code3 {o->maximum(50);} + } } Fl_Group {} { label Misc open @@ -600,14 +610,14 @@ progdefaults.changed = true;} } Fl_Group tabModems { label Modems open - xywh {0 25 401 195} color 51 selection_color 51 + xywh {0 25 401 195} color 51 selection_color 51 hide } { Fl_Tabs tabsModems {open xywh {0 25 401 195} color 51 selection_color 10 align 9 } { Fl_Group tabCW { label CW open - xywh {0 50 400 170} color 51 selection_color 51 + xywh {0 50 400 170} color 51 selection_color 51 hide } { Fl_Group {} {open xywh {1 60 398 155} box ENGRAVED_FRAME @@ -644,6 +654,8 @@ progdefaults.changed = true;} Fl_Value_Slider sldrCWxmtWPM { label TxWPM callback {progdefaults.CWspeed = (int)o->value(); +cntPreTiming->maximum((int)(2400/o->value())/2.0); +cntPostTiming->maximum((int)(2400/o->value())/2.0); progdefaults.changed = true;} xywh {65 135 325 20} type {Horz Knob} color 215 align 4 minimum 5 maximum 100 step 1 value 20 textsize 14 code0 {o->value(progdefaults.CWspeed);} @@ -694,12 +706,40 @@ progdefaults.changed = true;} Fl_Counter cntCWdefWPM { label Default callback {progdefaults.defCWspeed = (int)o->value(); -progdefaults.changed = true;} selected +progdefaults.changed = true;} xywh {65 160 64 21} type Simple align 4 minimum 5 maximum 200 step 1 value 18 code0 {o->value(progdefaults.defCWspeed);} } } } + Fl_Group tabCWQSK { + label QSK open + xywh {0 50 400 170} hide + } { + Fl_Check_Button btnQSK { + label {QSK on right channel} + callback {progdefaults.QSK=o->value(); +progdefaults.changed = true;} + xywh {35 75 175 15} down_box DOWN_BOX + code0 {o->value(progdefaults.QSK);} + } + Fl_Counter cntPreTiming { + label {Pre Timing} + callback {progdefaults.CWpre=o->value(); +progdefaults.changed = true;} + xywh {25 109 64 21} type Simple minimum 0 maximum 50 step 0.5 value 4 + code0 {o->value(progdefaults.CWpre);} + code1 {o->maximum((int)(2400/progdefaults.CWspeed)/2.0);} + } + Fl_Counter cntPostTiming { + label {Post Timing} + callback {progdefaults.CWpost=o->value(); +progdefaults.changed = true;} + xywh {125 109 64 21} type Simple minimum 0 maximum 50 step 0.5 value 4 + code0 {o->value(progdefaults.CWpre);} + code1 {o->maximum((int)(2400/progdefaults.CWspeed)/2.0);} + } + } Fl_Group tabDomEX { label DomEX open xywh {0 50 401 170} color 51 selection_color 51 hide @@ -817,6 +857,17 @@ progdefaults.changed = true;} xywh {300 172 79 28} } } + Fl_Group {} { + label PSKmail open + xywh {0 50 400 170} + } { + Fl_Check_Button btnPSKmailSweetSpot { + label {use PSK sweetspot} + callback {progdefaults.PSKmailSweetSpot = o->value();} + xywh {25 75 155 15} down_box DOWN_BOX value 1 + code0 {o->value(progdefaults.PSKmailSweetSpot);} + } + } Fl_Group tabRTTY { label RTTY open xywh {0 50 400 170} color 51 selection_color 51 hide @@ -851,10 +902,12 @@ progdefaults.changed = true;} xywh {179 122 77 24} down_box BORDER_BOX code0 {o->add(szStopBits);} } {} - Fl_Check_Button chkMsbFirst { - label {Send msb first} - callback {progdefaults.changed = true;} - xywh {15 126 120 24} down_box DOWN_BOX hide + Fl_Check_Button chkPseudoFSK { + label PseudoFSK + callback {progdefaults.PseudoFSK = o->value(); +progdefaults.changed = true;} + xywh {15 126 120 24} down_box DOWN_BOX + code0 {o->value(progdefaults.PseudoFSK);} } Fl_Button btnRestartRtty { label Restart @@ -865,17 +918,17 @@ resetRTTY();} Fl_Check_Button btnCRCRLF { label {CR-CR-LF} callback {progdefaults.changed = true;} - xywh {16 155 115 15} down_box DOWN_BOX when 6 + xywh {15 155 115 15} down_box DOWN_BOX when 6 } Fl_Check_Button btnAUTOCRLF { label AutoCRLF callback {progdefaults.changed = true;} - xywh {16 184 125 15} down_box DOWN_BOX + xywh {15 184 125 15} down_box DOWN_BOX } Fl_Counter cntrAUTOCRLF { label {after:} callback {progdefaults.changed = true;} - xywh {142 181 65 20} type Simple align 4 minimum 68 maximum 80 step 1 value 72 + xywh {150 181 65 20} type Simple align 4 minimum 68 maximum 80 step 1 value 72 } Fl_Check_Button btnRTTY_USB { label {RTTY is USB} diff --git a/src/dialogs/Config.h b/src/dialogs/Config.h new file mode 100644 index 00000000..030d8610 --- /dev/null +++ b/src/dialogs/Config.h @@ -0,0 +1,140 @@ +// generated by Fast Light User Interface Designer (fluid) version 1.0107 + +#ifndef Config_h +#define Config_h +#include +#include "globals.h" +#include "modem.h" +#include "configuration.h" +extern Fl_Double_Window *dlgConfig; +#include +#include +extern Fl_Tabs *tabsConfigure; +#include +extern Fl_Group *tabOperator; +#include +extern Fl_Input *inpMyCallsign; +extern Fl_Input *inpMyName; +extern Fl_Input *inpMyQth; +extern Fl_Input *inpMyLocator; +#include +extern Fl_Check_Button *btnUseLeadingZeros; +#include +extern Fl_Value_Input *nbrContestStart; +extern Fl_Value_Input *nbrContestDigits; +extern Fl_Group *tabWaterfall; +extern Fl_Check_Button *btnBlackman; +extern Fl_Check_Button *btnHamming; +extern Fl_Check_Button *btnHanning; +extern Fl_Check_Button *btnTriangular; +extern Fl_Check_Button *btnUseCursorLines; +extern Fl_Check_Button *btnUseBWTracks; +extern Fl_Check_Button *btnUseCursorCenterLine; +extern Fl_Check_Button *btnViewXmtSignal; +#include "colorbox.h" +extern colorbox *Palette; +#include +extern Fl_Button *btnColor[9]; +extern Fl_Button *btnLoadPalette; +extern Fl_Button *btnSavePalette; +extern Fl_Group *tabInterface; +#include +extern Fl_Input *inpTTYdev; +extern Fl_Round_Button *btnRTSptt; +extern Fl_Round_Button *btnDTRptt; +extern Fl_Round_Button *btnRTSplusV; +extern Fl_Round_Button *btnDTRplusV; +#include +extern Fl_Round_Button *btnPTT[5]; +extern Fl_Check_Button *chkUSEHAMLIB; +extern Fl_Check_Button *chkUSEMEMMAP; +extern Fl_ComboBox *cboHamlibRig; +extern Fl_Input *inpRIGdev; +#include +extern Fl_Choice *mnuBaudRate; +extern Fl_Check_Button *chkUSERIGCAT; +extern Fl_Button *btnInit_Interface; +extern Fl_Check_Button *btnQRZnotavailable; +extern Fl_Check_Button *btnQRZsocket; +extern Fl_Check_Button *btnQRZcdrom; +extern Fl_Group *tabSoundCard; +extern Fl_Round_Button *btnDsp[2]; +#include +extern void setMixerInput(int); +extern Fl_Light_Button *btnLineIn; +extern Fl_Light_Button *btnMicIn; +#include +extern void setPCMvolume(double); +extern Fl_Value_Slider *valPCMvolume; +#include +extern Fl_Spinner *cntRxRateCorr; +extern Fl_Spinner *cntTxRateCorr; +extern Fl_Spinner *cntTxOffset; +extern Fl_Value_Input *valCWsweetspot; +extern Fl_Value_Input *valRTTYsweetspot; +extern Fl_Value_Input *valPSKsweetspot; +extern Fl_Check_Button *btnStartAtSweetSpot; +extern Fl_Check_Button *btnsendid; +extern Fl_Group *tabModems; +extern Fl_Tabs *tabsModems; +extern Fl_Group *tabCW; +extern Fl_Value_Slider *sldrCWbandwidth; +#include +extern Fl_Counter *cntCWrange; +extern Fl_Check_Button *btnCWrcvTrack; +#include +extern Fl_Value_Output *valCWrcvWPM; +#include +extern Fl_Progress *prgsCWrcvWPM; +extern Fl_Value_Slider *sldrCWxmtWPM; +extern Fl_Counter *cntCWlowerlimit; +extern Fl_Counter *cntCWupperlimit; +extern Fl_Counter *cntCWweight; +extern Fl_Counter *cntCWdash2dot; +extern Fl_Counter *cntCWrisetime; +extern Fl_Counter *cntCWdefWPM; +extern Fl_Group *tabCWQSK; +extern Fl_Check_Button *btnQSK; +extern Fl_Counter *cntPreTiming; +extern Fl_Counter *cntPostTiming; +extern Fl_Group *tabDomEX; +extern Fl_Input *txtSecondary; +extern Fl_Button *btnRestartDomEX; +extern Fl_Counter *valDominoEX_BW; +extern Fl_Group *tabFeld; +#include "fontdef.h" +extern Fl_Choice *selHellFont; +extern Fl_Value_Slider *sldrHellBW; +extern Fl_Check_Button *btnHellXmtWidth; +extern Fl_Check_Button *btnHellRcvWidth; +extern Fl_Check_Button *btnBlackboard; +extern Fl_Check_Button *btnHellFastAttack; +extern Fl_Check_Button *btnHellSlowAttack; +extern Fl_Check_Button *btnFeldHellIdle; +extern Fl_Group *tabOlivia; +extern Fl_Choice *mnuOlivia_Tones; +extern Fl_Choice *mnuOlivia_Bandwidth; +extern Fl_Button *btnRestartOlivia; +extern Fl_Check_Button *btnPSKmailSweetSpot; +extern Fl_Group *tabRTTY; +extern Fl_Choice *selShift; +extern Fl_Choice *selBaud; +extern Fl_Choice *selBits; +extern Fl_Choice *selParity; +extern Fl_Choice *selStopBits; +extern Fl_Check_Button *chkPseudoFSK; +extern Fl_Button *btnRestartRtty; +extern Fl_Check_Button *btnCRCRLF; +extern Fl_Check_Button *btnAUTOCRLF; +extern Fl_Counter *cntrAUTOCRLF; +extern Fl_Check_Button *btnRTTY_USB; +extern Fl_Round_Button *btnRTTYafc[3]; +extern Fl_Check_Button *btnPreferXhairScope; +#include +extern Fl_Return_Button *btnCloseConfig; +extern Fl_Button *btnSaveConfig; +Fl_Double_Window* ConfigureDialog(); +void openConfig(); +void closeDialog(); +void createConfig(); +#endif diff --git a/src/dialogs/TextView.cxx b/src/dialogs/TextView.cxx index 17609688..715e2606 100644 --- a/src/dialogs/TextView.cxx +++ b/src/dialogs/TextView.cxx @@ -57,9 +57,6 @@ textview :: textview( int x, int y, int w, int h, const char *label ) scrollbar->linesize( 1 ); scrollbar->callback( _scrollbarCB, this ); - mitems = 0; - mpopup = (Fl_Menu_Button *)0; - box( FL_DOWN_BOX ); color( FL_WHITE ); @@ -473,29 +470,39 @@ void textview :: resize( int x, int y, int w, int h ) // Viewer for received text // derived from Class textview // -// redfines the handle() and menu_cb() functions specified in the +// redefines the handle() and menu_cb() functions specified in the // base class. All other functions are in the base class //===================================================================== +void TextView::saveFile() +{ + char * fn = File_Select( + "Select ASCII text file", + "*.txt", + "", 0); + if (fn) { + ofstream out(fn); + out << buff; + out.close(); + } +} + +Fl_Menu_Item viewmenu[] = { + {"divider", 0, 0, 0, FL_MENU_DIVIDER }, + {"clear", 0, 0, 0, FL_MENU_DIVIDER }, + {"Call", 0, 0 }, + {"Name", 0, 0 }, + {"Qth", 0, 0 }, + {"Loc", 0, 0 }, + {"RstIn", 0, 0, 0, FL_MENU_DIVIDER }, + {"Save to", 0, 0 }, + {0} +}; +int viewmenuNbr = 8; + TextView::TextView( int x, int y, int w, int h, const char *label ) : textview ( x, y, w, h, label ) { - static Fl_Menu_Item menupopup[] = { - {"Dismiss", 0, _menu_cb, this, FL_MENU_DIVIDER }, - {"divider", 0, _menu_cb, this, FL_MENU_DIVIDER }, - {"clear", 0, _menu_cb, this, FL_MENU_DIVIDER }, - {"Call", 0, _menu_cb, this}, - {"Name", 0, _menu_cb, this}, - {"Qth", 0, _menu_cb, this}, - {"Loc", 0, _menu_cb, this}, - {"RstIn", 0, _menu_cb, this}, - {0} - }; - mitems = menupopup; - - mpopup = new Fl_Menu_Button(-1, -1, -1, -1); - mpopup->menu(mitems); - mpopup->type(Fl_Menu_Button::POPUP1); cursorStyle = BLOCK_CURSOR; cursorON = true; wordwrap = true; @@ -503,20 +510,32 @@ TextView::TextView( int x, int y, int w, int h, const char *label ) void TextView::menu_cb(int val) { - if (val == 1) - add("\n <<================>>\n", RCV); - else if (val == 2) - clear(); - else if (val == 3) - inpCall->value(findtext().c_str()); - else if (val == 4) - inpName->value(findtext().c_str()); - else if (val == 5) - inpQth->value(findtext().c_str()); - else if (val == 6) - inpLoc->value(findtext().c_str()); - else if (val == 7) - inpRstIn->value(findtext().c_str()); + switch (val) { + case 0: + add("\n <<================>>\n", RCV); + break; + case 1: + clear(); + break; + case 2: + inpCall->value(findtext().c_str()); + break; + case 3: + inpName->value(findtext().c_str()); + break; + case 4: + inpQth->value(findtext().c_str()); + break; + case 5: + inpLoc->value(findtext().c_str()); + break; + case 6: + inpRstIn->value(findtext().c_str()); + break; + case 7: + saveFile(); + break; + } restoreFocus(); } @@ -524,16 +543,24 @@ int TextView::handle(int event) { // handle events inside the textview and invoked by Right Mouse button or scrollbar if (Fl::event_inside( this )) { + const Fl_Menu_Item * m; int xpos = Fl::event_x(); int ypos = Fl::event_y(); if (xpos > x() + w() - 20) { scrollbar->handle(event); return 1; - } else if (event == FL_RELEASE && Fl::event_button() == 3) { + } + if (event == FL_PUSH && Fl::event_button() == 3) { popx = xpos - x(); popy = ypos - y(); - mpopup->resize (xpos, ypos, -1, -1); - mpopup->popup(); + m = viewmenu->popup(xpos, ypos, 0, 0, 0); + if (m) { + for (int i = 0; i < viewmenuNbr; i++) + if (m == &viewmenu[i]) { + menu_cb(i); + break; + } + } return 1; } } @@ -547,23 +574,19 @@ int TextView::handle(int event) // base class. All other functions are in the base class //===================================================================== +Fl_Menu_Item editmenu[] = { + {"clear", 0, 0, 0, FL_MENU_DIVIDER }, + {"File", 0, 0, 0, FL_MENU_DIVIDER }, + {"^t", 0, 0 }, + {"^r", 0, 0, 0, FL_MENU_DIVIDER }, + {"Picture", 0, 0 }, + {0} +}; +int editmenuNbr = 5; + TextEdit::TextEdit( int x, int y, int w, int h, const char *label ) : textview ( x, y, w, h, label ) { - static Fl_Menu_Item menupopup[] = { - {"Dismiss", 0, _menu_cb, this, FL_MENU_DIVIDER }, - {"clear", 0, _menu_cb, this, FL_MENU_DIVIDER }, - {"File", 0, _menu_cb, this, FL_MENU_DIVIDER }, - {"^t", 0, _menu_cb, this}, - {"^r", 0, _menu_cb, this, FL_MENU_DIVIDER }, - {"Picture", 0, _menu_cb, this }, - {0} - }; - mitems = menupopup; - - mpopup = new Fl_Menu_Button(-1, -1, -1, -1); - mpopup->menu(mitems); - mpopup->type(Fl_Menu_Button::POPUP1); chrptr = 0; bkspaces = 0; textview::cursorStyle = HEAVY_CURSOR; @@ -595,22 +618,22 @@ void TextEdit::readFile() void TextEdit::menu_cb(int val) { - if (val == 1) { + if (val == 0) { clear(); chrptr = 0; bkspaces = 0; } - if (val == 2) + if (val == 1) readFile(); - if (val == 3 && buff.empty()) { + if (val == 2 && buff.empty()) { fl_lock(&trx_mutex); trx_state = STATE_TX; fl_unlock(&trx_mutex); wf->set_XmtRcvBtn(true); } - if (val == 4) + if (val == 3) add("^r"); - if (val == 5) + if (val == 4) if (active_modem->get_mode() == MODE_MFSK16) active_modem->makeTxViewer(0,0); } @@ -678,18 +701,6 @@ int TextEdit::handle_key() { return 1; } -// substitute the FN # you want to map for each -// ie: F1 ==> 1 + Fl_F -// then remove the two slashes from each of the following lines -// if (key == FL_Left) -// return handle_fnckey(n + FL_F); -// if (key == FL_Up) -// return handle_fnckey(n + FL_F); -// if (key == FL_Right) -// return handle_fnckey(n + FL_F); -// if (key == FL_Down) -// return handle_fnckey(n + FL_F); - if (key == FL_Left) { active_modem->searchDown(); return 1; @@ -732,27 +743,36 @@ int TextEdit::handle(int event) return 1; } if (event == FL_KEYBOARD) { -// textview::cursorON = true; return handle_key(); } if (Fl::event_inside( this )) { + const Fl_Menu_Item * m; int xpos = Fl::event_x(); int ypos = Fl::event_y(); if (xpos > x() + w() - 20) { scrollbar->handle(event); return 1; - } else if (event == FL_RELEASE && Fl::event_button() == 3) { - mpopup->resize (xpos, ypos, -1, -1); - mpopup->popup(); - textview::cursorON = true; - Fl::focus(this); - redraw(); + } + if (event == FL_PUSH && Fl::event_button() == 3) { + popx = xpos - x(); + popy = ypos - y(); + m = editmenu->popup(xpos, ypos, 0, 0, 0); + if (m) { + for (int i = 0; i < editmenuNbr; i++) + if (m == &editmenu[i]) { + menu_cb(i); + break; + } + } return 1; } + switch (event) { - case FL_RELEASE: + case FL_PUSH: textview::cursorON = true; + redraw(); Fl::focus(this); + return 1; case FL_FOCUS: textview::cursorON = true; redraw(); @@ -797,76 +817,3 @@ void TextEdit::cursorON() redraw(); } -//===================================================================== -// Class MacroEdit -// derived from base class textview -// redfines the handle() and menu_cb() functions specified in the -// base class. All other functions are in the base class -//===================================================================== - -MacroEdit::MacroEdit( int x, int y, int w, int h, const char *label ) - : textview ( x, y, w, h, label ) -{ - static Fl_Menu_Item menupopup[] = { - {"Dismiss", 0, _menu_cb, this, FL_MENU_DIVIDER }, - {"clear", 0, _menu_cb, this, FL_MENU_DIVIDER }, - {0} - }; - mitems = menupopup; - - mpopup = new Fl_Menu_Button(-1, -1, -1, -1); - mpopup->menu(mitems); - mpopup->type(Fl_Menu_Button::POPUP1); -} - -void MacroEdit::menu_cb(int val) -{ - if (val == 1) { - clear(); - } -} - -int MacroEdit::handle_key() { - int key = Fl::event_key(); - if (key == FL_Enter) { - add('\n'); - return 1; - } - if (key == FL_BackSpace) { - add (0x08); - return 1; - } - const char *ch = Fl::event_text(); - add(ch); - return 1; -} - -int MacroEdit::handle(int event) -{ -// handle events inside the MacroEdit widget - if (Fl::event_inside( this )) { - int xpos = Fl::event_x(); - int ypos = Fl::event_y(); - if (xpos > x() + w() - 20) { - scrollbar->handle(event); - return 1; - } else if (event == FL_RELEASE && Fl::event_button() == 3) { - mpopup->resize (xpos, ypos, -1, -1); - mpopup->popup(); - Fl::focus(this); - return 1; - } - } - switch (event) { - case FL_RELEASE: - case FL_FOCUS: - Fl::focus(this); - return 1; - case FL_UNFOCUS: - return 1; - case FL_KEYBOARD : - return handle_key(); - } - return 0; -} - diff --git a/src/dialogs/fl_digi.cxx b/src/dialogs/fl_digi.cxx index 0b845647..4d9e07bb 100644 --- a/src/dialogs/fl_digi.cxx +++ b/src/dialogs/fl_digi.cxx @@ -30,6 +30,7 @@ #include #include #include +#include #include "version.h" @@ -78,6 +79,8 @@ Fl_Double_Window *fl_digi_main=(Fl_Double_Window *)0; cMixer mixer; Fl_Button *btnTune = (Fl_Button *)0; +Fl_Tile *TiledGroup = (Fl_Tile *)0; +//Fl_Group *TiledGroup = (Fl_Group *)0; TextView *ReceiveText=(TextView *)0; TextEdit *TransmitText=(TextEdit *)0; Fl_Text_Buffer *rcvBuffer = (Fl_Text_Buffer *)0; @@ -123,32 +126,6 @@ Fl_Progress *pgrsSquelch = (Fl_Progress *)0; Fl_RGB_Image *feld_image = 0; - -#define Hmenu 24 -#define Hqsoframe 48 -#define Hnotes 24 -#define Hrcvtxt 200 -#define Hxmttxt 100 -//#define Hrcvtxt 160 -//#define Hxmttxt 100 -#define Hwfall 140 -//#define Hwfall 118 -#define Hstatus 22 -#define Hmacros 24 -#define Wmode 80 -#define Ws2n 100 -#define Wimd 100 -#define Wwarn 16 -#define bwAfcOnOff (Hwfall -22)/2 -#define bwSqlOnOff (Hwfall -22)/2 - -#define Wwfall 754 -//#define Wwfall 654 -#define HNOM (Hwfall + Hxmttxt + Hrcvtxt + Hmenu + (Hstatus + 4) + Hmacros + Hqsoframe + Hnotes) -#define WNOM (Wwfall + Hwfall - 22) -#define Wstatus (WNOM - Wmode - Ws2n - Wimd - Wwarn - bwAfcOnOff - bwSqlOnOff) - - void clearStatus() { clear_StatusMessages(); @@ -207,6 +184,8 @@ void clean_exit() { if (bSaveFreqList) saveFreqList(); + + progStatus.saveLastState(); mixer.closeMixer(); active_modem->set_stopflag(true); @@ -1115,18 +1094,24 @@ void create_fl_digi_main() { valXmtMixer->deactivate(); MixerFrame->end(); - Fl_Group *TextFrame = new Fl_Group(sw,Y, WNOM-sw, Hrcvtxt + Hxmttxt); + Fl_Tile *TiledGroup = new Fl_Tile(sw, Y, WNOM-sw, Hrcvtxt + Hxmttxt); +// Fl_Group *TiledGroup = new Fl_Group(sw, Y, WNOM-sw, Hrcvtxt + Hxmttxt); + Fl_Box *minbox = new Fl_Box(sw,Y + 66, WNOM-sw, Hxmttxt + Hrcvtxt - 66 - 32); + minbox->hide(); + ReceiveText = new TextView(sw, Y, WNOM-sw, Hrcvtxt, ""); - Fl_Group::current()->resizable(ReceiveText); - + FHdisp = new Raster(sw, Y, WNOM-sw, Hrcvtxt); FHdisp->hide(); Y += Hrcvtxt; TransmitText = new TextEdit(sw, Y, WNOM-sw, Hxmttxt); Y += Hxmttxt; - TextFrame->end(); - Fl_Group::current()->resizable(TextFrame); + + TiledGroup->resizable(minbox); + TiledGroup->end(); + Fl_Group::current()->resizable(TiledGroup); + Fl_Box *macroFrame = new Fl_Box(0, Y, WNOM, Hmacros); macroFrame->box(FL_ENGRAVED_FRAME); @@ -1156,20 +1141,20 @@ void create_fl_digi_main() { wfpack->type(1); wf = new waterfall(0, Y, Wwfall, Hwfall); wf->end(); - Fl_Pack *ypack = new Fl_Pack(WNOM-(Hwfall-22), Y, Hwfall-22, Hwfall); - ypack->type(0); + Fl_Pack *ypack = new Fl_Pack(WNOM-(Hwfall-22), Y, Hwfall-22, Hwfall); + ypack->type(0); - digiscope = new Digiscope (WNOM-(Hwfall-22), Y, Hwfall-22, Hwfall-22); - - pgrsSquelch = new Fl_Progress( - WNOM-(Hwfall-22), Y + Hwfall - 22, - Hwfall - 22, 10, ""); - pgrsSquelch->color(FL_BACKGROUND2_COLOR, FL_DARK_GREEN); - sldrSquelch = new Fl_Slider( - FL_HOR_NICE_SLIDER, - WNOM-(Hwfall-22), Y + Hwfall - 12, - Hwfall - 22, 12, ""); - + digiscope = new Digiscope (WNOM-(Hwfall-22), Y, Hwfall-22, Hwfall-22); + + pgrsSquelch = new Fl_Progress( + WNOM-(Hwfall-22), Y + Hwfall - 22, + Hwfall - 22, 10, ""); + pgrsSquelch->color(FL_BACKGROUND2_COLOR, FL_DARK_GREEN); + sldrSquelch = new Fl_Slider( + FL_HOR_NICE_SLIDER, + WNOM-(Hwfall-22), Y + Hwfall - 12, + Hwfall - 22, 12, ""); + sldrSquelch->minimum(0); sldrSquelch->maximum(100); sldrSquelch->step(1); @@ -1178,8 +1163,8 @@ void create_fl_digi_main() { sldrSquelch->callback((Fl_Callback*)cb_sldrSquelch); sldrSquelch->color(FL_INACTIVE_COLOR); - ypack->end(); - Fl_Group::current()->resizable(wf); + ypack->end(); + Fl_Group::current()->resizable(wf); wfpack->end(); Y += (Hwfall + 2); diff --git a/src/dialogs/font_browser.cxx b/src/dialogs/font_browser.cxx index 60b119cf..c80a020d 100644 --- a/src/dialogs/font_browser.cxx +++ b/src/dialogs/font_browser.cxx @@ -98,7 +98,7 @@ void Font_Browser::FontNameSelect() if (!fn) return; - fontnbr = (Fl_Font)reinterpret_cast(lst_Font->data(fn)); + fontnbr = (Fl_Font)reinterpret_cast(lst_Font->data(fn)); // show the font name in the input txt_OutputFont->value(Fl::get_font_name(fontnbr)); diff --git a/src/dialogs/ConfigCW.fl b/src/dialogs/oldcode/ConfigCW.fl similarity index 100% rename from src/dialogs/ConfigCW.fl rename to src/dialogs/oldcode/ConfigCW.fl diff --git a/src/dialogs/ConfigTTY.fl b/src/dialogs/oldcode/ConfigTTY.fl similarity index 100% rename from src/dialogs/ConfigTTY.fl rename to src/dialogs/oldcode/ConfigTTY.fl diff --git a/src/dominoex/dominoex.cxx b/src/dominoex/dominoex.cxx index dc580403..3c56752e 100644 --- a/src/dominoex/dominoex.cxx +++ b/src/dominoex/dominoex.cxx @@ -4,8 +4,8 @@ // Copyright (C) 2001, 2002, 2003 // Tomi Manninen (oh2bns@sral.fi) // Copyright (C) 2006 -// Hamish Moffatt (hamish@debian.org) -// Copyright (C) 2006 +// Hamish Moffatt (hamish@debian.org) +// Copyright (C) 2006 // David Freese (w1hkj@w1hkj.com) // fldigi is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -47,7 +47,7 @@ void dominoex::tx_init(cSound *sc) scard = sc; txstate = TX_STATE_PREAMBLE; txprevtone = 0; - counter = 0; + counter = 0; phaseacc = 0.0; if (trx_state != STATE_TUNE && progdefaults.sendid == true) wfid->transmit(mode); @@ -102,11 +102,11 @@ void dominoex::init() } dominoex::~dominoex() -{ - if (binsfft) delete binsfft; - if (hilbert) delete hilbert; - if (pipe) delete [] pipe; - if (scopedata) delete [] scopedata; +{ + if (binsfft) delete binsfft; + if (hilbert) delete hilbert; + if (pipe) delete [] pipe; + if (scopedata) delete [] scopedata; if (filt) delete filt; if (wfid) delete wfid; } @@ -162,7 +162,7 @@ dominoex::dominoex(trx_mode md) doublespaced = 0; samplerate = 11025; break; - default: + default: // case MODE_DOMINOEX8: symlen = 1024; basetone = 128; // 1000 Hz @@ -171,17 +171,17 @@ dominoex::dominoex(trx_mode md) } tonespacing = (double) (samplerate * ((doublespaced) ? 2 : 1)) / symlen; - + binsfft = new sfft( symlen, basetone - numtones*(doublespaced?2:1), - basetone + 2*numtones*(doublespaced ? 2 : 1) ); + basetone + 2*numtones*(doublespaced ? 2 : 1) ); hilbert = new C_FIR_filter(); hilbert->init_hilbert(37, 1); afcfilt = new Cmovavg(AFC_COUNT); - pipe = new domrxpipe[2 * symlen]; + pipe = new domrxpipe[2 * symlen]; scopedata = new double[2 * symlen]; pipeptr = 0; symcounter = 0; @@ -197,7 +197,7 @@ dominoex::dominoex(trx_mode md) filt = new C_FIR_filter(); filt->init_bandpass (127, 1, flo, fhi); - + fragmentsize = symlen; s2n = 0.0; @@ -207,11 +207,11 @@ dominoex::dominoex(trx_mode md) prev1vector = prev2vector = complex(0.0, 0.0); init(); -} - -//===================================================================== -// rx modules - +} + +//===================================================================== +// rx modules + complex dominoex::mixer(complex in, double f) { complex z; @@ -229,13 +229,13 @@ complex dominoex::mixer(complex in, double f) } void dominoex::recvchar(int c) -{ +{ if (c == -1) return; if (c & 0x100) put_sec_char(c & 0xFF); else - put_rx_char(c & 0xFF); + put_rx_char(c & 0xFF); } void dominoex::decodesymbol(unsigned char curtone, unsigned char prevtone) @@ -407,7 +407,7 @@ int dominoex::rx_process(double *buf, int len) complex z, *bins, noise; while (len-- > 0) { -// create analytic signal...shift in frequency to base band & bandpass filter +// create analytic signal...shift in frequency to base band & bandpass filter z.re = z.im = *buf++; hilbert->run(z, z); z = mixer(z, frequency); @@ -442,20 +442,20 @@ int dominoex::rx_process(double *buf, int len) pipeptr = (pipeptr + 1) % (2 * symlen); } return 0; -} - -//===================================================================== +} + +//===================================================================== // dominoex tx modules -int dominoex::get_secondary_char() -{ +int dominoex::get_secondary_char() +{ static unsigned int cptr = 0; - char chr; + char chr; if (cptr > strSecXmtText.length()) cptr = 0; chr = strSecXmtText[cptr++]; - put_sec_char( chr ); - return chr; -} + put_sec_char( chr ); + return chr; +} void dominoex::sendsymbol(int sym) { @@ -469,7 +469,7 @@ void dominoex::sendsymbol(int sym) if (reverse) tone = (numtones - 1) - tone; - f = tone * tonespacing + tx_frequency - bandwidth / 2; + f = tone * tonespacing + get_txfreq_woffset() - bandwidth / 2; phaseincr = twopi * f / samplerate; @@ -506,12 +506,12 @@ void dominoex::sendidle() { sendchar(0, 1); // } - -void dominoex::sendsecondary() -{ - int c = get_secondary_char(); - sendchar(c & 0xFF, 1); -} + +void dominoex::sendsecondary() +{ + int c = get_secondary_char(); + sendchar(c & 0xFF, 1); +} void dominoex::flushtx() { @@ -539,8 +539,8 @@ int dominoex::tx_process() i = get_tx_char(); if (i == 0) sendsecondary(); - else if (i == 3) - txstate = TX_STATE_END; + else if (i == 3) + txstate = TX_STATE_END; else sendchar(i, 0); if (stopflag) diff --git a/src/feld/feld.cxx b/src/feld/feld.cxx index d51ef6e0..c142bf14 100644 --- a/src/feld/feld.cxx +++ b/src/feld/feld.cxx @@ -294,7 +294,7 @@ int feld::rx_process(double *buf, int len) } break; default: - for (i = 0; i < n; i++) + for (i = 0; i < n; i++) rx(zp[i]); break; } @@ -368,7 +368,7 @@ double feld::nco(double freq) void feld::send_symbol(int currsymb, int nextsymb) { - double tone = tx_frequency; + double tone = get_txfreq_woffset(); double Amp; int outlen = 0; @@ -377,7 +377,7 @@ void feld::send_symbol(int currsymb, int nextsymb) switch (mode) { case MODE_FSKHELL : case MODE_FSKH105 : - tone = tx_frequency + (reverse ? -1 : 1) * (currsymb ? -1 : 1) * bandwidth / 2.0; + tone = get_txfreq_woffset() + (reverse ? -1 : 1) * (currsymb ? -1 : 1) * bandwidth / 2.0; break; case MODE_FELDHELL : default : diff --git a/src/ider/id.cxx b/src/ider/id.cxx index 66c84137..b7487209 100644 --- a/src/ider/id.cxx +++ b/src/ider/id.cxx @@ -59,7 +59,7 @@ void id::make_pulse() void id::make_tones() { double f; - double frequency = mode->get_txfreq(); + double frequency = mode->get_txfreq_woffset(); double sr = mode->get_samplerate(); for (int j = 0; j < NUMCHARS; j++) for (int i = 0; i < NUMTONES; i++) { diff --git a/src/include/Config.h b/src/include/Config.h index c1ed1834..030d8610 100644 --- a/src/include/Config.h +++ b/src/include/Config.h @@ -69,6 +69,7 @@ extern Fl_Value_Slider *valPCMvolume; #include extern Fl_Spinner *cntRxRateCorr; extern Fl_Spinner *cntTxRateCorr; +extern Fl_Spinner *cntTxOffset; extern Fl_Value_Input *valCWsweetspot; extern Fl_Value_Input *valRTTYsweetspot; extern Fl_Value_Input *valPSKsweetspot; @@ -92,6 +93,10 @@ extern Fl_Counter *cntCWweight; extern Fl_Counter *cntCWdash2dot; extern Fl_Counter *cntCWrisetime; extern Fl_Counter *cntCWdefWPM; +extern Fl_Group *tabCWQSK; +extern Fl_Check_Button *btnQSK; +extern Fl_Counter *cntPreTiming; +extern Fl_Counter *cntPostTiming; extern Fl_Group *tabDomEX; extern Fl_Input *txtSecondary; extern Fl_Button *btnRestartDomEX; @@ -110,13 +115,14 @@ extern Fl_Group *tabOlivia; extern Fl_Choice *mnuOlivia_Tones; extern Fl_Choice *mnuOlivia_Bandwidth; extern Fl_Button *btnRestartOlivia; +extern Fl_Check_Button *btnPSKmailSweetSpot; extern Fl_Group *tabRTTY; extern Fl_Choice *selShift; extern Fl_Choice *selBaud; extern Fl_Choice *selBits; extern Fl_Choice *selParity; extern Fl_Choice *selStopBits; -extern Fl_Check_Button *chkMsbFirst; +extern Fl_Check_Button *chkPseudoFSK; extern Fl_Button *btnRestartRtty; extern Fl_Check_Button *btnCRCRLF; extern Fl_Check_Button *btnAUTOCRLF; diff --git a/src/include/TextView.h b/src/include/TextView.h index 5752d38a..3743013f 100644 --- a/src/include/TextView.h +++ b/src/include/TextView.h @@ -94,7 +94,6 @@ public: protected: Fl_Scrollbar *scrollbar; Fl_Menu_Button *mpopup; - Fl_Menu_Item *mitems; void scrollbarCB(); inline static void _scrollbarCB( Fl_Widget* w, void* arg ) @@ -102,12 +101,6 @@ protected: ((textview*)arg)->scrollbarCB(); } - virtual void menu_cb(int){}; - inline static void _menu_cb(Fl_Widget *m, void *arg) - { - ((textview*)arg)->menu_cb(((Fl_Menu_*)m)->value()); - } - int lineCount(); void _backspace(); void _add(char c, int attribute); @@ -127,6 +120,7 @@ public: protected: int handle (int event); void menu_cb(int val); + void saveFile(); }; @@ -154,21 +148,4 @@ private: bool PauseBreak; }; -class MacroEdit : public textview { -public: - MacroEdit( int x, int y, int w, int h, const char *label = 0 ); - virtual void add( char *text, int attr = 1 ) {textview::add(text);}; - virtual void add( const char *text, int attr = 1) {textview::add((char*)text);}; - virtual void add( char c, int attr = 1) {textview::add(c);}; - virtual void clear() {textview::clear();}; -protected: - int handle_key(); - int handle (int event); - void menu_cb(int val); - virtual void setFont(Fl_Font fnt) { textview::setFont(fnt); } - virtual void setFontSize(int siz) { textview::setFontSize(siz); } - virtual void setFontColor(Fl_Color clr) { textview::setFontColor(clr); } -private: -}; - #endif diff --git a/src/include/complex.h b/src/include/complex.h index ca07d0b5..cb06ae7e 100644 --- a/src/include/complex.h +++ b/src/include/complex.h @@ -8,47 +8,52 @@ #include class complex { -public: - double re; - double im; +public: + double re; + double im; complex(double r = 0.0, double i = 0.0) { re = r; im = i; - } + } ~complex() {}; double real() { return re; }; void real(double R) {re = R;}; double imag() { return im; }; void imag(double I) {im = I;}; - complex conj () { - complex z; - z.re = re; z.im = -im; - return z; - } + +// 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; + z.im = re * y.im + im * y.re; return z; } + +// Z = X * y complex operator* (double y) { complex z; z.re = y * z.re; z.im = y * z.im; return z; - } - complex operator+ (complex y) { - complex z; - z.re = re + y.re; - z.im = im + y.im; - return z; } - complex operator- (complex y) { - complex z; - z.re = re - y.re; - z.im = im - y.im; - return z; + +// Z = X + Y + complex operator+ (complex y) { + complex z; + z.re = re + y.re; + z.im = im + y.im; + return z; } + +// Z = X - Y + complex operator- (complex y) { + complex z; + z.re = re - y.re; + z.im = im - y.im; + return z; + } + +// Z = X / Y complex operator/ (complex y) { double denom = y.re*y.re + y.im*y.im; if (denom == 0.0) denom = 1e-10; @@ -58,52 +63,45 @@ public: return z; } - complex ccor(complex x, complex y) { - complex z; - z.re = x.re * y.re + x.im * y.im; - z.im = x.re * y.im - x.im * y.re; - return z; - } - -// (complex conjugate of X) * Y - complex operator% (complex y) { // operator type for ccor in gmfsk code +// Z = (complex conjugate of X) * Y +// Z1 = x1 + jy1, or Z1 = |Z1|exp(jP1) +// 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 z; z.re = re * y.re + im * y.im; z.im = re * y.im - im * y.re; return z; } - - double ccorI(complex y) { - return (re * y.re + im * y.im); - } - double ccorQ(complex y) { - return (re * y.im - im * y.re); - } - double norm() { - return (re * re + im * im); + +// n = |Z| * |Z| + double norm() { + return (re * re + im * im); } + +// n = |Z| double mag() { return sqrt(norm()); } - double arg() { - return atan2(im, re); - } - complex csqrt() { - complex z; - z.re = sqrt(mag() + re) / M_SQRT2; - z.im = im / re / 2; - return z; - } -}; -inline complex cmac (complex *a, complex *b, int ptr, int len) { - complex z; - ptr = ptr % len; - for (int i = 0; i < len; i++) { - z = z + a[i] * b[ptr]; - ptr = (ptr + 1) % len; - } - return z; +// Z = x + jy +// Z = |Z|exp(jP) +// arg returns P + double arg() { + return atan2(im, re); + } + +}; + +inline complex cmac (complex *a, complex *b, int ptr, int len) { + complex z; + ptr = ptr % len; + for (int i = 0; i < len; i++) { + z = z + a[i] * b[ptr]; + ptr = (ptr + 1) % len; + } + return z; } diff --git a/src/include/configuration.h b/src/include/configuration.h index 7a010ef2..5ef3a7d5 100644 --- a/src/include/configuration.h +++ b/src/include/configuration.h @@ -20,6 +20,7 @@ struct configuration { double RTTYsweetspot; double PSKsweetspot; bool StartAtSweetSpot; + bool PSKmailSweetSpot; // RTTY double rtty_squelch; int rtty_shift; @@ -39,6 +40,7 @@ struct configuration { bool RTTY_USB; bool useUART; bool PreferXhairScope; + bool PseudoFSK; // CW bool useCWkeylineRTS; // use RTS for CW bool useCWkeylineDTR; // use DTR for CW @@ -52,6 +54,9 @@ struct configuration { int CWupperlimit; double CWrisetime; double CWdash2dot; + bool QSK; + double CWpre; + double CWpost; // FELD-HELL bool FELD_IDLE; @@ -105,6 +110,7 @@ struct configuration { string SCdevice; int RX_corr; int TX_corr; + int TxOffset; // Contest stuff bool UseLeadingZeros; int ContestStart; diff --git a/src/include/cw.h b/src/include/cw.h index 71355e02..0b7a3a13 100644 --- a/src/include/cw.h +++ b/src/include/cw.h @@ -123,6 +123,10 @@ protected: int lastsym; // last symbol sent double risetime; // leading/trailing edge rise time (msec) int knum; // number of samples on edges + double qrqbuf[OUTBUFSIZE]; // signal array for qrq drive + double qrqphase; // + bool firstelement; + // double *keyshape; // array defining leading edge // Receiving parameters: @@ -143,6 +147,7 @@ protected: double dash_tracking; inline double nco(double freq); + inline double qrqnco(); void update_syncscope(); void update_Status(); void sync_parameters(); diff --git a/src/include/font_browser.h b/src/include/font_browser.h index 3598d251..78a1242b 100644 --- a/src/include/font_browser.h +++ b/src/include/font_browser.h @@ -114,7 +114,7 @@ public: fontnbr = n; lst_Font->value(1); for ( int i = 1; i <= lst_Font->size() - 1; i++ ) { - if ((Fl_Font)reinterpret_cast(lst_Font->data(i)) == n) { + if ((Fl_Font)reinterpret_cast(lst_Font->data(i)) == n) { lst_Font->value(i); break; } diff --git a/src/include/main.h b/src/include/main.h index 0cc12fda..d495cc93 100644 --- a/src/include/main.h +++ b/src/include/main.h @@ -21,6 +21,31 @@ #include "rigclass.h" #endif +#define Hmenu 24 +#define Hqsoframe 48 +#define Hnotes 24 +#define Hrcvtxt 200 +#define Hxmttxt 100 +//#define Hrcvtxt 160 +//#define Hxmttxt 100 +#define Hwfall 140 +//#define Hwfall 118 +#define Hstatus 22 +#define Hmacros 24 +#define Wmode 80 +#define Ws2n 100 +#define Wimd 100 +#define Wwarn 16 +#define bwAfcOnOff (Hwfall -22)/2 +#define bwSqlOnOff (Hwfall -22)/2 + +#define Wwfall 754 +//#define Wwfall 654 +#define HNOM (Hwfall + Hxmttxt + Hrcvtxt + Hmenu + (Hstatus + 4) + Hmacros + Hqsoframe + Hnotes) +#define WNOM (Wwfall + Hwfall - 22) +#define Wstatus (WNOM - Wmode - Ws2n - Wimd - Wwarn - bwAfcOnOff - bwSqlOnOff) + + extern Fl_Mutex trx_mutex; extern Fl_Cond trx_cond; extern Fl_Thread trx_thread; diff --git a/src/include/modem.h b/src/include/modem.h index 8eb066e7..53bb5979 100644 --- a/src/include/modem.h +++ b/src/include/modem.h @@ -102,10 +102,9 @@ public: void set_sigsearch(int n) { sigsearch = n; freqerr = 0.0;}; bool freqlocked(); double get_txfreq(); + double get_txfreq_woffset(); void set_metric(double); double get_metric(); - void set_txoffset(double); - double get_txoffset(); void set_reverse(bool on); double get_bandwidth(); void set_bandwidth(double); @@ -115,6 +114,7 @@ public: int get_echo_char(); void ModulateXmtr(double *, int); + void ModulateStereo(double *, double *, int); void set_stopflag(bool b) { stopflag = b;}; diff --git a/src/include/rtty.h b/src/include/rtty.h index 96f91d8c..6d342ba5 100644 --- a/src/include/rtty.h +++ b/src/include/rtty.h @@ -77,7 +77,7 @@ private: int nbits; // RTTY_PARITY parity; int stoplen; - int msb; + int msb; bool useFSK; double phaseacc; @@ -114,6 +114,10 @@ private: double prevsymbol; complex prevsmpl; + double FSKbuf[OUTBUFSIZE]; // signal array for qrq drive + double FSKphaseacc; + double FSKnco(); + int rxmode; int txmode; int preamble; diff --git a/src/include/sound.h b/src/include/sound.h index f6cd3b0f..baf25cbf 100644 --- a/src/include/sound.h +++ b/src/include/sound.h @@ -84,6 +84,7 @@ public: void Close(); int Write(unsigned char *, int); int write_samples(double *, int); + int write_stereo(double *, double *, int); int Read(unsigned char *, int); int Read(double *, int); int Fd() { return device_fd; } diff --git a/src/include/status.h b/src/include/status.h index bb9b08d1..51a30671 100644 --- a/src/include/status.h +++ b/src/include/status.h @@ -12,11 +12,18 @@ using namespace std; struct status { - trx_mode lastmode; + int lastmode; + int mainX; + int mainY; + int mainW; + int mainH; + bool rigShown; + int rigX; + int rigY; public: - void readLastState(); void saveModeState(trx_mode m); void initLastState(); + void saveLastState(); friend std::istream &operator>>(std::istream &stream, status &c); friend std::ostream &operator<<(std::ostream &ostream, status c); }; diff --git a/src/include/version.h b/src/include/version.h index dcb35aa2..b0483d91 100644 --- a/src/include/version.h +++ b/src/include/version.h @@ -1,6 +1,6 @@ #ifndef _VERSION_H #define _VERSION_H -#define FLDIGI_VERSION "1.34" +#define FLDIGI_VERSION "1.35J" #endif diff --git a/src/main.cxx b/src/main.cxx index 618c666d..3060ca39 100644 --- a/src/main.cxx +++ b/src/main.cxx @@ -126,6 +126,7 @@ int main(int argc, char ** argv) { Fl::lock(); // start the gui thread!! Fl::visual(FL_RGB); // insure 24 bit color operation fl_register_images(); + Fl::set_fonts(0); rigcontrol = createRigDialog(); create_fl_digi_main(); @@ -150,15 +151,11 @@ int main(int argc, char ** argv) { trx_start(scDevice.c_str()); - progStatus.readLastState(); - progStatus.initLastState(); - - wf->opmode(); - progdefaults.initInterface(); - Fl::set_fonts(0); - + progStatus.initLastState(); + wf->opmode(); + if (mailserver || mailclient) { std::cout << "Starting pskmail transport layer" << std::endl; fflush(stdout); string PskMailLogName = PskMailDir; diff --git a/src/mfsk/mfsk.cxx b/src/mfsk/mfsk.cxx index 0e1c61db..5cc83abf 100644 --- a/src/mfsk/mfsk.cxx +++ b/src/mfsk/mfsk.cxx @@ -588,7 +588,7 @@ void mfsk::sendsymbol(int sym) { double f, phaseincr; - f = tx_frequency - bandwidth / 2; + f = get_txfreq_woffset() - bandwidth / 2; sym = grayencode(sym & (numtones - 1)); //printf("%5d", sym); @@ -668,9 +668,9 @@ void mfsk::sendpic(unsigned char *data, int len) if (txstate == TX_STATE_PICTURE) updateTxPic(data[i]); if (reverse) - f = tx_frequency - bandwidth * (data[i] - 128) / 256.0; + f = get_txfreq_woffset() - bandwidth * (data[i] - 128) / 256.0; else - f = tx_frequency + bandwidth * (data[i] - 128) / 256.0; + f = get_txfreq_woffset() + bandwidth * (data[i] - 128) / 256.0; for (j = 0; j < SAMPLES_PER_PIXEL; j++) { *ptr++ = cos(phaseacc); diff --git a/src/misc/configuration.cxx b/src/misc/configuration.cxx index e66e802d..439bdf6c 100644 --- a/src/misc/configuration.cxx +++ b/src/misc/configuration.cxx @@ -23,6 +23,7 @@ configuration progdefaults = { 1000, // int RTTYsweetspot; 1000, // int PSKsweetspot; true, // bool StartAtSweetSpot; + true, // bool PSKmailSweetSpot; // RTTY 25.0, // double rtty_squelch; 3, // int rtty_shift; = 170 @@ -42,6 +43,7 @@ configuration progdefaults = { false, // bool RTTY_USB; false, // bool useUART; false, // bool PreferXhairScope; + false, // bool PseudoFSK; // CW false, // bool useCWkeylineRTS; false, // bool useCWkeylineDTR; @@ -55,6 +57,9 @@ configuration progdefaults = { 50, // int CWupperlimit; 4.0, // double CWrisetime; 3.0, // double CWdash2dot; + false, // bool QSK; + 4.0, // double CWpre; + 4.0, // double CWpost; // FELD-HELL false, // bool FELD_IDLE; @@ -106,8 +111,9 @@ configuration progdefaults = { "fldigi ", // secondary text // Sound card "/dev/dsp", // string SCdevice; - 0, // double RX_corr; - 0, // double TX_corr; + 0, // int RX_corr; + 0, // int TX_corr; + 0, // int TxOffset; // Contest controls true, // bool UseLeadingZeros; 0, // int ContestStart; @@ -198,6 +204,7 @@ void configuration::writeDefaultsXML() writeXMLint(f, "FONTCOLOR", FontColor); writeXMLbool(f, "STARTATSWEETSPOT", StartAtSweetSpot); + writeXMLbool(f, "PSKMAILSWEETSPOT", PSKmailSweetSpot); writeXMLdbl(f, "CWSWEETSPOT", CWsweetspot); writeXMLdbl(f, "PSKSWEETSPOT", PSKsweetspot); writeXMLdbl(f, "RTTYSWEETSPOT", RTTYsweetspot); @@ -215,6 +222,7 @@ void configuration::writeDefaultsXML() writeXMLint(f, "RTTYAUTOCOUNT", rtty_autocount); writeXMLint(f, "RTTYAFCSPEED", rtty_afcspeed); writeXMLbool(f, "PREFERXHAIRSCOPE", PreferXhairScope); + writeXMLbool(f, "PseudoFSK", PseudoFSK); writeXMLint(f, "CWWEIGHT", CWweight); writeXMLint(f, "CWSPEED", CWspeed); @@ -226,6 +234,10 @@ void configuration::writeDefaultsXML() writeXMLbool(f, "CWTRACK", CWtrack); writeXMLdbl(f, "CWRISETIME", CWrisetime); writeXMLdbl(f, "CWDASH2DOT", CWdash2dot); + writeXMLbool(f, "QSK", QSK); + writeXMLdbl(f, "CWpre", CWpre); + writeXMLdbl(f, "CWpost", CWpost); + writeXMLint(f, "OLIVIATONES", oliviatones); writeXMLint(f, "OLIVIABW", oliviabw); writeXMLdbl(f, "DOMINOEXBW", DOMINOEX_BW); @@ -259,8 +271,9 @@ void configuration::writeDefaultsXML() writeXMLstr(f, "PTTDEV", PTTdev); writeXMLstr(f, "SECONDARYTEXT", secText); writeXMLstr(f, "SCDEVICE", SCdevice); - writeXMLdbl(f, "RXCORR", RX_corr); - writeXMLdbl(f, "TXCORR", TX_corr); + writeXMLint(f, "RXCORR", RX_corr); + writeXMLint(f, "TXCORR", TX_corr); + writeXMLint(f, "TXOFFSET", TxOffset); writeXMLbool(f, "USELEADINGZEROS", UseLeadingZeros); writeXMLint(f, "CONTESTSTART", ContestStart); writeXMLint(f, "CONTESTDIGITS", ContestDigits); @@ -390,6 +403,12 @@ void configuration::writeDefaults(ofstream &f) f << CWrisetime << endl; f << CWdash2dot << endl; f << defCWspeed << endl; + f << QSK << endl; + f << CWpre << endl; + f << CWpost << endl; + f << PseudoFSK << endl; + f << PSKmailSweetSpot << endl; + f << TxOffset << endl; } void configuration::readDefaults(ifstream &f) @@ -497,6 +516,12 @@ void configuration::readDefaults(ifstream &f) f >> CWrisetime; f >> CWdash2dot; f >> defCWspeed; + f >> QSK; + f >> CWpre; + f >> CWpost; + f >> PseudoFSK; + f >> PSKmailSweetSpot; + f >> TxOffset; } void configuration::loadDefaults() { @@ -514,11 +539,13 @@ void configuration::loadDefaults() { case PARITY_ONE : selParity->value(4); break; default : selParity->value(0); break; } - chkMsbFirst->value(rtty_msbfirst); +// chkMsbFirst->value(rtty_msbfirst); selStopBits->value(rtty_stop); btnCRCRLF->value(rtty_crcrlf); btnAUTOCRLF->value(rtty_autocrlf); cntrAUTOCRLF->value(rtty_autocount); + chkPseudoFSK->value(PseudoFSK); + for (int i = 0; i < 3; i++) if (rtty_afcspeed == i) btnRTTYafc[i]->value(1); @@ -550,7 +577,7 @@ void configuration::storeDefaults() { case 4 : rtty_parity = PARITY_ONE; break; default : rtty_parity = PARITY_NONE; break; } - rtty_msbfirst = chkMsbFirst->value(); +// rtty_msbfirst = chkMsbFirst->value(); rtty_stop = selStopBits->value(); rtty_crcrlf = btnCRCRLF->value(); rtty_autocrlf = btnAUTOCRLF->value(); @@ -666,6 +693,7 @@ int configuration::openDefaults() { valRTTYsweetspot->value(RTTYsweetspot); valPSKsweetspot->value(PSKsweetspot); btnStartAtSweetSpot->value(StartAtSweetSpot); + btnPSKmailSweetSpot->value(PSKmailSweetSpot); // txtCWFSKport->value(CWFSKport.c_str()); @@ -691,6 +719,11 @@ int configuration::openDefaults() { cntCWdash2dot->value(CWdash2dot); sldrCWxmtWPM->minimum(CWlowerlimit); sldrCWxmtWPM->maximum(CWupperlimit); + btnQSK->value(QSK); + cntPreTiming->maximum((int)(2400/CWspeed)/2.0); + cntPreTiming->value(CWpre); + cntPostTiming->maximum((int)(2400/CWspeed)/2.0); + cntPostTiming->value(CWpost); selHellFont->value(feldfontnbr); btnFeldHellIdle->value(FELD_IDLE); @@ -750,6 +783,7 @@ int configuration::openDefaults() { } cntRxRateCorr->value(RX_corr); cntTxRateCorr->value(TX_corr); + cntTxOffset->value(TxOffset); Fl::unlock(); @@ -853,9 +887,10 @@ void configuration::initInterface() { btnPTT[2]->activate(); rigMEM_init(); wf->setQSY(1); + activate_rig_menu_item(false); } else if (chkUSERIGCATis) { // start the rigCAT thread btnPTT[3]->activate(); - if (rigCAT_init() == false) { //btnPTTis == 1 ? true : false) == false) { + if (rigCAT_init() == false) { wf->USB(true); cboBand->show(); btnSideband->show(); diff --git a/src/misc/pskmail.cxx b/src/misc/pskmail.cxx index 75157b4a..808408f9 100644 --- a/src/misc/pskmail.cxx +++ b/src/misc/pskmail.cxx @@ -135,7 +135,7 @@ void check_formail() { parse_mailtext(); if (mailtext.length() > 0) { - if (mailserver) + if (mailserver && progdefaults.PSKmailSweetSpot) active_modem->set_freq(progdefaults.PSKsweetspot); pText = mailtext.begin(); diff --git a/src/misc/status.cxx b/src/misc/status.cxx index 7124b17a..8c0a8737 100644 --- a/src/misc/status.cxx +++ b/src/misc/status.cxx @@ -16,39 +16,71 @@ #include "wwv.h" #include "analysis.h" +#include "rigsupport.h" + extern void startup_modem(modem *m); status progStatus = { - MODE_BPSK31 // trx_mode lastmode; + (int)MODE_BPSK31, // trx_mode lastmode; + 0, // int mainX; + 0, // int mainY; + WNOM, // int mainW; + HNOM, // int mainH; + false, // bool rigShown; + 0, // int rigX; + 0, // int rigY; }; void status::saveModeState(trx_mode m) { - progStatus.lastmode = m; + lastmode = (int)m; +} + +void status::saveLastState() +{ + mainX = fl_digi_main->x(); + mainY = fl_digi_main->y(); + mainW = fl_digi_main->w(); + mainH = fl_digi_main->h(); + if (rigcontrol) + if (rigcontrol->visible()) { + rigShown = rigcontrol->visible(); + rigX = rigcontrol->x(); + rigY = rigcontrol->y(); + } string deffname = HomeDir; deffname.append("fldigi.status"); ofstream deffile(deffname.c_str(), ios::out); - deffile << (int)lastmode << endl; + deffile << lastmode << endl; + deffile << mainX << endl; + deffile << mainY << endl; + deffile << mainW << endl; + deffile << mainH << endl; + deffile << rigShown << endl; + deffile << rigX << endl; + deffile << rigY << endl; deffile.close(); } -void status::readLastState() -{ - int iMode; - string deffname = HomeDir; - deffname.append("fldigi.status"); - ifstream deffile(deffname.c_str(), ios::in); - if (deffile) { - deffile >> iMode; - deffile.close(); - lastmode = (trx_mode)iMode; - } -} - void status::initLastState() { - switch (lastmode) { + string deffname = HomeDir; + deffname.append("fldigi.status"); + ifstream deffile(deffname.c_str(), ios::in); + if (deffile) { + deffile >> lastmode; + deffile >> mainX; + deffile >> mainY; + deffile >> mainW; + deffile >> mainH; + deffile >> rigShown; + deffile >> rigX; + deffile >> rigY; + deffile.close(); + } + trx_mode m = (trx_mode) lastmode; + switch (m) { case MODE_CW : initCW(); break; case MODE_MFSK8 : initMFSK8(); break; case MODE_MFSK16 : initMFSK16(); break; @@ -86,4 +118,14 @@ void status::initLastState() active_modem->set_freq(progdefaults.RTTYsweetspot); else active_modem->set_freq(progdefaults.PSKsweetspot); + + fl_digi_main->resize(mainX, mainY, mainW, mainH); + if (rigShown == true) { + if (!rigcontrol) + createRigDialog(); + int rdW = rigcontrol->w(); + int rdH = rigcontrol->h(); + rigcontrol->resize(rigX, rigY, rdW, rdH); + rigcontrol->show(); + } } diff --git a/src/olivia/olivia.cxx b/src/olivia/olivia.cxx index 7c7d938c..8c3b3264 100644 --- a/src/olivia/olivia.cxx +++ b/src/olivia/olivia.cxx @@ -58,7 +58,7 @@ void olivia::tx_init(cSound *sc) preamblesent = 0; postamblesent = 0; - txbasefreq = tx_frequency; + txbasefreq = get_txfreq_woffset(); Rx->Flush(); @@ -279,7 +279,7 @@ void olivia::restart() Tx->Bandwidth = 125 * (1 << bw); Tx->SampleRate = 8000.0;//samplerate; Tx->OutputSampleRate = samplerate; - txbasefreq = tx_frequency; + txbasefreq = get_txfreq_woffset(); if (reverse) { Tx->FirstCarrierMultiplier = (txbasefreq + (Tx->Bandwidth / 2)) / 500; diff --git a/src/psk/psk.cxx b/src/psk/psk.cxx index 7849c74c..6e2d22a4 100644 --- a/src/psk/psk.cxx +++ b/src/psk/psk.cxx @@ -76,7 +76,7 @@ void psk::rx_init() dcd = 0; bitclk = 0; freqerr = 0.0; - if (mailserver) sigsearch = 3; + if (mailserver && progdefaults.PSKmailSweetSpot) sigsearch = 3; digiscope->mode(Digiscope::PHASE); put_MODEstatus(mode); } @@ -191,7 +191,7 @@ psk::psk(trx_mode pskmode) : modem() wfid = new id(this); pipeptr = 0; - if (mailserver) + if (mailserver && progdefaults.PSKmailSweetSpot) sigsearch = 3; else sigsearch = 0; @@ -283,7 +283,7 @@ void psk::searchUp() void psk::afc() { double error, ftest, sigpwr, noise; - if (mailserver) + if (mailserver && progdefaults.PSKmailSweetSpot) ftest = wf->peakFreq((int)progdefaults.PSKsweetspot, (int) bandwidth); else ftest = wf->peakFreq((int)frequency, (int)(bandwidth) ); @@ -293,7 +293,8 @@ void psk::afc() if (sigsearch) { freqerr = 0.0; if (sigpwr/noise > 2.0) {//afcthreshold) { - if (!mailserver || (mailserver && (fabs(progdefaults.PSKsweetspot - ftest) < 15))) { + if (!mailserver || (mailserver && !progdefaults.PSKmailSweetSpot) || + (mailserver && (fabs(progdefaults.PSKsweetspot - ftest) < 15))) { frequency = ftest; set_freq(frequency); sigsearch--; @@ -316,7 +317,7 @@ void psk::afc() set_freq (frequency); //sprintf(phasemsg,"%5.4f %8.2f", freqerr, frequency); //put_status(phasemsg); - } else if (mailserver) + } else if (mailserver && progdefaults.PSKmailSweetSpot) sigsearch = 3; } @@ -495,7 +496,7 @@ void psk::tx_symbol(int sym) } symbol = prevsymbol * symbol; // complex multiplication - delta = 2.0 * M_PI * tx_frequency / samplerate; + delta = 2.0 * M_PI * get_txfreq_woffset() / samplerate; for (int i = 0; i < symbollen; i++) { diff --git a/src/soundcard/sound.cxx b/src/soundcard/sound.cxx index 10f76485..17ae8f18 100644 --- a/src/soundcard/sound.cxx +++ b/src/soundcard/sound.cxx @@ -27,33 +27,37 @@ cSound::cSound(const char *dev ) { try { int err; - snd_buffer = new float[SND_BUF_LEN]; - src_buffer = new float[SND_BUF_LEN]; - cbuff = new unsigned char [2 * SND_BUF_LEN]; + snd_buffer = new float [2*SND_BUF_LEN]; //new float[SND_BUF_LEN]; + src_buffer = new float [2*SND_BUF_LEN]; //new float[SND_BUF_LEN]; + cbuff = new unsigned char [4 * SND_BUF_LEN]; //new unsigned char [2 * SND_BUF_LEN]; if (!snd_buffer || !src_buffer || !cbuff) throw("Cannot create src buffers"); - for (int i = 0; i < SND_BUF_LEN; i++) +// for (int i = 0; i < SND_BUF_LEN; i++) + for (int i = 0; i < 2*SND_BUF_LEN; i++) snd_buffer[i] = src_buffer[i] = 0.0; - for (int i = 0; i < 2 * SND_BUF_LEN; i++) +// for (int i = 0; i < 2 * SND_BUF_LEN; i++) + for (int i = 0; i < 4 * SND_BUF_LEN; i++) cbuff[i] = 0; tx_src_data = new SRC_DATA; rx_src_data = new SRC_DATA; if (!tx_src_data || !rx_src_data) throw("Cannot create source data structures"); - rx_src_state = src_new(SRC_SINC_FASTEST, 1, &err); + +// rx_src_state = src_new(SRC_SINC_FASTEST, 1, &err); + rx_src_state = src_new(SRC_SINC_FASTEST, 2, &err); if (rx_src_state == 0) throw(src_strerror(err)); - tx_src_data->src_ratio = 1.0; - tx_src_state = src_new(SRC_SINC_FASTEST, 1, &err); - if (rx_src_state == 0) + +// tx_src_state = src_new(SRC_SINC_FASTEST, 1, &err); + tx_src_state = src_new(SRC_SINC_FASTEST, 2, &err); + if (tx_src_state == 0) throw(src_strerror(err)); + rx_src_data->src_ratio = 1.0/(1.0 + rxppm/1e6); src_set_ratio ( rx_src_state, 1.0/(1.0 + rxppm/1e6)); -// tx_src_data->src_ratio = 1.0/(1.0 + txppm/1e6); - tx_src_data->src_ratio = 1.0 + txppm/1e6; // for gmfsk compatibility -// src_set_ratio ( tx_src_state, 1.0/(1.0 + txppm/1e6)); + tx_src_data->src_ratio = 1.0 + txppm/1e6; src_set_ratio ( tx_src_state, 1.0 + txppm/1e6); } catch (SndException){ @@ -99,7 +103,8 @@ int cSound::Open(int md, int freq) if (device_fd == -1) throw SndException(errno); Format(AFMT_S16_LE); // default: 16 bit little endian - Channels(1); // 1 channel +// Channels(1); // 1 channel + Channels(2); // 2 channels Frequency(freq); setfragsize(); } @@ -239,10 +244,12 @@ int cSound::Read(double *buffer, int buffersize) if (device_fd == -1) return -1; - numread = Read(cbuff, buffersize * 2); + numread = Read(cbuff, buffersize * 4); + for (int i = 0; i < buffersize * 2; i++) + src_buffer[i] = ibuff[i] / MAXSC; + for (int i = 0; i < buffersize; i++) - src_buffer[i] = - buffer[i] = ibuff[i] / MAXSC; + buffer[i] = src_buffer[2*i]; if (rxppm != progdefaults.RX_corr) { rxppm = progdefaults.RX_corr; @@ -253,6 +260,7 @@ int cSound::Read(double *buffer, int buffersize) return buffersize; // process using samplerate library + rx_src_data->data_in = src_buffer; rx_src_data->input_frames = buffersize; rx_src_data->data_out = snd_buffer; @@ -265,9 +273,10 @@ int cSound::Read(double *buffer, int buffersize) numread = rx_src_data->output_frames_gen; for (int i = 0; i < numread; i++) - buffer[i] = snd_buffer[i]; + buffer[i] = snd_buffer[2*i]; return numread; + } int cSound::write_samples(double *buf, int count) @@ -281,28 +290,26 @@ int cSound::write_samples(double *buf, int count) if (txppm != progdefaults.TX_corr) { txppm = progdefaults.TX_corr; -// tx_src_data->src_ratio = 1.0/(1.0 + txppm/1e6); -// src_set_ratio ( tx_src_state, 1.0/(1.0 + txppm/1e6)); tx_src_data->src_ratio = 1.0 + txppm/1e6; src_set_ratio ( tx_src_state, 1.0 + txppm/1e6); } if (txppm == 0) { - wbuff = new short int[count]; + wbuff = new short int[2*count]; p = (unsigned char *)wbuff; for (int i = 0; i < count; i++) { - wbuff[i] = (short int)(buf[i] * maxsc); + wbuff[2*i] = wbuff[2*i+1] = (short int)(buf[i] * maxsc); } count *= sizeof(short int); - retval = Write(p, count); + retval = Write(p, 2*count); delete [] wbuff; } else { float *inbuf; - inbuf = new float[count]; + inbuf = new float[2*count]; int bufsize; for (int i = 0; i < count; i++) - inbuf[i] = buf[i]; + inbuf[2*i] = inbuf[2*i+1] = buf[i]; tx_src_data->data_in = inbuf; tx_src_data->input_frames = count; tx_src_data->data_out = src_buffer; @@ -315,15 +322,80 @@ int cSound::write_samples(double *buf, int count) } delete [] inbuf; bufsize = tx_src_data->output_frames_gen; - wbuff = new short int[bufsize]; + wbuff = new short int[2*bufsize]; p = (unsigned char *)wbuff; - for (int i = 0; i < bufsize; i++) + for (int i = 0; i < 2*bufsize; i++) wbuff[i] = (short int)(src_buffer[i] * maxsc); + int num2write = bufsize * 2 * sizeof(short int); - retval = Write(p, bufsize * 2); + retval = Write(p, num2write); delete [] wbuff; - if (retval != bufsize * 2) + if (retval != num2write) + return -1; + retval = count; + } + + return retval; +} + +int cSound::write_stereo(double *bufleft, double *bufright, int count) +{ + int retval; + short int *wbuff; + unsigned char *p; + + if (device_fd == -1 || count <= 0) + return -1; + + if (txppm != progdefaults.TX_corr) { + txppm = progdefaults.TX_corr; + tx_src_data->src_ratio = 1.0 + txppm/1e6; + src_set_ratio ( tx_src_state, 1.0 + txppm/1e6); + } + + if (txppm == 0) { + wbuff = new short int[count]; + wbuff = new short int[2*count]; + p = (unsigned char *)wbuff; + for (int i = 0; i < count; i++) { + wbuff[2*i] = (short int)(bufleft[i] * maxsc); + wbuff[2*i + 1] = (short int)(bufright[i] * maxsc); + } + count *= sizeof(short int); + retval = Write(p, 2*count); + delete [] wbuff; + } + else { + float *inbuf; + inbuf = new float[2*count]; + int bufsize; + for (int i = 0; i < count; i++) { + inbuf[2*i] = bufleft[i]; + inbuf[2*i+1] = bufright[i]; + } + tx_src_data->data_in = inbuf; + tx_src_data->input_frames = count; + tx_src_data->data_out = src_buffer; + tx_src_data->output_frames = SND_BUF_LEN; + tx_src_data->end_of_input = 0; + + if (src_process(tx_src_state, tx_src_data) != 0) { + delete [] inbuf; + return -1; + } + delete [] inbuf; + bufsize = tx_src_data->output_frames_gen; + wbuff = new short int[2*bufsize]; + p = (unsigned char *)wbuff; + + for (int i = 0; i < 2*bufsize; i++) + wbuff[i] = (short int)(src_buffer[i] * maxsc); + + int num2write = bufsize * 2 * sizeof(short int); + retval = Write(p, num2write); + delete [] wbuff; + if (retval != num2write) return -1; retval = count; } diff --git a/src/throb/throb.cxx b/src/throb/throb.cxx index a2add2ea..3ce3287b 100644 --- a/src/throb/throb.cxx +++ b/src/throb/throb.cxx @@ -592,8 +592,8 @@ void throb::send(int symbol) tone2 = (num_tones - 1) - tone2; } - w1 = 2.0 * M_PI * (tx_frequency + freqs[tone1]) / THROB_SAMPLE_RATE; - w2 = 2.0 * M_PI * (tx_frequency + freqs[tone2]) / THROB_SAMPLE_RATE; + w1 = 2.0 * M_PI * (get_txfreq_woffset() + freqs[tone1]) / THROB_SAMPLE_RATE; + w2 = 2.0 * M_PI * (get_txfreq_woffset() + freqs[tone2]) / THROB_SAMPLE_RATE; for (i = 0; i < symlen; i++) outbuf[i] = txpulse[i] * diff --git a/src/trx/modem.cxx b/src/trx/modem.cxx index fc6a617b..4a50a54e 100644 --- a/src/trx/modem.cxx +++ b/src/trx/modem.cxx @@ -110,6 +110,10 @@ double modem::get_txfreq(void) return tx_frequency; } +double modem::get_txfreq_woffset(void) +{ + return (tx_frequency - progdefaults.TxOffset); +} int modem::get_freq() { @@ -202,3 +206,18 @@ void modem::ModulateXmtr(double *buffer, int len) } } +void modem::ModulateStereo(double *left, double *right, int len) +{ + scard->write_stereo(left, right, len); + if (progdefaults.viewXmtSignal) + for (int i = 0; i < len; i++) { + scdata[scptr] = left[i] * 0.1; + scptr++; + if (scptr == 512) { + wf->sig_data(scdata, 512); + scptr = 0; + } + } +} + + diff --git a/src/trx/trx.cxx b/src/trx/trx.cxx index 3301e5c3..f5661780 100644 --- a/src/trx/trx.cxx +++ b/src/trx/trx.cxx @@ -158,13 +158,13 @@ void trx_tune_loop() while (trx_state == STATE_TUNE) { if (_trx_tune == 0) { wf->set_XmtRcvBtn(true); - xmttune::keydown(active_modem->get_txfreq(), scard); + xmttune::keydown(active_modem->get_txfreq_woffset(), scard); _trx_tune = 1; } else - xmttune::tune(active_modem->get_txfreq(), scard); + xmttune::tune(active_modem->get_txfreq_woffset(), scard); } scard->Close(); - xmttune::keyup(active_modem->get_txfreq(), scard); + xmttune::keyup(active_modem->get_txfreq_woffset(), scard); _trx_tune = 0; } else MilliSleep(10);