summaryrefslogtreecommitdiff
path: root/README.md
blob: 258d17072917132182ec57d57fe7d3e6d82fd148 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# ditdah - Morse Code Decoder

[![CI](https://github.com/yuvadm/ditdah/workflows/CI/badge.svg)](https://github.com/yuvadm/ditdah/actions)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/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

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

## Usage

### Command Line Interface

**Decode a WAV file:**
```bash
cargo run -- input.wav
```

**With verbose output and timing:**
```bash
cargo run -- input.wav --verbose --time
```

**Generate test Morse code WAV files:**
```bash
cargo run -- --generate "SOS" --verbose
cargo run -- --generate "HELLO WORLD" --output test.wav --frequency 800 --wpm 25
```

**With debug logging:**
```bash
RUST_LOG=info cargo run -- input.wav
```

### Library Usage

**High-level API (recommended):**
```rust
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

```bash
cargo test
```

### Baseline Tests (Quick Verification)

```bash
# Basic test
cargo test baseline_decoder_test -- --nocapture

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

### Comprehensive Test Suite

```bash
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:

```rust
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](https://github.com/ggerganov/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](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`