kopia lustrzana https://github.com/jamescoxon/dl-fldigi
Inline macro tags
* Created ability to delay execution of designated tags until the time of occurrence in the transmit character stream. These include: - <DTMF - dual tones - <!WPM - CW words per minute - <!POST - CW post delay - <!PRE - CW pre delay - <!RISE - CW rise/decay time - <!MODEM - change to specified modem - <!GOHOME - move to mode sweet spot audio frequency - <!GOFREQ - move to a specific audio frequency - <!IDLE - idle for specified number of seconds - <!WAIT - wait for specified number of seconds - <!QSY - move to specifed RF and Audio frequency The <! tags use the same parameters as their non delayed counterparts * Added NULL modem, a device which does not receive but can enable transmit. - used as modem type before !QSY, !GOFREQ etc to suppress transmit of audio stream - used with <DTMF... to transmit DTMF tones and suppress any other modem audio stream * Changed end of transmission logic to MT63 modem to allow it to be specified in <!MODEM * Corrected string to numeric conversion * Added abort processing / queue reset * Modified macro parsing to allow multiple invocations of macro containing <! tags * Added ability to schedule a single macro execution at a specifice GMT date and time tag format <SKED:hhmm[:YYYYDDMM]> where the date defaults to current date.pull/2/head
rodzic
d2c33e4889
commit
bb258cd1fc
|
@ -368,6 +368,7 @@ fldigi_SOURCES += \
|
|||
include/rsid.h \
|
||||
include/rtty.h \
|
||||
include/view_rtty.h \
|
||||
include/nullmodem.h \
|
||||
include/rx_extract.h \
|
||||
include/speak.h \
|
||||
include/serial.h \
|
||||
|
@ -480,6 +481,7 @@ fldigi_SOURCES += \
|
|||
ssb/ssb.cxx \
|
||||
throb/throb.cxx \
|
||||
trx/modem.cxx \
|
||||
trx/nullmodem.cxx \
|
||||
trx/trx.cxx \
|
||||
waterfall/colorbox.cxx \
|
||||
waterfall/digiscope.cxx \
|
||||
|
|
|
@ -77,6 +77,7 @@
|
|||
#endif
|
||||
#include "rigio.h"
|
||||
#include "rigMEM.h"
|
||||
#include "nullmodem.h"
|
||||
#include "psk.h"
|
||||
#include "cw.h"
|
||||
#include "mfsk.h"
|
||||
|
@ -970,6 +971,11 @@ void init_modem(trx_mode mode, int freq)
|
|||
mode = NUM_MODES - 1;
|
||||
return init_modem(mode, freq);
|
||||
|
||||
case MODE_NULL:
|
||||
startup_modem(*mode_info[mode].modem ? *mode_info[mode].modem :
|
||||
*mode_info[mode].modem = new NULLMODEM, freq);
|
||||
break;
|
||||
|
||||
case MODE_CW:
|
||||
startup_modem(*mode_info[mode].modem ? *mode_info[mode].modem :
|
||||
*mode_info[mode].modem = new cw, freq);
|
||||
|
@ -2220,6 +2226,7 @@ void stopMacroTimer()
|
|||
progStatus.timer = 0;
|
||||
progStatus.repeatMacro = -1;
|
||||
Fl::remove_timeout(macro_timer);
|
||||
Fl::remove_timeout(macro_timed_execute);
|
||||
|
||||
btnMacroTimer->label(0);
|
||||
btnMacroTimer->color(FL_BACKGROUND_COLOR);
|
||||
|
@ -2240,6 +2247,32 @@ void macro_timer(void*)
|
|||
Fl::repeat_timeout(1.0, macro_timer);
|
||||
}
|
||||
|
||||
void macro_timed_execute(void *)
|
||||
{
|
||||
if (exec_date == zdate() && exec_time == ztime()) {
|
||||
macros.timed_execute();
|
||||
btnMacroTimer->label(0);
|
||||
btnMacroTimer->color(FL_BACKGROUND_COLOR);
|
||||
btnMacroTimer->set_output();
|
||||
} else {
|
||||
Fl::repeat_timeout(1.0, macro_timed_execute);
|
||||
}
|
||||
}
|
||||
|
||||
void startTimedExecute(std::string &title)
|
||||
{
|
||||
ENSURE_THREAD(FLMAIN_TID);
|
||||
Fl::add_timeout(0.0, macro_timed_execute);
|
||||
string txt = "Macro '";
|
||||
txt.append(title).append("' scheduled at ");
|
||||
txt.append(exec_time).append(", on ").append(exec_date).append("\n");
|
||||
btnMacroTimer->label("SKED");
|
||||
btnMacroTimer->color(fl_rgb_color(240, 240, 0));
|
||||
btnMacroTimer->redraw_label();
|
||||
ReceiveText->clear();
|
||||
ReceiveText->add(txt.c_str(), FTextBase::CTRL);
|
||||
}
|
||||
|
||||
void cbMacroTimerButton(Fl_Widget*, void*)
|
||||
{
|
||||
stopMacroTimer();
|
||||
|
@ -3017,6 +3050,7 @@ Fl_Menu_Item menu_[] = {
|
|||
{ mode_info[MODE_PSK250].name, 0, cb_init_mode, (void *)MODE_PSK250, 0, FL_NORMAL_LABEL, 0, 14, 0},
|
||||
{0,0,0,0,0,0,0,0,0},
|
||||
|
||||
{ mode_info[MODE_NULL].name, 0, cb_init_mode, (void *)MODE_NULL, 0, FL_NORMAL_LABEL, 0, 14, 0},
|
||||
{ mode_info[MODE_SSB].name, 0, cb_init_mode, (void *)MODE_SSB, 0, FL_NORMAL_LABEL, 0, 14, 0},
|
||||
|
||||
{ mode_info[MODE_WWV].name, 0, cb_init_mode, (void *)MODE_WWV, 0, FL_NORMAL_LABEL, 0, 14, 0},
|
||||
|
@ -3631,7 +3665,7 @@ void create_fl_digi_main_primary() {
|
|||
int Hmacrobtn;
|
||||
int xpos;
|
||||
int ypos;
|
||||
int wblank;
|
||||
int wBLANK;
|
||||
|
||||
int fnt = fl_font();
|
||||
int fsize = fl_size();
|
||||
|
@ -4273,14 +4307,14 @@ void create_fl_digi_main_primary() {
|
|||
Fl_Group *btngroup2 = new Fl_Group(0, Y + 1, progStatus.mainW - Hmacros, Hmacros - 1);
|
||||
Wmacrobtn = (btngroup2->w()) / NUMMACKEYS;
|
||||
Hmacrobtn = btngroup2->h() - 1;
|
||||
wblank = (btngroup2->w() - NUMMACKEYS * Wmacrobtn) / 2;
|
||||
wBLANK = (btngroup2->w() - NUMMACKEYS * Wmacrobtn) / 2;
|
||||
xpos = 0;
|
||||
ypos = btngroup2->y();
|
||||
for (int i = 0; i < NUMMACKEYS; i++) {
|
||||
if (i == 4 || i == 8) {
|
||||
bx = new Fl_Box(xpos, ypos, wblank, Hmacrobtn);
|
||||
bx = new Fl_Box(xpos, ypos, wBLANK, Hmacrobtn);
|
||||
bx->box(FL_FLAT_BOX);
|
||||
xpos += wblank;
|
||||
xpos += wBLANK;
|
||||
}
|
||||
btnMacro[NUMMACKEYS + i] = new Fl_Button(xpos, ypos, Wmacrobtn, Hmacrobtn,
|
||||
macros.name[NUMMACKEYS + i].c_str());
|
||||
|
@ -4452,14 +4486,14 @@ void create_fl_digi_main_primary() {
|
|||
Fl_Group *btngroup1 = new Fl_Group(0, Y+1, progStatus.mainW - Hmacros, Hmacros-1);
|
||||
Wmacrobtn = (btngroup1->w()) / NUMMACKEYS;
|
||||
Hmacrobtn = btngroup1->h() - 1;
|
||||
wblank = (btngroup1->w() - NUMMACKEYS * Wmacrobtn) / 2;
|
||||
wBLANK = (btngroup1->w() - NUMMACKEYS * Wmacrobtn) / 2;
|
||||
xpos = 0;
|
||||
ypos = btngroup1->y();
|
||||
for (int i = 0; i < NUMMACKEYS; i++) {
|
||||
if (i == 4 || i == 8) {
|
||||
bx = new Fl_Box(xpos, ypos, wblank, Hmacrobtn);
|
||||
bx = new Fl_Box(xpos, ypos, wBLANK, Hmacrobtn);
|
||||
bx->box(FL_FLAT_BOX);
|
||||
xpos += wblank;
|
||||
xpos += wBLANK;
|
||||
}
|
||||
btnMacro[i] = new Fl_Button(xpos, ypos, Wmacrobtn, Hmacrobtn,
|
||||
macros.name[i].c_str());
|
||||
|
@ -4817,6 +4851,7 @@ Fl_Menu_Item alt_menu_[] = {
|
|||
{ mode_info[MODE_PSK250].name, 0, cb_init_mode, (void *)MODE_PSK250, 0, FL_NORMAL_LABEL, 0, 14, 0},
|
||||
{0,0,0,0,0,0,0,0,0},
|
||||
|
||||
{ mode_info[MODE_NULL].name, 0, cb_init_mode, (void *)MODE_NULL, 0, FL_NORMAL_LABEL, 0, 14, 0},
|
||||
{ mode_info[MODE_SSB].name, 0, cb_init_mode, (void *)MODE_SSB, 0, FL_NORMAL_LABEL, 0, 14, 0},
|
||||
|
||||
{ mode_info[MODE_WWV].name, 0, cb_init_mode, (void *)MODE_WWV, 0, FL_NORMAL_LABEL, 0, 14, 0},
|
||||
|
@ -5608,10 +5643,55 @@ void get_tx_char_idle(void *)
|
|||
progStatus.repeatIdleTime = 0;
|
||||
}
|
||||
|
||||
int Qwait_time = 0;
|
||||
int Qidle_time = 0;
|
||||
|
||||
static int que_timeout = 0;
|
||||
bool que_ok = true;
|
||||
|
||||
void post_queue_execute(void*)
|
||||
{
|
||||
if (!que_timeout) {
|
||||
LOG_ERROR("%s", "timed out");
|
||||
return;
|
||||
}
|
||||
while (!que_ok && trx_state != STATE_RX) {
|
||||
que_timeout--;
|
||||
Fl::repeat_timeout(0.05, post_queue_execute);
|
||||
}
|
||||
trx_transmit();
|
||||
}
|
||||
|
||||
void queue_execute_after_rx(void*)
|
||||
{
|
||||
if (!que_timeout) {
|
||||
LOG_ERROR("%s", "timed out");
|
||||
return;
|
||||
}
|
||||
while (trx_state == STATE_TX) {
|
||||
que_timeout--;
|
||||
Fl::repeat_timeout(0.05, queue_execute_after_rx);
|
||||
return;
|
||||
}
|
||||
que_ok = false;
|
||||
que_timeout = 100; // 5 seconds
|
||||
Fl::add_timeout(0.05, post_queue_execute);
|
||||
queue_execute();
|
||||
}
|
||||
|
||||
char szTestChar[] = "E|I|S|T|M|O|A|V";
|
||||
int get_tx_char(void)
|
||||
{
|
||||
if (macro_idle_on) return -1;
|
||||
int c;
|
||||
static int pending = -1;
|
||||
enum { STATE_CHAR, STATE_CTRL };
|
||||
static int state = STATE_CHAR;
|
||||
|
||||
if (!que_ok) { return -1; }
|
||||
if (Qwait_time) { return -1; }
|
||||
if (Qidle_time) { return -1; }
|
||||
if (macro_idle_on) { return -1; }
|
||||
if (idling) { return -1; }
|
||||
|
||||
if (arq_text_available)
|
||||
return arq_get_char();
|
||||
|
@ -5619,24 +5699,19 @@ int get_tx_char(void)
|
|||
if (active_modem == cw_modem && progdefaults.QSKadjust)
|
||||
return szTestChar[2 * progdefaults.TestChar];
|
||||
|
||||
int c;
|
||||
static int pending = -1;
|
||||
if ( progStatus.repeatMacro && progStatus.repeatIdleTime > 0 &&
|
||||
!idling ) {
|
||||
Fl::add_timeout(progStatus.repeatIdleTime, get_tx_char_idle);
|
||||
idling = true;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pending >= 0) {
|
||||
c = pending;
|
||||
pending = -1;
|
||||
return c;
|
||||
}
|
||||
|
||||
enum { STATE_CHAR, STATE_CTRL };
|
||||
static int state = STATE_CHAR;
|
||||
|
||||
if ( progStatus.repeatMacro && progStatus.repeatIdleTime > 0 &&
|
||||
!idling ) {
|
||||
Fl::add_timeout(progStatus.repeatIdleTime, get_tx_char_idle);
|
||||
idling = true;
|
||||
}
|
||||
if (idling) return -1;
|
||||
|
||||
if (progStatus.repeatMacro > -1 && text2repeat.length()) {
|
||||
c = text2repeat[repeatchar];
|
||||
repeatchar++;
|
||||
|
@ -5648,12 +5723,15 @@ int get_tx_char(void)
|
|||
}
|
||||
|
||||
c = TransmitText->nextChar();
|
||||
|
||||
if (c == '^' && state == STATE_CHAR) {
|
||||
state = STATE_CTRL;
|
||||
c = TransmitText->nextChar();
|
||||
}
|
||||
switch (c) {
|
||||
case -1: break; // no character available
|
||||
case -1: // no character available
|
||||
queue_reset();
|
||||
break;
|
||||
case '\n':
|
||||
pending = '\n';
|
||||
return '\r';
|
||||
|
@ -5663,6 +5741,8 @@ int get_tx_char(void)
|
|||
REQ_SYNC(&FTextTX::clear_sent, TransmitText);
|
||||
state = STATE_CHAR;
|
||||
c = 3; // ETX
|
||||
if (progStatus.timer)
|
||||
REQ(startMacroTimer);
|
||||
break;
|
||||
case 'R':
|
||||
if (state != STATE_CTRL)
|
||||
|
@ -5671,6 +5751,8 @@ int get_tx_char(void)
|
|||
if (TransmitText->eot()) {
|
||||
REQ_SYNC(&FTextTX::clear_sent, TransmitText);
|
||||
c = 3; // ETX
|
||||
if (progStatus.timer)
|
||||
REQ(startMacroTimer);
|
||||
} else
|
||||
c = -1;
|
||||
break;
|
||||
|
@ -5688,6 +5770,19 @@ int get_tx_char(void)
|
|||
c = -1;
|
||||
REQ(clearQSO);
|
||||
break;
|
||||
case '!':
|
||||
if (state != STATE_CTRL)
|
||||
break;
|
||||
state = STATE_CHAR;
|
||||
if (queue_must_rx()) {
|
||||
c = 3;
|
||||
que_timeout = 400; // 20 seconds
|
||||
Fl::add_timeout(0.0, queue_execute_after_rx);
|
||||
} else {
|
||||
c = -1;
|
||||
queue_execute();
|
||||
}
|
||||
break;
|
||||
case '^':
|
||||
state = STATE_CHAR;
|
||||
break;
|
||||
|
@ -5870,7 +5965,6 @@ void start_tx()
|
|||
if (!(active_modem->get_cap() & modem::CAP_TX))
|
||||
return;
|
||||
trx_transmit();
|
||||
REQ(&waterfall::set_XmtRcvBtn, wf, true);
|
||||
}
|
||||
|
||||
void abort_tx()
|
||||
|
@ -5881,6 +5975,7 @@ void abort_tx()
|
|||
return;
|
||||
}
|
||||
if (trx_state == STATE_TX) {
|
||||
queue_reset();
|
||||
trx_start_modem(active_modem);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -235,8 +235,6 @@ void cDTMF::two_tones(int ch)
|
|||
|
||||
void cDTMF::send()
|
||||
{
|
||||
if (progdefaults.DTMFstr.empty()) return;
|
||||
|
||||
int c = 0, delay = 0;
|
||||
duration = 50;
|
||||
RT = (int)(active_modem->get_samplerate() * 4 / 1000.0); // 4 msec edge
|
||||
|
|
|
@ -43,6 +43,8 @@ using namespace std;
|
|||
// ... doing so will break the Fl_menu_item table 'menu_'. -Kamal
|
||||
|
||||
const struct mode_info_t mode_info[NUM_MODES] = {
|
||||
{ MODE_NULL, &null_modem, "NULL", "NULL", "", "NULL", "" },
|
||||
|
||||
{ MODE_CW, &cw_modem, "CW", "CW", "CW", "CW", "CW" },
|
||||
|
||||
{ MODE_CONTESTIA, &contestia_modem, "CTSTIA", "Contestia", "", "CONTESTI", "CT" },
|
||||
|
|
|
@ -148,6 +148,9 @@ extern Digiscope *digiscope;
|
|||
|
||||
extern std::string main_window_title;
|
||||
|
||||
extern int Qwait_time;
|
||||
extern int Qidle_time;
|
||||
|
||||
extern void toggleRSID();
|
||||
|
||||
extern void set_menus();
|
||||
|
@ -214,6 +217,10 @@ extern void put_WARNstatus(double);
|
|||
|
||||
extern void qsoSave_cb(Fl_Widget *b, void *);
|
||||
|
||||
extern bool que_ok;
|
||||
extern void post_queue_execute(void*);
|
||||
extern void queue_execute_after_rx(void*);
|
||||
|
||||
extern void put_rx_data(int *data, int len);
|
||||
extern int get_tx_char();
|
||||
extern int get_secondary_char();
|
||||
|
@ -259,6 +266,10 @@ extern void set_contestia_default_integ();
|
|||
|
||||
extern void startMacroTimer();
|
||||
extern void stopMacroTimer();
|
||||
extern void macro_timer(void *);
|
||||
extern void macro_timed_execute(void *);
|
||||
extern void startTimedExecute(std::string &);
|
||||
|
||||
extern void cb_ResetSerNbr();
|
||||
extern void updateOutSerNo();
|
||||
|
||||
|
|
|
@ -49,6 +49,8 @@ enum {
|
|||
MODE_PREV = -2,
|
||||
MODE_NEXT,
|
||||
|
||||
MODE_NULL,
|
||||
|
||||
MODE_CW,
|
||||
|
||||
MODE_CONTESTIA,
|
||||
|
|
|
@ -36,9 +36,10 @@ struct MACROTEXT {
|
|||
void openMacroFile();
|
||||
void saveMacroFile();
|
||||
void saveMacros(const std::string& fname);
|
||||
std::string expandMacro(int n);
|
||||
std::string expandMacro(std::string &s);
|
||||
void execute(int n);
|
||||
void repeat(int n);
|
||||
void timed_execute();
|
||||
MACROTEXT();
|
||||
private:
|
||||
std::string expanded;
|
||||
|
@ -53,6 +54,15 @@ extern std::string info2msg;
|
|||
extern std::string qso_time;
|
||||
extern std::string qso_exchange;
|
||||
|
||||
extern std::string exec_date;
|
||||
extern std::string exec_time;
|
||||
extern std::string exec_string;
|
||||
|
||||
void set_macro_env(void);
|
||||
|
||||
void queue_reset();
|
||||
void queue_execute();
|
||||
bool queue_must_rx();
|
||||
void idleTimer(void *);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -181,6 +181,8 @@ protected:
|
|||
virtual void s2nreport(void);
|
||||
};
|
||||
|
||||
extern modem *null_modem;
|
||||
|
||||
extern modem *cw_modem;
|
||||
|
||||
extern modem *mfsk8_modem;
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
// NULLMODEM.h -- BASIS FOR ALL MODEMS
|
||||
//
|
||||
// Copyright (C) 2006
|
||||
// Dave Freese, W1HKJ
|
||||
//
|
||||
// This file is part of fldigi.
|
||||
//
|
||||
// Fldigi is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Fldigi is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with fldigi. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifndef _NULLMODEM_H
|
||||
#define _NULLMODEM_H
|
||||
|
||||
#include "trx.h"
|
||||
#include "modem.h"
|
||||
#include "fft.h"
|
||||
#include "filters.h"
|
||||
#include "complex.h"
|
||||
|
||||
#define NULLMODEMSampleRate 8000
|
||||
|
||||
class NULLMODEM : public modem {
|
||||
protected:
|
||||
public:
|
||||
NULLMODEM();
|
||||
~NULLMODEM();
|
||||
void init();
|
||||
void rx_init();
|
||||
void restart();
|
||||
void tx_init(SoundBase *sc);
|
||||
int rx_process(const double *buf, int len);
|
||||
int tx_process();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
|
@ -43,11 +43,8 @@ extern void trx_tune();
|
|||
extern void trx_receive();
|
||||
|
||||
extern void trx_reset(void);
|
||||
extern void trx_start_macro_timer();
|
||||
|
||||
extern void trx_wait_state(void);
|
||||
|
||||
extern void macro_timer(void *);
|
||||
extern void trx_wait_state(void);
|
||||
|
||||
extern state_t trx_state;
|
||||
extern modem *active_modem;
|
||||
|
|
|
@ -52,12 +52,12 @@ using namespace std;
|
|||
|
||||
Fl_Double_Window *MacroEditDialog = (Fl_Double_Window *)0;
|
||||
|
||||
Fl_Button *btnMacroEditOK = (Fl_Button *)0;
|
||||
Fl_Button *btnMacroEditCancel = (Fl_Button *)0;
|
||||
Fl_Button *btnMacroEditApply = (Fl_Button *)0;
|
||||
Fl_Button *btnMacroEditClose = (Fl_Button *)0;
|
||||
Fl_Button *btnInsertMacro = (Fl_Button *)0;
|
||||
Fl_Input2 *macrotext = (Fl_Input2 *)0;
|
||||
Fl_Input2 *labeltext = (Fl_Input2 *)0;
|
||||
static int widths[] = {130, 0};
|
||||
static int widths[] = {150, 0};
|
||||
|
||||
Fl_Hold_Browser *macroDefs=(Fl_Hold_Browser *)0;
|
||||
|
||||
|
@ -151,6 +151,7 @@ void loadBrowser(Fl_Widget *widget) {
|
|||
w->add(_("<TUNE:NN>\ttune signal for NN sec"));
|
||||
w->add(_("<WAIT:NN>\tdelay xmt for NN sec"));
|
||||
w->add(_("<REPEAT>\trepeat macro continuously"));
|
||||
w->add(_("<SKED:hhmm[:YYYYDDMM]>\tschedule execution"));
|
||||
|
||||
w->add(LINE_SEP);
|
||||
w->add(_("<CWID>\tCW identifier"));
|
||||
|
@ -240,8 +241,10 @@ void loadBrowser(Fl_Widget *widget) {
|
|||
|
||||
void cbMacroEditOK(Fl_Widget *w, void *)
|
||||
{
|
||||
if (w == btnMacroEditCancel)
|
||||
goto ret;
|
||||
if (w == btnMacroEditClose) {
|
||||
MacroEditDialog->hide();
|
||||
return;
|
||||
}
|
||||
|
||||
if (iType == MACRO_EDIT_BUTTON) {
|
||||
macros.text[iMacro] = macrotext->value();
|
||||
|
@ -264,8 +267,6 @@ void cbMacroEditOK(Fl_Widget *w, void *)
|
|||
}
|
||||
else if (iType == MACRO_EDIT_INPUT)
|
||||
iInput->value(macrotext->value());
|
||||
ret:
|
||||
MacroEditDialog->hide();
|
||||
}
|
||||
|
||||
void cbInsertMacro(Fl_Widget *, void *)
|
||||
|
@ -315,30 +316,30 @@ void cbInsertMacro(Fl_Widget *, void *)
|
|||
|
||||
Fl_Double_Window* make_macroeditor(void)
|
||||
{
|
||||
Fl_Double_Window* w = new Fl_Double_Window(768, 190, "");
|
||||
Fl_Double_Window* w = new Fl_Double_Window(800, 190, "");
|
||||
|
||||
macrotext = new Fl_Input2(2, 22, 450, 140, _("Text:"));
|
||||
macrotext = new Fl_Input2(2, 22, 450, 140, _("Macro Text"));
|
||||
macrotext->type(FL_MULTILINE_INPUT);
|
||||
macrotext->textfont(FL_COURIER);
|
||||
macrotext->align(FL_ALIGN_TOP_LEFT);
|
||||
macrotext->align(FL_ALIGN_TOP);
|
||||
|
||||
btnInsertMacro = new Fl_Button(454, 86, 20, 20);
|
||||
btnInsertMacro = new Fl_Button(434, 2, 40, 20);
|
||||
btnInsertMacro->image(new Fl_Pixmap(left_arrow_icon));
|
||||
btnInsertMacro->callback(cbInsertMacro);
|
||||
|
||||
macroDefs = new Fl_Hold_Browser(476, 22, 290, 140, _("Select Tags:"));
|
||||
macroDefs = new Fl_Hold_Browser(452, 22, 346, 140, _("Select Tag"));
|
||||
macroDefs->column_widths(widths);
|
||||
macroDefs->align(FL_ALIGN_TOP_LEFT);
|
||||
macroDefs->align(FL_ALIGN_TOP);
|
||||
loadBrowser(macroDefs);
|
||||
|
||||
labeltext = new Fl_Input2(2 + 450 - 115, 164, 115, 24, _("Macro Button Label:"));
|
||||
labeltext->textfont(FL_COURIER);
|
||||
|
||||
btnMacroEditOK = new Fl_Button(476 + 145 - 80 - 1, 164, 80, 24, _("OK"));
|
||||
btnMacroEditOK->callback(cbMacroEditOK);
|
||||
btnMacroEditApply = new Fl_Button(452 + macroDefs->w()/2 - 80 - 1, 164, 80, 24, _("Apply"));
|
||||
btnMacroEditApply->callback(cbMacroEditOK);
|
||||
|
||||
btnMacroEditCancel = new Fl_Button(476 + 145 + 1 , 164, 80, 24, _("Cancel"));
|
||||
btnMacroEditCancel->callback(cbMacroEditOK);
|
||||
btnMacroEditClose = new Fl_Button(452 + macroDefs->w()/2 + 1 , 164, 80, 24, _("Close"));
|
||||
btnMacroEditClose->callback(cbMacroEditOK);
|
||||
|
||||
w->end();
|
||||
w->xclass(PACKAGE_NAME);
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
#include <unistd.h>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <queue>
|
||||
|
||||
#ifdef __WIN32__
|
||||
#include "speak.h"
|
||||
|
@ -62,6 +63,17 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
struct CMDS { string cmd; void (*fp)(string); };
|
||||
queue<CMDS> cmds;
|
||||
|
||||
// following used for debugging and development
|
||||
//void pushcmd(CMDS cmd)
|
||||
//{
|
||||
// LOG_INFO("%s, # = %d", cmd.cmd.c_str(), (int)cmds.size());
|
||||
// cmds.push(cmd);
|
||||
//}
|
||||
#define pushcmd(a) cmds.push((a))
|
||||
|
||||
MACROTEXT macros;
|
||||
CONTESTCNTR contest_count;
|
||||
static bool TransmitON = false;
|
||||
|
@ -70,20 +82,24 @@ static int mNbr;
|
|||
|
||||
std::string qso_time = "";
|
||||
std::string qso_exchange = "";
|
||||
static bool save_xchg;
|
||||
static size_t xbeg = 0, xend = 0;
|
||||
|
||||
string text2send = "";
|
||||
string text2repeat = "";
|
||||
string text2save = "";
|
||||
std::string exec_date = "";
|
||||
std::string exec_time = "";
|
||||
std::string exec_string = "";
|
||||
|
||||
std::string text2send = "";
|
||||
std::string text2repeat = "";
|
||||
//std::string text2save = "";
|
||||
std::string info1msg = "";
|
||||
std::string info2msg = "";
|
||||
|
||||
size_t repeatchar = 0;
|
||||
static size_t xbeg = 0, xend = 0;
|
||||
|
||||
static bool save_xchg;
|
||||
static bool expand;
|
||||
static bool GET = false;
|
||||
|
||||
string info1msg = "";
|
||||
string info2msg = "";
|
||||
static bool timed_exec = false;
|
||||
|
||||
static char cutnumbers[] = "T12345678N";
|
||||
static string cutstr;
|
||||
|
@ -204,6 +220,107 @@ static void pPOST(string &s, size_t &i, size_t endbracket)
|
|||
s.replace(i, endbracket - i + 1, "");
|
||||
}
|
||||
|
||||
static void setwpm(int d)
|
||||
{
|
||||
sldrCWxmtWPM->value(d);
|
||||
cntCW_WPM->value(d);
|
||||
}
|
||||
|
||||
static void doWPM(string s)
|
||||
{
|
||||
int number;
|
||||
string sTime = s.substr(6);
|
||||
if (sTime.length() > 0) {
|
||||
sscanf(sTime.c_str(), "%d", &number);
|
||||
if (number < 5) number = 5;
|
||||
if (number > 200) number = 200;
|
||||
progdefaults.CWspeed = number;
|
||||
REQ(setwpm, number);
|
||||
}
|
||||
}
|
||||
|
||||
static void pQueWPM(string &s, size_t &i, size_t endbracket)
|
||||
{
|
||||
struct CMDS cmd = { s.substr(i, endbracket - i + 1), doWPM };
|
||||
pushcmd(cmd);
|
||||
s.replace(i, endbracket - i + 1, "^!");
|
||||
}
|
||||
|
||||
static void setRISETIME(int d)
|
||||
{
|
||||
cntCWrisetime->value(d);
|
||||
}
|
||||
|
||||
static void doRISETIME(string s)
|
||||
{
|
||||
float number;
|
||||
string sVal = s.substr(7, s.length() - 8);
|
||||
if (sVal.length() > 0) {
|
||||
sscanf(sVal.c_str(), "%f", &number);
|
||||
if (number < 0) number = 0;
|
||||
if (number > 20) number = 20;
|
||||
progdefaults.CWrisetime = number;
|
||||
REQ(setRISETIME, number);
|
||||
}
|
||||
}
|
||||
|
||||
static void pQueRISETIME(string &s, size_t &i, size_t endbracket)
|
||||
{
|
||||
struct CMDS cmd = { s.substr(i, endbracket - i + 1), doRISETIME };
|
||||
pushcmd(cmd);
|
||||
s.replace(i, endbracket - i + 1, "^!");
|
||||
}
|
||||
|
||||
static void setPRE(int d)
|
||||
{
|
||||
cntPreTiming->value(d);
|
||||
}
|
||||
|
||||
static void doPRE(string s)
|
||||
{
|
||||
float number;
|
||||
string sVal = s.substr(6, s.length() - 7);
|
||||
if (sVal.length() > 0) {
|
||||
sscanf(sVal.c_str(), "%f", &number);
|
||||
if (number < 0) number = 0;
|
||||
if (number > 20) number = 20;
|
||||
progdefaults.CWpre = number;
|
||||
REQ(setPRE, number);
|
||||
}
|
||||
}
|
||||
|
||||
static void pQuePRE(string &s, size_t &i, size_t endbracket)
|
||||
{
|
||||
struct CMDS cmd = { s.substr(i, endbracket - i + 1), doPRE };
|
||||
pushcmd(cmd);
|
||||
s.replace(i, endbracket - i + 1, "^!");
|
||||
}
|
||||
|
||||
static void setPOST(int d)
|
||||
{
|
||||
cntPostTiming->value(d);
|
||||
}
|
||||
|
||||
static void doPOST(string s)
|
||||
{
|
||||
float number;
|
||||
string sVal = s.substr(7, s.length() - 8);
|
||||
if (sVal.length() > 0) {
|
||||
sscanf(sVal.c_str(), "%f", &number);
|
||||
if (number < -20) number = -20;
|
||||
if (number > 20) number = 20;
|
||||
progdefaults.CWpost = number;
|
||||
REQ(setPOST, number);
|
||||
}
|
||||
}
|
||||
|
||||
static void pQuePOST(string &s, size_t &i, size_t endbracket)
|
||||
{
|
||||
struct CMDS cmd = { s.substr(i, endbracket - i + 1), doPOST };
|
||||
pushcmd(cmd);
|
||||
s.replace(i, endbracket - i + 1, "^!");
|
||||
}
|
||||
|
||||
bool macro_idle_on = false;
|
||||
static float idleTime = 0;
|
||||
|
||||
|
@ -219,6 +336,31 @@ static void pIDLE(string &s, size_t &i, size_t endbracket)
|
|||
s.replace(i, endbracket - i + 1, "");
|
||||
}
|
||||
|
||||
static void doneIDLE(void *)
|
||||
{
|
||||
Qidle_time = 0;
|
||||
}
|
||||
|
||||
static void doIDLE(string s)
|
||||
{
|
||||
float number;
|
||||
string sTime = s.substr(7, s.length() - 8);
|
||||
if (sTime.length() > 0) {
|
||||
sscanf(sTime.c_str(), "%f", &number);
|
||||
Qidle_time = 1;
|
||||
Fl::add_timeout(number, doneIDLE);
|
||||
} else {
|
||||
Qidle_time = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void pQueIDLE(string &s, size_t &i, size_t endbracket)
|
||||
{
|
||||
struct CMDS cmd = { s.substr(i, endbracket - i + 1), doIDLE };
|
||||
pushcmd(cmd);
|
||||
s.replace(i, endbracket - i + 1, "^!");
|
||||
}
|
||||
|
||||
static bool useTune = false;
|
||||
static int tuneTime = 0;
|
||||
|
||||
|
@ -249,6 +391,33 @@ static void pWAIT(string &s, size_t &i, size_t endbracket)
|
|||
s.replace(i, endbracket - i + 1, "");
|
||||
}
|
||||
|
||||
static void doneWAIT(void *)
|
||||
{
|
||||
Qwait_time = 0;
|
||||
start_tx();
|
||||
}
|
||||
|
||||
static void doWAIT(string s)
|
||||
{
|
||||
int number;
|
||||
string sTime = s.substr(7, s.length() - 8);
|
||||
if (sTime.length() > 0) {
|
||||
sscanf(sTime.c_str(), "%d", &number);
|
||||
Qwait_time = number;
|
||||
Fl::add_timeout (number * 1.0, doneWAIT);
|
||||
} else
|
||||
Qwait_time = 0;
|
||||
que_ok = true;
|
||||
}
|
||||
|
||||
static void pQueWAIT(string &s, size_t &i, size_t endbracket)
|
||||
{
|
||||
struct CMDS cmd = { s.substr(i, endbracket - i + 1), doWAIT };
|
||||
pushcmd(cmd);
|
||||
s.replace(i, endbracket - i + 1, "^!");
|
||||
}
|
||||
|
||||
|
||||
static void pINFO1(string &s, size_t &i, size_t endbracket)
|
||||
{
|
||||
s.replace( i, 7, info1msg );
|
||||
|
@ -440,7 +609,6 @@ static void pID(string &s, size_t &i, size_t endbracket)
|
|||
static void pTEXT(string &s, size_t &i, size_t endbracket)
|
||||
{
|
||||
progdefaults.macrotextid = true;
|
||||
|
||||
s.replace( i, 6, "");
|
||||
}
|
||||
|
||||
|
@ -450,10 +618,16 @@ static void pCWID(string &s, size_t &i, size_t endbracket)
|
|||
s.replace( i, 6, "");
|
||||
}
|
||||
|
||||
static void doDTMF(string s)
|
||||
{
|
||||
progdefaults.DTMFstr = s.substr(6, s.length() - 7);
|
||||
}
|
||||
|
||||
static void pDTMF(string &s, size_t &i, size_t endbracket)
|
||||
{
|
||||
progdefaults.DTMFstr = s.substr(i + 6, endbracket - i - 6);
|
||||
s.replace(i, endbracket - i + 1, "");
|
||||
CMDS cmd = {s.substr(i, endbracket - i + 1), doDTMF};
|
||||
pushcmd(cmd);
|
||||
s.replace(i, endbracket - i + 1, "^!");
|
||||
}
|
||||
|
||||
static void pRX(string &s, size_t &i, size_t endbracket)
|
||||
|
@ -557,7 +731,7 @@ static void pCLRLOG(string &s, size_t &i, size_t endbracket)
|
|||
s.replace(i, 10, "^C");
|
||||
}
|
||||
|
||||
static void pMODEM_compat(string &s, size_t &i, size_t endbracket)
|
||||
static void pMODEM_compSKED(string &s, size_t &i, size_t endbracket)
|
||||
{
|
||||
size_t j, k,
|
||||
len = s.length();
|
||||
|
@ -584,6 +758,84 @@ static void pMODEM_compat(string &s, size_t &i, size_t endbracket)
|
|||
#include <float.h>
|
||||
#include "re.h"
|
||||
|
||||
static void doMODEM(string s)
|
||||
{
|
||||
static fre_t re("<!MODEM:([[:alnum:]-]+)((:[[:digit:].+-]*)*)>", REG_EXTENDED);
|
||||
string tomatch = s;
|
||||
|
||||
if (!re.match(tomatch.c_str())) {
|
||||
que_ok = true;
|
||||
return;
|
||||
}
|
||||
|
||||
const std::vector<regmatch_t>& o = re.suboff();
|
||||
string name = tomatch.substr(o[1].rm_so, o[1].rm_eo - o[1].rm_so);
|
||||
trx_mode m;
|
||||
for (m = 0; m < NUM_MODES; m++)
|
||||
if (name == mode_info[m].sname)
|
||||
break;
|
||||
// do we have arguments and a valid modem?
|
||||
if (o.size() == 2 || m == NUM_MODES) {
|
||||
que_ok = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// parse arguments
|
||||
vector<double> args;
|
||||
args.reserve(8);
|
||||
char* end;
|
||||
double d;
|
||||
for (const char* p = s.c_str() + o[2].rm_so + 1; *p; p++) {
|
||||
errno = 0;
|
||||
d = strtod(p, &end);
|
||||
if (!errno && p != end) {
|
||||
args.push_back(d);
|
||||
p = end;
|
||||
}
|
||||
else // push an invalid value
|
||||
args.push_back(DBL_MIN);
|
||||
}
|
||||
|
||||
try {
|
||||
switch (m) {
|
||||
case MODE_RTTY: // carrier shift, baud rate, bits per char
|
||||
if (args.at(0) != DBL_MIN)
|
||||
set_rtty_shift((int)args[0]);
|
||||
if (args.at(1) != DBL_MIN)
|
||||
set_rtty_baud((float)args[1]);
|
||||
if (args.at(2) != DBL_MIN)
|
||||
set_rtty_bits((int)args[2]);
|
||||
break;
|
||||
case MODE_CONTESTIA: // bandwidth, tones
|
||||
if (args.at(0) != DBL_MIN)
|
||||
set_contestia_bw((int)args[0]);
|
||||
if (args.at(1) != DBL_MIN)
|
||||
set_contestia_tones((int)args[1]);
|
||||
break;
|
||||
case MODE_OLIVIA: // bandwidth, tones
|
||||
if (args.at(0) != DBL_MIN)
|
||||
set_olivia_bw((int)args[0]);
|
||||
if (args.at(1) != DBL_MIN)
|
||||
set_olivia_tones((int)args[1]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (const exception& e) { }
|
||||
|
||||
if (active_modem->get_mode() != mode_info[m].mode)
|
||||
init_modem_sync(mode_info[m].mode);
|
||||
que_ok = true;
|
||||
}
|
||||
|
||||
static void pQueMODEM(string &s, size_t &i, size_t endbracket)
|
||||
{
|
||||
struct CMDS cmd = { s.substr(i, endbracket - i + 1), doMODEM };
|
||||
pushcmd(cmd);
|
||||
s.replace(i, endbracket - i + 1, "^!");
|
||||
}
|
||||
|
||||
static void pMODEM(string &s, size_t &i, size_t endbracket)
|
||||
{
|
||||
static fre_t re("<MODEM:([[:alnum:]-]+)((:[[:digit:].+-]*)*)>", REG_EXTENDED);
|
||||
|
@ -677,6 +929,8 @@ static void pAFC(string &s, size_t &i, size_t endbracket)
|
|||
|
||||
btnAFC->do_callback();
|
||||
}
|
||||
//pushcmd(s.substr(i, endbracket - i + 1));
|
||||
//s.replace(i, endbracket - i + 1, "^!");
|
||||
s.replace(i, endbracket - i + 1, "");
|
||||
}
|
||||
|
||||
|
@ -695,6 +949,8 @@ static void pLOCK(string &s, size_t &i, size_t endbracket)
|
|||
wf->xmtlock->damage();
|
||||
wf->xmtlock->do_callback();
|
||||
}
|
||||
//pushcmd(s.substr(i, endbracket - i + 1));
|
||||
//s.replace(i, endbracket - i + 1, "^!");
|
||||
s.replace(i, endbracket - i + 1, "");
|
||||
}
|
||||
|
||||
|
@ -712,6 +968,8 @@ static void pTX_RSID(string &s, size_t &i, size_t endbracket)
|
|||
|
||||
btnTxRSID->do_callback();
|
||||
}
|
||||
//pushcmd(s.substr(i, endbracket - i + 1));
|
||||
//s.replace(i, endbracket - i + 1, "^!");
|
||||
s.replace(i, endbracket - i + 1, "");
|
||||
}
|
||||
|
||||
|
@ -776,6 +1034,24 @@ static void pGOHOME(string &s, size_t &i, size_t endbracket)
|
|||
active_modem->set_freq(progdefaults.PSKsweetspot);
|
||||
}
|
||||
|
||||
static void doGOHOME(string s)
|
||||
{
|
||||
if (active_modem == cw_modem)
|
||||
active_modem->set_freq(progdefaults.CWsweetspot);
|
||||
else if (active_modem == rtty_modem)
|
||||
active_modem->set_freq(progdefaults.RTTYsweetspot);
|
||||
else
|
||||
active_modem->set_freq(progdefaults.PSKsweetspot);
|
||||
que_ok = true;
|
||||
}
|
||||
|
||||
static void pQueGOHOME(string &s, size_t &i, size_t endbracket)
|
||||
{
|
||||
struct CMDS cmd = { s.substr(i, endbracket - i + 1), doGOHOME };
|
||||
pushcmd(cmd);
|
||||
s.replace(i, endbracket - i + 1, "^!");
|
||||
}
|
||||
|
||||
static void pGOFREQ(string &s, size_t &i, size_t endbracket)
|
||||
{
|
||||
int number;
|
||||
|
@ -791,6 +1067,28 @@ static void pGOFREQ(string &s, size_t &i, size_t endbracket)
|
|||
s.replace(i, endbracket - i + 1, "");
|
||||
}
|
||||
|
||||
static void doGOFREQ(string s)
|
||||
{
|
||||
int number;
|
||||
string sGoFreq = s.substr(9, s.length() - 10);
|
||||
if (sGoFreq.length() > 0) {
|
||||
sscanf(sGoFreq.c_str(), "%d", &number);
|
||||
if (number < progdefaults.LowFreqCutoff)
|
||||
number = progdefaults.LowFreqCutoff;
|
||||
if (number > progdefaults.HighFreqCutoff)
|
||||
number = progdefaults.HighFreqCutoff;
|
||||
active_modem->set_freq(number);
|
||||
}
|
||||
que_ok = true;
|
||||
}
|
||||
|
||||
static void pQueGOFREQ(string &s, size_t &i, size_t endbracket)
|
||||
{
|
||||
struct CMDS cmd = { s.substr(i, endbracket - i + 1), doGOFREQ };
|
||||
pushcmd(cmd);
|
||||
s.replace(i, endbracket - i + 1, "^!");
|
||||
}
|
||||
|
||||
static void pQSYTO(string &s, size_t &i, size_t endbracket)
|
||||
{
|
||||
s.replace( i, 7, "");
|
||||
|
@ -830,7 +1128,6 @@ static void pQSY(string &s, size_t &i, size_t endbracket)
|
|||
if (audio > progdefaults.HighFreqCutoff)
|
||||
audio = progdefaults.HighFreqCutoff;
|
||||
}
|
||||
|
||||
if (rf && rf != wf->rfcarrier())
|
||||
qsy(rf, audio);
|
||||
else
|
||||
|
@ -839,6 +1136,48 @@ static void pQSY(string &s, size_t &i, size_t endbracket)
|
|||
s.replace(i, endbracket - i + 1, "");
|
||||
}
|
||||
|
||||
static void doQSY(string s)
|
||||
{
|
||||
int rf = 0;
|
||||
int audio = 0;
|
||||
float rfd = 0;
|
||||
string sGoFreq;
|
||||
sGoFreq = s.substr(6, s.length() - 7);
|
||||
// no frequency(s) specified
|
||||
if (sGoFreq.length() == 0) {
|
||||
que_ok = true;
|
||||
return;
|
||||
}
|
||||
// rf first value
|
||||
sscanf(sGoFreq.c_str(), "%f", &rfd);
|
||||
if (rfd > 0)
|
||||
rf = (int)(1000*rfd);
|
||||
size_t pos;
|
||||
if ((pos = sGoFreq.find(":")) != string::npos) {
|
||||
// af second value
|
||||
sGoFreq.erase(0, pos+1);
|
||||
if (sGoFreq.length())
|
||||
sscanf(sGoFreq.c_str(), "%d", &audio);
|
||||
if (audio < 0) audio = 0;
|
||||
if (audio < progdefaults.LowFreqCutoff)
|
||||
audio = progdefaults.LowFreqCutoff;
|
||||
if (audio > progdefaults.HighFreqCutoff)
|
||||
audio = progdefaults.HighFreqCutoff;
|
||||
}
|
||||
if (rf && rf != wf->rfcarrier())
|
||||
qsy(rf, audio);
|
||||
else
|
||||
active_modem->set_freq(audio);
|
||||
que_ok = true;
|
||||
}
|
||||
|
||||
static void pQueQSY(string &s, size_t &i, size_t endbracket)
|
||||
{
|
||||
struct CMDS cmd = { s.substr(i, endbracket - i + 1), doQSY };
|
||||
pushcmd(cmd);
|
||||
s.replace(i, endbracket - i + 1, "^!");
|
||||
}
|
||||
|
||||
static void pRIGMODE(string& s, size_t& i, size_t endbracket)
|
||||
{
|
||||
string sMode = s.substr(i+9, endbracket - i - 9);
|
||||
|
@ -859,7 +1198,7 @@ void set_macro_env(void)
|
|||
{
|
||||
enum {
|
||||
#ifndef __WOE32__
|
||||
PATH, FLDIGI_RX_IPC_KEY, FLDIGI_TX_IPC_KEY,
|
||||
pSKEDH, FLDIGI_RX_IPC_KEY, FLDIGI_TX_IPC_KEY,
|
||||
#endif
|
||||
FLDIGI_XMLRPC_ADDRESS, FLDIGI_XMLRPC_PORT,
|
||||
FLDIGI_ARQ_ADDRESS, FLDIGI_ARQ_PORT,
|
||||
|
@ -881,7 +1220,7 @@ void set_macro_env(void)
|
|||
const char* val;
|
||||
} env[] = {
|
||||
#ifndef __WOE32__
|
||||
{ "PATH", "" },
|
||||
{ "pSKEDH", "" },
|
||||
{ "FLDIGI_RX_IPC_KEY", "" },
|
||||
{ "FLDIGI_TX_IPC_KEY", "" },
|
||||
#endif
|
||||
|
@ -919,13 +1258,13 @@ void set_macro_env(void)
|
|||
};
|
||||
|
||||
#ifndef __WOE32__
|
||||
// PATH
|
||||
static string path = ScriptsDir;
|
||||
path.erase(path.length()-1,1);
|
||||
// pSKEDH
|
||||
static string pSKEDh = ScriptsDir;
|
||||
pSKEDh.erase(pSKEDh.length()-1,1);
|
||||
const char* p;
|
||||
if ((p = getenv("PATH")))
|
||||
path.append(":").append(p);
|
||||
env[PATH].val = path.c_str();
|
||||
if ((p = getenv("pSKEDH")))
|
||||
pSKEDh.append(":").append(p);
|
||||
env[pSKEDH].val = pSKEDh.c_str();
|
||||
|
||||
// IPC keys
|
||||
char key[2][8];
|
||||
|
@ -1132,6 +1471,65 @@ static void pCONT(string &s, size_t &i, size_t endbracket)
|
|||
expand = true;
|
||||
}
|
||||
|
||||
static void pSKED(string &s, size_t &i, size_t endbracket)
|
||||
{
|
||||
string data = s.substr(i+6, endbracket - i - 6);
|
||||
size_t p = data.find(":");
|
||||
if (p == std::string::npos) {
|
||||
exec_date = zdate();
|
||||
exec_time = data;
|
||||
if (exec_time.empty()) exec_time = ztime();
|
||||
} else {
|
||||
exec_time = data.substr(0, p);
|
||||
exec_date = data.substr(p+1);
|
||||
}
|
||||
timed_exec = true;
|
||||
s.replace(i, endbracket - i + 1, "");
|
||||
}
|
||||
|
||||
void queue_reset()
|
||||
{
|
||||
if (!cmds.empty()) {
|
||||
Fl::remove_timeout(post_queue_execute);
|
||||
Fl::remove_timeout(queue_execute_after_rx);
|
||||
Fl::remove_timeout(doneIDLE);
|
||||
Fl::remove_timeout(doneWAIT);
|
||||
while (!cmds.empty()) cmds.pop();
|
||||
}
|
||||
Qwait_time = 0;
|
||||
Qidle_time = 0;
|
||||
que_ok = true;
|
||||
}
|
||||
|
||||
void postQueue(string s)
|
||||
{
|
||||
ReceiveText->add(s.c_str(), FTextBase::CTRL);
|
||||
}
|
||||
|
||||
void queue_execute()
|
||||
{
|
||||
if (cmds.empty()) {
|
||||
Qwait_time = 0;
|
||||
Qidle_time = 0;
|
||||
que_ok = true;
|
||||
return;
|
||||
}
|
||||
CMDS cmd = cmds.front();
|
||||
cmds.pop();
|
||||
cmd.fp(cmd.cmd);
|
||||
LOG_INFO("%s", cmd.cmd.c_str());
|
||||
REQ(postQueue, cmd.cmd.append("\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
bool queue_must_rx()
|
||||
{
|
||||
static string rxcmds = "<!MOD<!WAI<!GOH<!QSY<!GOF";
|
||||
if (cmds.empty()) return false;
|
||||
CMDS cmd = cmds.front();
|
||||
return (rxcmds.find(cmd.cmd.substr(0,5)) != string::npos);
|
||||
}
|
||||
|
||||
struct MTAGS { const char *mTAG; void (*fp)(string &, size_t&, size_t );};
|
||||
|
||||
MTAGS mtags[] = {
|
||||
|
@ -1181,7 +1579,7 @@ MTAGS mtags[] = {
|
|||
{"<IDLE:", pIDLE},
|
||||
{"<TUNE:", pTUNE},
|
||||
{"<WAIT:", pWAIT},
|
||||
{"<MODEM>", pMODEM_compat},
|
||||
{"<MODEM>", pMODEM_compSKED},
|
||||
{"<MODEM:", pMODEM},
|
||||
{"<EXEC>", pEXEC},
|
||||
{"<STOP>", pSTOP},
|
||||
|
@ -1211,9 +1609,20 @@ MTAGS mtags[] = {
|
|||
{"<MAPIT:", pMAPIT},
|
||||
{"<MAPIT>", pMAPIT},
|
||||
{"<REPEAT>", pREPEAT},
|
||||
{"<SKED:", pSKED},
|
||||
#ifdef __WIN32__
|
||||
{"<TALK:", pTALK},
|
||||
#endif
|
||||
{"<!WPM:", pQueWPM},
|
||||
{"<!RISE:", pQueRISETIME},
|
||||
{"<!PRE:", pQuePRE},
|
||||
{"<!POST:", pQuePOST},
|
||||
{"<!GOHOME>", pQueGOHOME},
|
||||
{"<!GOFREQ:", pQueGOFREQ},
|
||||
{"<!QSY:", pQueQSY},
|
||||
{"<!IDLE:", pQueIDLE},
|
||||
{"<!WAIT:", pQueWAIT},
|
||||
{"<!MODEM:", pQueMODEM},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
|
@ -1328,14 +1737,14 @@ void MACROTEXT::loadnewMACROS(string &s, size_t &i, size_t endbracket)
|
|||
showMacroSet();
|
||||
}
|
||||
|
||||
string MACROTEXT::expandMacro(int n)
|
||||
string MACROTEXT::expandMacro(std::string &s)
|
||||
{
|
||||
size_t idx = 0;
|
||||
expand = true;
|
||||
TransmitON = false;
|
||||
ToggleTXRX = false;
|
||||
mNbr = n;
|
||||
expanded = text[n];
|
||||
// mNbr = n;
|
||||
expanded = s;//text[n];
|
||||
MTAGS *pMtags;
|
||||
|
||||
xbeg = xend = -1;
|
||||
|
@ -1455,9 +1864,30 @@ static void set_button(Fl_Button* button, bool value)
|
|||
button->do_callback();
|
||||
}
|
||||
|
||||
void MACROTEXT::timed_execute()
|
||||
{
|
||||
queue_reset();
|
||||
TransmitText->clear();
|
||||
text2send = expandMacro(exec_string);
|
||||
TransmitText->add(text2send.c_str());
|
||||
exec_string.clear();
|
||||
active_modem->set_stopflag(false);
|
||||
start_tx();
|
||||
}
|
||||
|
||||
void MACROTEXT::execute(int n)
|
||||
{
|
||||
text2save = text2send = expandMacro(n);
|
||||
mNbr = n;
|
||||
// text2save =
|
||||
text2send = expandMacro(text[n]);
|
||||
|
||||
if (timed_exec) {
|
||||
progStatus.repeatMacro = -1;
|
||||
exec_string = text[n];
|
||||
timed_exec = false;
|
||||
startTimedExecute(name[n]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (progStatus.repeatMacro == -1)
|
||||
TransmitText->add( text2send.c_str() );
|
||||
|
@ -1505,8 +1935,8 @@ void MACROTEXT::execute(int n)
|
|||
|
||||
void MACROTEXT::repeat(int n)
|
||||
{
|
||||
expandMacro(n);
|
||||
LOG_INFO("%s",text2repeat.c_str());
|
||||
expandMacro(text[n]);
|
||||
LOG_WARN("%s",text2repeat.c_str());
|
||||
macro_idle_on = false;
|
||||
if (idleTime) progStatus.repeatIdleTime = idleTime;
|
||||
}
|
||||
|
|
|
@ -79,13 +79,22 @@ int mt63::tx_process()
|
|||
if (c == 0x03) {
|
||||
stopflag = true;
|
||||
flush = Tx->DataInterleave;
|
||||
c = 0;
|
||||
}
|
||||
|
||||
if (c == -1 || stopflag == true) c = 0;
|
||||
|
||||
if (stopflag && flush-- == 0) {
|
||||
if (stopflag) {
|
||||
stopflag = false;
|
||||
while (--flush) {
|
||||
Tx->SendChar(0);
|
||||
for (int i = 0; i < Tx->Comb.Output.Len; i++)
|
||||
if (fabs(Tx->Comb.Output.Data[i]) > maxval)
|
||||
maxval = fabs(Tx->Comb.Output.Data[i]);
|
||||
for (int i = 0; i < Tx->Comb.Output.Len; i++) {
|
||||
Tx->Comb.Output.Data[i] /= maxval;
|
||||
}
|
||||
ModulateXmtr((Tx->Comb.Output.Data), Tx->Comb.Output.Len);
|
||||
}
|
||||
Tx->SendJam();
|
||||
for (int i = 0; i < Tx->Comb.Output.Len; i++)
|
||||
if (fabs(Tx->Comb.Output.Data[i]) > maxval)
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
modem *null_modem = 0;
|
||||
modem *cw_modem = 0;
|
||||
|
||||
modem *mfsk8_modem = 0;
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
// ----------------------------------------------------------------------------
|
||||
// NULLMODEM.cxx -- NULLMODEM modem
|
||||
//
|
||||
// Copyright (C) 2006
|
||||
// Dave Freese, W1HKJ
|
||||
//
|
||||
// This file is part of fldigi. Adapted from code contained in gMFSK source code
|
||||
// distribution.
|
||||
// gMFSK Copyright (C) 2001, 2002, 2003
|
||||
// Tomi Manninen (oh2bns@sral.fi)
|
||||
//
|
||||
// Fldigi is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Fldigi is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with fldigi. If not, see <http://www.gnu.org/licenses/>.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
|
||||
#include "nullmodem.h"
|
||||
#include "fl_digi.h"
|
||||
#include "ascii.h"
|
||||
|
||||
#define null_bw 1
|
||||
|
||||
NULLMODEM:: NULLMODEM() : modem()
|
||||
{
|
||||
mode = MODE_NULL;
|
||||
samplerate = 8000;
|
||||
restart();
|
||||
}
|
||||
|
||||
NULLMODEM::~NULLMODEM() {};
|
||||
|
||||
void NULLMODEM::tx_init(SoundBase *sc)
|
||||
{
|
||||
scard = sc;
|
||||
}
|
||||
|
||||
void NULLMODEM::rx_init()
|
||||
{
|
||||
put_MODEstatus(mode);
|
||||
}
|
||||
|
||||
void NULLMODEM::init()
|
||||
{
|
||||
modem::init();
|
||||
rx_init();
|
||||
digiscope->mode(Digiscope::SCOPE);
|
||||
}
|
||||
|
||||
void NULLMODEM::restart()
|
||||
{
|
||||
set_bandwidth(null_bw);
|
||||
}
|
||||
|
||||
|
||||
//=====================================================================
|
||||
// receive processing
|
||||
//=====================================================================
|
||||
|
||||
int NULLMODEM::rx_process(const double *buf, int len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
//=====================================================================
|
||||
// transmit processing
|
||||
//=====================================================================
|
||||
|
||||
|
||||
int NULLMODEM::tx_process()
|
||||
{
|
||||
MilliSleep(10);
|
||||
if ( get_tx_char() == 0x03 || stopflag) {
|
||||
stopflag = false;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -158,7 +158,6 @@ static void trx_xmit_wfall_end(int samplerate)
|
|||
void trx_xmit_wfall_queue(int samplerate, const double* buf, size_t len)
|
||||
{
|
||||
ENSURE_THREAD(TRX_TID);
|
||||
|
||||
ringbuffer<double>::vector_type wv[2];
|
||||
wv[0].buf = wv[1].buf = 0;
|
||||
|
||||
|
@ -302,15 +301,19 @@ void trx_trx_transmit_loop()
|
|||
return;
|
||||
}
|
||||
|
||||
push2talk->set(true);
|
||||
if (active_modem != ssb_modem) {
|
||||
push2talk->set(true);
|
||||
REQ(&waterfall::set_XmtRcvBtn, wf, true);
|
||||
}
|
||||
active_modem->tx_init(scard);
|
||||
|
||||
if (progdefaults.TransmitRSid)
|
||||
if ((active_modem != null_modem && active_modem != ssb_modem) &&
|
||||
progdefaults.TransmitRSid)
|
||||
ReedSolomon->send(true);
|
||||
|
||||
dtmf->send();
|
||||
|
||||
while (trx_state == STATE_TX) {
|
||||
if (active_modem != ssb_modem && !progdefaults.DTMFstr.empty())
|
||||
dtmf->send();
|
||||
try {
|
||||
if (active_modem->tx_process() < 0)
|
||||
trx_state = STATE_RX;
|
||||
|
@ -326,9 +329,6 @@ void trx_trx_transmit_loop()
|
|||
|
||||
trx_xmit_wfall_end(current_samplerate);
|
||||
|
||||
// if (progdefaults.TransmitRSid)
|
||||
// ReedSolomon->send(false);
|
||||
|
||||
scard->flush();
|
||||
if (scard->must_close(O_WRONLY))
|
||||
scard->Close(O_WRONLY);
|
||||
|
@ -407,6 +407,17 @@ void *trx_loop(void *args)
|
|||
trxrb.reset();
|
||||
trx_signal_state();
|
||||
}
|
||||
/*
|
||||
printf("trx state %s\n",
|
||||
trx_state == STATE_ABORT ? "abort" :
|
||||
trx_state == STATE_ENDED ? "ended" :
|
||||
trx_state == STATE_RESTART ? "restart" :
|
||||
trx_state == STATE_NEW_MODEM ? "new modem" :
|
||||
trx_state == STATE_TX ? "tx" :
|
||||
trx_state == STATE_TUNE ? "tune" :
|
||||
trx_state == STATE_RX ? "rx" :
|
||||
"unknown");
|
||||
*/
|
||||
switch (trx_state) {
|
||||
case STATE_ABORT:
|
||||
delete scard;
|
||||
|
@ -423,8 +434,6 @@ void *trx_loop(void *args)
|
|||
break;
|
||||
case STATE_TX:
|
||||
trx_trx_transmit_loop();
|
||||
if (progStatus.timer)
|
||||
REQ(startMacroTimer);
|
||||
break;
|
||||
case STATE_TUNE:
|
||||
trx_tune_loop();
|
||||
|
|
Ładowanie…
Reference in New Issue