Skip to content

Instantly share code, notes, and snippets.

@michaelfm1211
Last active May 26, 2023 22:49
Show Gist options
  • Save michaelfm1211/9da85d69ca3ae029e36aa2e88e210371 to your computer and use it in GitHub Desktop.
Save michaelfm1211/9da85d69ca3ae029e36aa2e88e210371 to your computer and use it in GitHub Desktop.
Morse code WAV file generator
from struct import pack
# WAV format reference: http://soundfile.sapp.org/doc/WaveFormat/
# one period of a sine wave in 8 samples
beep = bytes([0x80, 0xd9, 0xff, 0xd9, 0x80, 0x26, 0x01, 0x26]) * 80
# one period of silence
sil = bytes([80] * 8) * 80
# morse code
txt = "hello world"
morse = {'a': '.-', 'b': '-...', 'c': '-.-.', 'd': '-..', 'e': '.',
'f': '..-.', 'g': '--.', 'h': '....', 'i': '..', 'j': '.---',
'k': '-.-', 'l': '.-..', 'm': '--', 'n': '-.', 'o': '---',
'p': '.--.', 'q': '--.-', 'r': '.-.', 's': '...', 't': '-',
'u': '..-', 'v': '...-', 'w': '.--', 'x': '-..-', 'y': '-.--',
'z': '--..'}
data = bytes()
for i in range(len(txt)):
ch = txt[i]
if ch == ' ' and i != len(txt)-1:
data += sil * 4
continue
for sig in morse[ch]:
if sig == '.':
data += beep
else:
data += beep * 3
data += sil
if i != len(txt) - 1:
data += sil * 2
# ChunkID = "RIFF", Size = 0x2b, Format = "WAVE"
riff_hdr = pack('4sI4s', b'RIFF', 36 + len(data), b'WAVE')
# SubChunkID = "fmt ", Size = 0x10, AudioFormat = 1 (WAVE_FORMAT_PCR),
# NumChannels = 1, SampleRate (per second) = 8000,
# ByteRate (per second. = channels * sample * bps/8) = 8000,
# BlockAlign = 1 (= channels * bps/8)
wav_hdr = pack('4sIhhIIh', b'fmt ', 0x10, 1, 1, 8000, 8000, 1)
# BitsPerSample = 8
pcr_hdr = pack('h', 8)
# ID = "data", ChunkSize = 8
data_hdr = pack('4sI', b'data', len(data))
with open('test.wav', 'wb') as f:
f.write(riff_hdr)
f.write(wav_hdr)
f.write(pcr_hdr)
f.write(data_hdr)
f.write(data)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment