@@ -8,6 +8,8 @@ use crate::MAX_CHANNELS;
88
99use 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 {
7290impl 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 {
87105pub struct ChannelSplitterNode {
88106 registration : AudioContextRegistration ,
89107 channel_config : ChannelConfig ,
108+ number_of_outputs : usize ,
90109}
91110
92111impl 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
130145impl 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) ]
188212mod 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