Skip to content

Commit f22bc22

Browse files
committed
Merge remote-tracking branch 'origin/main' into feature/rename-channelconfig-audionodeoption
2 parents 47e37db + 95ebe22 commit f22bc22

File tree

2 files changed

+73
-3
lines changed

2 files changed

+73
-3
lines changed

src/node/dynamics_compressor.rs

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::render::{
88
};
99
use crate::{AtomicF32, RENDER_QUANTUM_SIZE};
1010

11-
use super::{AudioNode, AudioNodeOptions, ChannelConfig};
11+
use super::{AudioNode, AudioNodeOptions, ChannelConfig, ChannelCountMode, ChannelInterpretation};
1212

1313
// Converting a value 𝑣 in decibels to linear gain unit means returning 10𝑣/20.
1414
fn db_to_lin(val: f32) -> f32 {
@@ -53,11 +53,48 @@ impl Default for DynamicsCompressorOptions {
5353
ratio: 12., // unit less
5454
release: 0.25, // seconds
5555
threshold: -24., // dB
56-
audio_node_options: AudioNodeOptions::default(),
56+
audio_node_options: AudioNodeOptions {
57+
channel_count: 2,
58+
channel_count_mode: ChannelCountMode::ClampedMax,
59+
channel_interpretation: ChannelInterpretation::Speakers,
60+
},
5761
}
5862
}
5963
}
6064

65+
/// Assert that the channel count is valid for the DynamicsCompressorNode
66+
/// see <https://webaudio.github.io/web-audio-api/#audionode-channelcount-constraints>
67+
///
68+
/// # Panics
69+
///
70+
/// This function panics if given count is greater than 2
71+
///
72+
#[track_caller]
73+
#[inline(always)]
74+
fn assert_valid_channel_count(count: usize) {
75+
assert!(
76+
count <= 2,
77+
"NotSupportedError - DynamicsCompressorNode channel count cannot be greater than two"
78+
);
79+
}
80+
81+
/// Assert that the channel count is valid for the DynamicsCompressorNode
82+
/// see <https://webaudio.github.io/web-audio-api/#audionode-channelcountmode-constraints>
83+
///
84+
/// # Panics
85+
///
86+
/// This function panics if given count mode is [`ChannelCountMode::Max`]
87+
///
88+
#[track_caller]
89+
#[inline(always)]
90+
fn assert_valid_channel_count_mode(mode: ChannelCountMode) {
91+
assert_ne!(
92+
mode,
93+
ChannelCountMode::Max,
94+
"NotSupportedError - DynamicsCompressorNode channel count mode cannot be set to max"
95+
);
96+
}
97+
6198
/// `DynamicsCompressorNode` provides a compression effect.
6299
///
63100
/// It lowers the volume of the loudest parts of the signal and raises the volume
@@ -126,11 +163,27 @@ impl AudioNode for DynamicsCompressorNode {
126163
fn number_of_outputs(&self) -> usize {
127164
1
128165
}
166+
167+
// see <https://webaudio.github.io/web-audio-api/#audionode-channelcount-constraints>
168+
fn set_channel_count(&self, count: usize) {
169+
assert_valid_channel_count(count);
170+
self.channel_config.set_count(count, self.registration());
171+
}
172+
173+
// see <https://webaudio.github.io/web-audio-api/#audionode-channelcountmode-constraints>
174+
fn set_channel_count_mode(&self, mode: ChannelCountMode) {
175+
assert_valid_channel_count_mode(mode);
176+
self.channel_config
177+
.set_count_mode(mode, self.registration());
178+
}
129179
}
130180

131181
impl DynamicsCompressorNode {
132182
pub fn new<C: BaseAudioContext>(context: &C, options: DynamicsCompressorOptions) -> Self {
133183
context.base().register(move |registration| {
184+
assert_valid_channel_count(options.audio_node_options.channel_count);
185+
assert_valid_channel_count_mode(options.audio_node_options.channel_count_mode);
186+
134187
// attack, knee, ratio, release and threshold have automation rate constraints
135188
// https://webaudio.github.io/web-audio-api/#audioparam-automation-rate-constraints
136189
let attack_param_opts = AudioParamDescriptor {

src/node/waveshaper.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,9 @@ struct WaveShaperRenderer {
379379
downsampler_x2: Resampler,
380380
// down sampler configured to divide by 4 the upsampled signal
381381
downsampler_x4: Resampler,
382+
// check if silence can be propagated, i.e. if curve if None or if
383+
// it's output value for zero signal is zero (i.e. < 1e-9)
384+
can_propagate_silence: bool,
382385
}
383386

384387
impl AudioProcessor for WaveShaperRenderer {
@@ -393,7 +396,7 @@ impl AudioProcessor for WaveShaperRenderer {
393396
let input = &inputs[0];
394397
let output = &mut outputs[0];
395398

396-
if input.is_silent() {
399+
if input.is_silent() && self.can_propagate_silence {
397400
output.make_silent();
398401
return false;
399402
}
@@ -495,6 +498,19 @@ impl AudioProcessor for WaveShaperRenderer {
495498

496499
if let Some(curve) = msg.downcast_mut::<Option<Vec<f32>>>() {
497500
std::mem::swap(&mut self.curve, curve);
501+
502+
self.can_propagate_silence = if let Some(curve) = &self.curve {
503+
if curve.len() % 2 == 1 {
504+
curve[curve.len() / 2].abs() < 1e-9
505+
} else {
506+
let a = curve[curve.len() / 2 - 1];
507+
let b = curve[curve.len() / 2];
508+
((a + b) / 2.).abs() < 1e-9
509+
}
510+
} else {
511+
true
512+
};
513+
498514
return;
499515
}
500516

@@ -534,6 +550,7 @@ impl WaveShaperRenderer {
534550
upsampler_x4,
535551
downsampler_x2,
536552
downsampler_x4,
553+
can_propagate_silence: true,
537554
}
538555
}
539556
}

0 commit comments

Comments
 (0)