audio_processor_traits/
simple_processor.rs

1// Augmented Audio: Audio libraries and applications
2// Copyright (c) 2022 Pedro Tacla Yamada
3//
4// The MIT License (MIT)
5//
6// Permission is hereby granted, free of charge, to any person obtaining a copy
7// of this software and associated documentation files (the "Software"), to deal
8// in the Software without restriction, including without limitation the rights
9// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10// copies of the Software, and to permit persons to whom the Software is
11// furnished to do so, subject to the following conditions:
12//
13// The above copyright notice and this permission notice shall be included in
14// all copies or substantial portions of the Software.
15//
16// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22// THE SOFTWARE.
23//! Provides what is in some cases a simpler form of expressing signal processing.
24
25use crate::parameters::{AudioProcessorHandleProvider, AudioProcessorHandleRef};
26use crate::{AudioBuffer, AudioContext, AudioProcessor, MidiEventHandler, MidiMessageLike, Zero};
27use std::ops::{AddAssign, DivAssign};
28
29pub trait MonoAudioProcessor {
30    type SampleType: Copy;
31
32    fn m_prepare(&mut self, _context: &mut AudioContext) {}
33    fn m_process(
34        &mut self,
35        _context: &mut AudioContext,
36        sample: Self::SampleType,
37    ) -> Self::SampleType {
38        sample
39    }
40}
41
42#[derive(Default)]
43pub struct MonoCopyProcessor<Processor: MonoAudioProcessor> {
44    processor: Processor,
45}
46
47impl<Processor: MonoAudioProcessor> MonoCopyProcessor<Processor> {
48    pub fn new(processor: Processor) -> MonoCopyProcessor<Processor> {
49        Self { processor }
50    }
51
52    pub fn processor(&self) -> &Processor {
53        &self.processor
54    }
55
56    pub fn processor_mut(&mut self) -> &mut Processor {
57        &mut self.processor
58    }
59}
60
61impl<Processor: MonoAudioProcessor> AudioProcessor for MonoCopyProcessor<Processor>
62where
63    Processor::SampleType: Zero + AddAssign + DivAssign + From<f32>,
64{
65    type SampleType = Processor::SampleType;
66
67    fn prepare(&mut self, context: &mut AudioContext) {
68        self.processor.m_prepare(context);
69    }
70
71    fn process(&mut self, context: &mut AudioContext, data: &mut AudioBuffer<Self::SampleType>) {
72        for sample_num in 0..data.num_samples() {
73            let mut mono_input = Self::SampleType::zero();
74            for channel_num in 0..data.num_channels() {
75                mono_input += *data.get(channel_num, sample_num);
76            }
77            mono_input /= Self::SampleType::from(data.num_channels() as f32);
78
79            let output = self.processor.m_process(context, mono_input);
80
81            for channel_num in 0..data.num_channels() {
82                data.set(channel_num, sample_num, output);
83            }
84        }
85    }
86}
87
88impl<Processor: MidiEventHandler + MonoAudioProcessor> MidiEventHandler
89    for MonoCopyProcessor<Processor>
90{
91    fn process_midi_events<Message: MidiMessageLike>(&mut self, midi_messages: &[Message]) {
92        self.processor.process_midi_events(midi_messages)
93    }
94}
95
96pub struct MultiChannel<Processor: MonoAudioProcessor> {
97    processors: Vec<Processor>,
98    factory: Box<dyn Fn() -> Processor + Send>,
99}
100
101impl<Processor: MonoAudioProcessor> MultiChannel<Processor> {
102    pub fn new(factory: impl Fn() -> Processor + 'static + Send) -> MultiChannel<Processor> {
103        Self {
104            processors: vec![],
105            factory: Box::new(factory),
106        }
107    }
108
109    pub fn for_each(&mut self, mut f: impl FnMut(&mut Processor)) {
110        for processor in &mut self.processors {
111            f(processor);
112        }
113    }
114}
115
116impl<Processor: MonoAudioProcessor> AudioProcessor for MultiChannel<Processor> {
117    type SampleType = Processor::SampleType;
118
119    fn prepare(&mut self, context: &mut AudioContext) {
120        self.processors = (0..context.settings.input_channels)
121            .map(|_| (self.factory)())
122            .collect();
123        for processor in &mut self.processors {
124            processor.m_prepare(context);
125        }
126    }
127
128    fn process(&mut self, context: &mut AudioContext, data: &mut AudioBuffer<Self::SampleType>) {
129        for (channel, processor) in data.channels_mut().iter_mut().zip(&mut self.processors) {
130            for sample in channel {
131                *sample = processor.m_process(context, *sample);
132            }
133        }
134    }
135}
136
137impl<Processor: AudioProcessorHandleProvider + MonoAudioProcessor> AudioProcessorHandleProvider
138    for MultiChannel<Processor>
139{
140    fn generic_handle(&self) -> AudioProcessorHandleRef {
141        self.processors[0].generic_handle()
142    }
143}
144
145pub fn process_buffer<Processor, SampleType>(
146    context: &mut AudioContext,
147    processor: &mut Processor,
148    signal: &mut AudioBuffer<SampleType>,
149) where
150    Processor: MonoAudioProcessor<SampleType = SampleType>,
151    SampleType: Copy + AddAssign + num::Zero,
152{
153    for sample_num in 0..signal.num_samples() {
154        let mut mono_input = SampleType::zero();
155        for channel_num in 0..signal.num_channels() {
156            mono_input += *signal.get(channel_num, sample_num);
157        }
158
159        let output = processor.m_process(context, mono_input);
160
161        for channel_num in 0..signal.num_channels() {
162            signal.set(channel_num, sample_num, output);
163        }
164    }
165}