audio_visualizer/waveform/
plotters_png_file.rs1use crate::Channels;
27use plotters::prelude::*;
28use std::fs;
29use std::path::PathBuf;
30
31pub fn waveform_static_plotters_png_visualize(
34 samples: &[i16],
35 channels: Channels,
36 directory: &str,
37 filename: &str,
38) {
39 if channels.is_stereo() {
40 assert_eq!(
41 0,
42 samples.len() % 2,
43 "If stereo is provided, the length of the audio data must be even!"
44 );
45 let (left, right) = channels.stereo_interleavement().to_channel_data(samples);
46 waveform_static_plotters_png_visualize(
47 &left,
48 Channels::Mono,
49 directory,
50 &format!("left_{}", filename),
51 );
52 waveform_static_plotters_png_visualize(
53 &right,
54 Channels::Mono,
55 directory,
56 &format!("right_{}", filename),
57 );
58 return;
59 }
60
61 if !fs::exists(directory).unwrap() {
62 fs::create_dir(directory).unwrap();
63 }
64 let mut path = PathBuf::new();
65 path.push(directory);
66 path.push(filename);
67
68 let mut max = 0;
69 for sample in samples {
70 let sample = *sample as i32;
71 let sample = sample.abs();
72 if sample > max {
73 max = sample;
74 }
75 }
76
77 let width = (samples.len() / 5) as u32;
78 let width = if width > 4000 { 4000 } else { width };
79 let root = BitMapBackend::new(&path, (width, 1000)).into_drawing_area();
80 root.fill(&WHITE).unwrap();
81 let mut chart = ChartBuilder::on(&root)
82 .caption("y=music(t)", ("sans-serif", 50).into_font())
83 .margin(5)
84 .x_label_area_size(30)
85 .y_label_area_size(30)
86 .build_cartesian_2d(0.0..samples.len() as f32, -max as f32..max as f32)
87 .unwrap();
88
89 chart.configure_mesh().draw().unwrap();
90
91 chart
92 .draw_series(LineSeries::new(
93 samples
95 .iter()
96 .enumerate()
97 .map(|(sample_i, amplitude)| (sample_i as f32, *amplitude as f32)),
98 &RED,
99 ))
100 .unwrap()
101 .legend(|(x, y)| PathElement::new(vec![(x, y), (x + 20, y)], RED));
103
104 chart
105 .configure_series_labels()
106 .background_style(WHITE.mix(0.8))
107 .border_style(BLACK)
108 .draw()
109 .unwrap();
110}
111
112#[cfg(test)]
113mod tests {
114 use super::*;
115 use crate::tests::testutil::{decode_mp3, TEST_OUT_DIR, TEST_SAMPLES_DIR};
116 use crate::ChannelInterleavement;
117
118 #[test]
119 fn test_visualize_png_output() {
120 let mut path = PathBuf::new();
121 path.push(TEST_SAMPLES_DIR);
122 path.push("sample_1.mp3");
123
124 let lrlr_mp3_samples = decode_mp3(path.as_path());
125
126 waveform_static_plotters_png_visualize(
127 &lrlr_mp3_samples,
128 Channels::Stereo(ChannelInterleavement::LRLR),
129 TEST_OUT_DIR,
130 "waveform_static_plotters_png_visualize_example.png",
131 );
132 }
133}