1
1
//! The biquad filter control and renderer parts
2
- use num_complex :: Complex ;
2
+ use std :: any :: Any ;
3
3
use std:: f64:: consts:: { PI , SQRT_2 } ;
4
4
use std:: sync:: atomic:: { AtomicU32 , Ordering } ;
5
- use std:: sync:: Arc ;
5
+
6
+ use num_complex:: Complex ;
6
7
7
8
use crate :: context:: { AudioContextRegistration , AudioParamId , BaseAudioContext } ;
8
9
use crate :: param:: { AudioParam , AudioParamDescriptor } ;
@@ -309,7 +310,7 @@ pub struct BiquadFilterNode {
309
310
/// filter, depends on the `BiquadFilterType`
310
311
gain : AudioParam ,
311
312
/// `BiquadFilterType` represented as u32
312
- type_ : Arc < AtomicU32 > ,
313
+ type_ : AtomicU32 ,
313
314
}
314
315
315
316
impl AudioNode for BiquadFilterNode {
@@ -341,23 +342,32 @@ impl BiquadFilterNode {
341
342
context. register ( move |registration| {
342
343
let sample_rate = context. sample_rate ( ) ;
343
344
344
- let q_options = AudioParamDescriptor {
345
+ let BiquadFilterOptions {
346
+ q,
347
+ detune,
348
+ frequency,
349
+ gain,
350
+ type_,
351
+ channel_config,
352
+ } = options;
353
+
354
+ let q_param_options = AudioParamDescriptor {
345
355
min_value : f32:: MIN ,
346
356
max_value : f32:: MAX ,
347
357
default_value : 1. ,
348
358
automation_rate : crate :: param:: AutomationRate :: A ,
349
359
} ;
350
- let ( q_param, q_proc) = context. create_audio_param ( q_options , & registration) ;
351
- q_param. set_value ( options . q ) ;
360
+ let ( q_param, q_proc) = context. create_audio_param ( q_param_options , & registration) ;
361
+ q_param. set_value ( q) ;
352
362
353
- let detune_options = AudioParamDescriptor {
363
+ let detune_param_options = AudioParamDescriptor {
354
364
min_value : -153_600. ,
355
365
max_value : 153_600. ,
356
366
default_value : 0. ,
357
367
automation_rate : crate :: param:: AutomationRate :: A ,
358
368
} ;
359
- let ( d_param, d_proc) = context. create_audio_param ( detune_options , & registration) ;
360
- d_param. set_value ( options . detune ) ;
369
+ let ( d_param, d_proc) = context. create_audio_param ( detune_param_options , & registration) ;
370
+ d_param. set_value ( detune) ;
361
371
362
372
let freq_options = AudioParamDescriptor {
363
373
min_value : 0. ,
@@ -366,7 +376,7 @@ impl BiquadFilterNode {
366
376
automation_rate : crate :: param:: AutomationRate :: A ,
367
377
} ;
368
378
let ( f_param, f_proc) = context. create_audio_param ( freq_options, & registration) ;
369
- f_param. set_value ( options . frequency ) ;
379
+ f_param. set_value ( frequency) ;
370
380
371
381
let gain_options = AudioParamDescriptor {
372
382
min_value : f32:: MIN ,
@@ -375,16 +385,14 @@ impl BiquadFilterNode {
375
385
automation_rate : crate :: param:: AutomationRate :: A ,
376
386
} ;
377
387
let ( g_param, g_proc) = context. create_audio_param ( gain_options, & registration) ;
378
- g_param. set_value ( options. gain ) ;
379
-
380
- let type_ = Arc :: new ( AtomicU32 :: new ( options. type_ as u32 ) ) ;
388
+ g_param. set_value ( gain) ;
381
389
382
390
let renderer = BiquadFilterRenderer {
383
391
gain : g_proc,
384
392
detune : d_proc,
385
393
frequency : f_proc,
386
394
q : q_proc,
387
- type_ : Arc :: clone ( & type_ ) ,
395
+ type_,
388
396
x1 : Vec :: with_capacity ( MAX_CHANNELS ) ,
389
397
x2 : Vec :: with_capacity ( MAX_CHANNELS ) ,
390
398
y1 : Vec :: with_capacity ( MAX_CHANNELS ) ,
@@ -393,8 +401,8 @@ impl BiquadFilterNode {
393
401
394
402
let node = Self {
395
403
registration,
396
- channel_config : options . channel_config . into ( ) ,
397
- type_,
404
+ channel_config : channel_config. into ( ) ,
405
+ type_ : AtomicU32 :: new ( type_ as u32 ) ,
398
406
q : q_param,
399
407
detune : d_param,
400
408
frequency : f_param,
@@ -432,7 +440,7 @@ impl BiquadFilterNode {
432
440
/// Returns the biquad filter type
433
441
#[ must_use]
434
442
pub fn type_ ( & self ) -> BiquadFilterType {
435
- self . type_ . load ( Ordering :: SeqCst ) . into ( )
443
+ self . type_ . load ( Ordering :: Acquire ) . into ( )
436
444
}
437
445
438
446
/// biquad filter type setter
@@ -441,7 +449,8 @@ impl BiquadFilterNode {
441
449
///
442
450
/// * `type_` - the biquad filter type (lowpass, highpass,...)
443
451
pub fn set_type ( & self , type_ : BiquadFilterType ) {
444
- self . type_ . store ( type_ as u32 , Ordering :: SeqCst ) ;
452
+ self . type_ . store ( type_ as u32 , Ordering :: Release ) ;
453
+ self . registration . post_message ( type_) ;
445
454
}
446
455
447
456
/// Returns the frequency response for the specified frequencies
@@ -533,8 +542,8 @@ struct BiquadFilterRenderer {
533
542
/// boost/attenuation (dB) - its impact on the frequency response of the filter
534
543
/// depends on the `BiquadFilterType`
535
544
gain : AudioParamId ,
536
- /// `BiquadFilterType` represented as u32
537
- type_ : Arc < AtomicU32 > ,
545
+ /// `BiquadFilterType`
546
+ type_ : BiquadFilterType ,
538
547
// keep filter state for each channel
539
548
x1 : Vec < f64 > ,
540
549
x2 : Vec < f64 > ,
@@ -596,7 +605,7 @@ impl AudioProcessor for BiquadFilterRenderer {
596
605
}
597
606
598
607
// get a-rate parameters
599
- let type_: BiquadFilterType = self . type_ . load ( Ordering :: SeqCst ) . into ( ) ;
608
+ let type_ = self . type_ ;
600
609
let frequency = params. get ( & self . frequency ) ;
601
610
let detune = params. get ( & self . detune ) ;
602
611
let q = params. get ( & self . q ) ;
@@ -671,6 +680,15 @@ impl AudioProcessor for BiquadFilterRenderer {
671
680
672
681
true
673
682
}
683
+
684
+ fn onmessage ( & mut self , msg : & mut dyn Any ) {
685
+ if let Some ( & type_) = msg. downcast_ref :: < BiquadFilterType > ( ) {
686
+ self . type_ = type_;
687
+ return ;
688
+ }
689
+
690
+ log:: warn!( "BiquadFilterRenderer: Dropping incoming message {msg:?}" ) ;
691
+ }
674
692
}
675
693
676
694
#[ cfg( test) ]
0 commit comments