Skip to content

About

A real time morse code decoder written in C++ that listens to microphone input and prints decoded text to the terminal.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

6 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 

Repository files navigation

Morse Code Audio Decoder

A real time morse code decoder written in C++ that listens to microphone input and prints decoded text to the terminal.

How it works

The program runs a four-stage pipeline from raw audio to decoded letters.

Stage 1 — Audio capture PortAudio runs a background thread that reads from the microphone every ~11ms, collecting 512 raw float samples per callback. These are compressed into a single RMS (root mean square) value representing the loudness of that window. The value is stored atomically so the main thread can read it safely across threads.

Stage 2 — Signal processor Every 100ms the main loop reads the latest RMS and passes it to the signal processor, which answers one question: is a tone playing or is it silence? Rather than using a fixed threshold, it tracks an exponential moving average (EMA) of the background noise floor — updating only during silence so loud tones don't corrupt the baseline. If the current RMS exceeds the noise floor by a configurable sensitivity factor, a tone is detected.

Stage 3 — Timing classifier Converts the boolean tone/silence stream into morse events. Counts consecutive on/off frames and classifies them at transitions — a short tone is a dot, a long tone is a dash, a medium silence is a letter gap, a long silence is a word gap. Short silences between dots and dashes in the same letter are ignored.

Stage 4 — Decoder Accumulates dots and dashes into a pattern string. On a letter gap or word gap, looks up the pattern in a hash map of the full morse alphabet and prints the corresponding character. Unrecognized patterns print as ?.

Architecture

Microphone
    → PortAudio thread → audioCallback → RMS → atomic store
    → Main thread (100ms loop)
        → SignalProcessor  →  bool toneOn
        → TimingClassifier →  Event (DOT/DASH/LETTER_GAP/WORD_GAP)
        → Decoder          →  character printed to terminal

Dependencies

  • C++17
  • CMake 3.15+
  • PortAudio (libportaudio2, portaudio19-dev)

Build

sudo apt install libportaudio2 portaudio19-dev
mkdir build && cd build
cmake ..
cmake --build .

Run

./morse_decoder

Play morse audio near your microphone or tap on a surface. Decoded text prints to the terminal. Wait ~1.5 seconds after the last tone for the final letter to flush.

Tuning

Thresholds in main.cpp can be adjusted based on your microphone and tapping speed:

SignalProcessor signalP(0.1f, 3.0f);  // alpha, sensitivity
TimingClassifier tC(2, 6);            // dotThreshold, dashThreshold (in frames)

At 100ms per frame and 5 WPM morse speed, dots are ~2-3 frames and letter gaps are ~7 frames.

Project structure

src/
  audio.cpp / audio.h       — PortAudio capture, RMS computation
  signal.cpp / signal.h     — Adaptive noise floor, tone detection
  edge.cpp / edge.h         — Rising/falling edge detection
  timing.cpp / timing.h     — Dot/dash/gap classification
  decoder.cpp / decoder.h   — Morse table lookup, character output
  main.cpp                  — Pipeline orchestration
CMakeLists.txt

About

A real time morse code decoder written in C++ that listens to microphone input and prints decoded text to the terminal.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages