@@ -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 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
+
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,22 @@ 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 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
+ }
134
157
options. audio_node_options . channel_count = options. number_of_outputs ;
135
158
136
159
assert_valid_channel_count_mode ( options. audio_node_options . channel_count_mode ) ;
@@ -139,10 +162,11 @@ impl ChannelSplitterNode {
139
162
let node = ChannelSplitterNode {
140
163
registration,
141
164
channel_config : options. audio_node_options . into ( ) ,
165
+ number_of_outputs : options. number_of_outputs ,
142
166
} ;
143
167
144
168
let render = ChannelSplitterRenderer {
145
- number_of_outputs : node . channel_count ( ) ,
169
+ number_of_outputs : options . number_of_outputs ,
146
170
} ;
147
171
148
172
( node, Box :: new ( render) )
@@ -186,18 +210,59 @@ impl AudioProcessor for ChannelSplitterRenderer {
186
210
187
211
#[ cfg( test) ]
188
212
mod tests {
213
+ use float_eq:: assert_float_eq;
214
+
189
215
use crate :: context:: { BaseAudioContext , OfflineAudioContext } ;
190
216
use crate :: node:: { AudioNode , AudioScheduledSourceNode } ;
191
217
use crate :: AudioBuffer ;
192
218
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
+ }
194
258
195
259
#[ test]
196
260
fn test_splitter ( ) {
197
261
let sample_rate = 48000. ;
198
262
let mut context = OfflineAudioContext :: new ( 1 , 128 , sample_rate) ;
199
263
200
264
let splitter = context. create_channel_splitter ( 2 ) ;
265
+
201
266
// connect the 2nd output to the destination
202
267
splitter. connect_at ( & context. destination ( ) , 1 , 0 ) ;
203
268
0 commit comments