diff --git a/ChangeLog b/ChangeLog index 627341ab..8c59ed05 100644 --- a/ChangeLog +++ b/ChangeLog @@ -78,6 +78,8 @@ Change Log: 33) Changed DominoEX-FEC secondary char lookup to a std::map type. 34) Corrected two coding errors which produced compile warnings in dominoex.cxx and mt63base.cxx + 35) Bug fixes for the FM Hell modes + 36) Changed the way that the video text / id is generated. 2.10.3) 1) Corrected memory leak bug. diff --git a/configure.ac b/configure.ac index a467a799..b4d8493e 100644 --- a/configure.ac +++ b/configure.ac @@ -9,7 +9,7 @@ dnl major and minor must be integers; patch may dnl contain other characters or be empty m4_define(FLDIGI_MAJOR, [2]) m4_define(FLDIGI_MINOR, [11]) -m4_define(FLDIGI_PATCH, [AC]) +m4_define(FLDIGI_PATCH, [AG]) AC_INIT([fldigi], FLDIGI_MAJOR.FLDIGI_MINOR[FLDIGI_PATCH], [w1hkj AT w1hkj DOT com]) diff --git a/src/dex/dex.cxx b/src/dex/dex.cxx index e14e1e96..5611c0bf 100644 --- a/src/dex/dex.cxx +++ b/src/dex/dex.cxx @@ -63,6 +63,7 @@ void dex::rx_init() met2 = 0.0; counter = 0; phase[0] = 0.0; + currmag = prev1mag = prev2mag = 0.0; for (int i = 0; i < DEXMAXFFTS; i++) phase[i+1] = 0.0; put_MODEstatus(mode); @@ -141,6 +142,12 @@ dex::dex(trx_mode md) samplerate = 11025; break; + case MODE_DSX11: + symlen = 1024; + doublespaced = 1; + samplerate = 11025; + break; + case MODE_DEX22: symlen = 512; doublespaced = 0; @@ -157,14 +164,12 @@ dex::dex(trx_mode md) symlen = 1024; doublespaced = 1; samplerate = 8000; - + break; case MODE_DEX16: default: symlen = 512; doublespaced = 0; samplerate = 8000; - break; - } @@ -321,7 +326,29 @@ void dex::decodesymbol() c = (int)floor(fdiff + .5) - 2; if (c < 0) c += DEXNUMMTONES; - decodeEX(c); +// decodeEX(c); + + unsigned char symbols[4]; + double avg = (currmag + prev1mag + prev2mag) / 3.0; + if (avg == 0.0) avg = 1e-20; + double softmag = currmag / avg; + + for (int i = 0; i < 4; i++) { +// hard symbol decode + if (progdefaults.DEX_SOFT == false) { + if ((c & 1) == 1) symbols[3-i] = 255; + else symbols[3-i] = 1; +// soft symbol decode + } else + symbols[3-i] = (unsigned char)clamp(256.0 * (c & 1) * softmag, 1, 255); + + c = c / 2; + } + + Rxinlv->symbols(symbols); + + for (int i = 0; i < 4; i++) decodePairs(symbols[i]); + } int dex::harddecode() @@ -416,7 +443,8 @@ void dex::eval_s2n() } noise /= (paths * DEXNUMMTONES * 2 * (doublespaced?2:1) - 1); - s2n = decayavg( s2n, sig / noise, 8); + if (noise) + s2n = decayavg( s2n, sig / noise, 8); metric = 3*(20*log10(s2n) - 9.0); @@ -463,12 +491,15 @@ int dex::rx_process(const double *buf, int len) if (--synccounter <= 0) { synccounter = symlen; currsymbol = harddecode(); + currmag = pipe[pipeptr].vector[currsymbol].mag(); + eval_s2n(); decodesymbol(); synchronize(); update_syncscope(); - eval_s2n(); prev2symbol = prev1symbol; prev1symbol = currsymbol; + prev2mag = prev1mag; + prev1mag = currmag; } pipeptr++; if (pipeptr >= twosym) @@ -497,7 +528,7 @@ int dex::get_secondary_char() void dex::sendtone(int tone, int duration) { double f, phaseincr; - f = tone * tonespacing + get_txfreq_woffset() - bandwidth / 2; + f = (tone + 0.5) * tonespacing + get_txfreq_woffset() - bandwidth / 2; phaseincr = twopi * f / samplerate; for (int j = 0; j < duration; j++) { for (int i = 0; i < symlen; i++) { diff --git a/src/dialogs/confdialog.cxx b/src/dialogs/confdialog.cxx index cd38bedb..90db42c8 100644 --- a/src/dialogs/confdialog.cxx +++ b/src/dialogs/confdialog.cxx @@ -916,6 +916,13 @@ static void cb_valDEX_PATHS(Fl_Counter* o, void*) { progdefaults.changed = true; } +Fl_Check_Button *valDEX_SOFT=(Fl_Check_Button *)0; + +static void cb_valDEX_SOFT(Fl_Check_Button* o, void*) { + progdefaults.DEX_SOFT = o->value(); +progdefaults.changed = true; +} + Fl_Group *tabDomEX=(Fl_Group *)0; Fl_Input *txtSecondary=(Fl_Input *)0; @@ -2096,7 +2103,6 @@ l with your sound hardware."); { tabDEX = new Fl_Group(0, 44, 400, 170, "Dex"); tabDEX->color((Fl_Color)51); tabDEX->selection_color((Fl_Color)51); - tabDEX->hide(); { txtDEXSecondary = new Fl_Input(20, 75, 360, 44, "Secondary Text"); txtDEXSecondary->type(4); txtDEXSecondary->callback((Fl_Callback*)cb_txtDEXSecondary); @@ -2127,6 +2133,11 @@ l with your sound hardware."); valDEX_PATHS->callback((Fl_Callback*)cb_valDEX_PATHS); o->value(progdefaults.DEX_PATHS); } // Fl_Counter* valDEX_PATHS + { Fl_Check_Button* o = valDEX_SOFT = new Fl_Check_Button(110, 177, 70, 15, "Soft decode"); + valDEX_SOFT->down_box(FL_DOWN_BOX); + valDEX_SOFT->callback((Fl_Callback*)cb_valDEX_SOFT); + o->value(progdefaults.DEX_SOFT); + } // Fl_Check_Button* valDEX_SOFT tabDEX->end(); } // Fl_Group* tabDEX { tabDomEX = new Fl_Group(0, 50, 400, 170, "Dom"); @@ -2173,6 +2184,7 @@ l with your sound hardware."); { tabFeld = new Fl_Group(0, 50, 400, 170, "Feld"); tabFeld->color((Fl_Color)51); tabFeld->selection_color((Fl_Color)51); + tabFeld->hide(); { Fl_Choice* o = selHellFont = new Fl_Choice(175, 62, 122, 20, "Feld Hell Font:"); selHellFont->down_box(FL_BORDER_BOX); selHellFont->labelfont(4); diff --git a/src/dialogs/confdialog.fl b/src/dialogs/confdialog.fl index 3e2ce414..8b193b40 100644 --- a/src/dialogs/confdialog.fl +++ b/src/dialogs/confdialog.fl @@ -1056,7 +1056,7 @@ progdefaults.changed = true;} } Fl_Group tabDEX { label Dex open - xywh {0 44 400 170} color 51 selection_color 51 hide + xywh {0 44 400 170} color 51 selection_color 51 } { Fl_Input txtDEXSecondary { label {Secondary Text} @@ -1087,6 +1087,13 @@ progdefaults.changed = true;} xywh {20 174 63 21} type Simple minimum 4 maximum 8 step 1 value 5 code0 {o->value(progdefaults.DEX_PATHS);} } + Fl_Check_Button valDEX_SOFT { + label {Soft decode} + callback {progdefaults.DEX_SOFT = o->value(); +progdefaults.changed = true;} selected + xywh {110 177 70 15} down_box DOWN_BOX + code0 {o->value(progdefaults.DEX_SOFT);} + } } Fl_Group tabDomEX { label Dom open @@ -1131,7 +1138,7 @@ progdefaults.changed = true;} } Fl_Group tabFeld { label Feld open - xywh {0 50 400 170} color 51 selection_color 51 + xywh {0 50 400 170} color 51 selection_color 51 hide } { Fl_Choice selHellFont { label {Feld Hell Font:} @@ -1144,7 +1151,7 @@ progdefaults.changed = true;} open } {} Fl_Value_Slider sldrHellBW { label {Filter BW} - callback {progdefaults.HELL_BW = sldrHellBW->value();} selected + callback {progdefaults.HELL_BW = sldrHellBW->value();} xywh {30 190 345 20} type Horizontal color 215 align 5 minimum 10 maximum 2400 step 5 value 400 textsize 14 code0 {o->value(progdefaults.HELL_BW);} } diff --git a/src/dialogs/fl_digi.cxx b/src/dialogs/fl_digi.cxx index 666b3416..6474997a 100644 --- a/src/dialogs/fl_digi.cxx +++ b/src/dialogs/fl_digi.cxx @@ -207,6 +207,7 @@ Fl_Menu_Item quick_change_dex[] = { { mode_info[MODE_DEX5].name, 0, cb_init_mode, (void *)MODE_DEX5 }, { mode_info[MODE_DEX8].name, 0, cb_init_mode, (void *)MODE_DEX8 }, { mode_info[MODE_DEX11].name, 0, cb_init_mode, (void *)MODE_DEX11 }, + { mode_info[MODE_DSX11].name, 0, cb_init_mode, (void *)MODE_DSX11 }, { mode_info[MODE_DEX16].name, 0, cb_init_mode, (void *)MODE_DEX16 }, { mode_info[MODE_DEX22].name, 0, cb_init_mode, (void *)MODE_DEX22 }, { 0 } @@ -403,7 +404,7 @@ void init_modem(trx_mode mode) break; case MODE_DEX4: case MODE_DEX5: case MODE_DEX8: - case MODE_DEX11: case MODE_DEX16: case MODE_DEX22: + case MODE_DEX11: case MODE_DSX11: case MODE_DEX16: case MODE_DEX22: startup_modem(*mode_info[mode].modem ? *mode_info[mode].modem : *mode_info[mode].modem = new dex(mode)); quick_change = quick_change_dex; @@ -1045,6 +1046,7 @@ Fl_Menu_Item menu_[] = { { mode_info[MODE_DEX5].name, 0, cb_init_mode, (void *)MODE_DEX5, 0, FL_NORMAL_LABEL, 0, 14, 0}, { mode_info[MODE_DEX8].name, 0, cb_init_mode, (void *)MODE_DEX8, 0, FL_NORMAL_LABEL, 0, 14, 0}, { mode_info[MODE_DEX11].name, 0, cb_init_mode, (void *)MODE_DEX11, 0, FL_NORMAL_LABEL, 0, 14, 0}, +{ mode_info[MODE_DSX11].name, 0, cb_init_mode, (void *)MODE_DSX11, 0, FL_NORMAL_LABEL, 0, 14, 0}, { mode_info[MODE_DEX16].name, 0, cb_init_mode, (void *)MODE_DEX16, 0, FL_NORMAL_LABEL, 0, 14, 0}, { mode_info[MODE_DEX22].name, 0, cb_init_mode, (void *)MODE_DEX22, 0, FL_NORMAL_LABEL, 0, 14, 0}, {0,0,0,0,0,0,0,0,0}, @@ -1964,6 +1966,7 @@ void resetDEX() { md == MODE_DEX5 || md == MODE_DEX8 || md == MODE_DEX11 || + md == MODE_DSX11 || md == MODE_DEX16 || md == MODE_DEX22 ) { active_modem->restart(); diff --git a/src/dominoex/dominoex.cxx b/src/dominoex/dominoex.cxx index a5810f4b..593bd73c 100644 --- a/src/dominoex/dominoex.cxx +++ b/src/dominoex/dominoex.cxx @@ -529,7 +529,7 @@ int dominoex::get_secondary_char() void dominoex::sendtone(int tone, int duration) { double f, phaseincr; - f = tone * tonespacing + get_txfreq_woffset() - bandwidth / 2; + f = (tone + 0.5) * tonespacing + get_txfreq_woffset() - bandwidth / 2.0; phaseincr = twopi * f / samplerate; for (int j = 0; j < duration; j++) { for (int i = 0; i < symlen; i++) { diff --git a/src/feld/feld.cxx b/src/feld/feld.cxx index cda72ce7..9c487d0b 100644 --- a/src/feld/feld.cxx +++ b/src/feld/feld.cxx @@ -114,7 +114,7 @@ feld::feld(trx_mode m) feldcolumnrate = 17.5; break; case MODE_FSKH105: - feldcolumnrate = 17.5; + feldcolumnrate = 7.5;//17.5; break; case MODE_HELL80: feldcolumnrate = 35; @@ -132,15 +132,19 @@ feld::feld(trx_mode m) hell_bandwidth = txpixrate; - if (hell_bandwidth != progdefaults.HELL_BW) { - progdefaults.HELL_BW = hell_bandwidth; - set_bandwidth(hell_bandwidth); - } + set_bandwidth(hell_bandwidth); hilbert = new C_FIR_filter(); hilbert->init_hilbert(37, 1); + + filter_bandwidth = hell_bandwidth; + + if (filter_bandwidth != progdefaults.HELL_BW) + progdefaults.HELL_BW = filter_bandwidth; + +std::cout << hell_bandwidth << ", " << progdefaults.HELL_BW << std::endl; - lp = 1.5 * hell_bandwidth / samplerate; + lp = 1.5 * filter_bandwidth / samplerate; bpfilt = new fftfilt(0, lp, 1024); @@ -276,11 +280,10 @@ int feld::rx_process(const double *buf, int len) blackboard = btnBlackboard->value(); FL_UNLOCK_D(); - if (progdefaults.HELL_BW != hell_bandwidth) { + if (progdefaults.HELL_BW != filter_bandwidth) { double lp; - hell_bandwidth = progdefaults.HELL_BW; - set_bandwidth(hell_bandwidth); - lp = 1.5 * hell_bandwidth / 2.0 / samplerate; + filter_bandwidth = progdefaults.HELL_BW; + lp = 1.5 * filter_bandwidth / 2.0 / samplerate; bpfilt->create_filter(0, lp); } @@ -387,6 +390,8 @@ void feld::send_symbol(int currsymb, int nextsymb) Amp = 1.0; switch (mode) { case MODE_FSKHELL : + tone = midtone + (reverse ? -1 : 1) * (currsymb ? -1 : 1) * txpixrate / 2.0; + break; case MODE_FSKH105 : tone = midtone + (reverse ? -1 : 1) * (currsymb ? -1 : 1) * txpixrate / 2.0; break; diff --git a/src/globals/globals.cxx b/src/globals/globals.cxx index cca2188e..6ad13218 100644 --- a/src/globals/globals.cxx +++ b/src/globals/globals.cxx @@ -52,6 +52,7 @@ const struct mode_info_t mode_info[NUM_MODES] = { { MODE_DEX5, &dex5_modem, "DEX5", "DEX 5", "DEX5", "DEX" }, { MODE_DEX8, &dex8_modem, "DEX8", "DEX 8", "DEX8", "DEX" }, { MODE_DEX11, &dex11_modem, "DEX11", "DEX 11", "DEX11", "DEX" }, + { MODE_DSX11, &dsx11_modem, "DSX11", "DSX 11", "DSX11", "DEX" }, { MODE_DEX16, &dex16_modem, "DEX16", "DEX 16", "DEX16", "DEX" }, { MODE_DEX22, &dex22_modem, "DEX22", "DEX 22", "DEX22", "DEX" }, diff --git a/src/include/confdialog.h b/src/include/confdialog.h index 42ee0c15..ade27687 100644 --- a/src/include/confdialog.h +++ b/src/include/confdialog.h @@ -142,6 +142,7 @@ extern Fl_Input *txtDEXSecondary; extern Fl_Counter *valDEX_BW; extern Fl_Check_Button *valDEX_FILTER; extern Fl_Counter *valDEX_PATHS; +extern Fl_Check_Button *valDEX_SOFT; extern Fl_Group *tabDomEX; extern Fl_Input *txtSecondary; extern Fl_Counter *valDominoEX_BW; diff --git a/src/include/configuration.h b/src/include/configuration.h index 895e3f6a..b33cf4de 100644 --- a/src/include/configuration.h +++ b/src/include/configuration.h @@ -79,6 +79,7 @@ struct configuration { bool DEX_FILTER; string DEXsecText; int DEX_PATHS; + bool DEX_SOFT; // DOMINOEX double DOMINOEX_BW; bool DOMINOEX_FILTER; diff --git a/src/include/dex.h b/src/include/dex.h index a5b2b048..ff99fc47 100644 --- a/src/include/dex.h +++ b/src/include/dex.h @@ -93,6 +93,10 @@ protected: int currsymbol; int prev1symbol; int prev2symbol; + + double currmag; + double prev1mag; + double prev2mag; double met1; double met2; diff --git a/src/include/feld.h b/src/include/feld.h index 3940f69f..af933565 100644 --- a/src/include/feld.h +++ b/src/include/feld.h @@ -70,6 +70,7 @@ protected: double txphacc; double txcounter; double hell_bandwidth; + double filter_bandwidth; int depth; int dxmode; diff --git a/src/include/filters.h b/src/include/filters.h index 110b727f..d7af2de2 100644 --- a/src/include/filters.h +++ b/src/include/filters.h @@ -37,7 +37,7 @@ //===================================================================== class C_FIR_filter { -#define FIRBufferLen 1024 +#define FIRBufferLen 4096 private: int length; int decimateratio; diff --git a/src/include/globals.h b/src/include/globals.h index 70ffbea8..df5c7d7d 100644 --- a/src/include/globals.h +++ b/src/include/globals.h @@ -55,6 +55,7 @@ enum { MODE_DEX5, MODE_DEX8, MODE_DEX11, + MODE_DSX11, MODE_DEX16, MODE_DEX22, diff --git a/src/include/modem.h b/src/include/modem.h index 4e61a850..821e79c0 100644 --- a/src/include/modem.h +++ b/src/include/modem.h @@ -198,6 +198,7 @@ extern modem *dex4_modem; extern modem *dex5_modem; extern modem *dex8_modem; extern modem *dex11_modem; +extern modem *dsx11_modem; extern modem *dex16_modem; extern modem *dex22_modem; extern modem *dominoex4_modem; diff --git a/src/misc/configuration.cxx b/src/misc/configuration.cxx index f02d3609..42305b11 100644 --- a/src/misc/configuration.cxx +++ b/src/misc/configuration.cxx @@ -84,6 +84,7 @@ configuration progdefaults = { true, // bool DEX_FILTER; "fldigi-dex ", // string DEXsecText; 5, // int DEX_PATHS; + false, // bool DEX_SOFT; // DOMINOEX 2.0, // double DOMINOEX_BW; true, // bool DOMINOEX_FILTER @@ -251,7 +252,7 @@ enum TAG { \ CWTRACK, CWRISETIME, CWDASH2DOT, XQSK, CWPRE, CWPOST, CWID, CWIDWPM, OLIVIATONES, OLIVIABW, OLIVIASMARGIN, OLIVIASINTEG, OLIVIA8BIT, - DEXBW, DEXFILTER, DEXSECTEXT, DEXPATHS, + DEXBW, DEXFILTER, DEXSECTEXT, DEXPATHS, DEXSOFT, DOMINOEXBW, DOMINOEXFILTER, DOMINOEXFEC, DOMINOEXPATHS, FELDFONTNBR, FELDIDLE, WFPREFILTER, LATENCY, @@ -396,6 +397,7 @@ void configuration::writeDefaultsXML() writeXMLbool(f, "DEXFILTER", DEX_FILTER); writeXMLstr(f, "DEXSECTEXT", DEXsecText); writeXMLint(f, "DEXPATHS", DEX_PATHS); + writeXMLbool(f, "DEXSOFT", DEX_SOFT); writeXMLdbl(f, "DOMINOEXBW", DOMINOEX_BW); writeXMLbool(f, "DOMINOEXFILTER", DOMINOEX_FILTER); @@ -701,6 +703,9 @@ bool configuration::readDefaultsXML() case DEXPATHS : DEX_PATHS = atoi(xml->getNodeData()); break; + case DEXSOFT : + DEX_SOFT = atoi(xml->getNodeData()); + break; case DOMINOEXBW : DOMINOEX_BW = atof(xml->getNodeData()); break; @@ -1067,6 +1072,7 @@ bool configuration::readDefaultsXML() else if (!strcmp("DEXFILTER", nodeName)) tag = DEXFILTER; else if (!strcmp("DEXSECTEXT", nodeName)) tag = DEXSECTEXT; else if (!strcmp("DEXPATHS", nodeName)) tag = DEXPATHS; + else if (!strcmp("DEXSOFT", nodeName)) tag = DEXSOFT; else if (!strcmp("DOMINOEXBW", nodeName)) tag = DOMINOEXBW; else if (!strcmp("DOMINOEXFILTER", nodeName)) tag = DOMINOEXFILTER; else if (!strcmp("DOMINOEXFEC", nodeName)) tag = DOMINOEXFEC; @@ -1285,6 +1291,7 @@ int configuration::setDefaults() { valDEX_BW->value(DEX_BW); valDEX_FILTER->value(DEX_FILTER); valDEX_PATHS->value(DEX_PATHS); + valDEX_SOFT->value(DEX_SOFT); valDominoEX_BW->value(DOMINOEX_BW); valDominoEX_FILTER->value(DOMINOEX_FILTER); diff --git a/src/trx/modem.cxx b/src/trx/modem.cxx index ba3e27b7..f3ed9b46 100644 --- a/src/trx/modem.cxx +++ b/src/trx/modem.cxx @@ -3,6 +3,8 @@ #include +#include "filters.h" + #include "confdialog.h" #include "modem.h" #include "configuration.h" @@ -39,6 +41,7 @@ modem *dex4_modem = 0; modem *dex5_modem = 0; modem *dex8_modem = 0; modem *dex11_modem = 0; +modem *dsx11_modem = 0; modem *dex16_modem = 0; modem *dex22_modem = 0; modem *dominoex4_modem = 0; @@ -278,19 +281,21 @@ void modem::videoText() //===================================================================== // transmit processing of waterfall video id //===================================================================== -//#define progdefaults.videowidth 3 #define MAXCHARS 4 + #define NUMCOLS 8 -#define MAXBITS 7 #define NUMROWS 14 #define CHARSPACE 2 #define TONESPACING 8 -#define IDSYMLEN 4096 + +#define IDSYMLEN 2048 #define RISETIME 20 -struct mfntchr { char c; int byte[NUMROWS]; }; +struct mfntchr { char c; int byte[14];};//NUMROWS]; }; extern mfntchr idch[]; +C_FIR_filter vidfilt; + void modem::wfid_make_pulse() { double risetime = (samplerate / 1000) * RISETIME; @@ -303,34 +308,47 @@ void modem::wfid_make_pulse() void modem::wfid_make_tones() { - double f; - f = frequency + TONESPACING * ( progdefaults.videowidth * ((NUMCOLS - 1)) / 2.0 + (progdefaults.videowidth - 1) * CHARSPACE); + double f, flo, fhi; + f = TONESPACING * ( progdefaults.videowidth * (NUMCOLS - 1) + (progdefaults.videowidth) * CHARSPACE) / 2.0; + f = 2.0 * floor((frequency + f)/2.0); + fhi = f + 2 * TONESPACING; + flo = f - (progdefaults.videowidth * (NUMCOLS + CHARSPACE) + 2) * TONESPACING; for (int i = 0; i < NUMCOLS * progdefaults.videowidth; i++) { wfid_w[i] = f * 2.0 * M_PI / samplerate; f -= TONESPACING; if ( (i > 0) && (i % NUMCOLS == 0) ) f -= TONESPACING * CHARSPACE; } + vidfilt.init_bandpass( 1024, 1, flo/samplerate, fhi/samplerate) ; } void modem::wfid_send(long int symbol) { int i, j; int sym; - int msk = 0; + double val; + for (i = 0; i < IDSYMLEN; i++) { wfid_outbuf[i] = 0.0; + val = 0.0; sym = symbol; for (j = 0; j < NUMCOLS * progdefaults.videowidth; j++) { if ((sym & 1) == 1) - wfid_outbuf[i] += ((msk & 1) == 1 ? -1 : 1 ) * sin(wfid_w[j] * i)* wfid_txpulse[i]; + val += sin(wfid_w[j] * i); sym = sym >> 1; - msk = msk >> 1; } +// soft limit the signal + wfid_outbuf[i] = 0.707 * (1.0 - exp(fabs(val)/-3.0)) * (val >= 0.0 ? 1 : -1); } - for (i = 0; i < IDSYMLEN; i++) - wfid_outbuf[i] = wfid_outbuf[i] / (MAXBITS * progdefaults.videowidth); - + +// band pass filter the hard limited signal + + for (i = 0; i < IDSYMLEN; i++) { + val = wfid_outbuf[i]; + vidfilt.Irun (val, val); + wfid_outbuf[i] = val * wfid_txpulse[i]; + } + ModulateXmtr(wfid_outbuf, IDSYMLEN); } @@ -342,7 +360,7 @@ void modem::wfid_sendchar(char c) if (c < ' ' || c > '~') return; n = c - ' '; for (int row = 0; row < NUMROWS; row++) { - symbol = (idch[n].byte[NUMROWS - 1 -row]) >> (16 - NUMCOLS); + symbol = (idch[n].byte[NUMROWS - 1 - row]) >> (16 - NUMCOLS); wfid_send (symbol); if (stopflag) return; @@ -352,25 +370,32 @@ void modem::wfid_sendchar(char c) void modem::wfid_sendchars(string s) { long int symbol; - int len = s.length(); + int len; unsigned int n[progdefaults.videowidth]; int c; - while (len++ < progdefaults.videowidth) s.insert(0," "); + + while (s[0] == ' ') s.erase(0); + len = s.length(); - for (int i = 0; i < progdefaults.videowidth; i++) { + for (int i = 0; i < len; i++) { //progdefaults.videowidth; i++) { c = s[i]; if (c > '~' || c < ' ') c = ' '; c -= ' '; n[i] = c; } + // send rows from bottom to top so they appear to scroll down the waterfall correctly for (int row = 0; row < NUMROWS; row++) { symbol = 0; - for (int i = 0; i < progdefaults.videowidth; i++) { + for (int i = 0; i < len; i++) {//progdefaults.videowidth; i++) { symbol |= (idch[n[i]].byte[NUMROWS - 1 -row] >> (16 - NUMCOLS)); - if (i != (progdefaults.videowidth - 1) ) + if (i != (len - 1) ) symbol = symbol << NUMCOLS; } + + if (len < progdefaults.videowidth) + symbol = symbol << NUMCOLS * (progdefaults.videowidth - len) / 2; + wfid_send (symbol); if (stopflag) return; @@ -430,7 +455,7 @@ mfntchr idch[] = { {'.', { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xC000, 0xC000, 0xC000, 0x0000, 0x0000 }, }, {'/', { 0x0000, 0x0800, 0x0800, 0x1800, 0x1000, 0x3000, 0x2000, 0x6000, 0x4000, 0xC000, 0x8000, 0x8000, 0x0000, 0x0000 }, }, {'0', { 0x0000, 0x0000, 0x7800, 0xFC00, 0x8C00, 0x9C00, 0xB400, 0xE400, 0xC400, 0x8400, 0xFC00, 0x7800, 0x0000, 0x0000 }, }, -{'1', { 0x0000, 0x0000, 0x2000, 0x6000, 0xE000, 0xA000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x2000, 0x0000, 0x0000 }, }, +{'1', { 0x0000, 0x0000, 0x1000, 0x3000, 0x7000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x0000, 0x0000 }, }, {'2', { 0x0000, 0x0000, 0x7800, 0xFC00, 0x8400, 0x0C00, 0x1800, 0x3000, 0x6000, 0xC000, 0xFC00, 0xFC00, 0x0000, 0x0000 }, }, {'3', { 0x0000, 0x0000, 0xFC00, 0xFC00, 0x0400, 0x0C00, 0x1800, 0x1C00, 0x0400, 0x8400, 0xFC00, 0x7800, 0x0000, 0x0000 }, }, {'4', { 0x0000, 0x0000, 0x3800, 0x7800, 0x4800, 0xC800, 0x8800, 0xFC00, 0xFC00, 0x0800, 0x0800, 0x0800, 0x0000, 0x0000 }, }, diff --git a/src/widgets/FTextView.cxx b/src/widgets/FTextView.cxx index 87d70d91..66e922ea 100644 --- a/src/widgets/FTextView.cxx +++ b/src/widgets/FTextView.cxx @@ -187,7 +187,18 @@ void FTextBase::readFile(void) { const char *fn = file_select("Append text", "Text\t*.txt"); if (fn) { +#ifdef WIN32 + string text; + ifstream tfile(fn); + char ch; + while (tfile) { + tfile.get(ch); + if (ch != '\r') text += ch; + } + tbuf->append(text.c_str()); +#else tbuf->appendfile(fn); +#endif insert_position(tbuf->length()); show_insert_position(); }