Read a QTC series out on RTTY
N1MM's Send All: the whole series as one message — the heading, every
line with the operator's spacing between them, then the ending, with
`{TX}` and `{RX}` around it so it keys the transmitter and drops it
again. The shape is N1MM's, from `QTCWindow.cs:3609`. A line is the three
fields joined with hyphens, which is how N1MM writes them, and Snd n
sends one line again for a station that missed it.
One message rather than a button per line because a series is close to a
minute of transmission at 45 baud: the type-ahead buffer holds it and
paces the engine.
Three settings with N1MM's names and defaults — `WAESendAllHeadingText`,
`WAESendAllEndingText` and `WAESQTCSpacing` — on the QTC window's setup
dialog. `{ENTERLF}` is new to the expander and stands for a carriage
return and a line feed; `{QTC}` is filled in by the window, which is the
only place that knows which series is going out.
The messages are tested as text. Nothing has gone on the air.
Left out: N1MM's four SSB recordings, which need a voice keyer, and its
RTTY messages for the station taking traffic down, which are typed into
the digital window's transmit pane here.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PdAYHcdRktqKry7nk414TU
This commit is contained in:
@@ -113,6 +113,9 @@ public static class MessageExpander
|
||||
// the digital window's carriage return, which starts a new line on
|
||||
// the other station's screen
|
||||
"ENTER" => "\r",
|
||||
// the same with a line feed behind it, which is what N1MM's own
|
||||
// RTTY message defaults are written with
|
||||
"ENTERLF" => "\r\n",
|
||||
_ => null,
|
||||
};
|
||||
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
using System.Text;
|
||||
|
||||
namespace Nonemm.Session;
|
||||
|
||||
/// What a station sends on CW while exchanging QTC traffic, and N1MM's
|
||||
/// defaults for the parts an operator can change.
|
||||
/// What a station sends while exchanging QTC traffic, and N1MM's defaults for
|
||||
/// the parts an operator can change.
|
||||
///
|
||||
/// CW only. N1MM sends recorded voice messages on SSB and its digital window's
|
||||
/// templates on RTTY, and this program has neither.
|
||||
/// CW and RTTY. The two are laid out differently: on CW a line is the three
|
||||
/// fields with the operator's spacing between them and each one is keyed by
|
||||
/// hand, and on RTTY the fields are joined with hyphens and the whole series
|
||||
/// goes out as one message. N1MM plays recordings on SSB, and there is no voice
|
||||
/// keyer here.
|
||||
public static class QtcMessages
|
||||
{
|
||||
/// The gap between the fields of a QTC line, written the way N1MM writes
|
||||
@@ -28,6 +33,59 @@ public static class QtcMessages
|
||||
/// What the station reading traffic out asks before it starts.
|
||||
public const string AreYouReady = "QRV?";
|
||||
|
||||
/// What goes between the QTC lines on RTTY. N1MM keeps it as a macro rather
|
||||
/// than as characters, so an operator can put a carriage return there,
|
||||
/// which is what its default does.
|
||||
public const string DefaultRttySpacing = "{ENTER}";
|
||||
|
||||
/// What stands in front of the series and what closes it. `{QTC}` stands
|
||||
/// for the header, so the default reads the series out twice for a station
|
||||
/// that missed it the first time.
|
||||
public const string DefaultSendAllHeading = "{ENTERLF}{QTC} {QTC}";
|
||||
|
||||
public const string DefaultSendAllEnding = "{ENTERLF}QSL?? BK DE {MYCALL} K";
|
||||
|
||||
/// One line of traffic on RTTY: the three fields joined with hyphens. N1MM
|
||||
/// writes them this way and offers no setting for it, so neither does this.
|
||||
public static string RttyLine(string time, string call, string number) =>
|
||||
$"{time.Trim()}-{call.Trim()}-{number.Trim()}";
|
||||
|
||||
/// A whole series as one message, which is N1MM's Send All: the heading,
|
||||
/// then every line, then the ending, with `spacing` between them. It keys
|
||||
/// the transmitter itself and drops it at the end, so the operator presses
|
||||
/// one button and the series goes out.
|
||||
///
|
||||
/// The text macros in it are left as they stand — `{ENTER}`, `{MYCALL}` and
|
||||
/// the rest are filled in by the message expander, the same as in a
|
||||
/// function key. `{QTC}` is filled in here, because only this window knows
|
||||
/// which series is going out.
|
||||
///
|
||||
/// A series with no lines in it sends nothing.
|
||||
public static string SendAll(
|
||||
string heading,
|
||||
string ending,
|
||||
string spacing,
|
||||
string header,
|
||||
IReadOnlyList<string> lines)
|
||||
{
|
||||
if (lines.Count == 0)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
StringBuilder text = new();
|
||||
text.Append("{TX}").Append(WithHeader(heading, header)).Append(spacing);
|
||||
foreach (string line in lines)
|
||||
{
|
||||
text.Append(line).Append(' ').Append(spacing);
|
||||
}
|
||||
return text.Append(WithHeader(ending, header)).Append("{RX}").ToString();
|
||||
}
|
||||
|
||||
/// One line of a series on its own, for a station that asks for it again.
|
||||
/// It keys and drops the transmitter the same way Send All does.
|
||||
public static string SendOne(string spacing, string line) =>
|
||||
$"{{TX}}{spacing}{line}{spacing}{{RX}}";
|
||||
|
||||
public static string Spacing(string setting) =>
|
||||
setting.Replace("S", " ", StringComparison.Ordinal);
|
||||
|
||||
@@ -43,6 +101,11 @@ public static class QtcMessages
|
||||
/// The message that ends the exchange, sent whichever way the traffic went.
|
||||
/// `{QTC}` in it stands for the header of the series, so `TU {QTC} 73`
|
||||
/// goes out as `TU QTC 3/10 73`.
|
||||
public static string Tu(string template, string header) =>
|
||||
public static string Tu(string template, string header) => WithHeader(template, header);
|
||||
|
||||
/// `{QTC}` filled in with the header of the series. It is filled in here
|
||||
/// rather than by the message expander because only the QTC window knows
|
||||
/// which series is going out.
|
||||
private static string WithHeader(string template, string header) =>
|
||||
template.Replace("{QTC}", header.Trim().ToUpperInvariant(), StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user