audio_visualizer/spectrum/
plotters_png_file.rs1use plotters::prelude::*;
4use std::collections::BTreeMap;
5use std::fs;
6use std::path::PathBuf;
7
8pub fn spectrum_static_plotters_png_visualize(
9 frequency_spectrum: &BTreeMap<u32, f32>,
10 directory: &str,
11 filename: &str,
12) {
13 assert!(
15 !frequency_spectrum.iter().any(|(_, f)| f.is_nan()),
16 "There are NAN-values in the spectrum!"
17 );
18
19 let mut max = 0.0;
21 for mag in frequency_spectrum.values() {
22 if *mag > max {
23 max = *mag;
24 }
25 }
26
27 let max_frequency = *frequency_spectrum
28 .iter()
29 .skip(frequency_spectrum.len() - 2)
30 .last()
31 .unwrap()
32 .0;
33
34 if !fs::exists(directory).unwrap() {
35 fs::create_dir(directory).unwrap();
36 }
37 let mut path = PathBuf::new();
38 path.push(directory);
39 path.push(filename);
40
41 let mut width = frequency_spectrum.len() as u32;
42 if width < 700 {
43 width = 700;
44 }
45
46 let height = if width < 700 {
47 (width as f32 / 0.8) as u32
48 } else {
49 700
50 };
51
52 let root = BitMapBackend::new(&path, (width, height)).into_drawing_area();
53 root.fill(&WHITE).unwrap();
54 let mut chart = ChartBuilder::on(&root)
55 .caption("y=f magnitudes of sample", ("sans-serif", 20).into_font())
56 .margin(5)
57 .x_label_area_size(60)
58 .y_label_area_size(60)
59 .build_cartesian_2d(0.0..(max_frequency as f32) , 0.0..max)
60 .unwrap();
61
62 chart.configure_mesh().draw().unwrap();
63
64 chart
65 .draw_series(LineSeries::new(
66 frequency_spectrum
68 .iter()
69 .map(|(frequency, magnitude)| ((*frequency as f32) , *magnitude)),
70 &RED,
71 ))
72 .unwrap()
73 .label("frequency magnitude")
74 .legend(|(x, y)| PathElement::new(vec![(x, y), (x + 20, y)], RED));
75
76 chart
77 .configure_series_labels()
78 .background_style(WHITE.mix(0.8))
79 .border_style(BLACK)
80 .draw()
81 .unwrap();
82}
83
84#[cfg(test)]
85mod tests {
86 use super::*;
87 use crate::tests::testutil::TEST_OUT_DIR;
88
89 #[test]
90 fn test_visualize_sine_waves_spectrum_plotters() {
91 let mut spectrum = BTreeMap::new();
92 spectrum.insert(0, 0.0);
93 spectrum.insert(10, 5.0);
94 spectrum.insert(20, 20.0);
95 spectrum.insert(30, 40.0);
96 spectrum.insert(40, 80.0);
97 spectrum.insert(50, 120.0);
98 spectrum.insert(55, 130.0);
99 spectrum.insert(60, 140.0);
100 spectrum.insert(65, 130.0);
101 spectrum.insert(70, 120.0);
102 spectrum.insert(80, 80.0);
103 spectrum.insert(90, 40.0);
104 spectrum.insert(100, 20.0);
105 spectrum.insert(110, 5.0);
106 spectrum.insert(120, 0.0);
107 spectrum.insert(130, 0.0);
108
109 spectrum_static_plotters_png_visualize(
110 &spectrum,
111 TEST_OUT_DIR,
112 "spectrum_60hz_peak_plotters_visualization.png",
113 );
114 }
115
116 #[allow(non_snake_case)]
117 #[test]
118 #[should_panic]
119 fn test_panic_on_NAN() {
120 let mut spectrum = BTreeMap::new();
121 spectrum.insert(0, f32::NAN);
122
123 spectrum_static_plotters_png_visualize(
124 &spectrum,
125 TEST_OUT_DIR,
126 "spectrum_60hz_peak_plotters_visualization_NAN.png",
127 );
128 }
129}