limnus_audio_mixer/
lib.rs1use limnus_app::prelude::{App, Plugin};
6use limnus_assets::prelude::{Asset, Id};
7use limnus_local_resource::prelude::LocalResource;
8use std::fmt::{Debug, Formatter};
9use std::sync::{Arc, Mutex};
10
11pub type StereoSampleRef = Id<StereoSample>;
12
13#[derive(Asset)]
14pub struct StereoSample {
15 #[allow(unused)]
16 pub stereo_frames: Arc<oddio::Frames<[oddio::Sample; 2]>>, }
18
19impl Debug for StereoSample {
20 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
21 write!(f, "StereoSample ({})", self.stereo_frames.len())
22 }
23}
24
25impl StereoSample {
26 #[must_use]
27 pub const fn frames(&self) -> &Arc<oddio::Frames<[oddio::Sample; 2]>> {
28 &self.stereo_frames
29 }
30}
31
32#[derive(LocalResource)]
33pub struct AudioMixer {
34 #[allow(dead_code)]
35 pub mixer: Arc<Mutex<oddio::Mixer<[f32; 2]>>>,
36 #[allow(dead_code)]
37 mixer_control: oddio::MixerControl<[f32; 2]>,
38}
39
40impl Debug for AudioMixer {
41 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
42 write!(f, "Mixer")
43 }
44}
45
46impl Default for AudioMixer {
47 fn default() -> Self {
48 Self::new()
49 }
50}
51
52impl AudioMixer {
53 #[must_use]
54 pub fn new() -> Self {
55 let (mixer_control, mixer) = oddio::Mixer::<[f32; 2]>::new();
56
57 Self {
58 mixer_control,
59 mixer: Arc::new(Mutex::new(mixer)),
60 }
61 }
62
63 #[allow(unused)]
64 pub fn play(&mut self, stereo_sample: &StereoSample) {
65 let signal = oddio::FramesSignal::from(stereo_sample.frames().clone());
66 self.mixer_control.play(signal);
67 }
68}
69
70pub struct AudioMixerPlugin;
71
72impl Plugin for AudioMixerPlugin {
73 fn build(&self, app: &mut App) {
74 let mixer = AudioMixer::new();
75 app.insert_local_resource(mixer);
76 }
77}