1
1
//! The IIR filter control and renderer parts
2
+ use arrayvec:: ArrayVec ;
2
3
use num_complex:: Complex ;
4
+
3
5
use std:: f64:: consts:: PI ;
4
6
5
7
use crate :: context:: { AudioContextRegistration , BaseAudioContext } ;
@@ -254,7 +256,7 @@ struct IirFilterRenderer {
254
256
/// Normalized filter's coeffs -- `(b[n], a[n])`
255
257
norm_coeffs : Vec < ( f64 , f64 ) > ,
256
258
/// filter's states
257
- states : Vec < Vec < f64 > > ,
259
+ states : ArrayVec < Vec < f64 > , MAX_CHANNELS > ,
258
260
}
259
261
260
262
impl IirFilterRenderer {
@@ -292,7 +294,11 @@ impl IirFilterRenderer {
292
294
} ) ;
293
295
294
296
let coeffs_len = norm_coeffs. len ( ) ;
295
- let states = vec ! [ Vec :: <f64 >:: with_capacity( MAX_CHANNELS ) ; coeffs_len] ;
297
+
298
+ // eagerly assume stereo input, will adjust during rendering if needed
299
+ let mut states = ArrayVec :: new ( ) ;
300
+ states. push ( vec ! [ 0. ; coeffs_len] ) ;
301
+ states. push ( vec ! [ 0. ; coeffs_len] ) ;
296
302
297
303
Self {
298
304
norm_coeffs,
@@ -340,15 +346,16 @@ impl AudioProcessor for IirFilterRenderer {
340
346
// see https://webaudio.github.io/web-audio-api/#channels-tail-time
341
347
let num_channels = input. number_of_channels ( ) ;
342
348
343
- if num_channels != self . states [ 0 ] . len ( ) {
344
- self . states
345
- . iter_mut ( )
346
- . for_each ( |state| state. resize ( num_channels, 0. ) ) ;
349
+ if num_channels != self . states . len ( ) {
350
+ self . states . truncate ( num_channels) ;
351
+ for _ in self . states . len ( ) ..num_channels {
352
+ self . states . push ( vec ! [ 0. ; self . norm_coeffs. len( ) ] ) ;
353
+ }
347
354
}
348
355
349
356
output. set_number_of_channels ( num_channels) ;
350
357
} else {
351
- let num_channels = self . states [ 0 ] . len ( ) ;
358
+ let num_channels = self . states . len ( ) ;
352
359
output. set_number_of_channels ( num_channels) ;
353
360
}
354
361
@@ -359,17 +366,18 @@ impl AudioProcessor for IirFilterRenderer {
359
366
} else {
360
367
input. channel_data ( channel_number)
361
368
} ;
369
+ let channel_state = & mut self . states [ channel_number] ;
362
370
363
371
for ( & i, o) in input_channel. iter ( ) . zip ( output_channel. iter_mut ( ) ) {
364
372
let input = f64:: from ( i) ;
365
373
let b0 = self . norm_coeffs [ 0 ] . 0 ;
366
- let last_state = self . states [ 0 ] [ channel_number ] ;
374
+ let last_state = channel_state [ 0 ] ;
367
375
let output = b0. mul_add ( input, last_state) ;
368
376
369
377
// update states for next call
370
378
for ( i, ( b, a) ) in self . norm_coeffs . iter ( ) . skip ( 1 ) . enumerate ( ) {
371
- let state = self . states [ i + 1 ] [ channel_number ] ;
372
- self . states [ i ] [ channel_number ] = b * input - a * output + state;
379
+ let state = channel_state [ i + 1 ] ;
380
+ channel_state [ i ] = b * input - a * output + state;
373
381
}
374
382
375
383
#[ cfg( debug_assertions) ]
0 commit comments