feat: record CW QSOs again
CW was excluded because SmartSDR does not route the operator's own sidetone through DAX, so the recording sounds one-sided. The audio path is open all the same and the other station IS captured — which is the half worth keeping. The frontend had ONE list serving two purposes: which modes may be recorded, and which modes the voice keyer may transmit on. Adding CW to it would have let the DVK key the rig with speech on a CW frequency. They are now two lists: PHONE_MODES for the keyer, RECORDABLE_MODES (phone + CW) for the recorder. Digital modes stay out of both: their audio is a modem tone nobody will replay.
This commit is contained in:
@@ -7107,14 +7107,17 @@ func (a *App) qsoRecDir() string {
|
|||||||
// be e-mailed later), and auto-sends it to the contacted operator when enabled
|
// be e-mailed later), and auto-sends it to the contacted operator when enabled
|
||||||
// and an e-mail is known. Called right after a QSO is inserted (manual + UDP);
|
// and an e-mail is known. Called right after a QSO is inserted (manual + UDP);
|
||||||
// q must have its ID set.
|
// q must have its ID set.
|
||||||
// recordableMode reports whether a QSO mode is worth an audio recording —
|
// recordableMode reports whether a QSO mode is worth an audio recording: voice
|
||||||
// only voice (SSB/AM/FM) and CW. Digital modes (FT8/FT4/RTTY/PSK/JT…) carry no
|
// and CW. Digital modes (FT8/FT4/RTTY/PSK/JT…) carry only modem tones, which
|
||||||
// useful audio, so they are never recorded.
|
// nobody will ever replay, so they are never recorded.
|
||||||
|
//
|
||||||
|
// CW was excluded for a while because SmartSDR does not route the operator's own
|
||||||
|
// sidetone through DAX, making the recording sound one-sided. The audio path is
|
||||||
|
// open all the same and the other station IS captured — which is the half worth
|
||||||
|
// keeping. Operator's call.
|
||||||
func recordableMode(mode string) bool {
|
func recordableMode(mode string) bool {
|
||||||
switch strings.ToUpper(strings.TrimSpace(mode)) {
|
switch strings.ToUpper(strings.TrimSpace(mode)) {
|
||||||
// CW is intentionally excluded: SmartSDR doesn't route CW audio through DAX,
|
case "SSB", "USB", "LSB", "AM", "FM", "DV", "CW":
|
||||||
// so the recording is empty/useless. Phone modes only.
|
|
||||||
case "SSB", "USB", "LSB", "AM", "FM", "DV":
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
|
|||||||
+4
-2
@@ -3,10 +3,12 @@
|
|||||||
"version": "0.22.4",
|
"version": "0.22.4",
|
||||||
"date": "",
|
"date": "",
|
||||||
"en": [
|
"en": [
|
||||||
"FlexRadio: in split, OpsLog stays on the receive slice instead of following the transmitter."
|
"FlexRadio: in split, OpsLog stays on the receive slice instead of following the transmitter.",
|
||||||
|
"QSO recording works on CW again. Your own sidetone is not in the file, the other station is."
|
||||||
],
|
],
|
||||||
"fr": [
|
"fr": [
|
||||||
"FlexRadio : en split, OpsLog reste sur la slice de réception au lieu de suivre l'émission."
|
"FlexRadio : en split, OpsLog reste sur la slice de réception au lieu de suivre l'émission.",
|
||||||
|
"L'enregistrement des QSO fonctionne à nouveau en CW. Votre propre signal d'écoute n'est pas dans le fichier, celui du correspondant l'est."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
+10
-2
@@ -137,7 +137,15 @@ const DEFAULT_MODES = ['SSB','CW','FT8','FT4','RTTY','PSK31','AM','FM','DIGITALV
|
|||||||
// Modes the QSO recorder captures (phone only). Mirrors recordableMode() in
|
// Modes the QSO recorder captures (phone only). Mirrors recordableMode() in
|
||||||
// app.go — digital modes carry no useful audio, and CW has no DAX audio on Flex,
|
// app.go — digital modes carry no useful audio, and CW has no DAX audio on Flex,
|
||||||
// so neither is recorded (no REC badge / timer for them).
|
// so neither is recorded (no REC badge / timer for them).
|
||||||
const RECORDABLE_MODES = new Set(['SSB','USB','LSB','AM','FM','DV']);
|
// Modes a VOICE keyer may transmit on. Not a recording list — the DVK plays
|
||||||
|
// speech, and sending it on CW or a data slot keys the rig with a human voice.
|
||||||
|
const PHONE_MODES = new Set(['SSB','USB','LSB','AM','FM','DV']);
|
||||||
|
|
||||||
|
// Modes worth recording. Phone, plus CW: the audio path stays open in CW, so
|
||||||
|
// the other station's signal is captured. Your own sidetone is not in it —
|
||||||
|
// SmartSDR does not route it through DAX — and that is accepted. Digital modes
|
||||||
|
// stay out: their audio is a modem tone nobody will ever replay.
|
||||||
|
const RECORDABLE_MODES = new Set([...PHONE_MODES, 'CW']);
|
||||||
|
|
||||||
const emptyDetails: DetailsState = {
|
const emptyDetails: DetailsState = {
|
||||||
state: '', cnty: '', address: '',
|
state: '', cnty: '', address: '',
|
||||||
@@ -1233,7 +1241,7 @@ export default function App() {
|
|||||||
useEffect(() => { dvkAutoCqSecsRef.current = dvkAutoCqSecs; localStorage.setItem('opslog.dvkAutoCqSecs', String(dvkAutoCqSecs)); }, [dvkAutoCqSecs]);
|
useEffect(() => { dvkAutoCqSecsRef.current = dvkAutoCqSecs; localStorage.setItem('opslog.dvkAutoCqSecs', String(dvkAutoCqSecs)); }, [dvkAutoCqSecs]);
|
||||||
// The DVK is a VOICE keyer — transmitting it on CW/FT8/RTTY would key the rig
|
// The DVK is a VOICE keyer — transmitting it on CW/FT8/RTTY would key the rig
|
||||||
// with speech on a data slot. Only allow it on phone modes.
|
// with speech on a data slot. Only allow it on phone modes.
|
||||||
const isPhoneMode = (m: string) => RECORDABLE_MODES.has((m || '').toUpperCase());
|
const isPhoneMode = (m: string) => PHONE_MODES.has((m || '').toUpperCase());
|
||||||
const modeRef = useRef(mode);
|
const modeRef = useRef(mode);
|
||||||
useEffect(() => { modeRef.current = mode; }, [mode]);
|
useEffect(() => { modeRef.current = mode; }, [mode]);
|
||||||
function stopDvkAutoCq() { dvkAutoCqSlotRef.current = -1; dvkAutoCqGenRef.current++; }
|
function stopDvkAutoCq() { dvkAutoCqSlotRef.current = -1; dvkAutoCqGenRef.current++; }
|
||||||
|
|||||||
Reference in New Issue
Block a user