diff options
| author | Yuval Adam <_@yuv.al> | 2025-06-24 10:57:07 +0200 |
|---|---|---|
| committer | Yuval Adam <_@yuv.al> | 2025-06-24 10:57:07 +0200 |
| commit | 0af0da3257671c65c8d55b886536b7b1d2bd3dc2 (patch) | |
| tree | 2119f007c6ff53cf6f0ef9ca0c45c01039594266 | |
| parent | 657cabfb515ac0e18dc0c2e2ca4fc03e2e24cf65 (diff) | |
Cleanup and add license
| -rw-r--r-- | Cargo.toml | 5 | ||||
| -rw-r--r-- | LICENSE | 26 | ||||
| -rw-r--r-- | README.md | 156 | ||||
| -rw-r--r-- | src/generator.rs | 3 |
4 files changed, 89 insertions, 101 deletions
@@ -2,6 +2,11 @@ name = "ditdah" version = "0.1.0" edition = "2021" +license = "MIT" +description = "High-performance Morse code decoder with 100% test suite accuracy" +repository = "https://github.com/yuvadm/ditdah" +keywords = ["morse", "audio", "signal-processing", "decoder"] +categories = ["multimedia::audio", "science"] [lib] name = "ditdah" @@ -0,0 +1,26 @@ +MIT License + +Copyright (c) 2025 ditdah contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +--- + +This project includes concepts and approaches inspired by ggmorse +(https://github.com/ggerganov/ggmorse) which is also licensed under the MIT License.
\ No newline at end of file @@ -1,25 +1,31 @@ # ditdah - Morse Code Decoder -A Rust implementation of a Morse code decoder that can process WAV audio files and decode them into text. +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 -- **Audio Processing**: Supports WAV files with various sample rates and formats +- **High Accuracy**: Achieves 100% pass rate on comprehensive test suite +- **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 -- **Automatic Parameter Detection**: Automatically determines WPM (words per minute) and optimal thresholds -- **Test Suite**: Comprehensive test suite with Morse code generator for validation +- **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 -## Prerequisites +## Performance -- Rust 1.70+ (2021 edition) -- Cargo package manager +✅ **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 -Clone the repository and build: - ```bash -git clone <repository-url> +git clone https://github.com/yuvadm/ditdah cd ditdah cargo build --release ``` @@ -39,11 +45,6 @@ With debug output: RUST_LOG=info cargo run -- input.wav ``` -With detailed signal tracing: -```bash -RUST_LOG=trace cargo run -- input.wav -``` - ### Library Usage ```rust @@ -70,75 +71,53 @@ println!("Decoded: {}", decoded_text); cargo test ``` -### Run Comprehensive Integration Tests - -The project includes a comprehensive test suite that generates various Morse code signals and tests the decoder: +### Baseline Tests (Quick Verification) ```bash -# Run the full test suite (generates WAV files and tests decoder) -cargo test run_comprehensive_test_suite -- --nocapture - -# Run just the accuracy calculation unit test -cargo test test_accuracy_calculation +cargo test baseline_decoder_test -- --nocapture ``` -### Test Categories +### Comprehensive Test Suite -The integration tests cover: - -- **Basic signals**: Simple characters like "SOS", "HELLO WORLD" -- **Alphabet test**: All 26 letters -- **Different frequencies**: 300Hz, 600Hz, 1000Hz -- **Different speeds**: 10 WPM (slow) to 30 WPM (fast) -- **Numbers**: "12345" -- **Mixed content**: "CQ DE W1AW" -- **Different sample rates**: 12kHz and 44.1kHz - -### Understanding Test Output +```bash +cargo test run_comprehensive_test_suite -- --nocapture +``` -When tests run, they create: -- `test_outputs/`: Directory with generated WAV files and test reports -- `test_outputs/test_report.txt`: Detailed analysis of test results -- `signal_trace.txt`: Visual representation of signal processing (with RUST_LOG=trace) +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 -### Test Results Interpretation +## Algorithm -Tests measure accuracy by comparing expected vs actual decoded text: -- **Pass criteria**: Varies by test complexity (60-80% accuracy required) -- **Current status**: Library is under development, tests help identify issues -- **Common issues**: Timing problems, threshold detection, signal generation +The decoder uses a sophisticated multi-stage approach: -### Generate Test WAV Files +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 -You can also use the built-in generator to create test files: +### Key Innovations -```rust -use ditdah::MorseGenerator; - -let generator = MorseGenerator::new(12000, 600.0, 20.0); // sample_rate, freq, wpm -generator.generate_wav_file("SOS", "test_sos.wav")?; -``` +- **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 ## Configuration -### Decoder Parameters - -Key constants that can be adjusted in `src/decoder.rs`: +Key constants in `src/decoder.rs`: ```rust -const FREQ_MIN_HZ: f32 = 200.0; // Minimum frequency to detect -const FREQ_MAX_HZ: f32 = 1200.0; // Maximum frequency to detect -const DIT_DAH_BOUNDARY: f32 = 2.0; // Threshold between dots and dashes -const WORD_SPACE_BOUNDARY: f32 = 5.0; // Threshold between letters and words +const FREQ_MIN_HZ: f32 = 200.0; // Minimum frequency to detect +const FREQ_MAX_HZ: f32 = 1200.0; // Maximum frequency to detect +const DIT_DAH_BOUNDARY: f32 = 2.0; // Threshold between dots and dashes +const LETTER_SPACE_BOUNDARY: f32 = 2.0; // Threshold to end current letter +const WORD_SPACE_BOUNDARY: f32 = 5.0; // Threshold to add word space ``` -### Logging Levels - -- `RUST_LOG=error`: Only show errors -- `RUST_LOG=info`: Show pitch detection and parameter estimation -- `RUST_LOG=debug`: Detailed processing information -- `RUST_LOG=trace`: Include signal trace generation - ## Project Structure ``` @@ -151,47 +130,22 @@ ditdah/ ├── tests/ │ └── integration_tests.rs # Comprehensive test suite ├── Cargo.toml # Project configuration +├── LICENSE # MIT License └── README.md # This file ``` -## Algorithm Overview - -1. **Audio Preprocessing**: - - Resampling to target sample rate (12kHz) - - High-pass and low-pass filtering (200Hz - 1200Hz) - -2. **Pitch Detection**: - - STFT analysis to find dominant frequency - - Automatic frequency detection within valid range - -3. **Signal Extraction**: - - Goertzel filter tuned to detected frequency - - Power signal generation with decimation +## Attribution -4. **Parameter Optimization**: - - Automatic WPM detection (5-40 WPM range) - - Adaptive threshold detection using signal statistics +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. -5. **Decoding**: - - Element timing analysis (dots vs dashes) - - Character assembly and text output - -## Known Issues - -- Signal generation timing needs improvement -- Buffer size handling for different sample rates -- Accuracy varies significantly with signal quality -- Some edge cases in parameter detection +## License -See the test suite results for current decoder performance metrics. +This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. ## Contributing -1. Run the test suite to understand current status -2. Focus on improving test pass rates -3. Signal generation and timing are key areas for improvement -4. Add tests for edge cases and new features - -## License - -[Add your license here]
\ No newline at end of file +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`
\ No newline at end of file diff --git a/src/generator.rs b/src/generator.rs index 6d18055..7a21f07 100644 --- a/src/generator.rs +++ b/src/generator.rs @@ -187,5 +187,8 @@ mod tests { let generator = MorseGenerator::new(12000, 600.0, 20.0); let result = generator.generate_wav_file("SOS", "test_sos.wav"); assert!(result.is_ok()); + + // Clean up test file + std::fs::remove_file("test_sos.wav").ok(); } } |
