Merge remote branch 'jamescoxon/master'

pull/2/head
Philip Heron 2010-04-01 00:18:08 +01:00
commit e1a82fb0ac
25 zmienionych plików z 1016 dodań i 641 usunięć

170
ChangeLog
Wyświetl plik

@ -1,5 +1,15 @@
2010-03-20 David Freese <w1hkj@w1hkj.com>
2010-03-26 Stelios Bounanos <vcs@enotty.net>
80572f5: Improve monitoring of transmitted signal
2010-03-25 David Freese <w1hkj@w1hkj.com>
c517a1e: NBEMS files
b794fb1: Rx Contest Popup Menu
09c77b5: Olivia bug fix
b6b6d76: Contest Rig/Log View
4000fe0: CW Xmt WPM
35826a3: Cabrillo Report
3b63d8f: XBEG-XEND macro tags
2010-03-20 Giuseppe Ciaccio <ciaccio@disi.unige.it>
@ -503,161 +513,3 @@
4fff116: Add missing include
d1c206b: Restore MT-63 options
dfab290: Initialise pthreads/win32 in flarq
ecf1f10: Restore two channel capture
a8a734c: Fix millisleep function
2009-07-23 David Freese <w1hkj@w1hkj.com>
cf4c671: MT63 transmit bug fix
=Version 3.12=
2009-07-13 Stelios Bounanos <vcs@enotty.net>
3537f62: Add RSID notifications
2a4cd68: Improve frequency display kb entry
2009-07-11 David Freese <w1hkj@w1hkj.com>
9c291a8: Enable XMLRPC QSY capability
2009-07-06 Stelios Bounanos <vcs@enotty.net>
deea0f6: Add ITU zone to countries list
d54a2ca: Fix compilation on glibc 2.10
2009-07-02 David Freese <w1hkj@w1hkj.com>
9de9eb5: Xmlrpc mods
07a01b1: Logbook bug fix
2009-07-01 Stelios Bounanos <vcs@enotty.net>
42b638d: Fix socket fd leak
58c2f8b: Fix compilation error and warnings on 64bit archs
c07ec21: Add generic notifier
88bedac: Add dragging to table widget
757a8f8: Simplify RE classes
cbf0d87: Extend macro editor
53a2820: Improve dxcc, spot, pskrep performance
9648c30: Remove handling for REs without backref support
1b474a2: Fix config input field labels
d6d5974: Add Fl_Input2 mouse wheel handling
bf4cea4: Add automatic FText text_area resizing
e803fcd: Improve FText drag and drop
ec26eb6: Add band to RX text tooltip
8283833: Add string join and split functions
d70ea69: Print build info in crash handler
f25b5d1: Fix azimuth_long_path
d11f6fe: Add frequency display text paste support
2009-06-30 David Freese <w1hkj@w1hkj.com>
3bad2d4: xmlrpc mods
2009-06-12 Stelios Bounanos <vcs@enotty.net>
419123c: Fix text echo functions
2a83da3: Remove FText text colour adjustment
7a87b0b: Always set the FText cursor colour
2009-06-12 David Freese <w1hkj@w1hkj.com>
a8dfa58: Logbook bug fix
9b7786f: RigCAT mods
2009-06-01 Stelios Bounanos <vcs@enotty.net>
9f7b002: Fix Contest Country Files callsign lookup
2009-06-01 David Freese <w1hkj@w1hkj.com>
b539c1c: ADIF_2.2.3 compliance
8fc582e: Cut number mod for CW
2009-05-26 dave <dave@linux-dev.(none)>
7690a1c: FLARQ
2009-05-26 Stelios Bounanos <vcs@enotty.net>
d4b1a03: Merge flarq
91a1425: Move setup_nls function
9543fa7: Move make_pixmap function
ada43f4: Add new FText classes
bf6a2c3: Add thread id logging
8207c62: Prefer ALSA default devices
d04b780: Fix initial window sizes
4f90ecf: Fix format strings
2009-05-16 David Freese <w1hkj@w1hkj.com>
6b6cad9: PSK search algorithm
2009-05-12 Stelios Bounanos <vcs@enotty.net>
b95b8e1: Add win32 installer support
d626273: Fix VPATH builds
2009-05-05 David Freese <w1hkj@w1hkj.com>
b4112de: Added <RSID:on|off|t>, <AFC:on:off|t> macro tags
7ae826f: RTTY pseudo output, corrected stop bit inversion
2009-05-02 Stelios Bounanos <vcs@enotty.net>
ae5b9ca: Add more PNG text comments
974e1ec: Remove JPEG write support
44eceae: Fix xmlrpc-c m4 macro
2009-05-02 David Freese <w1hkj@w1hkj.com>
b030b4b: Fix OS dependent compile error
abc11f7: Updated memory mapped rig contol
2009-04-26 Stelios Bounanos <vcs@enotty.net>
31e1902: Add missing includes
6b2260c: Macro changes
8f37399: Fix possible trx_startup deadlock
edca452: Fix Makefile DEBUG flag
2009-04-25 David Freese <w1hkj@w1hkj.com>
affae09: CW default WPM (numeric keypad *) bug fix
2009-04-23 Stelios Bounanos <vcs@enotty.net>
f7309ef: Make the combo box popup modal
ed0ae5c: Fix OS X native file selector
88b3fd7: Fix uHRouter and parport PTT
9c63531: Fix format string
2009-04-23 David Freese <w1hkj@w1hkj.com>
8944198: CW replay bug
fc50717: CW Farnsworth timing addition
63ccc2f: MinGW serial i/o, hamlib, rigcat mods
2009-04-18 Stelios Bounanos <vcs@enotty.net>
206f815: Fix build without hamlib
2009-04-18 David Freese <w1hkj@w1hkj.com>
a9c21e5: Escape key bug fix
d2674d5: Macro <XOUT> parse error fix
2009-04-17 Stelios Bounanos <vcs@enotty.net>
9e060b8: Update version output
77bc966: Use band functions in logbook
2124791: Add functions to set the socket buffer size
4b1292c: Improve logging and error notification
d73c8fd: Add OS X and MinGW stack tracing
e192d1d: Add preliminary support for MinGW
01fd3d9: Change set_log macro
9d56656: Clean up headers
b4bf47f: Distribute cr.sh test script

Wyświetl plik

@ -9,7 +9,7 @@ dnl major and minor must be integers; patch may
dnl contain other characters or be empty
m4_define(FLDIGI_MAJOR, [3])
m4_define(FLDIGI_MINOR, [20])
m4_define(FLDIGI_PATCH, [.0b8])
m4_define(FLDIGI_PATCH, [.0b9])
m4_define(FLARQ_MAJOR, [4])
m4_define(FLARQ_MINOR, [3])
m4_define(FLARQ_PATCH, [.0b1])

Wyświetl plik

