From 6304d7d99227c19b9acee5a7d63957c3c9373d2c Mon Sep 17 00:00:00 2001 From: Christoph Berg Date: Tue, 10 Sep 2024 10:37:24 +0200 Subject: [PATCH] Allow setting CW speed liberally in range 6..60 wpm (#437) The old coding had a fixed list of allowed CW speeds that were stepped through using PgDn/PgUp. While this might make sense for different step sizes (for example 2 wpm between 12 and 30, and 5 wpm above 30), it was not used as such. All steps were 2 wpm, and jumps from 12 to 6 and 50 to 60 at the very ends of the scale. For slow speed contest training, it does make sense to allow speeds between 6 and 12 wpm. Also, since Hamlib keying was implemented, it's now very easy to set the speed directly in the rig, and tlf's forcing of the speed to match the old raster just got in the way. Drop the whole idea of a list of permitted CW speeds in tlf, and allow any integer between 6 and 60 wpm. PgDn/PgUp will tune up/down in 2wpm steps. If Hamlib keying is used, and the rig exposes the range of supported wpm values, additionally honor that. (The IC-7610 does, but rigctld does not.) Since "speed" is now the plain wpm value as an integer, clean up the code and remove all occurrences of GetCWSpeed() and SetCWSpeed() to directly reference the variable. (Especially the latter was easy to mix up with setspeed() which actually *sets* the rig speed, while SetCWSpeed was just a fat setter function for the internal variable.) Drop the test code around the speed list handling since there's nothing to test anymore. --- src/autocq.c | 2 +- src/callinput.c | 14 ++--- src/clear_display.c | 2 +- src/cw_utils.c | 132 +-------------------------------------- src/cw_utils.h | 5 -- src/gettxinfo.c | 7 +-- src/globalvars.h | 1 + src/hamlib_keyer.c | 12 +++- src/hamlib_keyer.h | 2 +- src/keyer.c | 6 +- src/main.c | 2 +- src/parse_logcfg.c | 5 +- src/qtcwin.c | 4 +- src/sendqrg.c | 3 +- src/speedupndown.c | 39 ++++++------ src/speedupndown.h | 4 ++ test/data.c | 2 +- test/test_cabrillo.c | 2 +- test/test_cw_utils.c | 41 ------------ test/test_getexchange.c | 1 - test/test_parse_logcfg.c | 7 +-- test/test_readcalls.c | 3 +- 22 files changed, 63 insertions(+), 233 deletions(-) delete mode 100644 test/test_cw_utils.c diff --git a/src/autocq.c b/src/autocq.c index 0daafa989..369b2871c 100644 --- a/src/autocq.c +++ b/src/autocq.c @@ -48,7 +48,7 @@ static int get_autocq_time() { return 0; // unknown } const int cw_message_len = cw_message_length(message[11]); - return (int)(1200.0 / GetCWSpeed()) * cw_message_len; + return (int)(1200.0 / speed) * cw_message_len; } #define NO_KEY -1 diff --git a/src/callinput.c b/src/callinput.c index 9d489b18b..1a7a4cd5a 100644 --- a/src/callinput.c +++ b/src/callinput.c @@ -339,7 +339,7 @@ int callinput(void) { while (x != ESCAPE) { nicebox(1, 1, 2, 12, "Cw"); attron(COLOR_PAIR(C_LOG) | A_STANDOUT); - mvprintw(2, 2, "Speed: %2u ", GetCWSpeed()); + mvprintw(2, 2, "Speed: %2u ", speed); mvprintw(3, 2, "Weight: %3d ", weight); printcall(); refreshp(); @@ -349,12 +349,12 @@ int callinput(void) { speedup(); attron(COLOR_PAIR(C_HEADER) | A_STANDOUT); - mvprintw(0, 14, "%2u", GetCWSpeed()); + mvprintw(0, 14, "%2u", speed); } else if (x == KEY_DOWN) { speeddown(); attron(COLOR_PAIR(C_HEADER) | A_STANDOUT); - mvprintw(0, 14, "%2u", GetCWSpeed()); + mvprintw(0, 14, "%2u", speed); } else x = ESCAPE; @@ -931,10 +931,10 @@ int autosend() { strcpy(hiscall_sent, current_qso.call); char_sent = 0; /* no char sent so far */ - timeout_sent = (1.2 / GetCWSpeed()) * getCWdots(current_qso.call[char_sent]); + timeout_sent = (1.2 / speed) * getCWdots(current_qso.call[char_sent]); timer = g_timer_new(); - timeout = (1.2 / GetCWSpeed()) * cw_message_length(current_qso.call); + timeout = (1.2 / speed) * cw_message_length(current_qso.call); x = -1; while ((x != ESCAPE) && (x != '\n' && x != KEY_ENTER)) { @@ -949,7 +949,7 @@ int autosend() { /* one char sent - display and set new timeout */ char_sent ++; timeout_sent += - (1.2 / GetCWSpeed()) * getCWdots(current_qso.call[char_sent]); + (1.2 / speed) * getCWdots(current_qso.call[char_sent]); } @@ -994,7 +994,7 @@ int autosend() { sendmessage(append); /* add char length to timeout */ - timeout += (1.2 / GetCWSpeed()) * getCWdots((char) x); + timeout += (1.2 / speed) * getCWdots((char) x); len = strlen(hiscall_sent); hiscall_sent[len] = x; diff --git a/src/clear_display.c b/src/clear_display.c index e413672bd..0de38cab0 100644 --- a/src/clear_display.c +++ b/src/clear_display.c @@ -133,7 +133,7 @@ void show_header_line() { attron(COLOR_PAIR(C_HEADER) | A_STANDOUT); mvaddstr(0, 0, spaces(29)); - mvprintw(0, 0, " %-8s S=%2i D=%i ", mode, GetCWSpeed(), cqdelay); + mvprintw(0, 0, " %-8s S=%2i D=%i ", mode, speed, cqdelay); mvaddstr(0, 21, fkey_header); } diff --git a/src/cw_utils.c b/src/cw_utils.c index fed66cd22..f0b8240e6 100644 --- a/src/cw_utils.c +++ b/src/cw_utils.c @@ -23,137 +23,7 @@ #include -// *INDENT-OFF* - -#define CW_SPEEDS "06121416182022242628303234363840424446485060" - /*< speed string with 2 chars each (in WPM) */ - -// *INDENT-ON* - -char speedstr[50] = CW_SPEEDS; -int speed = 10; - - -/* converts cw speed in wpm to an numbered index into speedstr table */ -int speed_conversion(int cwspeed) { - - int x; - - switch (cwspeed) { - - case 0 ... 6: { - x = 0; - break; - } - case 7 ... 12: { - x = 1; - break; - } - case 13 ... 14: { - x = 2; - break; - } - case 15 ... 16: { - x = 3; - break; - } - case 17 ... 18: { - x = 4; - break; - } - case 19 ... 20: { - x = 5; - break; - } - case 21 ... 22: { - x = 6; - break; - } - case 23 ... 24: { - x = 7; - break; - } - case 25 ... 26: { - x = 8; - break; - } - case 27 ... 28: { - x = 9; - break; - } - case 29 ... 30: { - x = 10; - break; - } - case 31 ... 32: { - x = 11; - break; - } - case 33 ... 34: { - x = 12; - break; - } - case 35 ... 36: { - x = 13; - break; - } - case 37 ... 38: { - x = 14; - break; - } - case 39 ... 40: { - x = 15; - break; - } - case 41 ... 42: { - x = 16; - break; - } - case 43 ... 44: { - x = 17; - break; - } - case 45 ... 46: { - x = 18; - break; - } - case 47 ... 48: { - x = 19; - break; - } - default: { - x = 20; - break; - } - } - - return (x); -} - - -/** Set CW speed - * - * Set CW speed to the nearest supported value. Converts it into an index into - * the speed table and stores that. - * \param wpm The CW speed in WPM - */ -void SetCWSpeed(unsigned int wpm) { - speed = speed_conversion(wpm); -} - - -/* Get CW speed - * - * Return the actual CW speed in WPM as integer - * \return The CW speed in WPM - */ -unsigned int GetCWSpeed() { - char buff[3]; - - g_strlcpy(buff, speedstr + (2 * speed), 3); - return (atoi(buff)); -} - +int speed = 20; /** get length of CW characters * diff --git a/src/cw_utils.h b/src/cw_utils.h index f0276daac..714d4a610 100644 --- a/src/cw_utils.h +++ b/src/cw_utils.h @@ -21,11 +21,6 @@ #ifndef CW_UTILS_H #define CW_UTILS_H -extern int speed; - -void SetCWSpeed(unsigned int wpm); -unsigned int GetCWSpeed(); - unsigned int getCWdots(char ch); unsigned int cw_message_length(char *message); diff --git a/src/gettxinfo.c b/src/gettxinfo.c index e616b1c9e..6bdf49f45 100644 --- a/src/gettxinfo.c +++ b/src/gettxinfo.c @@ -212,12 +212,11 @@ void gettxinfo(void) { retval = hamlib_keyer_get_speed(&rig_cwspeed); if (retval == RIG_OK) { - if (GetCWSpeed() != - rig_cwspeed) { // FIXME: doesn't work if rig speed is between the values from CW_SPEEDS - SetCWSpeed(rig_cwspeed); + if (speed != rig_cwspeed) { + speed = rig_cwspeed; attron(COLOR_PAIR(C_HEADER) | A_STANDOUT); - mvprintw(0, 14, "%2u", GetCWSpeed()); + mvprintw(0, 14, "%2u", speed); } } else { TLF_LOG_WARN("Problem with rig link: %s", rigerror(retval)); diff --git a/src/globalvars.h b/src/globalvars.h index 5955b71ca..6ca9b2d9d 100644 --- a/src/globalvars.h +++ b/src/globalvars.h @@ -130,6 +130,7 @@ extern int minitest; // minitest period length in seconds, 0 if not used extern int portnum; extern int lan_port; extern int txdelay; +extern int speed; /* CW speed in wpm */ extern int weight; extern int cw_bandwidth; extern int cwpoints; diff --git a/src/hamlib_keyer.c b/src/hamlib_keyer.c index 3552c11e9..69ddc2a7d 100644 --- a/src/hamlib_keyer.c +++ b/src/hamlib_keyer.c @@ -24,9 +24,17 @@ #include "sendqrg.h" #include "hamlib_keyer.h" -int hamlib_keyer_set_speed(int cwspeed) { +int hamlib_keyer_set_speed(int *cwspeed) { + gran_t keyspd_gran = my_rig->caps->level_gran[rig_setting2idx( + RIG_LEVEL_KEYSPD)]; value_t spd; - spd.i = cwspeed; + + /* if rig declared min/max speed, honor it. */ + if (keyspd_gran.min.i > 0 && *cwspeed < keyspd_gran.min.i) + *cwspeed = keyspd_gran.min.i; + if (keyspd_gran.max.i > 0 && *cwspeed > keyspd_gran.max.i) + *cwspeed = keyspd_gran.max.i; + spd.i = *cwspeed; pthread_mutex_lock(&tlf_rig_mutex); int ret = rig_set_level(my_rig, RIG_VFO_CURR, RIG_LEVEL_KEYSPD, spd); diff --git a/src/hamlib_keyer.h b/src/hamlib_keyer.h index cd9213627..a896c3052 100644 --- a/src/hamlib_keyer.h +++ b/src/hamlib_keyer.h @@ -17,7 +17,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -int hamlib_keyer_set_speed(int cwspeed); +int hamlib_keyer_set_speed(int *cwspeed); int hamlib_keyer_get_speed(int *cwspeed); int hamlib_keyer_send(char *cwmessage); int hamlib_keyer_stop(); diff --git a/src/keyer.c b/src/keyer.c index fc4d987a3..3d9a27ed1 100644 --- a/src/keyer.c +++ b/src/keyer.c @@ -157,7 +157,7 @@ int handle_common_key(int key) { speedup(); attron(COLOR_PAIR(C_HEADER) | A_STANDOUT); - mvprintw(0, 14, "%2u", GetCWSpeed()); + mvprintw(0, 14, "%2u", speed); } break; @@ -190,7 +190,7 @@ int handle_common_key(int key) { speeddown(); attron(COLOR_PAIR(C_HEADER) | A_STANDOUT); - mvprintw(0, 14, "%2u", GetCWSpeed()); + mvprintw(0, 14, "%2u", speed); } break; } @@ -204,7 +204,7 @@ int handle_common_key(int key) { nicebox(1, 1, 2, 12, "CW"); attron(COLOR_PAIR(C_LOG) | A_STANDOUT); - mvprintw(2, 2, "Speed: %2u ", GetCWSpeed()); + mvprintw(2, 2, "Speed: %2u ", speed); mvprintw(3, 2, "Weight: %3d ", weight); move(3, 10); refreshp(); diff --git a/src/main.c b/src/main.c index e632602c2..e92cbb614 100644 --- a/src/main.c +++ b/src/main.c @@ -853,7 +853,7 @@ static void keyer_init() { write_tone(); - snprintf(keyerbuff, 3, "%2u", GetCWSpeed()); + snprintf(keyerbuff, 3, "%2u", speed); netkeyer(K_SPEED, keyerbuff); // set speed netkeyer(K_WEIGHT, weightbuf); // set weight diff --git a/src/parse_logcfg.c b/src/parse_logcfg.c index c734df3b1..d074c06ea 100644 --- a/src/parse_logcfg.c +++ b/src/parse_logcfg.c @@ -48,6 +48,7 @@ #include "qtcvars.h" // Includes globalvars.h #include "setcontest.h" #include "set_tone.h" +#include "speedupndown.h" #include "startmsg.h" #include "tlf_curses.h" #include "searchlog.h" @@ -543,11 +544,11 @@ static int cfg_bandmap(const cfg_arg_t arg) { static int cfg_cwspeed(const cfg_arg_t arg) { int value = 0; /* avoid warning about uninitialized variables */ - int rc = cfg_integer((cfg_arg_t) {.int_p = &value, .min = 6, .max = 60}); + int rc = cfg_integer((cfg_arg_t) {.int_p = &value, .min = CW_SPEED_MIN, .max = CW_SPEED_MAX}); if (rc != PARSE_OK) { return rc; } - SetCWSpeed(value); + speed = value; return PARSE_OK; } diff --git a/src/qtcwin.c b/src/qtcwin.c index 6d793e257..a773eb778 100644 --- a/src/qtcwin.c +++ b/src/qtcwin.c @@ -1083,14 +1083,14 @@ void qtc_main_panel(int direction) { case KEY_PPAGE: speedup(); attron(COLOR_PAIR(C_HEADER) | A_STANDOUT); - mvprintw(0, 14, "%2u", GetCWSpeed()); + mvprintw(0, 14, "%2u", speed); break; // case KEY_NPAGE: speeddown(); attron(COLOR_PAIR(C_HEADER) | A_STANDOUT); - mvprintw(0, 14, "%2u", GetCWSpeed()); + mvprintw(0, 14, "%2u", speed); break; // Comma or Ctrl-K (^K), keyboard window diff --git a/src/sendqrg.c b/src/sendqrg.c index 96543b28d..f0784213a 100644 --- a/src/sendqrg.c +++ b/src/sendqrg.c @@ -170,11 +170,12 @@ int init_tlf_rig(void) { shownr("Freq =", (int) rigfreq); if (cwkeyer == HAMLIB_KEYER) { + retcode = hamlib_keyer_get_speed(&rig_cwspeed); /* read cw speed from rig */ if (retcode == RIG_OK) { shownr("CW speed = ", rig_cwspeed); - SetCWSpeed(rig_cwspeed); + speed = rig_cwspeed; } else { TLF_LOG_WARN("Could not read CW speed from rig: %s", rigerror(retcode)); if (!debugflag) diff --git a/src/speedupndown.c b/src/speedupndown.c index 74338ff88..184b8d432 100644 --- a/src/speedupndown.c +++ b/src/speedupndown.c @@ -32,15 +32,18 @@ #include "hamlib_keyer.h" #include "netkeyer.h" #include "sendbuf.h" +#include "speedupndown.h" #include "tlf.h" #include "tlf_curses.h" -void setspeed(void) { +static int setspeed(int cwspeed) { int retval = 0; char buff[3]; - int cwspeed = GetCWSpeed(); + + if (cwspeed < CW_SPEED_MIN || cwspeed > CW_SPEED_MAX) + return speed; snprintf(buff, 3, "%2u", cwspeed); @@ -48,7 +51,9 @@ void setspeed(void) { retval = netkeyer(K_SPEED, buff); - if (retval < 0) { + if (retval >= 0) { + speed = cwspeed; + } else { TLF_LOG_WARN("keyer not active"); // trxmode = SSBMODE; clear_display(); @@ -57,9 +62,11 @@ void setspeed(void) { if (cwkeyer == HAMLIB_KEYER) { - retval = hamlib_keyer_set_speed(cwspeed); + retval = hamlib_keyer_set_speed(&cwspeed); /* sets new cwspeed on success */ - if (retval < 0) { + if (retval >= 0) { + speed = cwspeed; + } else { TLF_LOG_WARN("Could not set CW speed: %s", rigerror(retval)); clear_display(); } @@ -78,7 +85,11 @@ void setspeed(void) { usleep(500000); sendmessage("CONV\015\n"); + + speed = cwspeed; } + + return speed; } /* ------------------------------------------------------------ @@ -90,14 +101,7 @@ int speedup(void) { if (trxmode != CWMODE) return (0); - if (speed < 20) { - - speed++; - setspeed(); - - } - - return (speed); + return setspeed(speed + CW_SPEED_STEP); } @@ -110,14 +114,7 @@ int speeddown(void) { if (trxmode != CWMODE) /* bail out, this is an SSB contest */ return (0); - if (speed >= 1) { - - speed--; - setspeed(); - - } - - return (speed); + return setspeed(speed - CW_SPEED_STEP); } diff --git a/src/speedupndown.h b/src/speedupndown.h index f71cbd4e9..1890949e0 100644 --- a/src/speedupndown.h +++ b/src/speedupndown.h @@ -22,6 +22,10 @@ #ifndef SPEEDUPNDOWN_H #define SPEEDUPNDOWN_H +#define CW_SPEED_MIN 6 +#define CW_SPEED_MAX 60 +#define CW_SPEED_STEP 2 /* up/down 2 wpm */ + int speedup(void); int speeddown(void); int setweight(int weight); diff --git a/test/data.c b/test/data.c index 28a0c9761..e5c86d32b 100644 --- a/test/data.c +++ b/test/data.c @@ -149,7 +149,7 @@ cqmode_t cqmode = CQ; bool demode = false; /* send DE before s&p call */ int announcefilter = FILTER_ANN; /* filter cluster announcements */ bool showscore_flag = false; /* show score window */ -int change_rst = 0; +bool change_rst = 0; int defer_store = 0; mystation_t my; char logfile[120] = "general.log"; diff --git a/test/test_cabrillo.c b/test/test_cabrillo.c index 84dcd0ba1..8be1e11ac 100644 --- a/test/test_cabrillo.c +++ b/test/test_cabrillo.c @@ -28,7 +28,7 @@ void store_qso(const char *file, char *logline) { } void cleanup_qso() { } void make_qtc_logline(struct read_qtc_t qtc_line, char *fname) { } char *getgrid(char *comment) { return comment; } -void checkexchange(int x) { } +void checkexchange(struct qso_t *qso, bool interactive) { } void add_to_keyer_terminal(char *buffer) {} int get_total_score() { diff --git a/test/test_cw_utils.c b/test/test_cw_utils.c deleted file mode 100644 index c5c6bf49b..000000000 --- a/test/test_cw_utils.c +++ /dev/null @@ -1,41 +0,0 @@ -#include "test.h" - -#include "../src/cw_utils.h" - -// OBJECT ../src/cw_utils.o - - -void test_SetSpeed_success(void **state) { - for (int i = 4; i <= 66; ++i) { - speed = -1; - - SetCWSpeed(i); - - int expected = (i - 9) / 2; // for 11..50 - - // special cases: - // - low speeds - if (i <= 6) { - expected = 0; - } else if (i <= 10) { - expected = 1; - } - // - high speeds - if (i > 48) { - expected = 20; - } - - assert_int_equal(speed, expected); - } -} - -void test_GetSpeed(void **state) { - SetCWSpeed(7); - assert_int_equal(GetCWSpeed(), 12); - SetCWSpeed(43); - assert_int_equal(GetCWSpeed(), 44); - SetCWSpeed(60); - assert_int_equal(GetCWSpeed(), 50); -} - - diff --git a/test/test_getexchange.c b/test/test_getexchange.c index 3c1a41a88..022f3736e 100644 --- a/test/test_getexchange.c +++ b/test/test_getexchange.c @@ -50,7 +50,6 @@ void speedup() {} void speeddown() {} void vk_play_file() {} int recall_exchange(void) { return 0; } -int GetCWSpeed(void) { return 0; } int send_lan_message(int opcode, char *message) { return 0; } void clusterinfo(void) {} void clear_display(void) {} diff --git a/test/test_parse_logcfg.c b/test/test_parse_logcfg.c index 21c65240c..9070dbe56 100644 --- a/test/test_parse_logcfg.c +++ b/test/test_parse_logcfg.c @@ -82,10 +82,7 @@ int get_total_score() { void ask(char *buffer, char *what) { } -static int wpm_spy; -void SetCWSpeed(unsigned int wpm) { - wpm_spy = wpm; -} +int speed; static char rst_init_spy[100]; void rst_init(char *init_string) { @@ -1000,7 +997,7 @@ void test_bandmap_d100(void **state) { void test_cwspeed(void **state) { int rc = call_parse_logcfg("CWSPEED= 18 \n"); assert_int_equal(rc, 0); - assert_int_equal(wpm_spy, 18); + assert_int_equal(speed, 18); } void test_cwtone(void **state) { diff --git a/test/test_readcalls.c b/test/test_readcalls.c index f6846a1ea..5ca543680 100644 --- a/test/test_readcalls.c +++ b/test/test_readcalls.c @@ -67,8 +67,7 @@ void stoptx() {} void qtc_main_panel(int direction) {} void add_local_spot() {} void sendmessage(const char *msg) {} -void printcall(const char *msg) {} -unsigned int GetCWSpeed() { return 10; } +void printcall(void) {} int speedup() { return 12; } int speeddown() { return 8; } void rst_recv_up() {}