@@ -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 ChannelSplitterNode
33+ /// see <https://webaudio.github.io/web-audio-api/#audionode-channelcount-constraints>
34+ ///
35+ /// # Panics
36+ ///
37+ /// This function panics if given count is not equal to number of outputs
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,23 @@ 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 explicitly set, we need to check
151+ // its value against number of outputs
152+ if options. audio_node_options . channel_count != DEFAULT_NUMBER_OF_OUTPUTS {
153+ assert_valid_channel_count (
154+ options. audio_node_options . channel_count ,
155+ options. number_of_outputs ,
156+ ) ;
157+ }
134158 options. audio_node_options . channel_count = options. number_of_outputs ;
135159
136160 assert_valid_channel_count_mode ( options. audio_node_options . channel_count_mode ) ;
@@ -139,10 +163,11 @@ impl ChannelSplitterNode {
139163 let node = ChannelSplitterNode {
140164 registration,
141165 channel_config : options. audio_node_options . into ( ) ,
166+ number_of_outputs : options. number_of_outputs ,
142167 } ;
143168
144169 let render = ChannelSplitterRenderer {
145- number_of_outputs : node . channel_count ( ) ,
170+ number_of_outputs : options . number_of_outputs ,
146171 } ;
147172
148173 ( node, Box :: new ( render) )
@@ -186,18 +211,59 @@ impl AudioProcessor for ChannelSplitterRenderer {
186211
187212#[ cfg( test) ]
188213mod tests {
214+ use float_eq:: assert_float_eq;
215+
189216 use crate :: context:: { BaseAudioContext , OfflineAudioContext } ;
190217 use crate :: node:: { AudioNode , AudioScheduledSourceNode } ;
191218 use crate :: AudioBuffer ;
192219
193- use float_eq:: assert_float_eq;
220+ use super :: * ;
221+
222+ #[ test]
223+ fn test_valid_constructor_options ( ) {
224+ let sample_rate = 48000. ;
225+ let context = OfflineAudioContext :: new ( 1 , 128 , sample_rate) ;
226+
227+ let options = ChannelSplitterOptions {
228+ number_of_outputs : 2 ,
229+ ..Default :: default ( )
230+ } ;
231+
232+ let splitter = ChannelSplitterNode :: new ( & context, options) ;
233+ assert_eq ! ( splitter. number_of_outputs( ) , 2 ) ;
234+ assert_eq ! ( splitter. channel_count( ) , 2 ) ;
235+ }
236+
237+ #[ test]
238+ #[ should_panic]
239+ fn test_invalid_constructor_options ( ) {
240+ let sample_rate = 48000. ;
241+ let context = OfflineAudioContext :: new ( 1 , 128 , sample_rate) ;
242+
243+ let mut options = ChannelSplitterOptions :: default ( ) ;
244+ options. audio_node_options . channel_count = 7 ;
245+
246+ let _splitter = ChannelSplitterNode :: new ( & context, options) ;
247+ }
248+
249+ #[ test]
250+ #[ should_panic]
251+ fn test_set_channel_count ( ) {
252+ let sample_rate = 48000. ;
253+ let context = OfflineAudioContext :: new ( 1 , 128 , sample_rate) ;
254+
255+ let options = ChannelSplitterOptions :: default ( ) ;
256+ let splitter = ChannelSplitterNode :: new ( & context, options) ;
257+ splitter. set_channel_count ( 3 ) ;
258+ }
194259
195260 #[ test]
196261 fn test_splitter ( ) {
197262 let sample_rate = 48000. ;
198263 let mut context = OfflineAudioContext :: new ( 1 , 128 , sample_rate) ;
199264
200265 let splitter = context. create_channel_splitter ( 2 ) ;
266+
201267 // connect the 2nd output to the destination
202268 splitter. connect_at ( & context. destination ( ) , 1 , 0 ) ;
203269
0 commit comments