MCPcopy Create free account
hub / github.com/BillyDM/Firewheel / draw_oscilloscope

Method draw_oscilloscope

examples/visualizer/src/ui.rs:28–86  ·  view source on GitHub ↗

A basic oscilloscope, using the audio data from the triple buffer node.

(&mut self, ui: &mut Ui)

Source from the content-addressed store, hash-verified

26
27 // A basic oscilloscope, using the audio data from the triple buffer node.
28 fn draw_oscilloscope(&mut self, ui: &mut Ui) {
29 const NUM_POINTS: usize = 200;
30
31 let size = ui.available_size();
32 let (_id, rect) = ui.allocate_space(size);
33
34 let mut output = self.audio_system.triple_buffer_state.output();
35 let Some(data) = output.data() else {
36 return;
37 };
38 let frames = data.frames;
39
40 let mut left_rect = rect;
41 left_rect.set_height(left_rect.height() / 2.0);
42 let mut right_rect = left_rect;
43 right_rect = right_rect.translate(vec2(0.0, left_rect.height()));
44
45 let to_left_rect =
46 RectTransform::from_to(Rect::from_x_y_ranges(0.0..=1.0, -1.0..=1.0), left_rect);
47 let to_right_rect =
48 RectTransform::from_to(Rect::from_x_y_ranges(0.0..=1.0, -1.0..=1.0), right_rect);
49
50 let build_points = |audio_data: &[f32], rect_transform: RectTransform| -> Vec<Pos2> {
51 (0..NUM_POINTS)
52 .map(|i| {
53 let x = i as f32 / NUM_POINTS as f32;
54
55 let pos = x * frames as f32;
56 let index = pos.floor() as usize;
57 let fract_index = pos.fract();
58
59 let s0 = audio_data.get(index).copied().unwrap_or(0.0);
60 let s1 = audio_data.get(index + 1).copied().unwrap_or(0.0);
61
62 let value = s0 + ((s1 - s0) * fract_index);
63
64 // Apply a windowing function to make the oscilloscope look
65 // "more interesting".
66 let y = value * (x * PI).sin();
67
68 rect_transform * pos2(x, y)
69 })
70 .collect()
71 };
72
73 let left_points = build_points(data.buffer.channel_slice(0).unwrap(), to_left_rect);
74 let right_points = build_points(data.buffer.channel_slice(1).unwrap(), to_right_rect);
75
76 let color = if ui.style().visuals.dark_mode {
77 egui::Color32::GREEN
78 } else {
79 egui::Color32::DARK_GREEN
80 };
81
82 ui.painter().extend([
83 epaint::Shape::line(left_points, PathStroke::new(2.0f32, color)),
84 epaint::Shape::line(right_points, PathStroke::new(2.0f32, color)),
85 ]);

Callers 1

updateMethod · 0.80

Calls 5

outputMethod · 0.80
dataMethod · 0.80
collectMethod · 0.80
channel_sliceMethod · 0.80
getMethod · 0.45

Tested by

no test coverage detected