Skip to content

Commit 6d093c8

Browse files
committed
fix: more compliant option checks + add some tests
1 parent 8c520b1 commit 6d093c8

File tree

2 files changed

+101
-12
lines changed

2 files changed

+101
-12
lines changed

src/node/channel_merger.rs

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ impl AudioNode for ChannelMergerNode {
101101

102102
fn set_channel_count(&self, count: usize) {
103103
assert_valid_channel_count(count);
104-
self.channel_config.set_count(count, self.registration());
105104
}
106105

107106
fn set_channel_count_mode(&self, mode: ChannelCountMode) {
@@ -174,10 +173,35 @@ impl AudioProcessor for ChannelMergerRenderer {
174173

175174
#[cfg(test)]
176175
mod tests {
176+
use float_eq::assert_float_eq;
177+
177178
use crate::context::{BaseAudioContext, OfflineAudioContext};
178179
use crate::node::{AudioNode, AudioScheduledSourceNode};
179180

180-
use float_eq::assert_float_eq;
181+
use super::*;
182+
183+
#[test]
184+
#[should_panic]
185+
fn test_invalid_constructor_options() {
186+
let sample_rate = 48000.;
187+
let context = OfflineAudioContext::new(1, 128, sample_rate);
188+
189+
let mut options = ChannelMergerOptions::default();
190+
options.audio_node_options.channel_count = 2;
191+
192+
let _merger = ChannelMergerNode::new(&context, options);
193+
}
194+
195+
#[test]
196+
#[should_panic]
197+
fn test_invalid_set_channel_count() {
198+
let sample_rate = 48000.;
199+
let context = OfflineAudioContext::new(1, 128, sample_rate);
200+
201+
let options = ChannelMergerOptions::default();
202+
let merger = ChannelMergerNode::new(&context, options);
203+
merger.set_channel_count(3);
204+
}
181205

182206
#[test]
183207
fn test_merge() {

src/node/channel_splitter.rs

Lines changed: 75 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ use crate::MAX_CHANNELS;
88

99
use super::{AudioNode, AudioNodeOptions, ChannelConfig, ChannelCountMode, ChannelInterpretation};
1010

11+
const DEFAULT_NUMBER_OF_OUTPUTS: usize = 6;
12+
1113
/// Assert that the given number of channels is valid for a ChannelMergerNode
1214
///
1315
/// # Panics
@@ -27,6 +29,22 @@ pub(crate) fn assert_valid_number_of_channels(number_of_channels: usize) {
2729
);
2830
}
2931

32+
/// Assert that the channel count is valid for the ChannelMergerNode
33+
/// see <https://webaudio.github.io/web-audio-api/#audionode-channelcount-constraints>
34+
///
35+
/// # Panics
36+
///
37+
/// This function panics if given count is greater than 2
38+
///
39+
#[track_caller]
40+
#[inline(always)]
41+
fn assert_valid_channel_count(count: usize, number_of_outputs: usize) {
42+
assert!(
43+
count == number_of_outputs,
44+
"InvalidStateError - channel count of ChannelSplitterNode must be equal to number of outputs"
45+
);
46+
}
47+
3048
/// Assert that the channel count mode is valid for the ChannelSplitterNode
3149
/// see <https://webaudio.github.io/web-audio-api/#audionode-channelcountmode-constraints>
3250
///
@@ -72,9 +90,9 @@ pub struct ChannelSplitterOptions {
7290
impl Default for ChannelSplitterOptions {
7391
fn default() -> Self {
7492
Self {
75-
number_of_outputs: 6,
93+
number_of_outputs: DEFAULT_NUMBER_OF_OUTPUTS,
7694
audio_node_options: AudioNodeOptions {
77-
channel_count: 6, // must be same as number_of_outputs
95+
channel_count: DEFAULT_NUMBER_OF_OUTPUTS, // must be same as number_of_outputs
7896
channel_count_mode: ChannelCountMode::Explicit,
7997
channel_interpretation: ChannelInterpretation::Discrete,
8098
},
@@ -87,6 +105,7 @@ impl Default for ChannelSplitterOptions {
87105
pub struct ChannelSplitterNode {
88106
registration: AudioContextRegistration,
89107
channel_config: ChannelConfig,
108+
number_of_outputs: usize,
90109
}
91110

92111
impl AudioNode for ChannelSplitterNode {
@@ -99,11 +118,7 @@ impl AudioNode for ChannelSplitterNode {
99118
}
100119

101120
fn set_channel_count(&self, count: usize) {
102-
assert_eq!(
103-
count,
104-
self.channel_count(),
105-
"InvalidStateError - Cannot edit channel count of ChannelSplitterNode"
106-
);
121+
assert_valid_channel_count(count, self.number_of_outputs);
107122
}
108123

109124
fn set_channel_count_mode(&self, mode: ChannelCountMode) {
@@ -123,14 +138,22 @@ impl AudioNode for ChannelSplitterNode {
123138
}
124139

125140
fn number_of_outputs(&self) -> usize {
126-
self.channel_count()
141+
self.number_of_outputs
127142
}
128143
}
129144

130145
impl ChannelSplitterNode {
131146
pub fn new<C: BaseAudioContext>(context: &C, mut options: ChannelSplitterOptions) -> Self {
132147
context.base().register(move |registration| {
133148
assert_valid_number_of_channels(options.number_of_outputs);
149+
150+
// if channel count has been explicitely set, we need to check its value against number of outputs
151+
if options.audio_node_options.channel_count != DEFAULT_NUMBER_OF_OUTPUTS {
152+
assert_valid_channel_count(
153+
options.audio_node_options.channel_count,
154+
options.number_of_outputs,
155+
);
156+
}
134157
options.audio_node_options.channel_count = options.number_of_outputs;
135158

136159
assert_valid_channel_count_mode(options.audio_node_options.channel_count_mode);
@@ -139,10 +162,11 @@ impl ChannelSplitterNode {
139162
let node = ChannelSplitterNode {
140163
registration,
141164
channel_config: options.audio_node_options.into(),
165+
number_of_outputs: options.number_of_outputs,
142166
};
143167

144168
let render = ChannelSplitterRenderer {
145-
number_of_outputs: node.channel_count(),
169+
number_of_outputs: options.number_of_outputs,
146170
};
147171

148172
(node, Box::new(render))
@@ -186,18 +210,59 @@ impl AudioProcessor for ChannelSplitterRenderer {
186210

187211
#[cfg(test)]
188212
mod tests {
213+
use float_eq::assert_float_eq;
214+
189215
use crate::context::{BaseAudioContext, OfflineAudioContext};
190216
use crate::node::{AudioNode, AudioScheduledSourceNode};
191217
use crate::AudioBuffer;
192218

193-
use float_eq::assert_float_eq;
219+
use super::*;
220+
221+
#[test]
222+
fn test_valid_constructor_options() {
223+
let sample_rate = 48000.;
224+
let context = OfflineAudioContext::new(1, 128, sample_rate);
225+
226+
let options = ChannelSplitterOptions {
227+
number_of_outputs: 2,
228+
..Default::default()
229+
};
230+
231+
let splitter = ChannelSplitterNode::new(&context, options);
232+
assert_eq!(splitter.number_of_outputs(), 2);
233+
assert_eq!(splitter.channel_count(), 2);
234+
}
235+
236+
#[test]
237+
#[should_panic]
238+
fn test_invalid_constructor_options() {
239+
let sample_rate = 48000.;
240+
let context = OfflineAudioContext::new(1, 128, sample_rate);
241+
242+
let mut options = ChannelSplitterOptions::default();
243+
options.audio_node_options.channel_count = 7;
244+
245+
let _splitter = ChannelSplitterNode::new(&context, options);
246+
}
247+
248+
#[test]
249+
#[should_panic]
250+
fn test_set_channel_count() {
251+
let sample_rate = 48000.;
252+
let context = OfflineAudioContext::new(1, 128, sample_rate);
253+
254+
let options = ChannelSplitterOptions::default();
255+
let splitter = ChannelSplitterNode::new(&context, options);
256+
splitter.set_channel_count(3);
257+
}
194258

195259
#[test]
196260
fn test_splitter() {
197261
let sample_rate = 48000.;
198262
let mut context = OfflineAudioContext::new(1, 128, sample_rate);
199263

200264
let splitter = context.create_channel_splitter(2);
265+
201266
// connect the 2nd output to the destination
202267
splitter.connect_at(&context.destination(), 1, 0);
203268

0 commit comments

Comments
 (0)