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/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 \
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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" },
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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_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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
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();
|
||||||
|
|
Ładowanie…
Reference in New Issue