From 042a0c44ed616d5e1792df486c125e8e503bd869 Mon Sep 17 00:00:00 2001 From: BehemothTheKitten Date: Wed, 23 Dec 2020 14:52:32 -0600 Subject: [PATCH] Addded options to transmit steady tones at various frequencies (including 1200/2200Hz) to -x command line argument in Direwolf. This is useful for calibrating FM deviation using a meter, devcal, or manually. See: https://groups.io/g/direwolf/topic/setting_deviation/78633292 Options are: -x a: alternating mark/space tones (original functionality) -x m or -x 1: steady mark tone (e.g. 1200Hz) -x s or -x 2: steady space tone (e.g. 2200Hz) -x p: set PTT only - for RTL-SDR adjustments Scope tested with mark_freq>=300Hz and space_freq<=5000Hz. Returns an error message if mark/space frequencies are set to 0. --- src/direwolf.c | 94 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 76 insertions(+), 18 deletions(-) diff --git a/src/direwolf.c b/src/direwolf.c index 327978e..8855367 100644 --- a/src/direwolf.c +++ b/src/direwolf.c @@ -193,7 +193,6 @@ int main (int argc, char *argv[]) //int eof; int j; char config_file[100]; - int xmit_calibrate_option = 0; int enable_pseudo_terminal = 0; struct digi_config_s digi_config; struct cdigi_config_s cdigi_config; @@ -231,6 +230,8 @@ int main (int argc, char *argv[]) float e_recv_ber = 0.0; /* Receive Bit Error Rate (BER). */ int X_fx25_xmit_enable = 0; /* FX.25 transmit enable. */ + int x_opt = 0; /* "-x N" option for transmitting calibration tones. */ + strlcpy(l_opt_logdir, "", sizeof(l_opt_logdir)); strlcpy(L_opt_logfile, "", sizeof(L_opt_logfile)); strlcpy(P_opt, "", sizeof(P_opt)); @@ -388,7 +389,7 @@ int main (int argc, char *argv[]) /* ':' following option character means arg is required. */ - c = getopt_long(argc, argv, "hP:B:gjJD:U:c:pxr:b:n:d:q:t:ul:L:Sa:E:T:e:X:A", + c = getopt_long(argc, argv, "hP:B:gjJD:U:c:px:r:b:n:d:q:t:ul:L:Sa:E:T:e:X:A", long_options, &option_index); if (c == -1) break; @@ -490,9 +491,22 @@ int main (int argc, char *argv[]) } break; - case 'x': /* -x for transmit calibration tones. */ + case 'x': /* -x N for transmit calibration tones. */ + + switch (*optarg) { + case 'a': x_opt = 1; break; // Alternating tones + case 'm': x_opt = 2; break; // Mark tone + case '1': x_opt = 2; break; // Mark tone alternative + case 's': x_opt = 3; break; // Space tone + case '2': x_opt = 3; break; // Space tone alternative + case 'p': x_opt = 4; break; // Set PTT only + default: + text_color_set(DW_COLOR_ERROR); + dw_printf ("Invalid option for -x. \n"); + exit (EXIT_FAILURE); + break; + } - xmit_calibrate_option = 1; break; case 'r': /* -r audio samples/sec. e.g. 44100 */ @@ -907,30 +921,70 @@ int main (int argc, char *argv[]) xmit_init (&audio_config, d_p_opt); /* - * If -x option specified, transmit alternating tones for transmitter + * If -x N option specified, transmit calibration tones for transmitter * audio level adjustment, up to 1 minute then quit. + * N = a: Alternating mark/space tones + * N = m: (or 1): Mark tone (e.g. 1200Hz) + * N = s: (or 2): Space tone (e.g. 2200Hz) + * N = p: Set PTT only. * TODO: enhance for more than one channel. */ - if (xmit_calibrate_option) { + if (x_opt != 0) { + if (audio_config.achan[0].mark_freq + && audio_config.achan[0].space_freq) { + int max_duration = 60; + int n = audio_config.achan[0].baud * max_duration; + int chan = 0; - int max_duration = 60; /* seconds */ - int n = audio_config.achan[0].baud * max_duration; - int chan = 0; - - text_color_set(DW_COLOR_INFO); - dw_printf ("\nSending transmit calibration tones. Press control-C to terminate.\n"); + text_color_set(DW_COLOR_INFO); + ptt_set(OCTYPE_PTT, chan, 1); - ptt_set (OCTYPE_PTT, chan, 1); - while (n-- > 0) { + switch (x_opt) { + case 1: // Alternating tones: -x a + dw_printf( + "\nSending alternating mark/space calibration tones (%d/%dHz).\nPress control-C to terminate.\n", + audio_config.achan[0].mark_freq, + audio_config.achan[0].space_freq); + while (n-- > 0) { + tone_gen_put_bit(chan, n & 1); + } + break; + case 2: // "Mark" tone: -x m + dw_printf( + "\nSending mark calibration tone (%dHz).\nPress control-C to terminate.\n", + audio_config.achan[0].mark_freq); + while (n-- > 0) { + tone_gen_put_bit(chan, 0); + } + break; + case 3: // "Space" tone: -x s + dw_printf( + "\nSending space calibration tone (%dHz).\nPress control-C to terminate.\n", + audio_config.achan[0].space_freq); + while (n-- > 0) { + tone_gen_put_bit(chan, 1); + } + break; + case 4: // Silence - set PTT only: -x p + dw_printf( + "\nSending silence (Set PTT only).\nPress control-C to terminate.\n"); + sleep(max_duration); + break; + } - tone_gen_put_bit (chan, n & 1); + ptt_set(OCTYPE_PTT, chan, 0); + exit(0); - } - ptt_set (OCTYPE_PTT, chan, 0); - exit (0); + } else { + text_color_set(DW_COLOR_ERROR); + dw_printf( + "\nSpace/mark frequencies not defined. Cannot calibrate using this modem type.\n"); + exit(EXIT_FAILURE); + } } + /* * Initialize the digipeater and IGate functions. */ @@ -1508,6 +1562,10 @@ static void usage (char **argv) dw_printf (" -p Enable pseudo terminal for KISS protocol.\n"); #endif dw_printf (" -x Send Xmit level calibration tones.\n"); + dw_printf (" a a = Alternating mark/space tones.\n"); + dw_printf (" m m (or 1) = Steady mark tone (e.g. 1200Hz).\n"); + dw_printf (" s s (or 2) = Steady space tone (e.g. 2200Hz).\n"); + dw_printf (" p p = Silence (Set PTT only).\n"); dw_printf (" -u Print UTF-8 test string and exit.\n"); dw_printf (" -S Print symbol tables and exit.\n"); dw_printf (" -T fmt Time stamp format for sent and received frames.\n");