Skip to content

Commit 5c2ea5e

Browse files
b-maorottier
authored andcommitted
refactor: harmonize biquad filter message passing
1 parent fb985f9 commit 5c2ea5e

File tree

2 files changed

+44
-25
lines changed

2 files changed

+44
-25
lines changed

src/node/biquad_filter.rs

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
//! The biquad filter control and renderer parts
2-
use num_complex::Complex;
2+
use std::any::Any;
33
use std::f64::consts::{PI, SQRT_2};
44
use std::sync::atomic::{AtomicU32, Ordering};
5-
use std::sync::Arc;
5+
6+
use num_complex::Complex;
67

78
use crate::context::{AudioContextRegistration, AudioParamId, BaseAudioContext};
89
use crate::param::{AudioParam, AudioParamDescriptor};
@@ -309,7 +310,7 @@ pub struct BiquadFilterNode {
309310
/// filter, depends on the `BiquadFilterType`
310311
gain: AudioParam,
311312
/// `BiquadFilterType` represented as u32
312-
type_: Arc<AtomicU32>,
313+
type_: AtomicU32,
313314
}
314315

315316
impl AudioNode for BiquadFilterNode {
@@ -341,23 +342,32 @@ impl BiquadFilterNode {
341342
context.register(move |registration| {
342343
let sample_rate = context.sample_rate();
343344

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 {
345355
min_value: f32::MIN,
346356
max_value: f32::MAX,
347357
default_value: 1.,
348358
automation_rate: crate::param::AutomationRate::A,
349359
};
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);
352362

353-
let detune_options = AudioParamDescriptor {
363+
let detune_param_options = AudioParamDescriptor {
354364
min_value: -153_600.,
355365
max_value: 153_600.,
356366
default_value: 0.,
357367
automation_rate: crate::param::AutomationRate::A,
358368
};
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);
361371

362372
let freq_options = AudioParamDescriptor {
363373
min_value: 0.,
@@ -366,7 +376,7 @@ impl BiquadFilterNode {
366376
automation_rate: crate::param::AutomationRate::A,
367377
};
368378
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);
370380

371381
let gain_options = AudioParamDescriptor {
372382
min_value: f32::MIN,
@@ -375,16 +385,14 @@ impl BiquadFilterNode {
375385
automation_rate: crate::param::AutomationRate::A,
376386
};
377387
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);
381389

382390
let renderer = BiquadFilterRenderer {
383391
gain: g_proc,
384392
detune: d_proc,
385393
frequency: f_proc,
386394
q: q_proc,
387-
type_: Arc::clone(&type_),
395+
type_,
388396
x1: Vec::with_capacity(MAX_CHANNELS),
389397
x2: Vec::with_capacity(MAX_CHANNELS),
390398
y1: Vec::with_capacity(MAX_CHANNELS),
@@ -393,8 +401,8 @@ impl BiquadFilterNode {
393401

394402
let node = Self {
395403
registration,
396-
channel_config: options.channel_config.into(),
397-
type_,
404+
channel_config: channel_config.into(),
405+
type_: AtomicU32::new(type_ as u32),
398406
q: q_param,
399407
detune: d_param,
400408
frequency: f_param,
@@ -432,7 +440,7 @@ impl BiquadFilterNode {
432440
/// Returns the biquad filter type
433441
#[must_use]
434442
pub fn type_(&self) -> BiquadFilterType {
435-
self.type_.load(Ordering::SeqCst).into()
443+
self.type_.load(Ordering::Acquire).into()
436444
}
437445

438446
/// biquad filter type setter
@@ -441,7 +449,8 @@ impl BiquadFilterNode {
441449
///
442450
/// * `type_` - the biquad filter type (lowpass, highpass,...)
443451
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_);
445454
}
446455

447456
/// Returns the frequency response for the specified frequencies
@@ -533,8 +542,8 @@ struct BiquadFilterRenderer {
533542
/// boost/attenuation (dB) - its impact on the frequency response of the filter
534543
/// depends on the `BiquadFilterType`
535544
gain: AudioParamId,
536-
/// `BiquadFilterType` represented as u32
537-
type_: Arc<AtomicU32>,
545+
/// `BiquadFilterType`
546+
type_: BiquadFilterType,
538547
// keep filter state for each channel
539548
x1: Vec<f64>,
540549
x2: Vec<f64>,
@@ -596,7 +605,7 @@ impl AudioProcessor for BiquadFilterRenderer {
596605
}
597606

598607
// get a-rate parameters
599-
let type_: BiquadFilterType = self.type_.load(Ordering::SeqCst).into();
608+
let type_ = self.type_;
600609
let frequency = params.get(&self.frequency);
601610
let detune = params.get(&self.detune);
602611
let q = params.get(&self.q);
@@ -671,6 +680,15 @@ impl AudioProcessor for BiquadFilterRenderer {
671680

672681
true
673682
}
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+
}
674692
}
675693

676694
#[cfg(test)]

src/node/oscillator.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -195,23 +195,24 @@ impl OscillatorNode {
195195
} = options;
196196

197197
// frequency audio parameter
198-
let freq_param_opts = AudioParamDescriptor {
198+
let freq_param_options = AudioParamDescriptor {
199199
min_value: -nyquist,
200200
max_value: nyquist,
201201
default_value: 440.,
202202
automation_rate: AutomationRate::A,
203203
};
204-
let (f_param, f_proc) = context.create_audio_param(freq_param_opts, &registration);
204+
let (f_param, f_proc) = context.create_audio_param(freq_param_options, &registration);
205205
f_param.set_value(frequency);
206206

207207
// detune audio parameter
208-
let det_param_opts = AudioParamDescriptor {
208+
let det_param_options = AudioParamDescriptor {
209209
min_value: -153_600.,
210210
max_value: 153_600.,
211211
default_value: 0.,
212212
automation_rate: AutomationRate::A,
213213
};
214-
let (det_param, det_proc) = context.create_audio_param(det_param_opts, &registration);
214+
let (det_param, det_proc) =
215+
context.create_audio_param(det_param_options, &registration);
215216
det_param.set_value(detune);
216217

217218
let renderer = OscillatorRenderer {

0 commit comments

Comments
 (0)