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
David Freese 2011-09-21 08:39:40 -05:00
rodzic d2c33e4889
commit bb258cd1fc
16 zmienionych plików z 794 dodań i 86 usunięć

Wyświetl plik

@ -368,6 +368,7 @@ fldigi_SOURCES += \
include/rsid.h \ include/rsid.h \
include/rtty.h \ include/rtty.h \
include/view_rtty.h \ include/view_rtty.h \
include/nullmodem.h \
include/rx_extract.h \ include/rx_extract.h \
include/speak.h \ include/speak.h \
include/serial.h \ include/serial.h \
@ -480,6 +481,7 @@ fldigi_SOURCES += \
ssb/ssb.cxx \ ssb/ssb.cxx \
throb/throb.cxx \ throb/throb.cxx \
trx/modem.cxx \ trx/modem.cxx \
trx/nullmodem.cxx \
trx/trx.cxx \ trx/trx.cxx \
waterfall/colorbox.cxx \ waterfall/colorbox.cxx \
waterfall/digiscope.cxx \ waterfall/digiscope.cxx \

Wyświetl plik

@ -77,6 +77,7 @@
#endif #endif
#include "rigio.h" #include "rigio.h"
#include "rigMEM.h" #include "rigMEM.h"
#include "nullmodem.h"
#include "psk.h" #include "psk.h"
#include "cw.h" #include "cw.h"
#include "mfsk.h" #include "mfsk.h"
@ -970,6 +971,11 @@ void init_modem(trx_mode mode, int freq)
mode = NUM_MODES - 1; mode = NUM_MODES - 1;
return init_modem(mode, freq); 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: case MODE_CW:
startup_modem(*mode_info[mode].modem ? *mode_info[mode].modem : startup_modem(*mode_info[mode].modem ? *mode_info[mode].modem :
*mode_info[mode].modem = new cw, freq); *mode_info[mode].modem = new cw, freq);
@ -2220,6 +2226,7 @@ void stopMacroTimer()
progStatus.timer = 0; progStatus.timer = 0;
progStatus.repeatMacro = -1; progStatus.repeatMacro = -1;
Fl::remove_timeout(macro_timer); Fl::remove_timeout(macro_timer);
Fl::remove_timeout(macro_timed_execute);
btnMacroTimer->label(0); btnMacroTimer->label(0);
btnMacroTimer->color(FL_BACKGROUND_COLOR); btnMacroTimer->color(FL_BACKGROUND_COLOR);
@ -2240,6 +2247,32 @@ void macro_timer(void*)
Fl::repeat_timeout(1.0, macro_timer); 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*) void cbMacroTimerButton(Fl_Widget*, void*)
{ {
stopMacroTimer(); 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}, { 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}, {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_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}, { 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 Hmacrobtn;
int xpos; int xpos;
int ypos; int ypos;
int wblank; int wBLANK;
int fnt = fl_font(); int fnt = fl_font();
int fsize = fl_size(); 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); Fl_Group *btngroup2 = new Fl_Group(0, Y + 1, progStatus.mainW - Hmacros, Hmacros - 1);
Wmacrobtn = (btngroup2->w()) / NUMMACKEYS; Wmacrobtn = (btngroup2->w()) / NUMMACKEYS;
Hmacrobtn = btngroup2->h() - 1; Hmacrobtn = btngroup2->h() - 1;
wblank = (btngroup2->w() - NUMMACKEYS * Wmacrobtn) / 2; wBLANK = (btngroup2->w() - NUMMACKEYS * Wmacrobtn) / 2;
xpos = 0; xpos = 0;
ypos = btngroup2->y(); ypos = btngroup2->y();
for (int i = 0; i < NUMMACKEYS; i++) { for (int i = 0; i < NUMMACKEYS; i++) {
if (i == 4 || i == 8) { 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); bx->box(FL_FLAT_BOX);
xpos += wblank; xpos += wBLANK;
} }
btnMacro[NUMMACKEYS + i] = new Fl_Button(xpos, ypos, Wmacrobtn, Hmacrobtn, btnMacro[NUMMACKEYS + i] = new Fl_Button(xpos, ypos, Wmacrobtn, Hmacrobtn,
macros.name[NUMMACKEYS + i].c_str()); 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); Fl_Group *btngroup1 = new Fl_Group(0, Y+1, progStatus.mainW - Hmacros, Hmacros-1);
Wmacrobtn = (btngroup1->w()) / NUMMACKEYS; Wmacrobtn = (btngroup1->w()) / NUMMACKEYS;
Hmacrobtn = btngroup1->h() - 1; Hmacrobtn = btngroup1->h() - 1;
wblank = (btngroup1->w() - NUMMACKEYS * Wmacrobtn) / 2; wBLANK = (btngroup1->w() - NUMMACKEYS * Wmacrobtn) / 2;
xpos = 0; xpos = 0;
ypos = btngroup1->y(); ypos = btngroup1->y();
for (int i = 0; i < NUMMACKEYS; i++) { for (int i = 0; i < NUMMACKEYS; i++) {
if (i == 4 || i == 8) { 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); bx->box(FL_FLAT_BOX);
xpos += wblank; xpos += wBLANK;
} }
btnMacro[i] = new Fl_Button(xpos, ypos, Wmacrobtn, Hmacrobtn, btnMacro[i] = new Fl_Button(xpos, ypos, Wmacrobtn, Hmacrobtn,
macros.name[i].c_str()); 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}, { 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}, {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_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}, { 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; 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"; char szTestChar[] = "E|I|S|T|M|O|A|V";
int get_tx_char(void) 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) if (arq_text_available)
return arq_get_char(); return arq_get_char();
@ -5619,24 +5699,19 @@ int get_tx_char(void)
if (active_modem == cw_modem && progdefaults.QSKadjust) if (active_modem == cw_modem && progdefaults.QSKadjust)
return szTestChar[2 * progdefaults.TestChar]; return szTestChar[2 * progdefaults.TestChar];
int c; if ( progStatus.repeatMacro && progStatus.repeatIdleTime > 0 &&
static int pending = -1; !idling ) {
Fl::add_timeout(progStatus.repeatIdleTime, get_tx_char_idle);
idling = true;
return -1;
}
if (pending >= 0) { if (pending >= 0) {
c = pending; c = pending;
pending = -1; pending = -1;
return c; 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()) { if (progStatus.repeatMacro > -1 && text2repeat.length()) {
c = text2repeat[repeatchar]; c = text2repeat[repeatchar];
repeatchar++; repeatchar++;
@ -5648,12 +5723,15 @@ int get_tx_char(void)
} }
c = TransmitText->nextChar(); c = TransmitText->nextChar();
if (c == '^' && state == STATE_CHAR) { if (c == '^' && state == STATE_CHAR) {
state = STATE_CTRL; state = STATE_CTRL;
c = TransmitText->nextChar(); c = TransmitText->nextChar();
} }
switch (c) { switch (c) {
case -1: break; // no character available case -1: // no character available
queue_reset();
break;
case '\n': case '\n':
pending = '\n'; pending = '\n';
return '\r'; return '\r';
@ -5663,6 +5741,8 @@ int get_tx_char(void)
REQ_SYNC(&FTextTX::clear_sent, TransmitText); REQ_SYNC(&FTextTX::clear_sent, TransmitText);
state = STATE_CHAR; state = STATE_CHAR;
c = 3; // ETX c = 3; // ETX
if (progStatus.timer)
REQ(startMacroTimer);
break; break;
case 'R': case 'R':
if (state != STATE_CTRL) if (state != STATE_CTRL)
@ -5671,6 +5751,8 @@ int get_tx_char(void)
if (TransmitText->eot()) { if (TransmitText->eot()) {
REQ_SYNC(&FTextTX::clear_sent, TransmitText); REQ_SYNC(&FTextTX::clear_sent, TransmitText);
c = 3; // ETX c = 3; // ETX
if (progStatus.timer)
REQ(startMacroTimer);
} else } else
c = -1; c = -1;
break; break;
@ -5688,6 +5770,19 @@ int get_tx_char(void)
c = -1; c = -1;
REQ(clearQSO); REQ(clearQSO);
break; 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 '^': case '^':
state = STATE_CHAR; state = STATE_CHAR;
break; break;
@ -5870,7 +5965,6 @@ void start_tx()
if (!(active_modem->get_cap() & modem::CAP_TX)) if (!(active_modem->get_cap() & modem::CAP_TX))
return; return;
trx_transmit(); trx_transmit();
REQ(&waterfall::set_XmtRcvBtn, wf, true);
} }
void abort_tx() void abort_tx()
@ -5881,6 +5975,7 @@ void abort_tx()
return; return;
} }
if (trx_state == STATE_TX) { if (trx_state == STATE_TX) {
queue_reset();
trx_start_modem(active_modem); trx_start_modem(active_modem);
} }
} }

