feat: offset + CTCSS tone BCD codecs (provisional encodings)

This commit is contained in:
2026-06-14 16:05:48 -04:00
parent 03000708b6
commit 5c597a10b8
2 changed files with 77 additions and 0 deletions
+31
View File
@@ -73,5 +73,36 @@ class TestParseFrames(unittest.TestCase):
self.assertEqual(civ.parse_frames(b""), [])
class TestOffsetCodec(unittest.TestCase):
# PROVISIONAL: 3-byte little-endian BCD in units of 100 Hz.
# Round-trip validated until pinned to a real capture (plan Task 6).
def test_offset_roundtrip(self):
for hz in (600_000, 5_000_000, 1_600_000, 0):
self.assertEqual(civ.bcd_to_offset(civ.offset_to_bcd(hz)), hz)
def test_offset_is_three_bytes(self):
self.assertEqual(len(civ.offset_to_bcd(600_000)), 3)
def test_offset_rejects_negative(self):
with self.assertRaises(ValueError):
civ.offset_to_bcd(-1)
class TestToneCodec(unittest.TestCase):
# ICOM convention: CTCSS tone as 2-byte BCD of tone*10. 131.8 -> "13 18".
def test_tone_to_bcd_known(self):
self.assertEqual(civ.tone_to_bcd(88.5), b"\x08\x85")
self.assertEqual(civ.tone_to_bcd(131.8), b"\x13\x18")
self.assertEqual(civ.tone_to_bcd(100.0), b"\x10\x00")
def test_bcd_to_tone_known(self):
self.assertAlmostEqual(civ.bcd_to_tone(b"\x13\x18"), 131.8)
self.assertAlmostEqual(civ.bcd_to_tone(b"\x08\x85"), 88.5)
def test_tone_roundtrip(self):
for hz in (67.0, 88.5, 131.8, 146.2, 203.5):
self.assertAlmostEqual(civ.bcd_to_tone(civ.tone_to_bcd(hz)), hz)
if __name__ == "__main__":
unittest.main()