AHICDM is a simple digital mode that transmits bits by varying the amount of silence between pulses. It is a narrowband mode that transmits slowly.

I only came across this modulation while looking at the Recently changed pages list of sigidwiki. It looked easy to implement, and didn’t have much written about it, so I decided to play around with the provided audio example.

I have never seen this modulation used in the wild, and the only mention I have seen of it is in the Signal Identification Wiki. This page is written by analyzing the audio recording provided on the wiki page.

Parameters

Name Value
Tone frequency 440 Hz
Tone duration 100 ms / 0.1 sec
Preamble duration 700 ms / 0.7 sec

Baud rate

The baud rate of this modulation depends on the content of the message. A message of all 1 bits will take longer to transmit compared to a message of all 0 bits.

Modulator

Below is a simple modulator written in Python.

#!/usr/bin/env python3
import os
import struct
import numpy as np

class AHICDM_Modulator:
    def __init__(self, freq=440, rate=64_000):
        self.rate = rate
        self.sample = 0
        self.freq = freq
        self.amp = 0
        self.phase = 0

    @property
    def time(self):
        return self.sample / self.rate

    def output_sample(self, sample):
        self.sample += 1
        sample = np.random.normal(sample, 0.01)
        sample += 1
        sample *= 128
        sample = int(sample)
        sample = max(0, min(sample, 255))
        os.write(1, bytes([sample]))

    def amplitude_duration(self, amplitude, duration):
        target = self.time + duration
        while self.time < target:
            self.amp = (self.amp * 0.991) + (amplitude * 0.009)
            self.phase += 2 * np.pi * self.freq / self.rate
            s = np.sin(self.phase) * self.amp
            self.output_sample(s)

    def send_bit(self, bit):
        if bit == 1:
            self.amplitude_duration(0, 0.3)
        else:
            self.amplitude_duration(0, 0.15)

        self.amplitude_duration(1, 0.1)

def bits(buf):
    for byte in buf:
        for i in range(8)[::-1]:
            i = (byte >> i) & 1
            yield int(i)
        
mod = AHICDM_Modulator()
mod.amplitude_duration(0, 0.88)
mod.amplitude_duration(1, 0.7)

for bit in bits(b"gkbrk.com"):
    mod.send_bit(bit)

mod.amplitude_duration(0, 0.7)
mod.amplitude_duration(1, 0.1)

Links