ditdah

Crates.ioditdah
lib.rsditdah
version0.2.0
created_at2025-06-24 11:09:06.753232+00
updated_at2025-06-24 11:09:06.753232+00
descriptionHigh-performance Morse code decoder with 100% test suite accuracy
homepage
repositoryhttps://github.com/yuvadm/ditdah
max_upload_size
id1724169
size68,391
Yuval Adam (yuvadm)

documentation

README

ditdah - Morse Code Decoder

CI License: MIT

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

git clone https://github.com/yuvadm/ditdah
cd ditdah
cargo build --release

Usage

Command Line Interface

Decode a WAV file:

cargo run -- input.wav

With verbose output and timing:

cargo run -- input.wav --verbose --time

Generate test Morse code WAV files:

cargo run -- --generate "SOS" --verbose
cargo run -- --generate "HELLO WORLD" --output test.wav --frequency 800 --wpm 25

With debug logging:

RUST_LOG=info cargo run -- input.wav

Library Usage

High-level API (recommended):

use ditdah::{decode_wav_file, decode_samples, MorseGenerator};

// Decode a WAV file directly
let decoded_text = decode_wav_file("morse.wav")?;
println!("Decoded: {}", decoded_text);

// Decode audio samples directly
let samples: Vec<f32> = /* your audio data */;
let decoded_text = decode_samples(&samples, 12000)?;
println!("Decoded: {}", decoded_text);

// Generate Morse code WAV files
let generator = MorseGenerator::new(12000, 600.0, 20.0);
generator.generate_wav_file("SOS", "output.wav")?;

Testing

Run All Tests

cargo test

Baseline Tests (Quick Verification)

# Basic test
cargo test baseline_decoder_test -- --nocapture

# With debug output
RUST_LOG=info cargo test baseline_decoder_test -- --nocapture

Comprehensive Test Suite

cargo test run_comprehensive_test_suite -- --nocapture

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:

  1. Audio Preprocessing: Resampling, bandpass filtering (200Hz-1200Hz)
  2. Pitch Detection: STFT-based frequency analysis
  3. Signal Extraction: Goertzel filtering tuned to detected frequency
  4. Self-Calibration: Intelligent timing analysis for dots vs dashes
  5. Letter Boundary Detection: Proper gap analysis for multi-letter words
  6. 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:

pub fn decode_wav_file<P: AsRef<std::path::Path>>(path: P) -> Result<String>
pub fn decode_samples(samples: &[f32], sample_rate: u32) -> Result<String>
pub use generator::MorseGenerator;

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

  1. Run the test suite to verify functionality: cargo test
  2. All tests should pass with 100% accuracy
  3. Add tests for new features or edge cases
  4. Ensure code is properly formatted: cargo fmt
  5. Run clippy for additional checks: cargo clippy
Commit count: 0

cargo fmt