@ -4,7 +4,7 @@
// Copyright (C) 2006-2010
// Dave Freese, W1HKJ
//
// This file is part of fldigi. Adapted from code contained in gmfsk source code
// 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)
@ -54,12 +54,12 @@ void cw::tx_init(SoundBase *sc)
void cw::rx_init()
{
cw_receive_state = RS_IDLE;
smpl_ctr = 0;
cw_rr_current = 0;
agc_peak = 0;
cw_receive_state = RS_IDLE;
smpl_ctr = 0;
cw_rr_current = 0;
agc_peak = 0;
set_scope_mode(Digiscope::SCOPE);
put_MODEstatus(mode);
update_Status();
usedefaultWPM = false;
scope_clear = true;
}
@ -96,13 +96,13 @@ cw::cw() : modem()
tx_frequency = get_txfreq_woffset();
risetime = progdefaults.CWrisetime;
QSKshape = progdefaults.QSKshape;
samplerate = CWSampleRate;
fragmentsize = CWMaxSymLen;
cw_speed = progdefaults.CWspeed;
bandwidth = progdefaults.CWbandwidth;
cw_send_speed = cw_speed;
cw_receive_speed = cw_speed;
cw_adaptive_receive_threshold = 2 * DOT_MAGIC / cw_speed;
@ -111,7 +111,7 @@ cw::cw() : modem()
cw_send_dash_length = 3 * cw_send_dot_length;
symbollen = (int)(samplerate * 1.2 / progdefaults.CWspeed);
fsymlen = (int)((50*(samplerate * 1.2 / progdefaults.CWfarnsworth) - 41*symbollen)/9);
memset(rx_rep_buf, 0, sizeof(rx_rep_buf));
// block of variables that get updated each time speed changes
@ -124,7 +124,7 @@ cw::cw() : modem()
lp = 0.5 * bandwidth / samplerate;
cwfilter = new C_FIR_filter();
cwfilter->init_lowpass (CW_FIRLEN, DEC_RATIO, lp);
bitfilter = new Cmovavg(8);
bitfilterlen = (int)(samplerate / frequency / 4);
bitfilterlen = bitfilterlen < 2 ? 2 : bitfilterlen;
@ -135,6 +135,7 @@ cw::cw() : modem()
makeshape();
sync_parameters();
wf->Bandwidth ((int)bandwidth);
update_Status();
// init();
}
@ -142,29 +143,29 @@ cw::cw() : modem()
// sync_parameters()
// Synchronize the dot, dash, end of element, end of character, and end
// of word timings and ranges to new values of Morse speed, or receive tolerance.
void cw::sync_parameters()
{
int lowerwpm, upperwpm, nusymbollen, nufsymlen;
int wpm = usedefaultWPM ? progdefaults.defCWspeed : progdefaults.CWspeed;
int fwpm = usedefaultWPM ? progdefaults.defCWspeed : progdefaults.CWfarnsworth;
cw_send_dot_length = DOT_MAGIC / progdefaults.CWspeed;
// if (usedefaultWPM == false)
// cw_send_dot_length = DOT_MAGIC / progdefaults.CWspeed;
// else
// cw_send_dot_length = DOT_MAGIC / progdefaults.defCWspeed;
cw_send_dash_length = 3 * cw_send_dot_length;
nusymbollen = (int)(samplerate * 1.2 / wpm);
nufsymlen = (int)((50*(samplerate * 1.2 / fwpm) - 41*symbollen)/9);
// nusymbollen = (int)(samplerate * 1.2 / progdefaults.CWspeed);
// nufsymlen = (int)((50*(samplerate * 1.2 / progdefaults.CWfarnsworth) - 41*symbollen)/9);
if (symbollen != nusymbollen ||
if (symbollen != nusymbollen ||
nufsymlen != fsymlen ||
risetime != progdefaults.CWrisetime ||
QSKshape != progdefaults.QSKshape ) {
@ -180,7 +181,7 @@ void cw::sync_parameters()
bitfilterlen = len;
bitfilter->setLength(bitfilterlen);
}
// check if user changed the tracking or the cw default speed
if ((cwTrack != progdefaults.CWtrack) ||
(cw_send_speed != progdefaults.CWspeed)) {
@ -190,13 +191,13 @@ void cw::sync_parameters()
}
cwTrack = progdefaults.CWtrack;
cw_send_speed = progdefaults.CWspeed;
// Receive parameters:
lowerwpm = cw_send_speed - progdefaults.CWrange;
upperwpm = cw_send_speed + progdefaults.CWrange;
if (lowerwpm < progdefaults.CWlowerlimit)
lowerwpm = progdefaults.CWlowerlimit;
if (upperwpm > progdefaults.CWupperlimit)
if (upperwpm > progdefaults.CWupperlimit)
upperwpm = progdefaults.CWupperlimit;
cw_lower_limit = 2 * DOT_MAGIC / upperwpm;
cw_upper_limit = 2 * DOT_MAGIC / lowerwpm;
@ -207,7 +208,7 @@ void cw::sync_parameters()
cw_receive_speed = cw_send_speed;
cw_adaptive_receive_threshold = 2 * cw_send_dot_length;
}
cw_receive_dot_length = DOT_MAGIC / cw_receive_speed;
cw_receive_dash_length = 3 * cw_receive_dot_length;
@ -235,7 +236,7 @@ void cw::update_tracking(int idot, int idash)
dash = idash;
else
dash = cw_send_dash_length;
cw_adaptive_receive_threshold = (long int)trackingfilter->run((dash + dot) / 2);
sync_parameters();
}
@ -248,15 +249,7 @@ void cw::update_tracking(int idot, int idash)
void cw::update_Status()
{
static char RXmsg[20];
static char TXmsg[20];
snprintf(RXmsg, sizeof(RXmsg), "Rx %d", cw_receive_speed);
if (usedefaultWPM)
snprintf(TXmsg, sizeof(TXmsg), "Tx %d **", progdefaults.defCWspeed);
else
snprintf(TXmsg, sizeof(TXmsg), "Tx %d", progdefaults.CWspeed);
put_Status1(RXmsg);
put_Status2(TXmsg);
put_MODEstatus("CW %s Rx %d", usedefaultWPM ? "*" : " ", cw_receive_speed);
}
//=======================================================================
@ -313,25 +306,25 @@ int cw::rx_process(const double *buf, int len)
wf->Bandwidth ((int)bandwidth);
}
// compute phase increment expected at our specific rx tone freq
// compute phase increment expected at our specific rx tone freq
delta = 2.0 * M_PI * frequency / samplerate;
while (len-- > 0) {
// Mix with the internal NCO
// Mix with the internal NCO
z = complex ( *buf * cos(phaseacc), *buf * sin(phaseacc) );
buf++;
phaseacc += delta;
if (phaseacc > M_PI)
phaseacc -= 2.0 * M_PI;
if (cwfilter->run ( z, z )) {
// update the basic sample counter used for morse timing
// update the basic sample counter used for morse timing
smpl_ctr += DEC_RATIO;
// demodulate
// demodulate
value = z.mag();
value = bitfilter->run(value);
// Compute a variable threshold value for tone
// Compute a variable threshold value for tone
// detection. Fast attack and slow decay.
if (value > agc_peak)
agc_peak = decayavg(agc_peak, value, 80.0);
@ -339,16 +332,16 @@ int cw::rx_process(const double *buf, int len)
agc_peak = decayavg(agc_peak, value, 800.0);
metric = clamp(agc_peak * 1000.0 , 0.0, 100.0);
// save correlation amplitude value for the sync scope
pipe[pipeptr] = value;
pipeptr = (pipeptr + 1) % pipesize;
if (!progStatus.sqlonoff || metric > progStatus.sldrSquelchValue ) {
// upward trend means tone starting
// upward trend means tone starting
if ((value > 0.66 * agc_peak) && (cw_receive_state != RS_IN_TONE))
handle_event(CW_KEYDOWN_EVENT, NULL);
// downward trend means tone stopping
// downward trend means tone stopping
if ((value < 0.33 * agc_peak) && (cw_receive_state == RS_IN_TONE))
handle_event(CW_KEYUP_EVENT, NULL);
}
@ -366,10 +359,10 @@ int cw::rx_process(const double *buf, int len)
return 0;
}
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
// Compare two timestamps, and return the difference between them in usecs.
int cw::usec_diff(unsigned int earlier, unsigned int later)
{
// Compare the timestamps.
@ -385,10 +378,10 @@ int cw::usec_diff(unsigned int earlier, unsigned int later)
//=======================================================================
// handle_event()
// high level cw decoder... gets called with keyup, keydown, reset and
// query commands.
// query commands.
// Keyup/down influences decoding logic.
// Reset starts everything out fresh.
// The query command returns CW_SUCCESS and the character that has
// The query command returns CW_SUCCESS and the character that has
// been decoded (may be '*',' ' or [a-z,0-9] or a few others)
// If there is no data ready, CW_ERROR is returned.
//=======================================================================
@ -429,13 +422,13 @@ int cw::handle_event(int cw_event, const char **c)
// The receive state is expected to be inside a tone.
if (cw_receive_state != RS_IN_TONE)
return CW_ERROR;
// Save the current timestamp
// Save the current timestamp
cw_rr_end_timestamp = smpl_ctr;
element_usec = usec_diff(cw_rr_start_timestamp, cw_rr_end_timestamp);
// make sure our timing values are up to date
sync_parameters();
// If the tone length is shorter than any noise cancelling
// If the tone length is shorter than any noise cancelling
// threshold that has been set, then ignore this tone.
if (cw_noise_spike_threshold > 0
&& element_usec < cw_noise_spike_threshold) {
@ -443,13 +436,13 @@ int cw::handle_event(int cw_event, const char **c)
return CW_ERROR;
}
// Set up to track speed on dot-dash or dash-dot pairs for this test to work, we need a dot dash pair or a
// dash dot pair to validate timing from and force the speed tracking in the right direction. This method
// Set up to track speed on dot-dash or dash-dot pairs for this test to work, we need a dot dash pair or a
// dash dot pair to validate timing from and force the speed tracking in the right direction. This method
// is fundamentally different than the method in the unix cw project. Great ideas come from staring at the
// screen long enough!. Its kind of simple really ... when you have no idea how fast or slow the cw is...
// screen long enough!. Its kind of simple really ... when you have no idea how fast or slow the cw is...
// the only way to get a threshold is by having both code elements and setting the threshold between them
// knowing that one is supposed to be 3 times longer than the other. with straight key code... this gets
// quite variable, but with most faster cw sent with electronic keyers, this is one relationship that is
// knowing that one is supposed to be 3 times longer than the other. with straight key code... this gets
// quite variable, but with most faster cw sent with electronic keyers, this is one relationship that is
// quite reliable. Lawrence Glaister (ve7it@shaw.ca)
if (last_element > 0) {
// check for dot dash sequence (current should be 3 x last)
@ -472,7 +465,7 @@ int cw::handle_event(int cw_event, const char **c)
// a dash is anything longer than 2 dot times
rx_rep_buf[cw_rr_current++] = CW_DASH_REPRESENTATION;
}
// We just added a representation to the receive buffer.
// We just added a representation to the receive buffer.
// If it's full, then reset everything as it probably noise
if (cw_rr_current == RECEIVE_CAPACITY - 1) {
cw_receive_state = RS_IDLE;
@ -496,14 +489,14 @@ int cw::handle_event(int cw_event, const char **c)
if (c == NULL) {
// else we had no place to put character...
cw_receive_state = RS_IDLE;
cw_rr_current = 0;
cw_rr_current = 0;
// reset decoding pointer
return CW_ERROR;
}
// compute length of silence so far
sync_parameters();
element_usec = usec_diff(cw_rr_end_timestamp, smpl_ctr);
// SHORT time since keyup... nothing to do yet
if (element_usec < (2 * cw_receive_dot_length))
return CW_ERROR;
@ -513,7 +506,7 @@ int cw::handle_event(int cw_event, const char **c)
if (element_usec >= (2 * cw_receive_dot_length) &&
element_usec <= (4 * cw_receive_dot_length) &&
cw_receive_state == RS_AFTER_TONE) {
// Look up the representation
// Look up the representation
*c = morse::rx_lookup(rx_rep_buf);
if (*c == NULL)
// invalid decode... let user see error
@ -526,7 +519,7 @@ int cw::handle_event(int cw_event, const char **c)
// LONG time since keyup... check for a word space
// FARNSWOTH MOD HERE -->
if ((element_usec > (4 * cw_receive_dot_length)) && !space_sent) {
*c = " ";
*c = " ";
space_sent = true;
return CW_SUCCESS;
}
@ -540,8 +533,8 @@ int cw::handle_event(int cw_event, const char **c)
//===========================================================================
// cw transmit routines
// Define the amplitude envelop for key down events (32 samples long)
// this is 1/2 cycle of a raised cosine
// Define the amplitude envelop for key down events (32 samples long)
// this is 1/2 cycle of a raised cosine
//===========================================================================
double keyshape[KNUM];
@ -554,11 +547,11 @@ void cw::makeshape()
if (knum >= symbollen)
knum = symbollen - 1;
if (knum > KNUM)
if (knum > KNUM)
knum = KNUM;
switch (QSKshape) {
case 1: // blackman
case 1: // blackman
for (int i = 0; i < knum; i++)
keyshape[i] = (0.42 - 0.50 * cos(M_PI * i/ knum) + 0.08 * cos(2 * M_PI * i / knum));
break;
@ -619,7 +612,7 @@ void cw::send_symbol(int bits, int len)
int symlen = 0;
float dsymlen = 0.0;
int currsym = bits & 1;
freq = get_txfreq_woffset();
delta = (int) (len * (progdefaults.CWweight - 50) / 100.0);
@ -651,12 +644,12 @@ void cw::send_symbol(int bits, int len)
kpost = keydown + (int)(progdefaults.CWpost * 8);
if (kpost < 0) kpost = 0;
if (firstelement) {
firstelement = false;
return;
}
if (currsym == 1) { // keydown
sample = 0;
if (lastsym == 1) {
@ -736,7 +729,7 @@ void cw::send_symbol(int bits, int len)
}
while (sample < duration)
outbuf[sample++] = 0 * nco(freq);
q_carryover = 0;
qsample = 0;
@ -758,7 +751,7 @@ void cw::send_symbol(int bits, int len)
else
ModulateXmtr(outbuf, duration);
}
lastsym = currsym;
firstelement = false;
}
@ -775,8 +768,8 @@ void cw::send_ch(int ch)
int flen;
sync_parameters();
// handle word space separately (7 dots spacing)
// last char already had 3 elements of inter-character spacing
// handle word space separately (7 dots spacing)
// last char already had 3 elements of inter-character spacing
if ((chout == ' ') || (chout == '\n')) {
firstelement = false;
@ -793,7 +786,7 @@ void cw::send_ch(int ch)
return;
}
// convert character code to a morse representation
// convert character code to a morse representation
if ((chout < 256) && (chout >= 0)) {
code = tx_lookup(chout); //cw_tx_lookup(ch);
firstelement = true;
@ -802,7 +795,7 @@ void cw::send_ch(int ch)
firstelement = false;
}
// loop sending out binary bits of cw character
// loop sending out binary bits of cw character
while (code > 1) {
send_symbol(code, symbollen);// & 1);
code = code >> 1;
@ -816,9 +809,9 @@ void cw::send_ch(int ch)
flen -= symbollen;
}
if (flen) send_symbol(0, flen);
FL_AWAKE();
if (ch != -1)
put_echo_char(ch);
}
@ -833,7 +826,7 @@ int cw::tx_process()
{
int c;
c = get_tx_char();
if (c == 0x03 || stopflag) {
if (c == 0x03 || stopflag) {
send_symbol(0, symbollen);
stopflag = false;
return -1;
@ -847,6 +840,7 @@ void cw::incWPM()
if (usedefaultWPM) return;
if (progdefaults.CWspeed < progdefaults.CWupperlimit) {
progdefaults.CWspeed++;
sync_parameters();
set_CWwpm();
update_Status();
}
@ -858,6 +852,7 @@ void cw::decWPM()
if (progdefaults.CWspeed > progdefaults.CWlowerlimit) {
progdefaults.CWspeed--;
set_CWwpm();
sync_parameters();
update_Status();
}
}

Wyświetl plik

@ -787,10 +787,12 @@ Fl_Value_Slider2 *sldrCWxmtWPM=(Fl_Value_Slider2 *)0;
static void cb_sldrCWxmtWPM(Fl_Value_Slider2* o, void*) {
progdefaults.CWspeed = (int)o->value();
sldrCWfarnsworth->maximum(o->value());
if (sldrCWfarnsworth->value() > o->value())
sldrCWfarnsworth->value(o->value());
cntCW_WPM->value(progdefaults.CWspeed);
sldrCWfarnsworth->maximum(progdefaults.CWspeed);
if (sldrCWfarnsworth->value() > progdefaults.CWspeed)
sldrCWfarnsworth->value(progdefaults.CWspeed);
progdefaults.changed = true;
sync_cw_parameters();
}
Fl_Counter2 *cntCWdefWPM=(Fl_Counter2 *)0;
@ -805,10 +807,11 @@ Fl_Counter *cntCWlowerlimit=(Fl_Counter *)0;
static void cb_cntCWlowerlimit(Fl_Counter* o, void*) {
progdefaults.CWlowerlimit = (int)o->value();
progdefaults.changed = true;
sldrCWxmtWPM->minimum(o->value());
sldrCWxmtWPM->minimum(progdefaults.CWlowerlimit);
sldrCWxmtWPM->value(progdefaults.CWspeed);
sldrCWxmtWPM->redraw();
cntCWupperlimit->minimum(o->value()+20);
cntCWupperlimit->minimum(progdefaults.CWlowerlimit+20);
cntCW_WPM->minimum(progdefaults.CWlowerlimit);
}
Fl_Counter *cntCWupperlimit=(Fl_Counter *)0;
@ -816,10 +819,11 @@ Fl_Counter *cntCWupperlimit=(Fl_Counter *)0;
static void cb_cntCWupperlimit(Fl_Counter* o, void*) {
progdefaults.CWupperlimit = (int)o->value();
progdefaults.changed = true;
sldrCWxmtWPM->maximum(o->value());
sldrCWxmtWPM->maximum(progdefaults.CWupperlimit);
sldrCWxmtWPM->value(progdefaults.CWspeed);
sldrCWxmtWPM->redraw();
cntCWlowerlimit->maximum(o->value()-20);
cntCWlowerlimit->maximum(progdefaults.CWupperlimit-20);
cntCW_WPM->maximum(progdefaults.CWupperlimit);
}
Fl_Value_Slider2 *sldrCWfarnsworth=(Fl_Value_Slider2 *)0;
@ -3310,7 +3314,6 @@ an merging"));
tabsModems->selection_color((Fl_Color)FL_LIGHT1);
tabsModems->align(FL_ALIGN_TOP_RIGHT);
{ tabCW = new Fl_Group(0, 50, 500, 320, _("CW"));
tabCW->hide();
{ tabsCW = new Fl_Tabs(0, 50, 500, 320);
tabsCW->selection_color((Fl_Color)FL_LIGHT1);
{ Fl_Group* o = new Fl_Group(0, 75, 500, 295, _("General"));
@ -3517,6 +3520,7 @@ an merging"));
cntCWdash2dot->labelcolor((Fl_Color)FL_FOREGROUND_COLOR);
cntCWdash2dot->minimum(2.5);
cntCWdash2dot->maximum(4);
cntCWdash2dot->step(0.1);
cntCWdash2dot->value(3);
cntCWdash2dot->callback((Fl_Callback*)cb_cntCWdash2dot);
cntCWdash2dot->align(FL_ALIGN_RIGHT);
@ -3536,6 +3540,7 @@ an merging"));
cntCWrisetime->labelcolor((Fl_Color)FL_FOREGROUND_COLOR);
cntCWrisetime->minimum(0);
cntCWrisetime->maximum(15);
cntCWrisetime->step(0.1);
cntCWrisetime->value(4);
cntCWrisetime->callback((Fl_Callback*)cb_cntCWrisetime);
cntCWrisetime->align(FL_ALIGN_RIGHT);
@ -3667,6 +3672,7 @@ an merging"));
valDominoEX_BW->labelcolor((Fl_Color)FL_FOREGROUND_COLOR);
valDominoEX_BW->minimum(1);
valDominoEX_BW->maximum(2);
valDominoEX_BW->step(0.1);
valDominoEX_BW->value(1.5);
valDominoEX_BW->callback((Fl_Callback*)cb_valDominoEX_BW);
valDominoEX_BW->align(FL_ALIGN_RIGHT);
@ -3690,6 +3696,7 @@ an merging"));
valDomCWI->labelfont(0);
valDomCWI->labelsize(14);
valDomCWI->labelcolor((Fl_Color)FL_FOREGROUND_COLOR);
valDomCWI->step(0.01);
valDomCWI->textsize(14);
valDomCWI->callback((Fl_Callback*)cb_valDomCWI);
valDomCWI->align(FL_ALIGN_TOP);
@ -3939,6 +3946,7 @@ an merging"));
tabOlivia->end();
} // Fl_Group* tabOlivia
{ tabPSK = new Fl_Group(0, 50, 517, 320, _("PSK"));
tabPSK->hide();
{ tabsPSK = new Fl_Tabs(0, 50, 517, 320);
tabsPSK->selection_color((Fl_Color)FL_LIGHT1);
{ Fl_Group* o = new Fl_Group(0, 75, 500, 295, _("General"));
@ -4309,6 +4317,7 @@ an merging"));
valTHOR_BW->labelcolor((Fl_Color)FL_FOREGROUND_COLOR);
valTHOR_BW->minimum(1);
valTHOR_BW->maximum(2);
valTHOR_BW->step(0.1);
valTHOR_BW->value(1.5);
valTHOR_BW->callback((Fl_Callback*)cb_valTHOR_BW);
valTHOR_BW->align(FL_ALIGN_RIGHT);
@ -4326,6 +4335,7 @@ an merging"));
valThorCWI->labelfont(0);
valThorCWI->labelsize(14);
valThorCWI->labelcolor((Fl_Color)FL_FOREGROUND_COLOR);
valThorCWI->step(0.01);
valThorCWI->textsize(14);
valThorCWI->callback((Fl_Callback*)cb_valThorCWI);
valThorCWI->align(FL_ALIGN_TOP);
@ -5056,6 +5066,7 @@ ll with your audio device."));
valPCMvolume->labelfont(0);
valPCMvolume->labelsize(14);
valPCMvolume->labelcolor((Fl_Color)FL_FOREGROUND_COLOR);
valPCMvolume->step(0.01);
valPCMvolume->value(0.8);
valPCMvolume->textsize(14);
valPCMvolume->callback((Fl_Callback*)cb_valPCMvolume);

Wyświetl plik

@ -91,7 +91,7 @@ static const char szBaudRates[] = "300|600|1200|2400|4800|9600|19200|38400|57600
code {} {}
Fl_Window {} {
label {Fldigi configuration} open
xywh {350 148 500 400} type Double color 45 selection_color 51 labelsize 18 align 80 visible
xywh {569 72 500 400} type Double color 45 selection_color 51 labelsize 18 align 80 visible
} {
Fl_Tabs tabsConfigure {open
xywh {-3 0 520 372} color 50 selection_color 50
@ -915,7 +915,7 @@ behaves inside the waterfall} xywh {15 196 150 22} down_box BORDER_BOX align 8
} {
Fl_Group tabCW {
label CW open
xywh {0 50 500 320} hide
xywh {0 50 500 320}
} {
Fl_Tabs tabsCW {open
xywh {0 50 500 320} selection_color 50
@ -972,10 +972,12 @@ progdefaults.changed = true;}
Fl_Value_Slider sldrCWxmtWPM {
label {TX WPM}
callback {progdefaults.CWspeed = (int)o->value();
sldrCWfarnsworth->maximum(o->value());
if (sldrCWfarnsworth->value() > o->value())
sldrCWfarnsworth->value(o->value());
progdefaults.changed = true;}
cntCW_WPM->value(progdefaults.CWspeed);
sldrCWfarnsworth->maximum(progdefaults.CWspeed);
if (sldrCWfarnsworth->value() > progdefaults.CWspeed)
sldrCWfarnsworth->value(progdefaults.CWspeed);
progdefaults.changed = true;
sync_cw_parameters();}
tooltip {My transmit CW WPM} xywh {20 240 400 20} type Horizontal align 8 minimum 5 maximum 100 step 1 value 20 textsize 14
code0 {o->value(progdefaults.CWspeed);}
code1 {o->labelsize(FL_NORMAL_SIZE);}
@ -994,10 +996,11 @@ progdefaults.changed = true;}
label {Lower limit}
callback {progdefaults.CWlowerlimit = (int)o->value();
progdefaults.changed = true;
sldrCWxmtWPM->minimum(o->value());
sldrCWxmtWPM->minimum(progdefaults.CWlowerlimit);
sldrCWxmtWPM->value(progdefaults.CWspeed);
sldrCWxmtWPM->redraw();
cntCWupperlimit->minimum(o->value()+20);}
cntCWupperlimit->minimum(progdefaults.CWlowerlimit+20);
cntCW_WPM->minimum(progdefaults.CWlowerlimit);}
tooltip {No slower than this} xywh {197 281 65 20} type Simple align 1 minimum 5 maximum 20 step 5 value 10
code0 {o->value(progdefaults.CWlowerlimit);}
code1 {o->labelsize(FL_NORMAL_SIZE);}
@ -1006,10 +1009,11 @@ cntCWupperlimit->minimum(o->value()+20);}
label {Upper limit}
callback {progdefaults.CWupperlimit = (int)o->value();
progdefaults.changed = true;
sldrCWxmtWPM->maximum(o->value());
sldrCWxmtWPM->maximum(progdefaults.CWupperlimit);
sldrCWxmtWPM->value(progdefaults.CWspeed);
sldrCWxmtWPM->redraw();
cntCWlowerlimit->maximum(o->value()-20);}
cntCWlowerlimit->maximum(progdefaults.CWupperlimit-20);
cntCW_WPM->maximum(progdefaults.CWupperlimit);}
tooltip {No faster than this} xywh {355 281 65 20} type Simple align 1 minimum 25 maximum 200 step 5 value 100
code0 {o->value(progdefaults.CWupperlimit);}
code1 {o->labelsize(FL_NORMAL_SIZE);}
@ -1397,7 +1401,7 @@ progdefaults.changed = true;}
}
Fl_Group tabPSK {
label PSK open
xywh {0 50 517 320}
xywh {0 50 517 320} hide
} {
Fl_Tabs tabsPSK {open
xywh {0 50 517 320} selection_color 50

Wyświetl plik

@ -40,6 +40,7 @@
#include <string>
#include <algorithm>
#include <map>
#include <dirent.h>
#include "gettext.h"
#include "fl_digi.h"
@ -103,8 +104,6 @@
#include "icons.h"
#include "status.h"
#include "rigsupport.h"
#include "qrunner.h"
@ -153,6 +152,11 @@ ssdv_rx *ssdv = (ssdv_rx *)0;
MixerBase* mixer = 0;
int rightof(Fl_Widget* w);
int leftof(Fl_Widget* w);
int above(Fl_Widget* w);
int below(Fl_Widget* w);
//bool useCheckButtons;
Fl_Group *mnuFrame;
@ -172,6 +176,8 @@ Raster *FHdisp;
Fl_Box *StatusBar = (Fl_Box *)0;
Fl_Box *Status2 = (Fl_Box *)0;
Fl_Box *Status1 = (Fl_Box *)0;
Fl_Counter2 *cntCW_WPM=(Fl_Counter2 *)0;
Fl_Button *btnCW_Default=(Fl_Button *)0;
Fl_Box *WARNstatus = (Fl_Box *)0;
Fl_Button *MODEstatus = (Fl_Button *)0;
Fl_Button *btnMacro[NUMMACKEYS];
@ -261,7 +267,6 @@ Fl_Button *qso_opPICK3;
Fl_Button *qsoClear3;
Fl_Button *qsoSave3;
Fl_Box *StatusSpace = (Fl_Box *)0;
Fl_Input2 *inpCall4;
Fl_Browser *qso_opBrowser = (Fl_Browser *)0;
@ -651,6 +656,17 @@ void startup_modem(modem* m, int f)
restoreFocus();
trx_mode id = m->get_mode();
if (id == MODE_CW) {
cntCW_WPM->show();
btnCW_Default->show();
Status1->hide();
} else {
cntCW_WPM->hide();
btnCW_Default->hide();
Status1->show();
}
if (id >= MODE_HELL_FIRST && id <= MODE_HELL_LAST) {
ReceiveText->hide();
FHdisp->show();
@ -1111,8 +1127,14 @@ void cb_mnuConfigWFcontrols(Fl_Menu_ *, void*) {
void cb_toggle_dl_online(Fl_Widget *, void *) {
progdefaults.loadDefaults();
// dl_online is a bool
progdefaults.dl_online = !progdefaults.dl_online;
/* If this is the first time we've come online... */
if (progdefaults.dl_online && !dl_fldigi_downloaded_once)
{
dl_fldigi_download();
dl_fldigi_downloaded_once = 1;
}
}
//jcoxon added 21/3/10
@ -1469,6 +1491,14 @@ void cb_ShowConfig(Fl_Widget*, void*)
void cb_ShowNBEMS(Fl_Widget*, void*)
{
DIR *nbems_dir;
nbems_dir = opendir(NBEMS_dir.c_str());
if (!nbems_dir) {
int ans = fl_choice2(_("Do not exist, create?"), _("No"), _("Yes"), 0);
if (!ans) return;
check_nbems_dirs();
}
closedir(nbems_dir);
cb_mnuVisitURL(0, (void*)NBEMS_dir.c_str());
}
@ -1615,7 +1645,7 @@ if (bHAB) return;
Fl_Input* in[] = {
inpCall1, inpCall2, inpCall3, inpCall4,
inpName1, inpName2,
inpTimeOn1, inpTimeOn2,
inpTimeOn1, inpTimeOn2, inpTimeOn3,
inpRstIn1, inpRstIn2,
inpRstOut1, inpRstOut2,
inpQth, inpLoc, inpAZ, inpState, inpVEprov, inpCountry,
@ -2086,7 +2116,7 @@ bool clean_exit(void) {
#define RIGCONTEST_MLABEL _("Rig control and contest")
#define DOCKEDSCOPE_MLABEL _("Docked scope")
#define WF_MLABEL _("Minimal controls")
#define DLFLDIGI_ONLINE_LABEL _("Online")
bool restore_minimize = false;
@ -2126,9 +2156,7 @@ void UI_select()
TopFrame1->hide();
TopFrame2->hide();
TopFrame3->hide();
Status1->hide();
Status2->hide();
StatusSpace->show();
inpCall4->show();
inpCall = inpCall4;
fl_digi_main->init_sizes();
@ -2207,9 +2235,7 @@ void UI_select()
qsoFreqDisp = qsoFreqDisp3;
}
}
StatusSpace->hide();
inpCall4->hide();
Status1->show();
Status2->show();
fl_digi_main->init_sizes();
}
@ -2470,6 +2496,17 @@ Fl_Menu_Item menu_[] = {
{ make_icon_label(_("&About"), help_about_icon), 'a', cb_mnuAboutURL, 0, 0, _FL_MULTI_LABEL, 0, 14, 0},
{0,0,0,0,0,0,0,0,0},
/* TODO: Remove this. As a debug/temporary measure, I'm adding in the DL Client menu to non --hab mode,
* since we don't yet have any other UI as complete as this to configure online/offline, etc. */
/* When you remove this; also remove the toggles entry on line TODO: 3791 */
{_("DL Client"), 0, 0, 0, FL_SUBMENU, FL_NORMAL_LABEL, 0, 14, 0},
{ DLFLDIGI_ONLINE_LABEL, 0, cb_toggle_dl_online, 0, FL_MENU_TOGGLE, FL_NORMAL_LABEL, 0, 14, 0},
{ make_icon_label(_("Configure"), help_about_icon), 0, (Fl_Callback*)cb_mnuConfigDLClient, 0, 0, _FL_MULTI_LABEL, 0, 14, 0},
{ make_icon_label(_("Tracker"), pskr_icon), 0, cb_mnuVisitTracker, 0, FL_MENU_DIVIDER, _FL_MULTI_LABEL, 0, 14, 0},
{ make_icon_label(_("Raw Data"), pskr_icon), 0, cb_mnuVisitView, 0, 0, _FL_MULTI_LABEL, 0, 14, 0},
{ make_icon_label(_("Help"), pskr_icon), 0, cb_mnuVisitDLClient, 0, 0, _FL_MULTI_LABEL, 0, 14, 0},
{0,0,0,0,0,0,0,0,0},
{" ", 0, 0, 0, FL_MENU_INACTIVE, FL_NORMAL_LABEL, 0, 14, 0},
{0,0,0,0,0,0,0,0,0},
};
@ -2869,6 +2906,32 @@ void setwfrange() {
wf->opmode();
}
void sync_cw_parameters()
{
active_modem->sync_parameters();
active_modem->update_Status();
}
void cb_cntCW_WPM(Fl_Widget * w, void *v)
{
Fl_Counter2 *cnt = (Fl_Counter2 *) w;
progdefaults.CWspeed = (int)cnt->value();
sldrCWxmtWPM->value(progdefaults.CWspeed);
if (sldrCWfarnsworth->value() > progdefaults.CWspeed)
sldrCWfarnsworth->value(progdefaults.CWspeed);
sldrCWfarnsworth->maximum(progdefaults.CWspeed);
progdefaults.changed = true;
sync_cw_parameters();
restoreFocus();
}
void cb_btnCW_Default(Fl_Widget *w, void *v)
{
active_modem->toggleWPM();
restoreFocus();
}
void create_fl_digi_main_primary() {
int fnt = fl_font();
@ -2883,8 +2946,7 @@ void create_fl_digi_main_primary() {
x_qsoframe += rig_control_width;
IMAGE_WIDTH = 4000;//progdefaults.HighFreqCutoff;
// if (progStatus.mainH < HNOM) progStatus.mainH = HNOM;
IMAGE_WIDTH = 4000;
Hwfall = progdefaults.wfheight;
@ -3409,68 +3471,80 @@ void create_fl_digi_main_primary() {
qsoSave3->tooltip(_("Save"));
fl_font(FL_HELVETICA, FL_NORMAL_SIZE);
const char *label2a = _("On");
btnTimeOn3 = new Fl_Button(
const char *label3a = _("Off");
const char *label4a = _("Call");
const char *label5a = _("# S");
const char *label6a = _("# R");
const char *label7a = _("Ex");
const char *xData = "00000";
const char *xCall = "WW8WWW/WWWW";
int wData = fl_width(xData);
int wCall = fl_width(xCall);
Fl_Box *bx4a = new Fl_Box(
pad + rightof(qsoSave3), y,
fl_width(label4a), h, label4a);
inpCall3 = new Fl_Input2(
pad + bx4a->x() + bx4a->w(), y,
wCall, h, "");
inpCall3->align(FL_ALIGN_INSIDE);
inpCall3->tooltip(_("Other call"));
Fl_Box *bx7a = new Fl_Box(
rightof(inpCall3), y,
fl_width(label7a), h, label7a);
bx7a->align(FL_ALIGN_INSIDE);
inpXchgIn2 = new Fl_Input2(
rightof(bx7a), y,
progStatus.mainW
- rightof(bx7a) - pad
- fl_width(label6a) - wData - pad
- fl_width(label5a) - wData - pad
- fl_width(label2a) - wData - pad
- fl_width(label3a) - wData - pad,
h, "");
inpXchgIn2->tooltip(_("Contest exchange in"));
Fl_Box *bx6a = new Fl_Box(
rightof(inpXchgIn2), y,
fl_width(label6a), h, label6a);
bx6a->align(FL_ALIGN_INSIDE);
inpSerNo2 = new Fl_Input2(
rightof(bx6a) + pad, y,
wData, h, "");
inpSerNo2->tooltip(_("Received serial number"));
Fl_Box *bx5a = new Fl_Box(
rightof(inpSerNo2), y,
fl_width(label5a), h, label5a);
bx5a->align(FL_ALIGN_INSIDE);
outSerNo2 = new Fl_Input2(
rightof(bx5a) + pad, y,
wData, h, "");
outSerNo2->tooltip(_("Sent serial number (read only)"));
outSerNo2->type(FL_NORMAL_OUTPUT);
btnTimeOn3 = new Fl_Button(
rightof(outSerNo2), y,
fl_width(label2a), h, label2a);
btnTimeOn3->tooltip(_("Press to update"));
btnTimeOn3->box(FL_NO_BOX);
btnTimeOn3->callback(cb_btnTimeOn);
inpTimeOn3 = new Fl_Input2(
pad + btnTimeOn3->x() + btnTimeOn3->w(), y,
w_inpTime - 2, h, "");
btnTimeOn3->x() + btnTimeOn3->w() + pad, y,
wData - 2, h, "");
inpTimeOn3->tooltip(_("Time On"));
inpTimeOn3->type(FL_INT_INPUT);
const char *label3a = _("Off");
Fl_Box *bx3a = new Fl_Box(pad + rightof(inpTimeOn3), y,
fl_width(label3a), h, label3a);
inpTimeOff3 = new Fl_Input2(
pad + bx3a->x() + bx3a->w(), y,
w_inpTime - 2, h, "");
bx3a->x() + bx3a->w() + pad, y,
wData, h, "");
inpTimeOff3->tooltip(_("Time Off"));
inpTimeOff3->type(FL_NORMAL_OUTPUT);
const char *label4a = _("Call");
Fl_Box *bx4a = new Fl_Box(
pad + rightof(inpTimeOff3), y,
fl_width(label4a), h, label4a);
inpCall3 = new Fl_Input2(
pad + bx4a->x() + bx4a->w(), y,
w_inpCall - 10, h, "");
inpCall3->tooltip(_("Other call"));
const char *label5a = _("# S");
Fl_Box *bx5a = new Fl_Box(
pad + rightof(inpCall3), y,
fl_width(label5a), h, label5a);
bx5a->align(FL_ALIGN_INSIDE);
outSerNo2 = new Fl_Input2(
rightof(bx5a), y,
w_SerNo, h, "");
outSerNo2->tooltip(_("Sent serial number (read only)"));
outSerNo2->type(FL_NORMAL_OUTPUT);
const char *label6a = _("# R");
Fl_Box *bx6a = new Fl_Box(
rightof(outSerNo2), y,
fl_width(label6a), h, label6a);
bx6a->align(FL_ALIGN_INSIDE);
inpSerNo2 = new Fl_Input2(
rightof(bx6a), y,
w_SerNo, h, "");
inpSerNo2->tooltip(_("Received serial number"));
const char *label7a = _("Ex");
Fl_Box *bx7a = new Fl_Box(
rightof(inpSerNo2), y,
fl_width(label7a), h, label7a);
bx7a->align(FL_ALIGN_INSIDE);
inpXchgIn2 = new Fl_Input2(
rightof(bx7a), y,
progStatus.mainW - rightof(bx7a) - pad, h, "");
inpXchgIn2->tooltip(_("Contest exchange in"));
TopFrame3->end();
}
TopFrame3->resizable(inpXchgIn2);
@ -3631,16 +3705,28 @@ void create_fl_digi_main_primary() {
MODEstatus->when(FL_WHEN_CHANGED);
MODEstatus->tooltip(_("Left click: change mode\nRight click: configure"));
cntCW_WPM = new Fl_Counter2(rightof(MODEstatus), Hmenu+Hrcvtxt+Hxmttxt+Hwfall,
Ws2n - Hstatus, Hstatus, "");
cntCW_WPM->callback(cb_cntCW_WPM);
cntCW_WPM->minimum(progdefaults.CWlowerlimit);
cntCW_WPM->maximum(progdefaults.CWupperlimit);
cntCW_WPM->value(progdefaults.CWspeed);
cntCW_WPM->type(1);
cntCW_WPM->step(1);
cntCW_WPM->tooltip(_("CW transmit WPM"));
cntCW_WPM->hide();
btnCW_Default = new Fl_Button(rightof(cntCW_WPM), Hmenu+Hrcvtxt+Hxmttxt+Hwfall,
Hstatus, Hstatus, "*");
btnCW_Default->callback(cb_btnCW_Default);
btnCW_Default->tooltip(_("Default WPM"));
btnCW_Default->hide();
Status1 = new Fl_Box(rightof(MODEstatus), Hmenu+Hrcvtxt+Hxmttxt+Hwfall, Ws2n, Hstatus, "");
Status1->box(FL_DOWN_BOX);
Status1->color(FL_BACKGROUND2_COLOR);
Status1->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE);
StatusSpace = new Fl_Box(rightof(MODEstatus), Hmenu+Hrcvtxt+Hxmttxt+Hwfall, Ws2n, Hstatus, "");
StatusSpace->box(FL_DOWN_BOX);
StatusSpace->color(FL_BACKGROUND2_COLOR);
StatusSpace->hide();
Status2 = new Fl_Box(rightof(Status1), Hmenu+Hrcvtxt+Hxmttxt+Hwfall, Wimd, Hstatus, "");
Status2->box(FL_DOWN_BOX);
Status2->color(FL_BACKGROUND2_COLOR);
@ -3648,7 +3734,7 @@ void create_fl_digi_main_primary() {
inpCall4 = new Fl_Input2(
rightof(Status1), Hmenu+Hrcvtxt+Hxmttxt+Hwfall,
Wimd, Hstatus, "Callsign:");
Wimd, Hstatus, "");//"Callsign:");
inpCall4->align(FL_ALIGN_LEFT);
inpCall4->tooltip(_("Other call"));
inpCall4->hide();
@ -3784,6 +3870,8 @@ void create_fl_digi_main_primary() {
if (!dxcc_is_open())
getMenuItem(COUNTRIES_MLABEL)->hide();
/* TODO: REMOVE ME: SEE LINE 2471 */ if (progdefaults.dl_online) getMenuItem(DLFLDIGI_ONLINE_LABEL)->set();
UI_select();
wf->UI_select(progStatus.WF_UI);
@ -3919,7 +4007,7 @@ Fl_Menu_Item alt_menu_[] = {
{0,0,0,0,0,0,0,0,0},
{_("DL Client"), 0, 0, 0, FL_SUBMENU, FL_NORMAL_LABEL, 0, 14, 0},
{ "Online", 0, cb_toggle_dl_online, 0, FL_MENU_TOGGLE, FL_NORMAL_LABEL, 0, 14, 0},
{ DLFLDIGI_ONLINE_LABEL, 0, cb_toggle_dl_online, 0, FL_MENU_TOGGLE, FL_NORMAL_LABEL, 0, 14, 0},
{ make_icon_label(_("Configure"), help_about_icon), 0, (Fl_Callback*)cb_mnuConfigDLClient, 0, 0, _FL_MULTI_LABEL, 0, 14, 0},
{ make_icon_label(_("Tracker"), pskr_icon), 0, cb_mnuVisitTracker, 0, FL_MENU_DIVIDER, _FL_MULTI_LABEL, 0, 14, 0},
{ make_icon_label(_("Raw Data"), pskr_icon), 0, cb_mnuVisitView, 0, 0, _FL_MULTI_LABEL, 0, 14, 0},
@ -4162,6 +4250,21 @@ void create_fl_digi_main_WF_only() {
MODEstatus->when(FL_WHEN_CHANGED);
MODEstatus->tooltip(_("Left click: change mode\nRight click: configure"));
cntCW_WPM = new Fl_Counter2(rightof(MODEstatus), Y, Ws2n - Hstatus, Hstatus, "");
cntCW_WPM->callback(cb_cntCW_WPM);
cntCW_WPM->minimum(progdefaults.CWlowerlimit);
cntCW_WPM->maximum(progdefaults.CWupperlimit);
cntCW_WPM->value(progdefaults.CWspeed);
cntCW_WPM->tooltip(_("CW transmit WPM"));
cntCW_WPM->type(1);
cntCW_WPM->step(1);
cntCW_WPM->hide();
btnCW_Default = new Fl_Button(rightof(cntCW_WPM), Y, Hstatus, Hstatus, "*");
btnCW_Default->callback(cb_btnCW_Default);
btnCW_Default->tooltip(_("Default WPM"));
btnCW_Default->hide();
Status1 = new Fl_Box(rightof(MODEstatus), Y, Ws2n, Hstatus, "");
Status1->box(FL_DOWN_BOX);
Status1->color(FL_BACKGROUND2_COLOR);
@ -4338,16 +4441,14 @@ void create_fl_digi_main_dl_fldigi() {
Y = Hmenu + pad;
TopFrameHAB = new Fl_Group(0, Y, progStatus.mainW, TopFrameHABheight);
const char *flights = progdefaults.flightsAvaliable.c_str();
//const char *flights = "ATLAS|ICARUS";
{ Fl_Choice* o = habFlightXML = new Fl_Choice(10, (Y + TopFrameHABheight - Hentry - 5), w_habTime, Hentry, _("Flight"));
{ habFlightXML = new Fl_Choice(10, (Y + TopFrameHABheight - Hentry - 5), w_habTime, Hentry, _("Flight"));
habFlightXML->tooltip(_("Select flight you are tracking"));
habFlightXML->down_box(FL_BORDER_BOX);
habFlightXML->align(FL_ALIGN_TOP);
habFlightXML->when(FL_WHEN_CHANGED);
habFlightXML->callback((Fl_Callback*)dl_selFlightXML);
o->add(flights);
} // Fl_Choice* selFlightXML
habFlightXML->callback((Fl_Callback *) dl_fldigi_select_payload);
}
{ habTime = new Fl_Input2((rightof(habFlightXML) + 2), (Y + TopFrameHABheight - Hentry - 5), w_habTime, Hentry, "Time");
habTime->tooltip(_("Time"));
@ -4547,7 +4648,7 @@ void create_fl_digi_main_dl_fldigi() {
struct {
bool var; const char* label;
} toggles[] = {
{ progStatus.DOCKEDSCOPE, DOCKEDSCOPE_MLABEL }
{ progStatus.DOCKEDSCOPE, DOCKEDSCOPE_MLABEL },
};
Fl_Menu_Item* toggle;
for (size_t i = 0; i < sizeof(toggles)/sizeof(*toggles); i++) {
@ -4560,6 +4661,9 @@ void create_fl_digi_main_dl_fldigi() {
}
}
if (progdefaults.dl_online)
getMenuItem(DLFLDIGI_ONLINE_LABEL, alt_menu_)->set();
make_scopeviewer();
noop_controls();
@ -4898,6 +5002,7 @@ void set_CWwpm()
{
FL_LOCK_D();
sldrCWxmtWPM->value(progdefaults.CWspeed);
cntCW_WPM->value(progdefaults.CWspeed);
FL_UNLOCK_D();
}
@ -5399,3 +5504,5 @@ void set_rtty_bits(int bits)
}
}
}

Wyświetl plik

@ -1727,7 +1727,7 @@ int main (int argc, char *argv[] )
fl_filename_expand(dirbuf, sizeof(dirbuf) - 1, "$USERPROFILE/NBEMS.files/");
NBEMS_dir = dirbuf;
#else
fl_filename_expand(dirbuf, sizeof(dirbuf) - 1, "$HOME/NBEMS.files/");
fl_filename_expand(dirbuf, sizeof(dirbuf) - 1, "$HOME/.nbems/");
NBEMS_dir = dirbuf;
#endif
}

Wyświetl plik

@ -23,4 +23,5 @@ public:
int writeLog (const char *, cQsoDb *);
};
#endif

Wyświetl plik

@ -1081,12 +1081,9 @@
"Reception report server port", \
"4739") \
/* Flight Data */ \
ELEM_(std::string, flight_sel, "XMLSELECTED", "", "") \
ELEM_(int, flight_sel_num, "XMLSELECTEDNUM", "", 0) \
ELEM_(std::string, flightsAvaliable, "", "", "") \
ELEM_(std::string, xmlSentence_delimiter, "", "", "$$") \
ELEM_(std::string, xmlField_delimiter, "", "", ",") \
ELEM_(std::string, xmlFields, "", "", "7") \
ELEM_(int, xmlFields, "", "", 7) \
ELEM_(std::string, xmlCallsign, "", "", "") \
/* GPS Device Info */ \
ELEM_(std::string, gpsDevice, "GPSDEVICE", "", "") \

Wyświetl plik

@ -15,14 +15,19 @@
#include <curl/types.h>
#include <curl/easy.h>
#include <FL/Fl_Choice.H>
#include "confdialog.h"
#include "fl_digi.h"
#include "main.h"
extern bool dl_fldigi_downloaded_once;
extern Fl_Choice *habFlightXML;
void dl_fldigi_init();
void dl_fldigi_post(const char *data, const char *identity);
void dl_selFlightXML(Fl_Choice* o, void*);
void dl_xmlList();
void dl_fldigi_download();
void dl_fldigi_update_payloads();
void dl_fldigi_select_payload(Fl_Choice* o, void *a);
#endif

Wyświetl plik

@ -51,6 +51,7 @@ extern Fl_Tile_Check *TiledGroup;
extern Fl_Box *StatusBar;
extern Fl_Box *Status2;
extern Fl_Box *Status1;
extern Fl_Counter2 *cntCW_WPM;
extern Fl_Box *WARNstatus;
extern Fl_Button *MODEstatus;
extern Fl_Slider2 *sldrSquelch;
@ -255,4 +256,6 @@ void set_olivia_tones(int tones);
void set_rtty_shift(int shift);
void set_rtty_baud(float baud);
void set_rtty_bits(int bits);
void sync_cw_parameters();
#endif

Wyświetl plik

@ -82,4 +82,7 @@ extern int rxmsgid;
extern TXMSGSTRUC txmsgst;
extern int txmsgid;
void check_nbems_dirs(void);
extern bool nbems_dirs_checked;
#endif

Wyświetl plik

@ -136,6 +136,8 @@ public:
virtual void incWPM() {};
virtual void decWPM() {};
virtual void toggleWPM() {};
virtual void sync_parameters() {};
virtual void update_Status() {};
// for waterfall id transmission
private:

Wyświetl plik

@ -30,8 +30,9 @@
#include "modem.h"
#include "jalocha/pj_mfsk.h"
#include "sound.h"
#define TONE_DURATION 8192
#define TONE_DURATION (SCBLOCKSIZE * 16)
#define SR4 ((TONE_DURATION) / 4)
class olivia : public modem {
@ -58,21 +59,21 @@ private:
int sinteg;
int tones;
int bw;
double tone_bw;
int preamblesent;
int postamblesent;
double preamblephase;
double txbasefreq;
double last_txbasefreq;
double tone_midfreq;
double lastfreq;
double ampshape[TONE_DURATION / 4];
double ampshape[SR4];
double tonebuff[TONE_DURATION];
double nco(double freq);
void send_tones();
void create_tones();
public:
olivia();

Wyświetl plik

@ -65,4 +65,6 @@ extern bool bHistory;
trx_wait_state(); \
} while (0)
void trx_xmit_wfall_queue(int samplerate, const double* buf, size_t len);
#endif

Wyświetl plik

@ -55,6 +55,7 @@ enum {
//4096
#define SC_SMPLRATE 8000
#define WFBLOCKSIZE 512
struct RGB {
uchar R;

Wyświetl plik

@ -858,6 +858,8 @@ void cabrillo_append_qso (FILE *fp, cQsoRec *rec)
int ifreq = 0;
size_t len = 0;
exch_out.clear();
if (btnCabFreq->value()) {
ifreq = (int)(1000.0 * atof(rec->getField(FREQ)));
snprintf(freq, sizeof(freq), "%d", ifreq);
@ -894,26 +896,25 @@ void cabrillo_append_qso (FILE *fp, cQsoRec *rec)
if (btnCabRSTsent->value()) {
rst_out = rec->getField(RST_SENT);
rst_out = rst_out.substr(0,rst_len);
qsoline.append(rst_out); qsoline.append(" ");
exch_out.append(rst_out).append(" ");
}
if (btnCabSerialOUT->value()) {
exch_out = rec->getField(STX);
if (exch_out.length())
exch_out += ' ';
}
if (btnCabMyXchg->value()) {
exch_out.append(rec->getField(MYXCHG));
exch_out.append(" ");
}
if (contestnbr == BARTG_RTTY) {
exch_out.append(rec->getField(TIME_OFF));
exch_out.append(" ");
exch_out.append(rec->getField(STX)).append(" ");
}
if (exch_out.length() > 10) exch_out = exch_out.substr(0,10);
if ((len = exch_out.length()) < 10) exch_out.append(10 - len, ' ');
qsoline.append(exch_out); qsoline.append(" ");
if (btnCabMyXchg->value()) {
exch_out.append(rec->getField(MYXCHG)).append(" ");
}
if (contestnbr == BARTG_RTTY && exch_out.length() < 11) {
exch_out.append(rec->getField(TIME_OFF)).append(" ");
}
if (exch_out.length() > 14) exch_out = exch_out.substr(0,14);
if ((len = exch_out.length()) < 14) exch_out.append(14 - len, ' ');
qsoline.append(exch_out).append(" ");
if (btnCabCall->value()) {
call = rec->getField(CALL);
@ -935,8 +936,8 @@ void cabrillo_append_qso (FILE *fp, cQsoRec *rec)
}
if (btnCabXchgIn->value())
exch_in.append(rec->getField(XCHG1));
if (exch_in.length() > 10) exch_in = exch_in.substr(0,10);
if ((len = exch_in.length()) < 10) exch_in.append(10 - len, ' ');
if (exch_in.length() > 14) exch_in = exch_in.substr(0,14);
if ((len = exch_in.length()) < 14) exch_in.append(14 - len, ' ');
qsoline.append(exch_in);
fprintf (fp, "%s\n", qsoline.c_str());

Wyświetl plik

@ -81,7 +81,7 @@ Save tags and all enclosed text to date-time stamped file, ie:\n\n\
const char *txtWrapInfo = "\
Detect the occurance of [WRAP:beg] and [WRAP:end]\n\
Save tags and all enclosed text to date-time stamped file, ie:\n\n\
~/NBEMS.files/WRAP/recv/extract-20090127-092515.wrap";
~/.nbems/WRAP/recv/extract-20090127-092515.wrap";
#endif
#define bufsize 16
@ -118,6 +118,7 @@ void rx_extract_reset()
void rx_extract_add(int c)
{
if (!c) return;
check_nbems_dirs();
if (!bInit) {
rx_extract_reset();
@ -178,7 +179,7 @@ void rx_extract_add(int c)
number_commas = count(rx_buff.begin(), rx_buff.end(), progdefaults.xmlField_delimiter.at(0));
//Gets info for number of fields
min_number_fields = atoi(progdefaults.xmlFields.c_str());
min_number_fields = progdefaults.xmlFields;
//Check rules - telem string length and number of fields and whether each field has been validated
if ((rx_buff.length() < total_string_length) and (number_commas == min_number_fields - 1)) {

Wyświetl plik

@ -197,9 +197,7 @@ int main(int argc, char ** argv)
appname = argv[0];
debug_exec(argv);
/* Needs to be run once, at the start of the program (calls curl_global_init) when there are no threads,
* since it is the only thread-unsafe/global-modifying function of the library */
dl_fldigi_init();
set_platform_ui();
CREATE_THREAD_ID(); // only call this once
SET_THREAD_ID(FLMAIN_TID);
@ -229,14 +227,17 @@ int main(int argc, char ** argv)
#else
fl_filename_expand(dirbuf, sizeof(dirbuf) - 1, "$HOME/.fldigi/");
HomeDir = dirbuf;
fl_filename_expand(dirbuf, sizeof(dirbuf) - 1, "$HOME/NBEMS.files/");
fl_filename_expand(dirbuf, sizeof(dirbuf) - 1, "$HOME/.nbems/");
NBEMS_dir = dirbuf;
fl_filename_expand(dirbuf, sizeof(dirbuf) - 1, "$HOME/");
PskMailDir = dirbuf;
#endif
}
set_platform_ui();
/* Needs to be run once, at the start of the program (calls curl_global_init) when there are no threads,
* since it is the only thread-unsafe/global-modifying function of the library
* dl_fldigi_init requires the "HomeDir" global above. */
dl_fldigi_init();
generate_option_help();
generate_version_text();
@ -246,7 +247,6 @@ int main(int argc, char ** argv)
if (main_window_title.empty())
main_window_title = PACKAGE_TARNAME;
dl_xmlList();
checkdirectories();
try {
debug::start(string(HomeDir).append("status_log.txt").c_str());
@ -288,8 +288,23 @@ int main(int argc, char ** argv)
qsl_open(string(HomeDir).append("AGMemberList.txt").c_str(), QSL_EQSL);
progStatus.loadLastState();
/* if --hab was specified, default dl_online to true */
progdefaults.dl_online = bHAB;
create_fl_digi_main(argc, argv);
/* Attempt regardless to load the cache of payload information */
dl_fldigi_update_payloads();
/* Only if we're online, go ahead and automatically download new payload info. */
if (progdefaults.dl_online)
{
/* This must be called after the UI is created */
dl_fldigi_download();
dl_fldigi_downloaded_once = 1;
}
if (!have_config || show_cpucheck) {
double speed = speed_test(SRC_SINC_FASTEST, 8);
@ -1103,6 +1118,33 @@ static void checkdirectories(void)
{ FlightXMLDir, "flightxml", 0}
};
int r;
for (size_t i = 0; i < sizeof(fldigi_dirs)/sizeof(*fldigi_dirs); i++) {
if (fldigi_dirs[i].suffix)
fldigi_dirs[i].dir.assign(HomeDir).append(fldigi_dirs[i].suffix).append(PATH_SEP);
if ((r = mkdir(fldigi_dirs[i].dir.c_str(), 0777)) == -1 && errno != EEXIST) {
cerr << _("Could not make directory") << ' ' << fldigi_dirs[i].dir
<< ": " << strerror(errno) << '\n';
exit(EXIT_FAILURE);
}
else if (r == 0 && fldigi_dirs[i].new_dir_func)
fldigi_dirs[i].new_dir_func();
}
}
bool nbems_dirs_checked = false;
void check_nbems_dirs(void)
{
if (nbems_dirs_checked) return;
struct DIRS {
string& dir;
const char* suffix;
void (*new_dir_func)(void);
};
DIRS NBEMS_dirs[] = {
{ NBEMS_dir, 0, 0 },
{ ARQ_dir, "ARQ", 0 },
@ -1119,19 +1161,6 @@ static void checkdirectories(void)
};
int r;
for (size_t i = 0; i < sizeof(fldigi_dirs)/sizeof(*fldigi_dirs); i++) {
if (fldigi_dirs[i].suffix)
fldigi_dirs[i].dir.assign(HomeDir).append(fldigi_dirs[i].suffix).append(PATH_SEP);
if ((r = mkdir(fldigi_dirs[i].dir.c_str(), 0777)) == -1 && errno != EEXIST) {
cerr << _("Could not make directory") << ' ' << fldigi_dirs[i].dir
<< ": " << strerror(errno) << '\n';
exit(EXIT_FAILURE);
}
else if (r == 0 && fldigi_dirs[i].new_dir_func)
fldigi_dirs[i].new_dir_func();
}
for (size_t i = 0; i < sizeof(NBEMS_dirs)/sizeof(*NBEMS_dirs); i++) {
if (NBEMS_dirs[i].suffix)
NBEMS_dirs[i].dir.assign(NBEMS_dir).append(NBEMS_dirs[i].suffix).append(PATH_SEP);
@ -1144,6 +1173,7 @@ static void checkdirectories(void)
else if (r == 0 && NBEMS_dirs[i].new_dir_func)
NBEMS_dirs[i].new_dir_func();
}
nbems_dirs_checked = true;
}
// Print an error message and exit. If stderr is not a terminal

Wyświetl plik

@ -766,3 +766,4 @@ void pskmail_notify_s2n(double s2n_ncount, double s2n_avg, double s2n_stddev)
ReceiveText->add(buf, FTextBase::CTRL);
}
}

Wyświetl plik

@ -10,34 +10,66 @@
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <sys/file.h>
#include <FL/Fl_Choice.H>
#include "configuration.h"
#include "dl_fldigi.h"
#include "util.h"
#include "confdialog.h"
#include "fl_digi.h"
#include "main.h"
#include "qrunner.h"
#include "irrXML.h"
using namespace std;
using namespace irr; // irrXML is located
using namespace io; // in the namespace irr::io
#define DL_FLDIGI_DEBUG
#define DL_FLDIGI_CACHE_FILE "dl_fldigi_cache.xml"
int dl_fldigi_initialised = 0;
struct dl_fldigi_threadinfo
struct dl_fldigi_post_threadinfo
{
CURL *curl;
char *post_data;
};
void *dl_fldigi_thread(void *thread_argument);
struct dl_fldigi_download_threadinfo
{
CURL *curl;
FILE *file;
};
struct payload
{
char *name;
char *sentence_delimiter;
char *field_delimiter;
int fields;
char *callsign;
int shift;
int baud;
int coding;
struct payload *next;
};
bool dl_fldigi_downloaded_once = false;
int dl_fldigi_initialised = 0;
const char *dl_fldigi_cache_file;
struct payload *payload_list = NULL;
static void *dl_fldigi_post_thread(void *thread_argument);
static void *dl_fldigi_download_thread(void *thread_argument);
void dl_fldigi_delete_payloads();
void dl_fldigi_init()
{
CURLcode r;
const char *home;
char *cache_file;
size_t i, fsz;
#ifdef DL_FLDIGI_DEBUG
fprintf(stderr, "dl_fldigi: dl_fldigi_init() was executed in thread %li\n", pthread_self());
@ -49,11 +81,42 @@ void dl_fldigi_init()
if (r != 0)
{
fprintf(stderr, "dl_fldigi: curl_global_init failed: (%i) %s\n", r, curl_easy_strerror(r));
/* The only scenario in which we exit. */
exit(EXIT_FAILURE);
}
home = HomeDir.c_str();
fsz = strlen(home) + strlen(DL_FLDIGI_CACHE_FILE) + 1;
i = 0;
cache_file = (char *) malloc(fsz);
if (cache_file == NULL)
{
fprintf(stderr, "dl_fldigi: denied %zi bytes of RAM for 'cache_file'\n", fsz);
exit(EXIT_FAILURE);
}
memcpy(cache_file + i, home, strlen(home));
i += strlen(home);
memcpy(cache_file + i, DL_FLDIGI_CACHE_FILE, strlen(DL_FLDIGI_CACHE_FILE));
i += strlen(DL_FLDIGI_CACHE_FILE);
cache_file[i] = '\0';
i++;
if (i != fsz)
{
fprintf(stderr, "dl_fldigi: assertion failed \"i == fsz\" (i = %zi, fsz = %zi) \n", i, fsz);
}
dl_fldigi_cache_file = cache_file;
#ifdef DL_FLDIGI_DEBUG
fprintf(stderr, "dl_fldigi: cache file is '%s'\n", dl_fldigi_cache_file);
#endif
dl_fldigi_initialised = 1;
full_memory_barrier();
}
@ -62,7 +125,7 @@ void dl_fldigi_post(const char *data, const char *identity)
{
char *data_safe, *identity_safe, *post_data;
size_t i, data_length, identity_length, post_data_length;
struct dl_fldigi_threadinfo *t;
struct dl_fldigi_post_threadinfo *t;
pthread_t thread;
CURL *curl;
CURLcode r1, r2, r3;
@ -157,15 +220,12 @@ void dl_fldigi_post(const char *data, const char *identity)
if (progdefaults.dl_online)
{
#ifdef DL_FLDIGI_DEBUG
fprintf(stdout, "dl_fldigi: preparing to post '%s'\n", post_data);
fprintf(stderr, "dl_fldigi: preparing to post '%s'\n", post_data);
#endif
}
else
{
#ifdef DL_FLDIGI_DEBUG
fprintf(stdout, "dl_fldigi: (offline mode) would have posted '%s'\n", post_data);
#endif
fprintf(stderr, "dl_fldigi: (offline mode) would have posted '%s'\n", post_data);
curl_easy_cleanup(curl);
return;
}
@ -194,11 +254,11 @@ void dl_fldigi_post(const char *data, const char *identity)
return;
}
t = (struct dl_fldigi_threadinfo *) malloc(sizeof(struct dl_fldigi_threadinfo));
t = (struct dl_fldigi_post_threadinfo *) malloc(sizeof(struct dl_fldigi_post_threadinfo));
if (t == NULL)
{
fprintf(stderr, "dl_fldigi: denied %zi bytes of RAM for 'struct dl_fldigi_threadinfo'\n", sizeof(struct dl_fldigi_threadinfo));
fprintf(stderr, "dl_fldigi: denied %zi bytes of RAM for 'struct dl_fldigi_post_threadinfo'\n", sizeof(struct dl_fldigi_post_threadinfo));
curl_easy_cleanup(curl);
return;
}
@ -210,9 +270,11 @@ void dl_fldigi_post(const char *data, const char *identity)
full_memory_barrier();
/* the 4th argument passes the thread the information it needs */
if (pthread_create(&thread, NULL, dl_fldigi_thread, (void *) t) != 0)
if (pthread_create(&thread, NULL, dl_fldigi_post_thread, (void *) t) != 0)
{
perror("pthread_create");
perror("dl_fldigi: post pthread_create");
curl_easy_cleanup(curl);
return;
}
#ifdef DL_FLDIGI_DEBUG
@ -220,14 +282,14 @@ void dl_fldigi_post(const char *data, const char *identity)
#endif
}
void *dl_fldigi_thread(void *thread_argument)
void *dl_fldigi_post_thread(void *thread_argument)
{
struct dl_fldigi_threadinfo *t;
t = (struct dl_fldigi_threadinfo *) thread_argument;
struct dl_fldigi_post_threadinfo *t;
t = (struct dl_fldigi_post_threadinfo *) thread_argument;
CURLcode result;
#ifdef DL_FLDIGI_DEBUG
fprintf(stdout, "dl_fldigi: (thread %li) posting '%s'\n", pthread_self(), t->post_data);
fprintf(stderr, "dl_fldigi: (thread %li) posting '%s'\n", pthread_self(), t->post_data);
#endif
result = curl_easy_perform(t->curl);
@ -235,11 +297,11 @@ void *dl_fldigi_thread(void *thread_argument)
#ifdef DL_FLDIGI_DEBUG
if (result == 0)
{
fprintf(stdout, "dl_fldigi: (thread %li) curl result (%i) Success!\n", pthread_self(), result);
fprintf(stderr, "dl_fldigi: (thread %li) curl result (%i) Success!\n", pthread_self(), result);
}
else
{
fprintf(stdout, "dl_fldigi: (thread %li) curl result (%i) %s\n", pthread_self(), result, curl_easy_strerror(result));
fprintf(stderr, "dl_fldigi: (thread %li) curl result (%i) %s\n", pthread_self(), result, curl_easy_strerror(result));
}
#endif
@ -250,195 +312,415 @@ void *dl_fldigi_thread(void *thread_argument)
pthread_exit(0);
}
void dl_selFlightXML(Fl_Choice* o, void*) {
progdefaults.flight_sel = o->text();
progdefaults.flight_sel_num = o->value();
#if !defined(__CYGWIN__)
cout << progdefaults.flight_sel.c_str() << endl;
#endif
void dl_fldigi_download()
{
pthread_t thread;
struct dl_fldigi_download_threadinfo *t;
CURL *curl;
CURLcode res;
FILE * xmlFile;
string server_address = "http://www.robertharrison.org/listen/";
string xml_file, xml_file_dir;
curl = curl_easy_init();
if(curl) {
//Also in here we need to add a function to check that we have the most recent version
xml_file = progdefaults.flight_sel;
xml_file.append(".xml");
//make string of directory and file
xml_file_dir = FlightXMLDir;
xml_file_dir.append(xml_file);
#if !defined(__CYGWIN__)
cout << xml_file_dir << endl;
#endif
//make string of server address and file
server_address.append(xml_file);
#if !defined(__CYGWIN__)
cout << server_address << endl;
#endif
xmlFile = fopen (xml_file_dir.c_str(),"w");
curl_easy_setopt(curl, CURLOPT_URL, server_address.c_str());
curl_easy_setopt(curl , CURLOPT_WRITEDATA , xmlFile );
res = curl_easy_perform(curl);
//always cleanup
fclose(xmlFile);
curl_easy_cleanup(curl);
}
IrrXMLReader* xml = createIrrXMLReader(xml_file_dir.c_str());
// strings for storing the data we want to get out of the file
string sentence_delimiter;
string field_delimiter;
string fields;
string callsign;
string xmldata;
string xmlfielddata;
string seqnumber;
while(xml && xml->read())
CURLcode r1, r3;
FILE *file;
int r2;
if (!dl_fldigi_initialised)
{
if (!strcmp("sentence_delimiter", xml->getNodeName())) {
xml->read();
sentence_delimiter = xml->getNodeData();
progdefaults.xmlSentence_delimiter = sentence_delimiter;
//telemSentence_delimiter->value(progdefaults.xmlSentence_delimiter.c_str());
xml->read();
}
else if (!strcmp("field_delimiter", xml->getNodeName())) {
xml->read();
field_delimiter = xml->getNodeData();
progdefaults.xmlField_delimiter = field_delimiter;
//telemField_delimiter->value(progdefaults.xmlField_delimiter.c_str());
xml->read();
}
else if (!strcmp("fields", xml->getNodeName())) {
xml->read();
fields = xml->getNodeData();
progdefaults.xmlFields = fields;
//telemFields->value(progdefaults.xmlFields.c_str());
xml->read();
}
else if (!strcmp("callsign", xml->getNodeName())) {
xml->read();
callsign = xml->getNodeData();
if (callsign != "dbfield") {
progdefaults.xmlCallsign = callsign;
fprintf(stderr, "dl_fldigi: a call to dl_fldigi_download was aborted; dl_fldigi has not been initialised\n");
return;
}
if (!progdefaults.dl_online)
{
fprintf(stderr, "dl_fldigi: a call to dl_fldigi_download was aborted: refusing to download a file whist in offline mode.\n");
return;
}
#ifdef DL_FLDIGI_DEBUG
fprintf(stderr, "dl_fldigi: dl_fldigi_download() was executed in \"parent\" thread %li\n", pthread_self());
fprintf(stderr, "dl_fldigi: begin download attempt...\n");
#endif
curl = curl_easy_init();
if (!curl)
{
fprintf(stderr, "dl_fldigi: curl_easy_init failed\n");
return;
}
r1 = curl_easy_setopt(curl, CURLOPT_URL, "http://www.robertharrison.org/listen/allpayloads.php");
if (r1 != 0)
{
fprintf(stderr, "dl_fldigi: curl_easy_setopt (CURLOPT_URL) failed: %s\n", curl_easy_strerror(r1));
curl_easy_cleanup(curl);
return;
}
t = (struct dl_fldigi_download_threadinfo *) malloc(sizeof(struct dl_fldigi_download_threadinfo));
if (t == NULL)
{
fprintf(stderr, "dl_fldigi: denied %zi bytes of RAM for 'struct dl_fldigi_download_threadinfo'\n", sizeof(struct dl_fldigi_download_threadinfo));
curl_easy_cleanup(curl);
return;
}
file = fopen(dl_fldigi_cache_file, "w");
if (file == NULL)
{
perror("dl_fldigi: fopen cache file");
curl_easy_cleanup(curl);
return;
}
r2 = flock(fileno(file), LOCK_EX | LOCK_NB);
if (r2 == EWOULDBLOCK)
{
fprintf(stderr, "dl_fldigi: cache file is locked; not downloading\n");
curl_easy_cleanup(curl);
fclose(file);
return;
}
else if (r2 != 0)
{
perror("dl_fldigi: flock cache file");
curl_easy_cleanup(curl);
fclose(file);
return;
}
r3 = curl_easy_setopt(curl, CURLOPT_WRITEDATA, file);
if (r3 != 0)
{
fprintf(stderr, "dl_fldigi: curl_easy_setopt (CURLOPT_WRITEDATA) failed: %s\n", curl_easy_strerror(r3));
curl_easy_cleanup(curl);
flock(fileno(file), LOCK_UN);
fclose(file);
return;
}
t->curl = curl;
t->file = file;
/* !! */
full_memory_barrier();
/* the 4th argument passes the thread the information it needs */
if (pthread_create(&thread, NULL, dl_fldigi_download_thread, (void *) t) != 0)
{
perror("dl_fldigi: download pthread_create");
flock(fileno(file), LOCK_UN);
fclose(file);
return;
}
#ifdef DL_FLDIGI_DEBUG
fprintf(stderr, "dl_fldigi: created a thread to perform the download, returning now\n");
#endif
}
void *dl_fldigi_download_thread(void *thread_argument)
{
struct dl_fldigi_download_threadinfo *t;
t = (struct dl_fldigi_download_threadinfo *) thread_argument;
CURLcode result;
#ifdef DL_FLDIGI_DEBUG
fprintf(stderr, "dl_fldigi: (thread %li) performing download...\n", pthread_self());
#endif
result = curl_easy_perform(t->curl);
curl_easy_cleanup(t->curl);
flock(fileno(t->file), LOCK_UN);
fclose(t->file);
free(t);
if (result == 0)
{
#ifdef DL_FLDIGI_DEBUG
fprintf(stderr, "dl_fldigi: (thread %li) curl result (%i) Success!\n", pthread_self(), result);
#endif
/* ask qrunner to deal with this */
REQ(dl_fldigi_update_payloads);
}
else
{
#ifdef DL_FLDIGI_DEBUG
fprintf(stderr, "dl_fldigi: (thread %li) curl result (%i) %s\n", pthread_self(), result, curl_easy_strerror(result));
#endif
}
pthread_exit(0);
}
void dl_fldigi_delete_payloads()
{
struct payload *d, *n;
if (bHAB)
{
habFlightXML->clear();
}
d = payload_list;
while (d != NULL)
{
#define auto_free(x) do { void *a = (x); if (a != NULL) { free(a); } } while (0)
auto_free(d->name);
auto_free(d->sentence_delimiter);
auto_free(d->field_delimiter);
auto_free(d->callsign);
n = d->next;
free(d);
d = n;
}
payload_list = NULL;
}
void dl_fldigi_update_payloads()
{
FILE *file;
int r1, r_shift, r_baud;
const char *r_coding;
IrrXMLReader *xml;
struct payload *p, *n;
#ifdef DL_FLDIGI_DEBUG
fprintf(stderr, "dl_fldigi: (thread %li) attempting to update UI...\n", pthread_self());
#endif
file = fopen(dl_fldigi_cache_file, "r");
if (file == NULL)
{
perror("dl_fldigi: fopen cache file (read)");
return;
}
r1 = flock(fileno(file), LOCK_SH | LOCK_NB);
if (r1 == EWOULDBLOCK)
{
fprintf(stderr, "dl_fldigi: cache file is locked; not updating UI\n");
fclose(file);
return;
}
else if (r1 != 0)
{
perror("dl_fldigi: flock cache file (read)");
fclose(file);
return;
}
#ifdef DL_FLDIGI_DEBUG
fprintf(stderr, "dl_fldigi: opened file, now updating UI...\n");
#endif
dl_fldigi_delete_payloads();
xml = createIrrXMLReader(file);
if (!xml)
{
fprintf(stderr, "dl_fldigi: parsing payload info: createIrrXMLReader failed\n");
flock(fileno(file), LOCK_UN);
fclose(file);
return;
}
p = payload_list;
while (xml->read())
{
if (xml->getNodeType() == EXN_ELEMENT)
{
if (strcmp("name", xml->getNodeName()) == 0)
{
n = (struct payload *) malloc(sizeof(struct payload));
if (n == NULL)
{
fprintf(stderr, "dl_fldigi: denied %zi bytes of RAM for 'struct payload'\n", sizeof(struct payload));
dl_fldigi_delete_payloads();
delete xml;
flock(fileno(file), LOCK_UN);
fclose(file);
return;
}
/* Nulls all the char pointers, the next pointer, zeroes the ints */
memset(n, 0, sizeof(struct payload));
if (p == NULL)
{
payload_list = n;
p = n;
}
else
{
p->next = n;
p = p->next;
}
xml->read();
p->name = strdup(xml->getNodeData());
xml->read();
if (bHAB)
{
habFlightXML->add(p->name);
}
#ifdef DL_FLDIGI_DEBUG
fprintf(stderr, "dl_fldigi: adding payload '%s'\n", p->name);
#endif
}
else if (strcmp("sentence_delimiter", xml->getNodeName()) == 0)
{
xml->read();
p->sentence_delimiter = strdup(xml->getNodeData());
xml->read();
}
else if (strcmp("field_delimiter", xml->getNodeName()) == 0)
{
xml->read();
p->field_delimiter = strdup(xml->getNodeData());
xml->read();
}
else if (strcmp("fields", xml->getNodeName()) == 0)
{
xml->read();
p->fields = atoi(xml->getNodeData());
xml->read();
}
else if (strcmp("callsign", xml->getNodeName()) == 0)
{
xml->read();
p->callsign = strdup(xml->getNodeData());
xml->read();
}
else if (strcmp("shift", xml->getNodeName()) == 0)
{
xml->read();
r_shift = atoi(xml->getNodeData());
xml->read();
if (r_shift == 170)
{
p->shift = 4;
}
else if (r_shift == 350)
{
p->shift = 7;
}
else if (r_shift == 425)
{
p->shift = 8;
}
}
else if (strcmp("baud", xml->getNodeName()) == 0)
{
xml->read();
r_baud = atoi(xml->getNodeData());
xml->read();
if (r_baud == 45)
{
p->baud = 0;
}
else if (r_baud == 50)
{
p->baud = 2;
}
else if (r_baud == 100)
{
p->baud = 5;
}
else if (r_baud == 150)
{
p->baud = 7;
}
else if (r_baud == 200)
{
p->baud = 8;
}
else if (r_baud == 300)
{
p->baud = 9;
}
}
else if (strcmp("coding", xml->getNodeName()) == 0)
{
/* Why does this need to be commented? XXX */
// xml->read();
r_coding = xml->getNodeData();
xml->read();
if (strcmp("baudot", r_coding) == 0)
{
p->coding = 0;
}
else if (strcmp("ascii-7", r_coding) == 0)
{
p->coding = 1;
}
else if (strcmp("ascii-8", r_coding) == 0)
{
p->coding = 2;
}
}
xml->read();
}
else if (!strcmp("shift", xml->getNodeName())) {
xml->read();
fields = xml->getNodeData();
int shift_int= atoi(fields.c_str());
if (shift_int == 170) {
progdefaults.rtty_shift = 4;
}
else if (shift_int == 350) {
progdefaults.rtty_shift = 7;
}
else if (shift_int == 425) {
progdefaults.rtty_shift = 8;
}
}
#ifdef DL_FLDIGI_DEBUG
fprintf(stderr, "dl_fldigi: UI updated.\n");
#endif
delete xml;
flock(fileno(file), LOCK_UN);
fclose(file);
}
void dl_fldigi_select_payload(Fl_Choice* o, void *a)
{
struct payload *p;
#ifdef DL_FLDIGI_DEBUG
fprintf(stderr, "dl_fldigi: (thread %li) attempting to configure payload...\n", pthread_self());
#endif
p = payload_list;
while (p != NULL)
{
if (p->name != NULL && strcmp(p->name, o->text()) == 0)
{
#ifdef DL_FLDIGI_DEBUG
fprintf(stderr, "dl_fldigi: configuring payload '%s'...\n", p->name);
#endif
progdefaults.xmlSentence_delimiter = p->sentence_delimiter;
progdefaults.xmlField_delimiter = p->field_delimiter;
progdefaults.xmlFields = p->fields;
progdefaults.xmlCallsign = p->callsign;
progdefaults.rtty_shift = p->shift;
progdefaults.rtty_baud = p->baud;
progdefaults.rtty_bits = p->coding;
selShift->value(progdefaults.rtty_shift);
resetRTTY();
xml->read();
}
else if (!strcmp("baud", xml->getNodeName())) {
xml->read();
fields = xml->getNodeData();
int baud_int = atoi(fields.c_str());
if (baud_int == 45) {
progdefaults.rtty_baud = 0;
}
else if (baud_int == 50) {
progdefaults.rtty_baud = 2;
}
else if (baud_int == 100) {
progdefaults.rtty_baud = 5;
}
else if (baud_int == 150) {
progdefaults.rtty_baud = 7;
}
else if (baud_int == 200) {
progdefaults.rtty_baud = 8;
}
else if (baud_int == 300) {
progdefaults.rtty_baud = 9;
}
selBaud->value(progdefaults.rtty_baud);
resetRTTY();
xml->read();
}
else if (!strcmp("coding", xml->getNodeName())) {
xml->read();
fields = xml->getNodeData();
// "5 (baudot)|7 (ascii)|8 (ascii)";
if (fields == "baudot") {
progdefaults.rtty_bits = 0;
}
else if (fields == "ascii-7") {
progdefaults.rtty_bits = 1;
}
else if (fields == "ascii-8") {
progdefaults.rtty_bits = 2;
}
selBits->value(progdefaults.rtty_bits);
resetRTTY();
xml->read();
}
}
#if !defined(__CYGWIN__)
cout << "Done" << endl;
#endif
// delete the xml parser after usage
delete xml;
progdefaults.changed = true;
}
// This is the writer call back function used by curl
static int writer(char *data, size_t size, size_t nmemb, std::string *buffer)
{
// What we will return
int result = 0;
// Is there anything in the buffer?
if (buffer != NULL)
{
// Append the data to the buffer
buffer->append(data, size * nmemb);
// How much did we write?
result = size * nmemb;
}
return result;
}
void dl_xmlList() {
CURL *curl;
CURLcode res;
string buffer;
int i=0;
curl = curl_easy_init();
if(curl) {
//Also in here we need to add a function to check that we have the most recent version
curl_easy_setopt(curl, CURLOPT_URL, "http://www.robertharrison.org/listen/payload.php");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writer);
curl_easy_setopt(curl , CURLOPT_WRITEDATA , &buffer );
res = curl_easy_perform(curl);
//
/* always cleanup */
curl_easy_cleanup(curl);
}
//Remove \n and add | (needed for GUI selection
for(i = buffer.find("\n", 0); i != string::npos; i = buffer.find("\n", i))
{
i++; // Move past the last discovered instance to avoid finding same
// string
buffer.erase(i-1, 1);
buffer.insert(i-1, "|");
}
progdefaults.flightsAvaliable = buffer;
//cout << buffer << endl; // Print out flightsAvailable string
return;
}
//bool have_config = progdefaults.readDefaultsXML();
p = p->next;
}
fprintf(stderr, "dl_fldigi: (should never happen): unable to find payload to configure\n");
}

Wyświetl plik

@ -66,8 +66,6 @@ void olivia::tx_init(SoundBase *sc)
postamblesent = 0;
txbasefreq = get_txfreq_woffset();
if (last_txbasefreq != txbasefreq) create_tones();
Rx->Flush();
while (Rx->GetChar(c) > 0)
@ -88,30 +86,30 @@ void olivia::tx_init(SoundBase *sc)
escape = 0;
}
void olivia::create_tones()
{
double freqa, freqb;
int i, j;
if (reverse) {
freqa = txbasefreq + (bandwidth / 2.0);
freqb = txbasefreq - (bandwidth / 2.0);
} else {
freqa = txbasefreq - (bandwidth / 2.0);
freqb = txbasefreq + (bandwidth / 2.0);
}
for (i = 0, j = 0; i < SR4; i++, j++)
tonebuff[2*SR4 + j] = tonebuff[i] = nco(freqa) * ampshape[j];
for (i = SR4, j = 0; i < 2*SR4; i++, j++)
tonebuff[3*SR4 + j] = tonebuff[i] = nco(freqb) * ampshape[j];
}
void olivia::send_tones()
{
for (int j = 0; j < 8192; j += 512)
ModulateXmtr(&tonebuff[j], 512);
if (tone_midfreq != txbasefreq || tone_bw != bandwidth) {
double freqa, freqb;
tone_bw = bandwidth;
tone_midfreq = txbasefreq;
if (reverse) {
freqa = tone_midfreq + (tone_bw / 2.0);
freqb = tone_midfreq - (tone_bw / 2.0);
} else {
freqa = tone_midfreq - (tone_bw / 2.0);
freqb = tone_midfreq + (tone_bw / 2.0);
}
preamblephase = 0;
for (int i = 0; i < SR4; i++)
tonebuff[2*SR4 + i] = tonebuff[i] = nco(freqa) * ampshape[i];
preamblephase = 0;
for (int i = 0; i < SR4; i++)
tonebuff[3*SR4 + i] = tonebuff[SR4 + i] = nco(freqb) * ampshape[i];
}
for (int j = 0; j < TONE_DURATION; j += SCBLOCKSIZE)
ModulateXmtr(&tonebuff[j], SCBLOCKSIZE);
}
void olivia::rx_init()
@ -151,14 +149,15 @@ int olivia::tx_process()
if (preamblesent != 1) {
send_tones();
preamblesent = 1;
preamblesent = 1;
// Olivia Transmitter class requires at least character
Tx->PutChar(0);
}
// The encoder works with BitsPerSymbol length blocks. If the
// modem already has that many characters buffered, don't try
// to read any more. If stopflag is set, we will always read
// whatever there is.
if (stopflag || (Tx->GetReadReady() < Tx->BitsPerSymbol)) {
if ((c = get_tx_char()) == 0x03 || stopflag ) {
stopflag = true;
@ -186,7 +185,6 @@ int olivia::tx_process()
if (stopflag && Tx->DoPostambleYet() == 1 && postamblesent != 1) {
postamblesent = 1;
preamblephase = Tx->GetSymbolPhase();
send_tones();
}
@ -274,8 +272,6 @@ void olivia::restart()
Tx->SampleRate = samplerate;
Tx->OutputSampleRate = samplerate;
txbasefreq = get_txfreq_woffset();
last_txbasefreq = txbasefreq;
create_tones();
if (reverse) {
Tx->FirstCarrierMultiplier = (txbasefreq + (Tx->Bandwidth / 2)) / 500;
@ -324,7 +320,6 @@ void olivia::restart()
metric = 0;
sigpwr = 1e-10; noisepwr = 1e-8;
// Rx->PrintParameters();
}
@ -348,10 +343,14 @@ olivia::olivia()
mode = MODE_OLIVIA;
lastfreq = 0;
for (int i = 0; i < SR4; i++) ampshape[i] = 1.0;
for (int i = 0; i < SR4 / 8; i++)
ampshape[i] = ampshape[SR4 - 1 - i] = 0.5 * (1.0 - cos(M_PI * i / (SR4/8)));
for (int i = 0; i < SR4; i++) ampshape[i] = 1.0;
for (int i = 0; i < SR4 / 8; i++)
ampshape[i] = ampshape[SR4 - 1 - i] = 0.5 * (1.0 - cos(M_PI * i / (SR4/8)));
for (int i = 0; i < TONE_DURATION; i++) tonebuff[i] = 0;
tone_bw = -1;
tone_midfreq = -1;
}
olivia::~olivia()

Wyświetl plik

@ -36,7 +36,6 @@
#include "configuration.h"
#include "waterfall.h"
#include "qrunner.h"
#include "mbuffer.h"
#include "status.h"
#include "debug.h"
@ -281,8 +280,6 @@ double modem::PTTnco()
return sin(PTTphaseacc);
}
mbuffer<double, 512 * 2, 2> _mdm_scdbl;
double modem::sigmaN (double es_ovr_n0)
{
double sn_ratio, sigma;
@ -389,18 +386,8 @@ void modem::ModulateXmtr(double *buffer, int len)
return;
}
if (!progdefaults.viewXmtSignal)
return;
for (int i = 0; i < len; i++) {
_mdm_scdbl[scptr] = buffer[i] * progdefaults.TxMonitorLevel;
scptr++;
if (scptr == 512) {
//for (int i = 0; i < 512; i++) printf("%f\n", _mdm_scdbl[i]);
REQ(&waterfall::sig_data, wf, _mdm_scdbl.c_array(), 512, samplerate );
scptr = 0;
_mdm_scdbl.next(); // change buffers
}
}
if (progdefaults.viewXmtSignal)
trx_xmit_wfall_queue(samplerate, buffer, (size_t)len);
}
#include <iostream>
@ -419,17 +406,8 @@ void modem::ModulateStereo(double *left, double *right, int len)
return;
}
if (!progdefaults.viewXmtSignal)
return;
for (int i = 0; i < len; i++) {
_mdm_scdbl[scptr] = left[i] * progdefaults.TxMonitorLevel;
scptr++;
if (scptr == 512) {
REQ(&waterfall::sig_data, wf, _mdm_scdbl.c_array(), 512, samplerate);
scptr = 0;
_mdm_scdbl.next(); // change buffers
}
}
if (progdefaults.viewXmtSignal)
trx_xmit_wfall_queue(samplerate, left, (size_t)len);
}

Wyświetl plik

@ -92,8 +92,6 @@ static int _trx_tune;
// is also passed to the waterfall signal drawing routines.
#define NUMMEMBUFS 1024
static ringbuffer<double> trxrb(ceil2(NUMMEMBUFS * SCBLOCKSIZE));
// Vector used for direct access to the ringbuffer
static ringbuffer<double>::vector_type rbvec[2];
static float fbuf[SCBLOCKSIZE];
bool bHistory = false;
@ -102,6 +100,101 @@ static bool trxrunning = false;
#include "tune.cxx"
//=============================================================================
// Draws the xmit data one WFBLOCKSIZE-sized block at a time
static void trx_xmit_wfall_draw(int samplerate)
{
ENSURE_THREAD(FLMAIN_TID);
ringbuffer<double>::vector_type rv[2];
#define block_read_(vec_) \
while (vec_.len >= WFBLOCKSIZE) { \
wf->sig_data(vec_.buf, WFBLOCKSIZE, samplerate); \
vec_.len -= WFBLOCKSIZE; \
vec_.buf += WFBLOCKSIZE; \
trxrb.read_advance(WFBLOCKSIZE); \
}
trxrb.get_rv(rv);
block_read_(rv[0]); // read blocks from the first vector
if (rv[0].len + rv[1].len < WFBLOCKSIZE)
return;
if (rv[0].len == 0)
block_read_(rv[1]);
#undef block_read_
// read non-contiguous data into tmp buffer so that we can
// still draw it one block at a time
if (unlikely(trxrb.read_space() >= WFBLOCKSIZE)) {
double buf[WFBLOCKSIZE];
do {
trxrb.read(buf, WFBLOCKSIZE);
wf->sig_data(buf, WFBLOCKSIZE, samplerate);
} while (trxrb.read_space() >= WFBLOCKSIZE);
}
}
// Called by trx_trx_transmit_loop() to handle data that may be left in the
// ringbuffer when we stop transmitting. Will pad with zeroes to a multiple of
// WFBLOCKSIZE.
static void trx_xmit_wfall_end(int samplerate)
{
ENSURE_THREAD(TRX_TID);
size_t pad = WFBLOCKSIZE - trxrb.read_space() % WFBLOCKSIZE;
if (pad == WFBLOCKSIZE) // rb empty or multiple of WFBLOCKSIZE
return;
ringbuffer<double>::vector_type wv[2];
trxrb.get_wv(wv, pad);
assert(wv[0].len + wv[1].len == pad);
if (likely(wv[0].len)) { // fill first vector, write rest to second vector
memset(wv[0].buf, 0, wv[0].len * sizeof(*wv[0].buf));
if (pad > wv[0].len)
memset(wv[1].buf, 0, (pad - wv[0].len) * sizeof(*wv[1].buf));
}
else // all write space is in the second write vector
memset(wv[1].buf, 0, pad * sizeof(*wv[1].buf));
trxrb.write_advance(pad);
REQ(trx_xmit_wfall_draw, samplerate);
}
// Copy buf to the ringbuffer if it has enough space. Queue a waterfall
// request whenever there are at least WFBLOCKSIZE samples to draw.
void trx_xmit_wfall_queue(int samplerate, const double* buf, size_t len)
{
ENSURE_THREAD(TRX_TID);
ringbuffer<double>::vector_type wv[2];
trxrb.get_wv(wv, len);
if (unlikely(wv[0].len + wv[1].len < len)) // not enough space
return;
#define write_(vec_, len_) \
for (size_t i = 0; i < len_; i++) \
vec_[i] = buf[i] * progdefaults.TxMonitorLevel;
size_t n = MIN(wv[0].len, len);
write_(wv[0].buf, n);
if (len > n) { // write the rest to the second vector
buf += n;
n = len - n;
write_(wv[1].buf, n);
}
#undef write_
trxrb.write_advance(len);
if (trxrb.read_space() >= WFBLOCKSIZE)
REQ(trx_xmit_wfall_draw, samplerate);
}
//=============================================================================
void trx_trx_receive_loop()
{
size_t numread;
@ -143,6 +236,8 @@ void trx_trx_receive_loop()
}
active_modem->rx_init();
ringbuffer<double>::vector_type rbvec[2];
while (1) {
//New stuff added by jcoxon
if (status_count >= 1000) {
@ -294,6 +389,8 @@ void trx_trx_transmit_loop()
}
}
trx_xmit_wfall_end(current_samplerate);
if (progdefaults.TransmitRSid)
ReedSolomon->send(false);
@ -371,6 +468,8 @@ void *trx_loop(void *args)
for (;;) {
if (unlikely(old_state != trx_state)) {
old_state = trx_state;
if (trx_state == STATE_TX || trx_state == STATE_TUNE)
trxrb.reset();
trx_signal_state();
}
switch (trx_state) {

Wyświetl plik

@ -108,8 +108,8 @@ Fl_Menu_Item FTextRX::menu[] = {
{ make_icon_label(_("Country"), enter_key_icon), 0, 0, 0, 0, _FL_MULTI_LABEL },
{ make_icon_label(_("Locator"), enter_key_icon), 0, 0, 0, 0, _FL_MULTI_LABEL },
{ make_icon_label(_("RST(r)"), enter_key_icon), 0, 0, 0, FL_MENU_DIVIDER, _FL_MULTI_LABEL },
{ make_icon_label(_("Serial number"), enter_key_icon), 0, 0, 0, 0, _FL_MULTI_LABEL },
{ make_icon_label(_("Exchange In"), enter_key_icon), 0, 0, 0, FL_MENU_DIVIDER, _FL_MULTI_LABEL },
{ make_icon_label(_("Exchange In"), enter_key_icon), 0, 0, 0, 0, _FL_MULTI_LABEL },
{ make_icon_label(_("Serial number"), enter_key_icon), 0, 0, 0, FL_MENU_DIVIDER, _FL_MULTI_LABEL },
{ make_icon_label(_("Insert marker"), insert_link_icon), 0, 0, 0, 0, _FL_MULTI_LABEL },
{ 0 }, // VIEW_MENU_COPY