1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
use audio_processor_traits::simple_processor::SimpleAudioProcessor;
use audio_processor_traits::Float;
pub struct PanProcessor<SampleType> {
panning: SampleType,
}
impl<SampleType: Float> Default for PanProcessor<SampleType> {
fn default() -> Self {
Self::new(SampleType::from(0.0).unwrap())
}
}
impl<SampleType: Float> PanProcessor<SampleType> {
pub fn new(panning: SampleType) -> Self {
PanProcessor { panning }
}
pub fn panning(&self) -> SampleType {
self.panning
}
pub fn set_panning(&mut self, panning: SampleType) {
self.panning = panning;
}
}
impl<SampleType> SimpleAudioProcessor for PanProcessor<SampleType>
where
SampleType: Float + Sync + Send,
{
type SampleType = SampleType;
fn s_process_frame(&mut self, frame: &mut [SampleType]) {
let zero = SampleType::zero();
let one = SampleType::one();
let panning = self.panning;
let left_input = frame[0];
let right_input = frame[1];
if panning > zero {
let left_output = left_input * (one - panning);
let right_output = right_input + left_input * panning;
frame[0] = left_output;
frame[1] = right_output;
} else if panning < zero {
let left_output = left_input + right_input * (-panning);
let right_output = right_input * (one + panning);
frame[0] = left_output;
frame[1] = right_output;
}
}
}
#[cfg(test)]
mod test {
use audio_processor_testing_helpers::assert_f_eq;
use audio_processor_traits::simple_processor::process_buffer;
use audio_processor_traits::AudioBuffer;
use audio_processor_traits::InterleavedAudioBuffer;
use super::*;
#[test]
fn test_pan_noop() {
let mut pan = PanProcessor::default();
let mut samples = [1., 1., 1., 1., 1., 1.];
let mut input = InterleavedAudioBuffer::new(2, &mut samples);
process_buffer(&mut pan, &mut input);
for frame in input.frames() {
for sample in frame.iter() {
assert_f_eq!(*sample, 1.);
}
}
}
#[test]
fn test_hard_pan_to_left() {
let mut pan = PanProcessor::new(-1.0);
let mut samples = [1., 1., 1., 1., 1., 1.];
let mut input = InterleavedAudioBuffer::new(2, &mut samples);
process_buffer(&mut pan, &mut input);
for sample_index in 0..input.num_samples() {
let left = *input.get(0, sample_index);
let right = *input.get(1, sample_index);
assert_f_eq!(left, 2.0);
assert_f_eq!(right, 0.0);
}
}
#[test]
fn test_hard_pan_to_right() {
let mut pan = PanProcessor::new(1.0);
let mut samples = [1., 1., 1., 1., 1., 1.];
let mut input = InterleavedAudioBuffer::new(2, &mut samples);
process_buffer(&mut pan, &mut input);
for sample_index in 0..input.num_samples() {
let left = *input.get(0, sample_index);
let right = *input.get(1, sample_index);
assert_f_eq!(right, 2.0);
assert_f_eq!(left, 0.0);
}
}
}