@springfield/ham-radio-utils 4.7.0 → 4.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-map-channels.d.ts","sourceRoot":"","sources":["../../src/memory/memory-map-channels.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,iBAAiB,EACtB,KAAK,cAAc,EAEnB,KAAK,YAAY,EACjB,KAAK,sBAAsB,EAC3B,KAAK,aAAa,EAInB,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"memory-map-channels.d.ts","sourceRoot":"","sources":["../../src/memory/memory-map-channels.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,iBAAiB,EACtB,KAAK,cAAc,EAEnB,KAAK,YAAY,EACjB,KAAK,sBAAsB,EAC3B,KAAK,aAAa,EAInB,MAAM,4BAA4B,CAAC;AAoJpC;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,cAAc,EACzB,QAAQ,EAAE,aAAa,GACtB,sBAAsB,EAAE,CAsG1B;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,cAAc,EAAE,QAAQ,EAAE,aAAa,GAAG,aAAa,CAmBzG;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,cAAc,EAAE,OAAO,EAAE,YAAY,GAAG,aAAa,CA8JxG;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,cAAc,EACzB,QAAQ,EAAE,UAAU,EACpB,YAAY,EAAE,iBAAiB,GAC9B,YAAY,CAOd;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,cAAc,EACzB,OAAO,EAAE,YAAY,EACrB,QAAQ,EAAE,UAAU,EACpB,YAAY,EAAE,iBAAiB,GAC9B,UAAU,CAGZ"}
|
|
@@ -82,6 +82,25 @@ function kenwoodUsedFlag(receiveFrequency, transmitFrequency) {
|
|
|
82
82
|
}
|
|
83
83
|
return 2;
|
|
84
84
|
}
|
|
85
|
+
/** TM-D710 chmap band codes: 0=118 MHz, 5=144, 6=200, 7=300, 8=400, 9=800. */
|
|
86
|
+
function kenwoodChmapBand(receiveFrequency) {
|
|
87
|
+
if (receiveFrequency < 136_000_000) {
|
|
88
|
+
return 0;
|
|
89
|
+
}
|
|
90
|
+
if (receiveFrequency < 200_000_000) {
|
|
91
|
+
return 5;
|
|
92
|
+
}
|
|
93
|
+
if (receiveFrequency < 300_000_000) {
|
|
94
|
+
return 6;
|
|
95
|
+
}
|
|
96
|
+
if (receiveFrequency < 400_000_000) {
|
|
97
|
+
return 7;
|
|
98
|
+
}
|
|
99
|
+
if (receiveFrequency < 800_000_000) {
|
|
100
|
+
return 8;
|
|
101
|
+
}
|
|
102
|
+
return 9;
|
|
103
|
+
}
|
|
85
104
|
function asRecord(value) {
|
|
86
105
|
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
87
106
|
return undefined;
|
|
@@ -307,11 +326,15 @@ export function programToChannelSettings(memoryMap, program) {
|
|
|
307
326
|
record[nameField] = channel.name ?? '';
|
|
308
327
|
}
|
|
309
328
|
if (extrasStruct) {
|
|
310
|
-
|
|
329
|
+
const extraRecord = {
|
|
311
330
|
used: kenwoodUsedFlag(receiveFrequency, transmitFrequency),
|
|
312
331
|
lockout: channelSettings.skip === 'S' || channelSettings.lockout === true,
|
|
313
332
|
group: typeof channelSettings.group === 'number' ? channelSettings.group : 0,
|
|
314
333
|
};
|
|
334
|
+
if (structHasField(extrasStruct, 'band')) {
|
|
335
|
+
extraRecord.band = typeof channelSettings.band === 'number' ? channelSettings.band : kenwoodChmapBand(receiveFrequency);
|
|
336
|
+
}
|
|
337
|
+
extras[index] = extraRecord;
|
|
315
338
|
}
|
|
316
339
|
}
|
|
317
340
|
const bag = { ...program.settings, [bindings.records]: records };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-map-channels.js","sourceRoot":"","sources":["../../src/memory/memory-map-channels.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Frequency,\n type RadioChannel,\n type RadioMemoryConfig,\n type RadioMemoryMap,\n type RadioMemoryMapToneValue,\n type RadioProgram,\n type RadioProgrammedChannel,\n type RadioSettings,\n type RadioSettingValue,\n type RadioTone,\n RadioToneType,\n} from '@springfield/ham-radio-api';\nimport { decodeMemoryMap, encodeMemoryMap } from './memory-map-codec.js';\n\nfunction isToneValue(value: RadioSettingValue | undefined): value is RadioMemoryMapToneValue {\n return Boolean(value && typeof value === 'object' && !Array.isArray(value) && 'mode' in value);\n}\n\nfunction toneToRadioTone(value: RadioSettingValue | undefined): RadioTone {\n if (!isToneValue(value) || value.mode === 'none') {\n return { tone: 0, type: RadioToneType.CTCSS };\n }\n\n if (value.mode === 'ctcss') {\n return { tone: value.value, type: RadioToneType.CTCSS };\n }\n\n return { tone: value.code, type: RadioToneType.DCS };\n}\n\nfunction radioToneToMapTone(tone: RadioTone | undefined): RadioMemoryMapToneValue {\n if (!tone || !tone.tone) {\n return { mode: 'none' };\n }\n\n if (tone.type === RadioToneType.DCS) {\n return { mode: 'dcs', code: Number(tone.tone), polarity: 'N' };\n }\n\n return { mode: 'ctcss', value: Number(tone.tone) };\n}\n\nfunction noneTone(): RadioTone {\n return { tone: 0, type: RadioToneType.CTCSS };\n}\n\nfunction isNoneTone(tone: RadioTone | undefined): boolean {\n return !tone || !tone.tone;\n}\n\nfunction structHasField(struct: { fields: { id: string }[] } | undefined, fieldId: string): boolean {\n return Boolean(struct?.fields.some((field) => field.id === fieldId));\n}\n\nfunction transmitFrequencyFromRecord(record: Record<string, RadioSettingValue>, bindings: NonNullable<RadioMemoryMap['channelBindings']>): number {\n const receiveFrequency = Number(record[bindings.receiveFrequency] ?? 0);\n const offsetOrTransmit = Number(record[bindings.transmitFrequency] ?? 0);\n\n if (record.split === true) {\n return offsetOrTransmit;\n }\n\n if (record.duplex === '+') {\n return receiveFrequency + offsetOrTransmit;\n }\n\n if (record.duplex === '-') {\n return receiveFrequency - offsetOrTransmit;\n }\n\n // Kenwood stores simplex as duplex \"\" and offset 0. Empty duplex is not an absolute TX frequency.\n if (record.duplex === '') {\n return receiveFrequency;\n }\n\n if (record.duplex === undefined) {\n return bindings.transmitFrequency === bindings.receiveFrequency ? receiveFrequency : offsetOrTransmit;\n }\n\n return offsetOrTransmit;\n}\n\nfunction applyKenwoodToneMode(\n record: Record<string, RadioSettingValue>,\n bindings: NonNullable<RadioMemoryMap['channelBindings']>,\n): { receiveTone: RadioTone; transmitTone: RadioTone } {\n const hasToneModeBits = 'tone_mode' in record || 'ctcss_mode' in record || 'dtcs_mode' in record;\n\n if (!hasToneModeBits) {\n return {\n receiveTone: toneToRadioTone(record[bindings.receiveTone]),\n transmitTone: toneToRadioTone(record[bindings.transmitTone]),\n };\n }\n\n if (record.tone_mode === true) {\n return { receiveTone: noneTone(), transmitTone: toneToRadioTone(record[bindings.transmitTone]) };\n }\n\n if (record.ctcss_mode === true) {\n const tone = toneToRadioTone(record[bindings.receiveTone]);\n return { receiveTone: tone, transmitTone: tone };\n }\n\n if (record.dtcs_mode === true) {\n const tone = toneToRadioTone(record.dtcs_code);\n return { receiveTone: tone, transmitTone: tone };\n }\n\n return { receiveTone: noneTone(), transmitTone: noneTone() };\n}\n\nfunction kenwoodUsedFlag(receiveFrequency: number, transmitFrequency: number): number {\n const frequency = transmitFrequency || receiveFrequency;\n\n if (frequency < 150_000_000) {\n return 0;\n }\n\n if (frequency < 400_000_000) {\n return 1;\n }\n\n return 2;\n}\n\nfunction asRecord(value: RadioSettingValue | undefined): Record<string, RadioSettingValue> | undefined {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return undefined;\n }\n\n return value as Record<string, RadioSettingValue>;\n}\n\n/**\n * Project decoded memory-map channel structs into RadioProgrammedChannel[].\n */\nexport function bindingsToChannels(\n memoryMap: RadioMemoryMap,\n settings: RadioSettings,\n): RadioProgrammedChannel[] {\n const bindings = memoryMap.channelBindings;\n\n if (!bindings) {\n return [];\n }\n\n const records = settings[bindings.records];\n const names = bindings.names ? settings[bindings.names] : undefined;\n const extras = bindings.extras ? settings[bindings.extras] : undefined;\n const recordItems = Array.isArray(records) ? records : [];\n const nameItems = Array.isArray(names) ? names : [];\n const extraItems = Array.isArray(extras) ? extras : [];\n const nameField = bindings.nameField ?? 'name';\n const boundFieldIds = new Set([\n bindings.receiveFrequency,\n bindings.transmitFrequency,\n bindings.receiveTone,\n bindings.transmitTone,\n nameField,\n ]);\n\n const channels: RadioProgrammedChannel[] = [];\n\n for (let index = 0; index < recordItems.length; index += 1) {\n const record = asRecord(recordItems[index]);\n const extraRecord = asRecord(extraItems[index]);\n\n if (bindings.extras && extraItems.length > 0 && extraRecord === undefined) {\n continue;\n }\n\n if (!record) {\n continue;\n }\n\n const nameRecord = asRecord(nameItems[index]);\n const nameFromTable = typeof nameRecord?.[nameField] === 'string' ? nameRecord[nameField] : '';\n const nameFromRecord = typeof record[nameField] === 'string' ? record[nameField] : '';\n const name = nameFromTable || nameFromRecord;\n\n const receiveFrequency = Number(record[bindings.receiveFrequency] ?? 0);\n const transmitFrequency = transmitFrequencyFromRecord(record, bindings);\n const tones = applyKenwoodToneMode(record, bindings);\n\n const channelSettings: RadioSettings = {};\n\n for (const [fieldId, fieldValue] of Object.entries(record)) {\n if (boundFieldIds.has(fieldId) || fieldId.startsWith('_')) {\n continue;\n }\n\n channelSettings[fieldId] = fieldValue;\n }\n\n if (extraRecord) {\n for (const [fieldId, fieldValue] of Object.entries(extraRecord)) {\n if (fieldId.startsWith('_') || fieldId === 'used') {\n continue;\n }\n\n channelSettings[fieldId] = fieldValue;\n }\n\n if (typeof extraRecord.lockout === 'boolean') {\n channelSettings.skip = extraRecord.lockout ? 'S' : '';\n }\n }\n\n // Map Chirp lowpower index onto legacy transmitPower watts for UV-5R UI compatibility.\n if (typeof channelSettings.lowpower === 'number') {\n channelSettings.transmitPower = channelSettings.lowpower === 0 ? 5 : 1;\n }\n\n if (typeof channelSettings.wide === 'boolean') {\n channelSettings.mode = channelSettings.wide ? 'FM' : 'NFM';\n }\n\n if (typeof channelSettings.scan === 'boolean') {\n channelSettings.skip = channelSettings.scan ? '' : 'S';\n }\n\n if (typeof channelSettings.skip === 'boolean') {\n channelSettings.skip = channelSettings.skip ? 'S' : '';\n }\n\n const radioChannel: RadioChannel = {\n name,\n receiveFrequency: Frequency(receiveFrequency),\n transmitFrequency: Frequency(transmitFrequency),\n receiveTone: tones.receiveTone,\n transmitTone: tones.transmitTone,\n };\n\n channels.push({\n channelNumber: index,\n radioChannel,\n settings: Object.keys(channelSettings).length > 0 ? channelSettings : undefined,\n });\n }\n\n return channels;\n}\n\n/**\n * Strip channel-bound structs from decoded settings so RadioProgram.settings\n * only contains radio-wide settings.\n */\nexport function settingsWithoutChannels(memoryMap: RadioMemoryMap, settings: RadioSettings): RadioSettings {\n const bindings = memoryMap.channelBindings;\n\n if (!bindings) {\n return settings;\n }\n\n const next: RadioSettings = { ...settings };\n delete next[bindings.records];\n\n if (bindings.names) {\n delete next[bindings.names];\n }\n\n if (bindings.extras) {\n delete next[bindings.extras];\n }\n\n return next;\n}\n\n/**\n * Merge RadioProgram channels back into a memory-map settings bag for encode.\n */\nexport function programToChannelSettings(memoryMap: RadioMemoryMap, program: RadioProgram): RadioSettings {\n const bindings = memoryMap.channelBindings;\n\n if (!bindings) {\n return program.settings;\n }\n\n const recordsStruct = memoryMap.structs.find((struct) => struct.id === bindings.records);\n const namesStruct = bindings.names ? memoryMap.structs.find((struct) => struct.id === bindings.names) : undefined;\n const extrasStruct = bindings.extras ? memoryMap.structs.find((struct) => struct.id === bindings.extras) : undefined;\n const count = recordsStruct?.count ?? 0;\n const nameField = bindings.nameField ?? 'name';\n\n const records: RadioSettingValue[] = Array.from({ length: count }, () => null);\n const names: RadioSettingValue[] = Array.from({ length: count }, () => null);\n const extras: RadioSettingValue[] = Array.from({ length: count }, () => null);\n\n for (const programmed of program.channels) {\n const index = programmed.channelNumber;\n\n if (index < 0 || index >= count) {\n continue;\n }\n\n if (typeof programmed.radioChannel === 'string') {\n continue;\n }\n\n const channel = programmed.radioChannel;\n const channelSettings = programmed.settings ?? {};\n const receiveFrequency = Number(channel.receiveFrequency);\n const transmitFrequency = Number(channel.transmitFrequency);\n let offset = transmitFrequency;\n let duplex: RadioSettingValue = '';\n let split = false;\n\n if (transmitFrequency === receiveFrequency) {\n offset = 0;\n duplex = '';\n } else if (transmitFrequency > receiveFrequency) {\n offset = transmitFrequency - receiveFrequency;\n duplex = '+';\n } else {\n offset = receiveFrequency - transmitFrequency;\n duplex = '-';\n }\n\n if (channelSettings.split === true) {\n split = true;\n duplex = '';\n offset = transmitFrequency;\n }\n\n const usesOffset =\n 'duplex' in channelSettings || extrasStruct || structHasField(recordsStruct, 'duplex');\n const usesKenwoodToneBits =\n 'tone_mode' in channelSettings ||\n 'ctcss_mode' in channelSettings ||\n extrasStruct ||\n structHasField(recordsStruct, 'tone_mode') ||\n structHasField(recordsStruct, 'ctcss_mode');\n\n const record: Record<string, RadioSettingValue> = {\n [bindings.receiveFrequency]: receiveFrequency,\n [bindings.transmitFrequency]: usesOffset ? offset : transmitFrequency,\n [bindings.receiveTone]: radioToneToMapTone(channel.receiveTone),\n [bindings.transmitTone]: radioToneToMapTone(channel.transmitTone),\n };\n\n if (usesOffset) {\n record.duplex = typeof channelSettings.duplex === 'string' ? channelSettings.duplex : duplex;\n record.split = typeof channelSettings.split === 'boolean' ? channelSettings.split : split;\n record.offset = offset;\n }\n\n if (usesKenwoodToneBits) {\n record.tone_mode = false;\n record.ctcss_mode = false;\n record.dtcs_mode = false;\n record.cross_mode = false;\n\n if (channel.transmitTone?.type === RadioToneType.DCS || channel.receiveTone?.type === RadioToneType.DCS) {\n record.dtcs_mode = true;\n record.dtcs_code = radioToneToMapTone(channel.transmitTone?.type === RadioToneType.DCS ? channel.transmitTone : channel.receiveTone);\n } else if (!isNoneTone(channel.receiveTone) && !isNoneTone(channel.transmitTone)) {\n record.ctcss_mode = true;\n } else if (!isNoneTone(channel.transmitTone)) {\n record.tone_mode = true;\n }\n }\n\n for (const [key, value] of Object.entries(channelSettings)) {\n if (key === 'transmitPower') {\n record.lowpower = value === 5 || value === 4 || value === 0 ? 0 : 1;\n continue;\n }\n\n if (key === 'mode') {\n record.wide = value === 'FM';\n record.mode = value;\n continue;\n }\n\n if (key === 'skip') {\n record.scan = value !== 'S';\n record.skip = value === 'S';\n continue;\n }\n\n record[key] = value;\n }\n\n if (record.lowpower === undefined) {\n record.lowpower = 0;\n }\n\n if (record.wide === undefined) {\n record.wide = true;\n }\n\n if (record.scan === undefined) {\n record.scan = true;\n }\n\n records[index] = record;\n\n if (namesStruct) {\n names[index] = { [nameField]: channel.name ?? '' };\n } else {\n record[nameField] = channel.name ?? '';\n }\n\n if (extrasStruct) {\n extras[index] = {\n used: kenwoodUsedFlag(receiveFrequency, transmitFrequency),\n lockout: channelSettings.skip === 'S' || channelSettings.lockout === true,\n group: typeof channelSettings.group === 'number' ? channelSettings.group : 0,\n };\n }\n }\n\n const bag: RadioSettings = { ...program.settings, [bindings.records]: records };\n\n if (bindings.names && namesStruct) {\n bag[bindings.names] = names;\n }\n\n if (bindings.extras && extrasStruct) {\n bag[bindings.extras] = extras;\n }\n\n return bag;\n}\n\n/**\n * Decode a full RadioProgram (channels + radio-wide settings) from memory.\n */\nexport function decodeRadioProgram(\n memoryMap: RadioMemoryMap,\n contents: Uint8Array,\n memoryConfig: RadioMemoryConfig,\n): RadioProgram {\n const decoded = decodeMemoryMap(memoryMap, contents, memoryConfig);\n\n return {\n channels: bindingsToChannels(memoryMap, decoded),\n settings: settingsWithoutChannels(memoryMap, decoded),\n };\n}\n\n/**\n * Encode a RadioProgram into an existing memory image (patch in place).\n */\nexport function encodeRadioProgram(\n memoryMap: RadioMemoryMap,\n program: RadioProgram,\n contents: Uint8Array,\n memoryConfig: RadioMemoryConfig,\n): Uint8Array {\n const bag = programToChannelSettings(memoryMap, program);\n return encodeMemoryMap(memoryMap, bag, contents, memoryConfig);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"memory-map-channels.js","sourceRoot":"","sources":["../../src/memory/memory-map-channels.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Frequency,\n type RadioChannel,\n type RadioMemoryConfig,\n type RadioMemoryMap,\n type RadioMemoryMapToneValue,\n type RadioProgram,\n type RadioProgrammedChannel,\n type RadioSettings,\n type RadioSettingValue,\n type RadioTone,\n RadioToneType,\n} from '@springfield/ham-radio-api';\nimport { decodeMemoryMap, encodeMemoryMap } from './memory-map-codec.js';\n\nfunction isToneValue(value: RadioSettingValue | undefined): value is RadioMemoryMapToneValue {\n return Boolean(value && typeof value === 'object' && !Array.isArray(value) && 'mode' in value);\n}\n\nfunction toneToRadioTone(value: RadioSettingValue | undefined): RadioTone {\n if (!isToneValue(value) || value.mode === 'none') {\n return { tone: 0, type: RadioToneType.CTCSS };\n }\n\n if (value.mode === 'ctcss') {\n return { tone: value.value, type: RadioToneType.CTCSS };\n }\n\n return { tone: value.code, type: RadioToneType.DCS };\n}\n\nfunction radioToneToMapTone(tone: RadioTone | undefined): RadioMemoryMapToneValue {\n if (!tone || !tone.tone) {\n return { mode: 'none' };\n }\n\n if (tone.type === RadioToneType.DCS) {\n return { mode: 'dcs', code: Number(tone.tone), polarity: 'N' };\n }\n\n return { mode: 'ctcss', value: Number(tone.tone) };\n}\n\nfunction noneTone(): RadioTone {\n return { tone: 0, type: RadioToneType.CTCSS };\n}\n\nfunction isNoneTone(tone: RadioTone | undefined): boolean {\n return !tone || !tone.tone;\n}\n\nfunction structHasField(struct: { fields: { id: string }[] } | undefined, fieldId: string): boolean {\n return Boolean(struct?.fields.some((field) => field.id === fieldId));\n}\n\nfunction transmitFrequencyFromRecord(record: Record<string, RadioSettingValue>, bindings: NonNullable<RadioMemoryMap['channelBindings']>): number {\n const receiveFrequency = Number(record[bindings.receiveFrequency] ?? 0);\n const offsetOrTransmit = Number(record[bindings.transmitFrequency] ?? 0);\n\n if (record.split === true) {\n return offsetOrTransmit;\n }\n\n if (record.duplex === '+') {\n return receiveFrequency + offsetOrTransmit;\n }\n\n if (record.duplex === '-') {\n return receiveFrequency - offsetOrTransmit;\n }\n\n // Kenwood stores simplex as duplex \"\" and offset 0. Empty duplex is not an absolute TX frequency.\n if (record.duplex === '') {\n return receiveFrequency;\n }\n\n if (record.duplex === undefined) {\n return bindings.transmitFrequency === bindings.receiveFrequency ? receiveFrequency : offsetOrTransmit;\n }\n\n return offsetOrTransmit;\n}\n\nfunction applyKenwoodToneMode(\n record: Record<string, RadioSettingValue>,\n bindings: NonNullable<RadioMemoryMap['channelBindings']>,\n): { receiveTone: RadioTone; transmitTone: RadioTone } {\n const hasToneModeBits = 'tone_mode' in record || 'ctcss_mode' in record || 'dtcs_mode' in record;\n\n if (!hasToneModeBits) {\n return {\n receiveTone: toneToRadioTone(record[bindings.receiveTone]),\n transmitTone: toneToRadioTone(record[bindings.transmitTone]),\n };\n }\n\n if (record.tone_mode === true) {\n return { receiveTone: noneTone(), transmitTone: toneToRadioTone(record[bindings.transmitTone]) };\n }\n\n if (record.ctcss_mode === true) {\n const tone = toneToRadioTone(record[bindings.receiveTone]);\n return { receiveTone: tone, transmitTone: tone };\n }\n\n if (record.dtcs_mode === true) {\n const tone = toneToRadioTone(record.dtcs_code);\n return { receiveTone: tone, transmitTone: tone };\n }\n\n return { receiveTone: noneTone(), transmitTone: noneTone() };\n}\n\nfunction kenwoodUsedFlag(receiveFrequency: number, transmitFrequency: number): number {\n const frequency = transmitFrequency || receiveFrequency;\n\n if (frequency < 150_000_000) {\n return 0;\n }\n\n if (frequency < 400_000_000) {\n return 1;\n }\n\n return 2;\n}\n\n/** TM-D710 chmap band codes: 0=118 MHz, 5=144, 6=200, 7=300, 8=400, 9=800. */\nfunction kenwoodChmapBand(receiveFrequency: number): number {\n if (receiveFrequency < 136_000_000) {\n return 0;\n }\n\n if (receiveFrequency < 200_000_000) {\n return 5;\n }\n\n if (receiveFrequency < 300_000_000) {\n return 6;\n }\n\n if (receiveFrequency < 400_000_000) {\n return 7;\n }\n\n if (receiveFrequency < 800_000_000) {\n return 8;\n }\n\n return 9;\n}\n\nfunction asRecord(value: RadioSettingValue | undefined): Record<string, RadioSettingValue> | undefined {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return undefined;\n }\n\n return value as Record<string, RadioSettingValue>;\n}\n\n/**\n * Project decoded memory-map channel structs into RadioProgrammedChannel[].\n */\nexport function bindingsToChannels(\n memoryMap: RadioMemoryMap,\n settings: RadioSettings,\n): RadioProgrammedChannel[] {\n const bindings = memoryMap.channelBindings;\n\n if (!bindings) {\n return [];\n }\n\n const records = settings[bindings.records];\n const names = bindings.names ? settings[bindings.names] : undefined;\n const extras = bindings.extras ? settings[bindings.extras] : undefined;\n const recordItems = Array.isArray(records) ? records : [];\n const nameItems = Array.isArray(names) ? names : [];\n const extraItems = Array.isArray(extras) ? extras : [];\n const nameField = bindings.nameField ?? 'name';\n const boundFieldIds = new Set([\n bindings.receiveFrequency,\n bindings.transmitFrequency,\n bindings.receiveTone,\n bindings.transmitTone,\n nameField,\n ]);\n\n const channels: RadioProgrammedChannel[] = [];\n\n for (let index = 0; index < recordItems.length; index += 1) {\n const record = asRecord(recordItems[index]);\n const extraRecord = asRecord(extraItems[index]);\n\n if (bindings.extras && extraItems.length > 0 && extraRecord === undefined) {\n continue;\n }\n\n if (!record) {\n continue;\n }\n\n const nameRecord = asRecord(nameItems[index]);\n const nameFromTable = typeof nameRecord?.[nameField] === 'string' ? nameRecord[nameField] : '';\n const nameFromRecord = typeof record[nameField] === 'string' ? record[nameField] : '';\n const name = nameFromTable || nameFromRecord;\n\n const receiveFrequency = Number(record[bindings.receiveFrequency] ?? 0);\n const transmitFrequency = transmitFrequencyFromRecord(record, bindings);\n const tones = applyKenwoodToneMode(record, bindings);\n\n const channelSettings: RadioSettings = {};\n\n for (const [fieldId, fieldValue] of Object.entries(record)) {\n if (boundFieldIds.has(fieldId) || fieldId.startsWith('_')) {\n continue;\n }\n\n channelSettings[fieldId] = fieldValue;\n }\n\n if (extraRecord) {\n for (const [fieldId, fieldValue] of Object.entries(extraRecord)) {\n if (fieldId.startsWith('_') || fieldId === 'used') {\n continue;\n }\n\n channelSettings[fieldId] = fieldValue;\n }\n\n if (typeof extraRecord.lockout === 'boolean') {\n channelSettings.skip = extraRecord.lockout ? 'S' : '';\n }\n }\n\n // Map Chirp lowpower index onto legacy transmitPower watts for UV-5R UI compatibility.\n if (typeof channelSettings.lowpower === 'number') {\n channelSettings.transmitPower = channelSettings.lowpower === 0 ? 5 : 1;\n }\n\n if (typeof channelSettings.wide === 'boolean') {\n channelSettings.mode = channelSettings.wide ? 'FM' : 'NFM';\n }\n\n if (typeof channelSettings.scan === 'boolean') {\n channelSettings.skip = channelSettings.scan ? '' : 'S';\n }\n\n if (typeof channelSettings.skip === 'boolean') {\n channelSettings.skip = channelSettings.skip ? 'S' : '';\n }\n\n const radioChannel: RadioChannel = {\n name,\n receiveFrequency: Frequency(receiveFrequency),\n transmitFrequency: Frequency(transmitFrequency),\n receiveTone: tones.receiveTone,\n transmitTone: tones.transmitTone,\n };\n\n channels.push({\n channelNumber: index,\n radioChannel,\n settings: Object.keys(channelSettings).length > 0 ? channelSettings : undefined,\n });\n }\n\n return channels;\n}\n\n/**\n * Strip channel-bound structs from decoded settings so RadioProgram.settings\n * only contains radio-wide settings.\n */\nexport function settingsWithoutChannels(memoryMap: RadioMemoryMap, settings: RadioSettings): RadioSettings {\n const bindings = memoryMap.channelBindings;\n\n if (!bindings) {\n return settings;\n }\n\n const next: RadioSettings = { ...settings };\n delete next[bindings.records];\n\n if (bindings.names) {\n delete next[bindings.names];\n }\n\n if (bindings.extras) {\n delete next[bindings.extras];\n }\n\n return next;\n}\n\n/**\n * Merge RadioProgram channels back into a memory-map settings bag for encode.\n */\nexport function programToChannelSettings(memoryMap: RadioMemoryMap, program: RadioProgram): RadioSettings {\n const bindings = memoryMap.channelBindings;\n\n if (!bindings) {\n return program.settings;\n }\n\n const recordsStruct = memoryMap.structs.find((struct) => struct.id === bindings.records);\n const namesStruct = bindings.names ? memoryMap.structs.find((struct) => struct.id === bindings.names) : undefined;\n const extrasStruct = bindings.extras ? memoryMap.structs.find((struct) => struct.id === bindings.extras) : undefined;\n const count = recordsStruct?.count ?? 0;\n const nameField = bindings.nameField ?? 'name';\n\n const records: RadioSettingValue[] = Array.from({ length: count }, () => null);\n const names: RadioSettingValue[] = Array.from({ length: count }, () => null);\n const extras: RadioSettingValue[] = Array.from({ length: count }, () => null);\n\n for (const programmed of program.channels) {\n const index = programmed.channelNumber;\n\n if (index < 0 || index >= count) {\n continue;\n }\n\n if (typeof programmed.radioChannel === 'string') {\n continue;\n }\n\n const channel = programmed.radioChannel;\n const channelSettings = programmed.settings ?? {};\n const receiveFrequency = Number(channel.receiveFrequency);\n const transmitFrequency = Number(channel.transmitFrequency);\n let offset = transmitFrequency;\n let duplex: RadioSettingValue = '';\n let split = false;\n\n if (transmitFrequency === receiveFrequency) {\n offset = 0;\n duplex = '';\n } else if (transmitFrequency > receiveFrequency) {\n offset = transmitFrequency - receiveFrequency;\n duplex = '+';\n } else {\n offset = receiveFrequency - transmitFrequency;\n duplex = '-';\n }\n\n if (channelSettings.split === true) {\n split = true;\n duplex = '';\n offset = transmitFrequency;\n }\n\n const usesOffset =\n 'duplex' in channelSettings || extrasStruct || structHasField(recordsStruct, 'duplex');\n const usesKenwoodToneBits =\n 'tone_mode' in channelSettings ||\n 'ctcss_mode' in channelSettings ||\n extrasStruct ||\n structHasField(recordsStruct, 'tone_mode') ||\n structHasField(recordsStruct, 'ctcss_mode');\n\n const record: Record<string, RadioSettingValue> = {\n [bindings.receiveFrequency]: receiveFrequency,\n [bindings.transmitFrequency]: usesOffset ? offset : transmitFrequency,\n [bindings.receiveTone]: radioToneToMapTone(channel.receiveTone),\n [bindings.transmitTone]: radioToneToMapTone(channel.transmitTone),\n };\n\n if (usesOffset) {\n record.duplex = typeof channelSettings.duplex === 'string' ? channelSettings.duplex : duplex;\n record.split = typeof channelSettings.split === 'boolean' ? channelSettings.split : split;\n record.offset = offset;\n }\n\n if (usesKenwoodToneBits) {\n record.tone_mode = false;\n record.ctcss_mode = false;\n record.dtcs_mode = false;\n record.cross_mode = false;\n\n if (channel.transmitTone?.type === RadioToneType.DCS || channel.receiveTone?.type === RadioToneType.DCS) {\n record.dtcs_mode = true;\n record.dtcs_code = radioToneToMapTone(channel.transmitTone?.type === RadioToneType.DCS ? channel.transmitTone : channel.receiveTone);\n } else if (!isNoneTone(channel.receiveTone) && !isNoneTone(channel.transmitTone)) {\n record.ctcss_mode = true;\n } else if (!isNoneTone(channel.transmitTone)) {\n record.tone_mode = true;\n }\n }\n\n for (const [key, value] of Object.entries(channelSettings)) {\n if (key === 'transmitPower') {\n record.lowpower = value === 5 || value === 4 || value === 0 ? 0 : 1;\n continue;\n }\n\n if (key === 'mode') {\n record.wide = value === 'FM';\n record.mode = value;\n continue;\n }\n\n if (key === 'skip') {\n record.scan = value !== 'S';\n record.skip = value === 'S';\n continue;\n }\n\n record[key] = value;\n }\n\n if (record.lowpower === undefined) {\n record.lowpower = 0;\n }\n\n if (record.wide === undefined) {\n record.wide = true;\n }\n\n if (record.scan === undefined) {\n record.scan = true;\n }\n\n records[index] = record;\n\n if (namesStruct) {\n names[index] = { [nameField]: channel.name ?? '' };\n } else {\n record[nameField] = channel.name ?? '';\n }\n\n if (extrasStruct) {\n const extraRecord: Record<string, RadioSettingValue> = {\n used: kenwoodUsedFlag(receiveFrequency, transmitFrequency),\n lockout: channelSettings.skip === 'S' || channelSettings.lockout === true,\n group: typeof channelSettings.group === 'number' ? channelSettings.group : 0,\n };\n\n if (structHasField(extrasStruct, 'band')) {\n extraRecord.band = typeof channelSettings.band === 'number' ? channelSettings.band : kenwoodChmapBand(receiveFrequency);\n }\n\n extras[index] = extraRecord;\n }\n }\n\n const bag: RadioSettings = { ...program.settings, [bindings.records]: records };\n\n if (bindings.names && namesStruct) {\n bag[bindings.names] = names;\n }\n\n if (bindings.extras && extrasStruct) {\n bag[bindings.extras] = extras;\n }\n\n return bag;\n}\n\n/**\n * Decode a full RadioProgram (channels + radio-wide settings) from memory.\n */\nexport function decodeRadioProgram(\n memoryMap: RadioMemoryMap,\n contents: Uint8Array,\n memoryConfig: RadioMemoryConfig,\n): RadioProgram {\n const decoded = decodeMemoryMap(memoryMap, contents, memoryConfig);\n\n return {\n channels: bindingsToChannels(memoryMap, decoded),\n settings: settingsWithoutChannels(memoryMap, decoded),\n };\n}\n\n/**\n * Encode a RadioProgram into an existing memory image (patch in place).\n */\nexport function encodeRadioProgram(\n memoryMap: RadioMemoryMap,\n program: RadioProgram,\n contents: Uint8Array,\n memoryConfig: RadioMemoryConfig,\n): Uint8Array {\n const bag = programToChannelSettings(memoryMap, program);\n return encodeMemoryMap(memoryMap, bag, contents, memoryConfig);\n}\n"]}
|
package/package.json
CHANGED
|
@@ -125,6 +125,31 @@ function kenwoodUsedFlag(receiveFrequency: number, transmitFrequency: number): n
|
|
|
125
125
|
return 2;
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
+
/** TM-D710 chmap band codes: 0=118 MHz, 5=144, 6=200, 7=300, 8=400, 9=800. */
|
|
129
|
+
function kenwoodChmapBand(receiveFrequency: number): number {
|
|
130
|
+
if (receiveFrequency < 136_000_000) {
|
|
131
|
+
return 0;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (receiveFrequency < 200_000_000) {
|
|
135
|
+
return 5;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (receiveFrequency < 300_000_000) {
|
|
139
|
+
return 6;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (receiveFrequency < 400_000_000) {
|
|
143
|
+
return 7;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (receiveFrequency < 800_000_000) {
|
|
147
|
+
return 8;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return 9;
|
|
151
|
+
}
|
|
152
|
+
|
|
128
153
|
function asRecord(value: RadioSettingValue | undefined): Record<string, RadioSettingValue> | undefined {
|
|
129
154
|
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
130
155
|
return undefined;
|
|
@@ -404,11 +429,17 @@ export function programToChannelSettings(memoryMap: RadioMemoryMap, program: Rad
|
|
|
404
429
|
}
|
|
405
430
|
|
|
406
431
|
if (extrasStruct) {
|
|
407
|
-
|
|
432
|
+
const extraRecord: Record<string, RadioSettingValue> = {
|
|
408
433
|
used: kenwoodUsedFlag(receiveFrequency, transmitFrequency),
|
|
409
434
|
lockout: channelSettings.skip === 'S' || channelSettings.lockout === true,
|
|
410
435
|
group: typeof channelSettings.group === 'number' ? channelSettings.group : 0,
|
|
411
436
|
};
|
|
437
|
+
|
|
438
|
+
if (structHasField(extrasStruct, 'band')) {
|
|
439
|
+
extraRecord.band = typeof channelSettings.band === 'number' ? channelSettings.band : kenwoodChmapBand(receiveFrequency);
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
extras[index] = extraRecord;
|
|
412
443
|
}
|
|
413
444
|
}
|
|
414
445
|
|