Skip to content

Commit fefec26

Browse files
committed
fix: reimplement tail time + prepare multichannel
1 parent e48ac74 commit fefec26

File tree

1 file changed

+62
-27
lines changed

1 file changed

+62
-27
lines changed

src/node/convolver.rs

Lines changed: 62 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ pub struct ConvolverOptions {
7272
impl Default for ConvolverOptions {
7373
fn default() -> Self {
7474
Self {
75-
buffer: Default::default(),
76-
disable_normalization: Default::default(),
75+
buffer: None,
76+
disable_normalization: false,
7777
audio_node_options: AudioNodeOptions {
7878
channel_count: 2,
7979
channel_count_mode: ChannelCountMode::ClampedMax,
@@ -222,7 +222,11 @@ impl ConvolverNode {
222222
assert_valid_channel_count_mode(audio_node_options.channel_count_mode);
223223

224224
let mut node = context.base().register(move |registration| {
225-
let renderer = ConvolverRenderer { inner: None };
225+
let renderer = ConvolverRenderer {
226+
convolvers: None,
227+
impulse_length: 0,
228+
tail_count: 0,
229+
};
226230

227231
let node = Self {
228232
registration,
@@ -278,24 +282,33 @@ impl ConvolverNode {
278282
1.
279283
};
280284

281-
let mut samples = vec![0.; buffer.length()];
282-
samples
283-
.iter_mut()
284-
.zip(buffer.get_channel_data(0))
285-
.for_each(|(o, i)| *o = *i * scale);
286-
287-
let mut convolver = FFTConvolver::<f32>::default();
285+
let mut convolvers = Vec::<FFTConvolver<f32>>::new();
288286
// Size of the partition changes a lot the perf...
289287
// - RENDER_QUANTUM_SIZE -> 20x (compared to real-time)
290288
// - RENDER_QUANTUM_SIZE * 8 -> 134x
291-
convolver
292-
.init(RENDER_QUANTUM_SIZE * 8, &samples)
293-
.expect("Unable to initialize convolution engine");
289+
let partition_size = RENDER_QUANTUM_SIZE * 8;
290+
291+
[0..buffer.number_of_channels()].iter().for_each(|_| {
292+
let mut scaled_channel = vec![0.; buffer.length()];
293+
scaled_channel
294+
.iter_mut()
295+
.zip(buffer.get_channel_data(0))
296+
.for_each(|(o, i)| *o = *i * scale);
297+
298+
let mut convolver = FFTConvolver::<f32>::default();
299+
convolver
300+
.init(RENDER_QUANTUM_SIZE * 8, &samples)
301+
.expect("Unable to initialize convolution engine");
294302

295-
// let padded_buffer = AudioBuffer::from(samples, sample_rate);
296-
// let convolve = ConvolverRendererInner::new(padded_buffer);
303+
convolvers.push(convolver);
304+
});
305+
306+
let msg = ConvolverInfosMessage {
307+
convolvers: Some(convolvers),
308+
impulse_length: buffer.length(),
309+
};
297310

298-
self.registration.post_message(Some(convolver));
311+
self.registration.post_message(msg);
299312
self.buffer = Some(buffer);
300313
}
301314

@@ -310,8 +323,15 @@ impl ConvolverNode {
310323
}
311324
}
312325

326+
struct ConvolverInfosMessage {
327+
convolvers: Option<Vec<FFTConvolver<f32>>>,
328+
impulse_length: usize,
329+
}
330+
313331
struct ConvolverRenderer {
314-
inner: Option<FFTConvolver<f32>>,
332+
convolvers: Option<Vec<FFTConvolver<f32>>>,
333+
impulse_length: usize,
334+
tail_count: usize,
315335
}
316336

317337
impl AudioProcessor for ConvolverRenderer {
@@ -327,34 +347,49 @@ impl AudioProcessor for ConvolverRenderer {
327347
let output = &mut outputs[0];
328348
output.force_mono();
329349

330-
let convolver = match &mut self.inner {
350+
let convolvers = match &mut self.convolvers {
331351
None => {
332352
// no convolution buffer set, passthrough
333353
*output = input.clone();
334354
return !input.is_silent();
335355
}
336-
Some(convolver) => convolver,
356+
Some(convolvers) => convolvers,
337357
};
338358

359+
// @todo - https://webaudio.github.io/web-audio-api/#Convolution-channel-configurations
339360
let mut mono = input.clone();
340361
mono.mix(1, ChannelInterpretation::Speakers);
341-
let input = &mono.channel_data(0)[..];
342-
let output = &mut output.channel_data_mut(0)[..];
343362

344-
let _ = convolver.process(input, output);
363+
// let input = &mono.channel_data(0)[..];
364+
// let output = &mut output.channel_data_mut(0)[..];
365+
let _ = convolvers[0].process(&mono.channel_data(0), &mut output.channel_data_mut(0));
345366

346367
// handle tail time
347-
// if input.is_silent() {
348-
// return convolver.tail(output);
349-
// }
368+
if input.is_silent() {
369+
self.tail_count += RENDER_QUANTUM_SIZE;
370+
371+
if self.tail_count >= self.impulse_length {
372+
return false;
373+
} else {
374+
return true
375+
}
376+
}
377+
378+
self.tail_count = 0;
350379

351380
true
352381
}
353382

354383
fn onmessage(&mut self, msg: &mut dyn Any) {
355-
if let Some(convolver) = msg.downcast_mut::<Option<FFTConvolver<f32>>>() {
384+
if let Some(msg) = msg.downcast_mut::<ConvolverInfosMessage>() {
385+
let ConvolverInfosMessage {
386+
convolvers,
387+
impulse_length,
388+
} = msg;
356389
// Avoid deallocation in the render thread by swapping the convolver.
357-
std::mem::swap(&mut self.inner, convolver);
390+
std::mem::swap(&mut self.convolvers, convolvers);
391+
self.impulse_length = *impulse_length;
392+
358393
return;
359394
}
360395

0 commit comments

Comments
 (0)