-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbasic_linear.rs
More file actions
65 lines (53 loc) · 2.27 KB
/
basic_linear.rs
File metadata and controls
65 lines (53 loc) · 2.27 KB
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
use non_empty_slice::NonEmptyVec;
/// Basic linear spectrogram example
///
/// This example demonstrates:
/// - Creating a simple sine wave
/// - Computing a linear-frequency power spectrogram
/// - Accessing spectrogram data and axes
use spectrograms::{LinearPowerSpectrogram, SpectrogramParams, StftParams, WindowType, nzu};
use std::f64::consts::PI;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Generate a 1-second sine wave at 440 Hz
let sample_rate = 16000.0;
let duration = 1.0;
let frequency = 440.0;
let samples: Vec<f64> = (0..(duration * sample_rate) as usize)
.map(|i| (2.0 * PI * frequency * i as f64 / sample_rate).sin())
.collect();
let samples = NonEmptyVec::new(samples).unwrap();
println!("Generated {} samples at {} Hz", samples.len(), sample_rate);
// Set up spectrogram parameters
let stft = StftParams::new(
nzu!(512), // n_fft: FFT window size
nzu!(256), // hop_size: samples between frames
WindowType::Hanning, // window function
true, // centre: pad signal for centered frames
)?;
let params = SpectrogramParams::new(stft, sample_rate)?;
// Compute the spectrogram (this is the convenience API)
let spec = LinearPowerSpectrogram::compute(&samples, ¶ms, None)?;
// Access spectrogram properties
println!("\nSpectrogram properties:");
println!(" Frequency bins: {}", spec.n_bins());
println!(" Time frames: {}", spec.n_frames());
println!(" Shape: {} x {}", spec.n_bins(), spec.n_frames());
// Access frequency and time axes
let (f_min, f_max) = spec.axes().frequency_range();
println!("\nFrequency range: {:.1} Hz to {:.1} Hz", f_min, f_max);
let duration_computed = spec.axes().duration();
println!("Duration: {:.3} seconds", duration_computed);
// Find the peak frequency in the first frame
let first_frame_data = spec.data().column(0);
let (peak_bin, peak_power) = first_frame_data
.iter()
.enumerate()
.max_by(|(_, a), (_, b)| a.partial_cmp(b).unwrap())
.unwrap();
let peak_freq = spec.axes().frequencies()[peak_bin];
println!(
"\nPeak in first frame: {:.1} Hz (power: {:.2e})",
peak_freq, peak_power
);
Ok(())
}