audio_processor_traits/
simple_processor.rs1use 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}