ditdah - Morse Code Decoder
A high-performance Rust implementation of a Morse code decoder that can process WAV audio files and decode them into text with 100% accuracy on the comprehensive test suite.
Features
- High Accuracy: Achieves 100% pass rate on comprehensive test suite
- Clean Library API: High-level functions for easy integration (
decode_wav_file,decode_samples) - Full-Featured CLI: Decode files, generate test audio, verbose output, timing information
- Audio Processing: Supports WAV files with various sample rates (12kHz, 44.1kHz) and formats
- Signal Processing: Uses FFT-based pitch detection, Goertzel filtering, and adaptive threshold detection
- Self-Calibrating: Automatically determines timing, WPM, and optimal thresholds
- Robust Decoding: Handles uniform dot/dash sequences and complex multi-letter words
- Comprehensive Testing: Built-in test suite with Morse code generator for validation
Performance
✅ All tests passing with 100% accuracy:
- Basic signals (SOS, HELLO WORLD)
- Full alphabet (A-Z)
- Numbers (0-9)
- Different frequencies (300Hz - 1000Hz)
- Variable speeds (10-30 WPM)
- Different sample rates (12kHz, 44.1kHz)
- Complex content (CQ DE W1AW)
Installation
Usage
Command Line Interface
Decode a WAV file:
With verbose output and timing:
Generate test Morse code WAV files:
With debug logging:
RUST_LOG=info
Library Usage
High-level API (recommended):
use ;
// Decode a WAV file directly
let decoded_text = decode_wav_file?;
println!;
// Decode audio samples directly
let samples: = /* your audio data */;
let decoded_text = decode_samples?;
println!;
// Generate Morse code WAV files
let generator = new;
generator.generate_wav_file?;
Testing
Run All Tests
Baseline Tests (Quick Verification)
# Basic test
# With debug output
RUST_LOG=info
Comprehensive Test Suite
The test suite automatically:
- Generates test WAV files with known Morse content
- Decodes them using the library
- Measures accuracy and reports results
- Cleans up temporary files automatically
Algorithm
The decoder uses a sophisticated multi-stage approach:
- Audio Preprocessing: Resampling, bandpass filtering (200Hz-1200Hz)
- Pitch Detection: STFT-based frequency analysis
- Signal Extraction: Goertzel filtering tuned to detected frequency
- Self-Calibration: Intelligent timing analysis for dots vs dashes
- Letter Boundary Detection: Proper gap analysis for multi-letter words
- Character Assembly: Morse pattern to text conversion
Key Innovations
- Self-calibrating timing: Handles both uniform sequences (EEEE, TTTT) and mixed patterns
- Adaptive gap detection: Distinguishes element gaps, letter gaps, and word gaps
- Robust parameter estimation: Works across different speeds and frequencies
Library API
The library provides a clean, high-level API:
;
All signal processing complexity is handled internally - the library automatically:
- Detects audio format and converts to the required sample rate
- Performs frequency analysis and filtering
- Calibrates timing parameters
- Decodes Morse patterns to text
Project Structure
ditdah/
├── src/
│ ├── main.rs # CLI application
│ ├── lib.rs # Public library API
│ ├── decoder.rs # Internal Morse decoder implementation
│ └── generator.rs # Public Morse code generator
├── tests/
│ └── integration_tests.rs # Comprehensive test suite
├── .github/workflows/ # CI pipeline
├── Cargo.toml # Rust 2024 edition project configuration
├── LICENSE # MIT License
└── README.md # This file
Attribution
This implementation is based on the excellent work from ggmorse by Georgi Gerganov, which provided inspiration for the signal processing pipeline. The Rust implementation includes significant enhancements for robustness and accuracy.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Contributing
- Run the test suite to verify functionality:
cargo test - All tests should pass with 100% accuracy
- Add tests for new features or edge cases
- Ensure code is properly formatted:
cargo fmt - Run clippy for additional checks:
cargo clippy