Wyświetl plik

@ -235,8 +235,6 @@ void cDTMF::two_tones(int ch)
void cDTMF::send() void cDTMF::send()
{ {
if (progdefaults.DTMFstr.empty()) return;
int c = 0, delay = 0; int c = 0, delay = 0;
duration = 50; duration = 50;
RT = (int)(active_modem->get_samplerate() * 4 / 1000.0); // 4 msec edge RT = (int)(active_modem->get_samplerate() * 4 / 1000.0); // 4 msec edge

Wyświetl plik

@ -43,6 +43,8 @@ using namespace std;
// ... doing so will break the Fl_menu_item table 'menu_'. -Kamal // ... doing so will break the Fl_menu_item table 'menu_'. -Kamal
const struct mode_info_t mode_info[NUM_MODES] = { 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_CW, &cw_modem, "CW", "CW", "CW", "CW", "CW" },
{ MODE_CONTESTIA, &contestia_modem, "CTSTIA", "Contestia", "", "CONTESTI", "CT" }, { MODE_CONTESTIA, &contestia_modem, "CTSTIA", "Contestia", "", "CONTESTI", "CT" },

Wyświetl plik

@ -148,6 +148,9 @@ extern Digiscope *digiscope;
extern std::string main_window_title; extern std::string main_window_title;
extern int Qwait_time;
extern int Qidle_time;
extern void toggleRSID(); extern void toggleRSID();
extern void set_menus(); extern void set_menus();
@ -214,6 +217,10 @@ extern void put_WARNstatus(double);
extern void qsoSave_cb(Fl_Widget *b, void *); 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 void put_rx_data(int *data, int len);
extern int get_tx_char(); extern int get_tx_char();
extern int get_secondary_char(); extern int get_secondary_char();
@ -259,6 +266,10 @@ extern void set_contestia_default_integ();
extern void startMacroTimer(); extern void startMacroTimer();
extern void stopMacroTimer(); 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 cb_ResetSerNbr();
extern void updateOutSerNo(); extern void updateOutSerNo();

Wyświetl plik

@ -49,6 +49,8 @@ enum {
MODE_PREV = -2, MODE_PREV = -2,
MODE_NEXT, MODE_NEXT,
MODE_NULL,
MODE_CW, MODE_CW,
MODE_CONTESTIA, MODE_CONTESTIA,

Wyświetl plik

@ -36,9 +36,10 @@ struct MACROTEXT {
void openMacroFile(); void openMacroFile();
void saveMacroFile(); void saveMacroFile();
void saveMacros(const std::string& fname); void saveMacros(const std::string& fname);
std::string expandMacro(int n); std::string expandMacro(std::string &s);
void execute(int n); void execute(int n);
void repeat(int n); void repeat(int n);
void timed_execute();
MACROTEXT(); MACROTEXT();
private: private:
std::string expanded; std::string expanded;
@ -53,6 +54,15 @@ extern std::string info2msg;
extern std::string qso_time; extern std::string qso_time;
extern std::string qso_exchange; 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 set_macro_env(void);
void queue_reset();
void queue_execute();
bool queue_must_rx();
void idleTimer(void *);
#endif #endif

Wyświetl plik

@ -181,6 +181,8 @@ protected:
virtual void s2nreport(void); virtual void s2nreport(void);
}; };
extern modem *null_modem;
extern modem *cw_modem; extern modem *cw_modem;
extern modem *mfsk8_modem; extern modem *mfsk8_modem;

Wyświetl plik

@ -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

Wyświetl plik

@ -43,11 +43,8 @@ extern void trx_tune();
extern void trx_receive(); extern void trx_receive();
extern void trx_reset(void); extern void trx_reset(void);
extern void trx_start_macro_timer();
extern void trx_wait_state(void); extern void trx_wait_state(void);
extern void macro_timer(void *);
extern state_t trx_state; extern state_t trx_state;
extern modem *active_modem; extern modem *active_modem;

Wyświetl plik

@ -52,12 +52,12 @@ using namespace std;
Fl_Double_Window *MacroEditDialog = (Fl_Double_Window *)0; Fl_Double_Window *MacroEditDialog = (Fl_Double_Window *)0;
Fl_Button *btnMacroEditOK = (Fl_Button *)0; Fl_Button *btnMacroEditApply = (Fl_Button *)0;
Fl_Button *btnMacroEditCancel = (Fl_Button *)0; Fl_Button *btnMacroEditClose = (Fl_Button *)0;
Fl_Button *btnInsertMacro = (Fl_Button *)0; Fl_Button *btnInsertMacro = (Fl_Button *)0;
Fl_Input2 *macrotext = (Fl_Input2 *)0; Fl_Input2 *macrotext = (Fl_Input2 *)0;
Fl_Input2 *labeltext = (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; 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(_("<TUNE:NN>\ttune signal for NN sec"));
w->add(_("<WAIT:NN>\tdelay xmt for NN sec")); w->add(_("<WAIT:NN>\tdelay xmt for NN sec"));
w->add(_("<REPEAT>\trepeat macro continuously")); w->add(_("<REPEAT>\trepeat macro continuously"));
w->add(_("<SKED:hhmm[:YYYYDDMM]>\tschedule execution"));
w->add(LINE_SEP); w->add(LINE_SEP);
w->add(_("<CWID>\tCW identifier")); w->add(_("<CWID>\tCW identifier"));
@ -240,8 +241,10 @@ void loadBrowser(Fl_Widget *widget) {
void cbMacroEditOK(Fl_Widget *w, void *) void cbMacroEditOK(Fl_Widget *w, void *)
{ {
if (w == btnMacroEditCancel) if (w == btnMacroEditClose) {
goto ret; MacroEditDialog->hide();
return;
}
if (iType == MACRO_EDIT_BUTTON) { if (iType == MACRO_EDIT_BUTTON) {
macros.text[iMacro] = macrotext->value(); macros.text[iMacro] = macrotext->value();
@ -264,8 +267,6 @@ void cbMacroEditOK(Fl_Widget *w, void *)
} }
else if (iType == MACRO_EDIT_INPUT) else if (iType == MACRO_EDIT_INPUT)
iInput->value(macrotext->value()); iInput->value(macrotext->value());
ret:
MacroEditDialog->hide();
} }
void cbInsertMacro(Fl_Widget *, void *) void cbInsertMacro(Fl_Widget *, void *)
@ -315,30 +316,30 @@ void cbInsertMacro(Fl_Widget *, void *)
Fl_Double_Window* make_macroeditor(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->type(FL_MULTILINE_INPUT);
macrotext->textfont(FL_COURIER); 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->image(new Fl_Pixmap(left_arrow_icon));
btnInsertMacro->callback(cbInsertMacro); 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->column_widths(widths);
macroDefs->align(FL_ALIGN_TOP_LEFT); macroDefs->align(FL_ALIGN_TOP);
loadBrowser(macroDefs); loadBrowser(macroDefs);
labeltext = new Fl_Input2(2 + 450 - 115, 164, 115, 24, _("Macro Button Label:")); labeltext = new Fl_Input2(2 + 450 - 115, 164, 115, 24, _("Macro Button Label:"));
labeltext->textfont(FL_COURIER); labeltext->textfont(FL_COURIER);
btnMacroEditOK = new Fl_Button(476 + 145 - 80 - 1, 164, 80, 24, _("OK")); btnMacroEditApply = new Fl_Button(452 + macroDefs->w()/2 - 80 - 1, 164, 80, 24, _("Apply"));
btnMacroEditOK->callback(cbMacroEditOK); btnMacroEditApply->callback(cbMacroEditOK);
btnMacroEditCancel = new Fl_Button(476 + 145 + 1 , 164, 80, 24, _("Cancel")); btnMacroEditClose = new Fl_Button(452 + macroDefs->w()/2 + 1 , 164, 80, 24, _("Close"));
btnMacroEditCancel->callback(cbMacroEditOK); btnMacroEditClose->callback(cbMacroEditOK);
w->end(); w->end();
w->xclass(PACKAGE_NAME); w->xclass(PACKAGE_NAME);

Wyświetl plik

@ -55,6 +55,7 @@
#include <unistd.h> #include <unistd.h>
#include <string> #include <string>
#include <fstream> #include <fstream>
#include <queue>
#ifdef __WIN32__ #ifdef __WIN32__
#include "speak.h" #include "speak.h"
@ -62,6 +63,17 @@
using namespace std; 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; MACROTEXT macros;
CONTESTCNTR contest_count; CONTESTCNTR contest_count;
static bool TransmitON = false; static bool TransmitON = false;
@ -70,20 +82,24 @@ static int mNbr;
std::string qso_time = ""; std::string qso_time = "";
std::string qso_exchange = ""; std::string qso_exchange = "";
static bool save_xchg;
static size_t xbeg = 0, xend = 0;
string text2send = ""; std::string exec_date = "";
string text2repeat = ""; std::string exec_time = "";
string text2save = ""; std::string exec_string = "";
std::string text2send = "";
std::string text2repeat = "";
//std::string text2save = "";
std::string info1msg = "";
std::string info2msg = "";
size_t repeatchar = 0; size_t repeatchar = 0;
static size_t xbeg = 0, xend = 0;
static bool save_xchg;
static bool expand; static bool expand;
static bool GET = false; static bool GET = false;
static bool timed_exec = false;
string info1msg = "";
string info2msg = "";
static char cutnumbers[] = "T12345678N"; static char cutnumbers[] = "T12345678N";
static string cutstr; static string cutstr;
@ -204,6 +220,107 @@ static void pPOST(string &s, size_t &i, size_t endbracket)
s.replace(i, endbracket - i + 1, ""); 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; bool macro_idle_on = false;
static float idleTime = 0; 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, ""); 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 bool useTune = false;
static int tuneTime = 0; 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, ""); 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) static void pINFO1(string &s, size_t &i, size_t endbracket)
{ {
s.replace( i, 7, info1msg ); 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) static void pTEXT(string &s, size_t &i, size_t endbracket)
{ {
progdefaults.macrotextid = true; progdefaults.macrotextid = true;
s.replace( i, 6, ""); s.replace( i, 6, "");
} }
@ -450,10 +618,16 @@ static void pCWID(string &s, size_t &i, size_t endbracket)
s.replace( i, 6, ""); 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) static void pDTMF(string &s, size_t &i, size_t endbracket)
{ {
progdefaults.DTMFstr = s.substr(i + 6, endbracket - i - 6); CMDS cmd = {s.substr(i, endbracket - i + 1), doDTMF};
s.replace(i, endbracket - i + 1, ""); pushcmd(cmd);
s.replace(i, endbracket - i + 1, "^!");
} }
static void pRX(string &s, size_t &i, size_t endbracket) 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"); 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, size_t j, k,
len = s.length(); len = s.length();
@ -584,6 +758,84 @@ static void pMODEM_compat(string &s, size_t &i, size_t endbracket)
#include <float.h> #include <float.h>
#include "re.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 void pMODEM(string &s, size_t &i, size_t endbracket)
{ {
static fre_t re("<MODEM:([[:alnum:]-]+)((:[[:digit:].+-]*)*)>", REG_EXTENDED); 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(); btnAFC->do_callback();
} }
//pushcmd(s.substr(i, endbracket - i + 1));
//s.replace(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->damage();
wf->xmtlock->do_callback(); wf->xmtlock->do_callback();
} }
//pushcmd(s.substr(i, endbracket - i + 1));
//s.replace(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(); btnTxRSID->do_callback();
} }
//pushcmd(s.substr(i, endbracket - i + 1));
//s.replace(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); 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) static void pGOFREQ(string &s, size_t &i, size_t endbracket)
{ {
int number; int number;
@ -791,6 +1067,28 @@ static void pGOFREQ(string &s, size_t &i, size_t endbracket)
s.replace(i, endbracket - i + 1, ""); 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) static void pQSYTO(string &s, size_t &i, size_t endbracket)
{ {
s.replace( i, 7, ""); s.replace( i, 7, "");
@ -830,7 +1128,6 @@ static void pQSY(string &s, size_t &i, size_t endbracket)
if (audio > progdefaults.HighFreqCutoff) if (audio > progdefaults.HighFreqCutoff)
audio = progdefaults.HighFreqCutoff; audio = progdefaults.HighFreqCutoff;
} }
if (rf && rf != wf->rfcarrier()) if (rf && rf != wf->rfcarrier())
qsy(rf, audio); qsy(rf, audio);
else else
@ -839,6 +1136,48 @@ static void pQSY(string &s, size_t &i, size_t endbracket)
s.replace(i, endbracket - i + 1, ""); 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) static void pRIGMODE(string& s, size_t& i, size_t endbracket)
{ {
string sMode = s.substr(i+9, endbracket - i - 9); string sMode = s.substr(i+9, endbracket - i - 9);
@ -859,7 +1198,7 @@ void set_macro_env(void)
{ {
enum { enum {
#ifndef __WOE32__ #ifndef __WOE32__
PATH, FLDIGI_RX_IPC_KEY, FLDIGI_TX_IPC_KEY, pSKEDH, FLDIGI_RX_IPC_KEY, FLDIGI_TX_IPC_KEY,
#endif #endif
FLDIGI_XMLRPC_ADDRESS, FLDIGI_XMLRPC_PORT, FLDIGI_XMLRPC_ADDRESS, FLDIGI_XMLRPC_PORT,
FLDIGI_ARQ_ADDRESS, FLDIGI_ARQ_PORT, FLDIGI_ARQ_ADDRESS, FLDIGI_ARQ_PORT,
@ -881,7 +1220,7 @@ void set_macro_env(void)
const char* val; const char* val;
} env[] = { } env[] = {
#ifndef __WOE32__ #ifndef __WOE32__
{ "PATH", "" }, { "pSKEDH", "" },
{ "FLDIGI_RX_IPC_KEY", "" }, { "FLDIGI_RX_IPC_KEY", "" },
{ "FLDIGI_TX_IPC_KEY", "" }, { "FLDIGI_TX_IPC_KEY", "" },
#endif #endif
@ -919,13 +1258,13 @@ void set_macro_env(void)
}; };
#ifndef __WOE32__ #ifndef __WOE32__
// PATH // pSKEDH
static string path = ScriptsDir; static string pSKEDh = ScriptsDir;
path.erase(path.length()-1,1); pSKEDh.erase(pSKEDh.length()-1,1);
const char* p; const char* p;
if ((p = getenv("PATH"))) if ((p = getenv("pSKEDH")))
path.append(":").append(p); pSKEDh.append(":").append(p);
env[PATH].val = path.c_str(); env[pSKEDH].val = pSKEDh.c_str();
// IPC keys // IPC keys
char key[2][8]; char key[2][8];
@ -1132,6 +1471,65 @@ static void pCONT(string &s, size_t &i, size_t endbracket)
expand = true; 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 );}; struct MTAGS { const char *mTAG; void (*fp)(string &, size_t&, size_t );};
MTAGS mtags[] = { MTAGS mtags[] = {
@ -1181,7 +1579,7 @@ MTAGS mtags[] = {
{"<IDLE:", pIDLE}, {"<IDLE:", pIDLE},
{"<TUNE:", pTUNE}, {"<TUNE:", pTUNE},
{"<WAIT:", pWAIT}, {"<WAIT:", pWAIT},
{"<MODEM>", pMODEM_compat}, {"<MODEM>", pMODEM_compSKED},
{"<MODEM:", pMODEM}, {"<MODEM:", pMODEM},
{"<EXEC>", pEXEC}, {"<EXEC>", pEXEC},
{"<STOP>", pSTOP}, {"<STOP>", pSTOP},
@ -1211,9 +1609,20 @@ MTAGS mtags[] = {
{"<MAPIT:", pMAPIT}, {"<MAPIT:", pMAPIT},
{"<MAPIT>", pMAPIT}, {"<MAPIT>", pMAPIT},
{"<REPEAT>", pREPEAT}, {"<REPEAT>", pREPEAT},
{"<SKED:", pSKED},
#ifdef __WIN32__ #ifdef __WIN32__
{"<TALK:", pTALK}, {"<TALK:", pTALK},
#endif #endif
{"<!WPM:", pQueWPM},
{"<!RISE:", pQueRISETIME},
{"<!PRE:", pQuePRE},
{"<!POST:", pQuePOST},
{"<!GOHOME>", pQueGOHOME},
{"<!GOFREQ:", pQueGOFREQ},
{"<!QSY:", pQueQSY},
{"<!IDLE:", pQueIDLE},
{"<!WAIT:", pQueWAIT},
{"<!MODEM:", pQueMODEM},
{0, 0} {0, 0}
}; };
@ -1328,14 +1737,14 @@ void MACROTEXT::loadnewMACROS(string &s, size_t &i, size_t endbracket)
showMacroSet(); showMacroSet();
} }
string MACROTEXT::expandMacro(int n) string MACROTEXT::expandMacro(std::string &s)
{ {
size_t idx = 0; size_t idx = 0;
expand = true; expand = true;
TransmitON = false; TransmitON = false;
ToggleTXRX = false; ToggleTXRX = false;
mNbr = n; // mNbr = n;
expanded = text[n]; expanded = s;//text[n];
MTAGS *pMtags; MTAGS *pMtags;
xbeg = xend = -1; xbeg = xend = -1;
@ -1455,9 +1864,30 @@ static void set_button(Fl_Button* button, bool value)
button->do_callback(); 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) 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) if (progStatus.repeatMacro == -1)
TransmitText->add( text2send.c_str() ); TransmitText->add( text2send.c_str() );
@ -1505,8 +1935,8 @@ void MACROTEXT::execute(int n)
void MACROTEXT::repeat(int n) void MACROTEXT::repeat(int n)
{ {
expandMacro(n); expandMacro(text[n]);
LOG_INFO("%s",text2repeat.c_str()); LOG_WARN("%s",text2repeat.c_str());
macro_idle_on = false; macro_idle_on = false;
if (idleTime) progStatus.repeatIdleTime = idleTime; if (idleTime) progStatus.repeatIdleTime = idleTime;
} }

Wyświetl plik

@ -79,13 +79,22 @@ int mt63::tx_process()
if (c == 0x03) { if (c == 0x03) {
stopflag = true; stopflag = true;
flush = Tx->DataInterleave; flush = Tx->DataInterleave;
c = 0;
} }
if (c == -1 || stopflag == true) c = 0; if (c == -1 || stopflag == true) c = 0;
if (stopflag && flush-- == 0) { if (stopflag) {
stopflag = false; 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(); Tx->SendJam();
for (int i = 0; i < Tx->Comb.Output.Len; i++) for (int i = 0; i < Tx->Comb.Output.Len; i++)
if (fabs(Tx->Comb.Output.Data[i]) > maxval) if (fabs(Tx->Comb.Output.Data[i]) > maxval)

Wyświetl plik

@ -42,6 +42,7 @@
using namespace std; using namespace std;
modem *null_modem = 0;
modem *cw_modem = 0; modem *cw_modem = 0;
modem *mfsk8_modem = 0; modem *mfsk8_modem = 0;

Wyświetl plik

@ -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;
}

Wyświetl plik

@ -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) void trx_xmit_wfall_queue(int samplerate, const double* buf, size_t len)
{ {
ENSURE_THREAD(TRX_TID); ENSURE_THREAD(TRX_TID);
ringbuffer<double>::vector_type wv[2]; ringbuffer<double>::vector_type wv[2];
wv[0].buf = wv[1].buf = 0; wv[0].buf = wv[1].buf = 0;
@ -302,15 +301,19 @@ void trx_trx_transmit_loop()
return; return;
} }
push2talk->set(true); if (active_modem != ssb_modem) {
push2talk->set(true);
REQ(&waterfall::set_XmtRcvBtn, wf, true);
}
active_modem->tx_init(scard); active_modem->tx_init(scard);
if (progdefaults.TransmitRSid) if ((active_modem != null_modem && active_modem != ssb_modem) &&
progdefaults.TransmitRSid)
ReedSolomon->send(true); ReedSolomon->send(true);
dtmf->send();
while (trx_state == STATE_TX) { while (trx_state == STATE_TX) {
if (active_modem != ssb_modem && !progdefaults.DTMFstr.empty())
dtmf->send();
try { try {
if (active_modem->tx_process() < 0) if (active_modem->tx_process() < 0)
trx_state = STATE_RX; trx_state = STATE_RX;
@ -326,9 +329,6 @@ void trx_trx_transmit_loop()
trx_xmit_wfall_end(current_samplerate); trx_xmit_wfall_end(current_samplerate);
// if (progdefaults.TransmitRSid)
// ReedSolomon->send(false);
scard->flush(); scard->flush();
if (scard->must_close(O_WRONLY)) if (scard->must_close(O_WRONLY))
scard->Close(O_WRONLY); scard->Close(O_WRONLY);
@ -407,6 +407,17 @@ void *trx_loop(void *args)
trxrb.reset(); trxrb.reset();
trx_signal_state(); 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) { switch (trx_state) {
case STATE_ABORT: case STATE_ABORT:
delete scard; delete scard;
@ -423,8 +434,6 @@ void *trx_loop(void *args)
break; break;
case STATE_TX: case STATE_TX:
trx_trx_transmit_loop(); trx_trx_transmit_loop();
if (progStatus.timer)
REQ(startMacroTimer);
break; break;
case STATE_TUNE: case STATE_TUNE:
trx_tune_loop(); trx_tune_loop();