Skip to main content

limnus_audio_mixer/
lib.rs

1/*
2 * Copyright (c) Peter Bjorklund. All rights reserved. https://github.com/swamp/limnus
3 * Licensed under the MIT License. See LICENSE in the project root for license information.
4 */
5use 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]>>, // Not sure why it needs to be wrapped in Arc
17}
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}