blob: df2665e48965a0e6d4f84ab2a491d9a223d5ceb2 (
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
|
// src/lib.rs
// Library interface for ditdah
mod decoder;
pub mod generator;
use decoder::MorseDecoder;
pub use generator::MorseGenerator;
use anyhow::Result;
/// High-level convenience function to decode a WAV file directly
///
/// # Example
/// ```no_run
/// use ditdah::decode_wav_file;
///
/// let decoded_text = decode_wav_file("morse.wav").unwrap();
/// println!("Decoded: {}", decoded_text);
/// ```
pub fn decode_wav_file<P: AsRef<std::path::Path>>(path: P) -> Result<String> {
use hound::{SampleFormat, WavReader};
let mut reader = WavReader::open(path)?;
let spec = reader.spec();
// Check supported formats
if spec.sample_format != SampleFormat::Int && spec.sample_format != SampleFormat::Float {
anyhow::bail!(
"Unsupported sample format: {:?}. Only 16-bit Int and 32-bit Float are supported.",
spec.sample_format
);
}
// Create decoder with automatic sample rate conversion
let mut decoder = MorseDecoder::new(spec.sample_rate, 12000)?;
// Read all samples
let samples_f32: Vec<f32> = if spec.sample_format == SampleFormat::Int {
reader
.samples::<i16>()
.map(|s| s.unwrap() as f32 / 32768.0)
.collect()
} else {
reader.samples::<f32>().map(|s| s.unwrap()).collect()
};
// Convert to mono if necessary
let mono_samples: Vec<f32> = if spec.channels > 1 {
samples_f32
.chunks_exact(spec.channels as usize)
.map(|chunk| chunk.iter().sum::<f32>() / spec.channels as f32)
.collect()
} else {
samples_f32
};
// Process in chunks for better memory efficiency
const CHUNK_SIZE: usize = 4096;
for chunk in mono_samples.chunks(CHUNK_SIZE) {
decoder.process(chunk)?;
}
decoder.finalize()
}
/// High-level convenience function to decode audio samples directly
///
/// # Example
/// ```no_run
/// use ditdah::decode_samples;
///
/// // For real audio data with sufficient length for processing
/// let samples = vec![0.0; 48000]; // 4 seconds of audio at 12kHz
/// let decoded_text = decode_samples(&samples, 12000).unwrap();
/// println!("Decoded: {}", decoded_text);
/// ```
pub fn decode_samples(samples: &[f32], sample_rate: u32) -> Result<String> {
let mut decoder = MorseDecoder::new(sample_rate, 12000)?;
const CHUNK_SIZE: usize = 4096;
for chunk in samples.chunks(CHUNK_SIZE) {
decoder.process(chunk)?;
}
decoder.finalize()
}
|