1use super::SCRATCH_FRAMES;
5use super::source::AudioSource;
6use crate::dsl::{ENGINE_VERSION, Node};
7use crate::streaming::EffectChain;
8
9#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
11pub struct SourceId(u64);
12
13trait AnySource: AudioSource + std::any::Any {}
17impl<T: AudioSource + 'static> AnySource for T {}
18
19struct MixedSource {
20 id: u64,
21 source: Box<dyn AnySource + Send>,
22 gain: f32,
23 bus: BusId,
25}
26
27#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
31pub struct BusId(u32);
32
33impl BusId {
34 pub const MASTER: BusId = BusId(0);
37}
38
39#[derive(Clone, Copy, PartialEq, Eq, Debug)]
40enum BusKind {
41 Master,
42 Input,
43 Fx,
44}
45
46#[derive(Clone, Debug, PartialEq, Eq)]
48pub enum MixerError {
49 NotStreamable,
51 UnknownBus,
53}
54
55impl std::fmt::Display for MixerError {
56 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
57 match self {
58 MixerError::NotStreamable => {
59 write!(f, "effect chain contains a non-streamable node")
60 }
61 MixerError::UnknownBus => {
62 write!(f, "unknown bus (foreign or stale BusId)")
63 }
64 }
65 }
66}
67
68impl std::error::Error for MixerError {}
69
70struct Bus {
73 name: String,
74 kind: BusKind,
75 gain: f32,
76 to_master: f32,
78 inserts: Option<(EffectChain, EffectChain)>,
80 sends: Vec<(u32, f32)>,
82}
83
84pub struct Mixer {
111 sources: Vec<MixedSource>,
112 buses: Vec<Bus>,
114 next_id: u64,
115 sample_rate: u32,
116 scratch: Vec<f32>,
118 master_l: Vec<f32>,
119 master_r: Vec<f32>,
120 bus_l: Vec<f32>,
121 bus_r: Vec<f32>,
122 fx_in: Vec<(Vec<f32>, Vec<f32>)>,
124}
125
126impl Mixer {
127 pub fn new(sample_rate: u32) -> Self {
131 Mixer::build(sample_rate)
132 }
133
134 fn build(sample_rate: u32) -> Self {
135 let master = Bus {
136 name: "master".into(),
137 kind: BusKind::Master,
138 gain: 1.0,
139 to_master: 1.0,
140 inserts: None,
141 sends: Vec::new(),
142 };
143 Mixer {
144 sources: Vec::new(),
145 buses: vec![master],
146 next_id: 1,
147 sample_rate,
148 scratch: vec![0.0; SCRATCH_FRAMES * 2],
151 master_l: vec![0.0; SCRATCH_FRAMES],
152 master_r: vec![0.0; SCRATCH_FRAMES],
153 bus_l: vec![0.0; SCRATCH_FRAMES],
154 bus_r: vec![0.0; SCRATCH_FRAMES],
155 fx_in: Vec::new(),
156 }
157 }
158
159 pub fn add(&mut self, source: impl AudioSource + Send + 'static) -> SourceId {
161 self.add_to(BusId::MASTER, source)
162 }
163
164 pub fn add_to(&mut self, bus: BusId, source: impl AudioSource + Send + 'static) -> SourceId {
167 let bus = if (bus.0 as usize) < self.buses.len() {
168 bus
169 } else {
170 BusId::MASTER
171 };
172 let id = self.next_id;
173 self.next_id += 1;
174 self.sources.push(MixedSource {
175 id,
176 source: Box::new(source),
177 gain: 1.0,
178 bus,
179 });
180 SourceId(id)
181 }
182
183 pub fn bus(&mut self, name: impl Into<String>) -> BusId {
185 self.push_bus(name.into(), BusKind::Input, None)
186 }
187
188 pub fn fx_bus(
191 &mut self,
192 name: impl Into<String>,
193 effects: Vec<Node>,
194 ) -> Result<BusId, MixerError> {
195 let inserts = self.build_chain(&effects)?;
196 Ok(self.push_bus(name.into(), BusKind::Fx, inserts))
197 }
198
199 fn push_bus(
200 &mut self,
201 name: String,
202 kind: BusKind,
203 inserts: Option<(EffectChain, EffectChain)>,
204 ) -> BusId {
205 let id = self.buses.len() as u32;
207 self.buses.push(Bus {
208 name,
209 kind,
210 gain: 1.0,
211 to_master: 1.0,
212 inserts,
213 sends: Vec::new(),
214 });
215 BusId(id)
216 }
217
218 pub fn bus_named(&self, name: &str) -> Option<BusId> {
220 self.buses
221 .iter()
222 .position(|b| b.name == name)
223 .map(|i| BusId(i as u32))
224 }
225
226 pub fn set_bus_effects(&mut self, bus: BusId, effects: Vec<Node>) -> Result<(), MixerError> {
230 let inserts = self.build_chain(&effects)?;
231 match self.buses.get_mut(bus.0 as usize) {
232 Some(b) => {
233 b.inserts = inserts;
234 Ok(())
235 }
236 None => Err(MixerError::UnknownBus),
237 }
238 }
239
240 pub fn master_effects(&mut self, effects: Vec<Node>) -> Result<(), MixerError> {
242 self.set_bus_effects(BusId::MASTER, effects)
243 }
244
245 pub fn set_send(&mut self, from: BusId, to_fx: BusId, level: f32) {
248 let valid = matches!(
249 self.buses.get(from.0 as usize).map(|b| b.kind),
250 Some(BusKind::Input)
251 ) && matches!(
252 self.buses.get(to_fx.0 as usize).map(|b| b.kind),
253 Some(BusKind::Fx)
254 );
255 if !valid {
256 return;
257 }
258 let level = level.max(0.0);
259 let bus = &mut self.buses[from.0 as usize];
260 if let Some(s) = bus.sends.iter_mut().find(|s| s.0 == to_fx.0) {
261 s.1 = level;
262 } else {
263 bus.sends.push((to_fx.0, level));
264 }
265 }
266
267 pub fn set_bus_gain(&mut self, bus: BusId, gain: f32) {
269 if let Some(b) = self.buses.get_mut(bus.0 as usize) {
270 b.gain = gain.max(0.0);
271 }
272 }
273
274 pub fn set_bus_dry(&mut self, bus: BusId, level: f32) {
276 if bus != BusId::MASTER
277 && let Some(b) = self.buses.get_mut(bus.0 as usize)
278 {
279 b.to_master = level.max(0.0);
280 }
281 }
282
283 fn build_chain(
285 &self,
286 effects: &[Node],
287 ) -> Result<Option<(EffectChain, EffectChain)>, MixerError> {
288 if effects.is_empty() {
289 return Ok(None);
290 }
291 let sr = self.sample_rate;
292 let build = || EffectChain::try_new(effects, sr, ENGINE_VERSION);
293 let l = build().ok_or(MixerError::NotStreamable)?;
294 let r = build().ok_or(MixerError::NotStreamable)?;
295 Ok(Some((l, r)))
296 }
297
298 pub fn set_gain(&mut self, id: SourceId, gain: f32) {
300 if let Some(s) = self.sources.iter_mut().find(|s| s.id == id.0) {
301 s.gain = gain.max(0.0);
302 }
303 }
304
305 pub fn get_mut<T: AudioSource + 'static>(&mut self, id: SourceId) -> Option<&mut T> {
308 let s = self.sources.iter_mut().find(|s| s.id == id.0)?;
309 let any: &mut dyn std::any::Any = s.source.as_mut();
310 any.downcast_mut::<T>()
311 }
312
313 pub fn remove(&mut self, id: SourceId) {
315 self.sources.retain(|s| s.id != id.0);
316 }
317
318 pub fn source_count(&self) -> usize {
320 self.sources.len()
321 }
322
323 pub fn contains(&self, id: SourceId) -> bool {
325 self.sources.iter().any(|s| s.id == id.0)
326 }
327}
328
329fn grow(v: &mut Vec<f32>, n: usize) {
331 if v.len() < n {
332 v.resize(n, 0.0);
333 }
334}
335
336impl AudioSource for Mixer {
337 fn fill(&mut self, out: &mut [f32]) -> usize {
338 let frames = out.len() / 2;
339
340 let mut scratch = std::mem::take(&mut self.scratch);
343 let mut master_l = std::mem::take(&mut self.master_l);
344 let mut master_r = std::mem::take(&mut self.master_r);
345 let mut bus_l = std::mem::take(&mut self.bus_l);
346 let mut bus_r = std::mem::take(&mut self.bus_r);
347 let mut fx_in = std::mem::take(&mut self.fx_in);
348
349 grow(&mut scratch, frames * 2);
350 grow(&mut master_l, frames);
351 grow(&mut master_r, frames);
352 grow(&mut bus_l, frames);
353 grow(&mut bus_r, frames);
354 if fx_in.len() < self.buses.len() {
355 fx_in.resize_with(self.buses.len(), || (Vec::new(), Vec::new()));
356 }
357 for (l, r) in fx_in.iter_mut() {
358 grow(l, frames);
359 grow(r, frames);
360 }
361
362 master_l[..frames].fill(0.0);
363 master_r[..frames].fill(0.0);
364 for (l, r) in fx_in.iter_mut() {
365 l[..frames].fill(0.0);
366 r[..frames].fill(0.0);
367 }
368
369 let scr = &mut scratch[..frames * 2];
370
371 for s in self.sources.iter_mut().filter(|s| s.bus == BusId::MASTER) {
373 s.source.fill(scr);
374 for f in 0..frames {
375 master_l[f] += scr[f * 2] * s.gain;
376 master_r[f] += scr[f * 2 + 1] * s.gain;
377 }
378 }
379
380 for bi in 1..self.buses.len() {
382 if self.buses[bi].kind != BusKind::Input {
383 continue;
384 }
385 bus_l[..frames].fill(0.0);
386 bus_r[..frames].fill(0.0);
387 let bus_id = bi as u32;
388 for s in self.sources.iter_mut().filter(|s| s.bus.0 == bus_id) {
389 s.source.fill(scr);
390 for f in 0..frames {
391 bus_l[f] += scr[f * 2] * s.gain;
392 bus_r[f] += scr[f * 2 + 1] * s.gain;
393 }
394 }
395 if let Some((cl, cr)) = &mut self.buses[bi].inserts {
396 cl.process(&mut bus_l[..frames]);
397 cr.process(&mut bus_r[..frames]);
398 }
399 let fader = self.buses[bi].gain;
400 let dry = fader * self.buses[bi].to_master;
401 for f in 0..frames {
402 master_l[f] += bus_l[f] * dry;
403 master_r[f] += bus_r[f] * dry;
404 }
405 for &(target, level) in &self.buses[bi].sends {
406 let k = target as usize;
407 if k < fx_in.len() {
408 let g = fader * level;
409 let (fl, fr) = &mut fx_in[k];
410 for f in 0..frames {
411 fl[f] += bus_l[f] * g;
412 fr[f] += bus_r[f] * g;
413 }
414 }
415 }
416 }
417
418 #[allow(clippy::needless_range_loop)]
423 for bi in 1..self.buses.len() {
424 if self.buses[bi].kind != BusKind::Fx {
425 continue;
426 }
427 let bus_id = bi as u32;
428 let (fl, fr) = &mut fx_in[bi];
429 for s in self.sources.iter_mut().filter(|s| s.bus.0 == bus_id) {
430 s.source.fill(scr);
431 for f in 0..frames {
432 fl[f] += scr[f * 2] * s.gain;
433 fr[f] += scr[f * 2 + 1] * s.gain;
434 }
435 }
436 }
437
438 #[allow(clippy::needless_range_loop)]
441 for bi in 1..self.buses.len() {
442 if self.buses[bi].kind != BusKind::Fx {
443 continue;
444 }
445 let (fl, fr) = &mut fx_in[bi];
446 if let Some((cl, cr)) = &mut self.buses[bi].inserts {
447 cl.process(&mut fl[..frames]);
448 cr.process(&mut fr[..frames]);
449 }
450 let ret = self.buses[bi].gain * self.buses[bi].to_master;
451 for f in 0..frames {
452 master_l[f] += fl[f] * ret;
453 master_r[f] += fr[f] * ret;
454 }
455 }
456
457 if let Some((cl, cr)) = &mut self.buses[0].inserts {
459 cl.process(&mut master_l[..frames]);
460 cr.process(&mut master_r[..frames]);
461 }
462 let master_gain = self.buses[0].gain;
463 for f in 0..frames {
464 out[f * 2] = master_l[f] * master_gain;
465 out[f * 2 + 1] = master_r[f] * master_gain;
466 }
467
468 self.scratch = scratch;
469 self.master_l = master_l;
470 self.master_r = master_r;
471 self.bus_l = bus_l;
472 self.bus_r = bus_r;
473 self.fx_in = fx_in;
474 frames
475 }
476
477 fn reset(&mut self) {
480 for s in self.sources.iter_mut() {
481 s.source.reset();
482 }
483 }
484}