@@ -8,6 +8,8 @@ use crate::MAX_CHANNELS;
8
8
9
9
use super :: { AudioNode , AudioNodeOptions , ChannelConfig , ChannelCountMode , ChannelInterpretation } ;
10
10
11
+ const DEFAULT_NUMBER_OF_OUTPUTS : usize = 6 ;
12
+
11
13
/// Assert that the given number of channels is valid for a ChannelMergerNode
12
14
///
13
15
/// # Panics
@@ -27,6 +29,22 @@ pub(crate) fn assert_valid_number_of_channels(number_of_channels: usize) {
27
29
) ;
28
30
}
29
31
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
+
30
48
/// Assert that the channel count mode is valid for the ChannelSplitterNode
31
49
/// see <https://webaudio.github.io/web-audio-api/#audionode-channelcountmode-constraints>
32
50
///
@@ -72,9 +90,9 @@ pub struct ChannelSplitterOptions {
72
90
impl Default for ChannelSplitterOptions {
73
91
fn default ( ) -> Self {
74
92
Self {
75
- number_of_outputs : 6 ,
93
+ number_of_outputs : DEFAULT_NUMBER_OF_OUTPUTS ,
76
94
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
78
96
channel_count_mode : ChannelCountMode :: Explicit ,
79
97
channel_interpretation : ChannelInterpretation :: Discrete ,
80
98
} ,
@@ -87,6 +105,7 @@ impl Default for ChannelSplitterOptions {
87
105
pub struct ChannelSplitterNode {
88
106
registration : AudioContextRegistration ,
89
107
channel_config : ChannelConfig ,
108
+ number_of_outputs : usize ,
90
109
}
91
110
92
111
impl AudioNode for ChannelSplitterNode {
@@ -99,11 +118,7 @@ impl AudioNode for ChannelSplitterNode {
99
118
}
100
119
101
120
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 ) ;
107
122
}
108
123
109
124
fn set_channel_count_mode ( & self , mode : ChannelCountMode ) {
@@ -123,14 +138,23 @@ impl AudioNode for ChannelSplitterNode {
123
138
}
124
139
125
140
fn number_of_outputs ( & self ) -> usize {
126
- self . channel_count ( )
141
+ self . number_of_outputs
127
142
}
128
143
}
129
144
130
145
impl ChannelSplitterNode {
131
146
pub fn new < C : BaseAudioContext > ( context : & C , mut options : ChannelSplitterOptions ) -> Self {
132
147
context. base ( ) . register ( move |registration| {
133
148
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
+ }
134
158
options. audio_node_options . channel_count = options. number_of_outputs ;
135
159
136
160
assert_valid_channel_count_mode ( options. audio_node_options . channel_count_mode ) ;
@@ -139,10 +163,11 @@ impl ChannelSplitterNode {
139
163
let node = ChannelSplitterNode {
140
164
registration,
141
165
channel_config : options. audio_node_options . into ( ) ,
166
+ number_of_outputs : options. number_of_outputs ,
142
167
} ;
143
168
144
169
let render = ChannelSplitterRenderer {
145
- number_of_outputs : node . channel_count ( ) ,
170
+ number_of_outputs : options . number_of_outputs ,
146
171
} ;
147
172
148
173
( node, Box :: new ( render) )
@@ -186,18 +211,59 @@ impl AudioProcessor for ChannelSplitterRenderer {
186
211
187
212
#[ cfg( test) ]
188
213
mod tests {
214
+ use float_eq:: assert_float_eq;
215
+
189
216
use crate :: context:: { BaseAudioContext , OfflineAudioContext } ;
190
217
use crate :: node:: { AudioNode , AudioScheduledSourceNode } ;
191
218
use crate :: AudioBuffer ;
192
219
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
+ }
194
259
195
260
#[ test]
196
261
fn test_splitter ( ) {
197
262
let sample_rate = 48000. ;
198
263
let mut context = OfflineAudioContext :: new ( 1 , 128 , sample_rate) ;
199
264
200
265
let splitter = context. create_channel_splitter ( 2 ) ;
266
+
201
267
// connect the 2nd output to the destination
202
268
splitter. connect_at ( & context. destination ( ) , 1 , 0 ) ;
203
269
0 commit comments