Skip to content

Commit de445a1

Browse files
committed
Fast path and benchmark for ConstantSourceNode
1 parent 3d874d9 commit de445a1

File tree

2 files changed

+39
-17
lines changed

2 files changed

+39
-17
lines changed

benches/my_benchmark.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,17 @@ pub fn bench_audio_buffer_decode() {
5050
assert_eq!(buffer.length(), 101129);
5151
}
5252

53+
pub fn bench_constant_source() {
54+
let mut ctx = OfflineAudioContext::new(2, black_box(SAMPLES), SAMPLE_RATE);
55+
let mut src = ctx.create_constant_source();
56+
57+
src.connect(&ctx.destination());
58+
src.start_at(1.);
59+
src.stop_at(9.);
60+
61+
assert_eq!(ctx.start_rendering_sync().length(), SAMPLES);
62+
}
63+
5364
pub fn bench_sine() {
5465
let mut ctx = OfflineAudioContext::new(2, black_box(SAMPLES), SAMPLE_RATE);
5566
let mut osc = ctx.create_oscillator();
@@ -301,6 +312,7 @@ macro_rules! iai_or_criterion {
301312
iai_or_criterion!(
302313
bench_ctor,
303314
bench_audio_buffer_decode,
315+
bench_constant_source,
304316
bench_sine,
305317
bench_sine_gain,
306318
bench_sine_gain_delay,

src/node/constant_source.rs

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -201,23 +201,33 @@ impl AudioProcessor for ConstantSourceRenderer {
201201

202202
let offset = params.get(&self.offset);
203203
let output_channel = output.channel_data_mut(0);
204-
let mut current_time = scope.current_time;
205-
206-
output_channel
207-
.iter_mut()
208-
.zip(offset.iter().cycle())
209-
.for_each(|(o, &value)| {
210-
if current_time < self.start_time || current_time >= self.stop_time {
211-
*o = 0.;
212-
} else {
213-
// as we pick values directly from the offset param which is already
214-
// computed at sub-sample accuracy, we don't need to do more than
215-
// copying the values to their right place.
216-
*o = value;
217-
}
218-
219-
current_time += dt;
220-
});
204+
205+
// fast path
206+
if offset.len() == 1
207+
&& self.start_time <= scope.current_time
208+
&& self.stop_time > next_block_time
209+
{
210+
output_channel.fill(offset[0]);
211+
} else {
212+
// sample accurate path
213+
let mut current_time = scope.current_time;
214+
215+
output_channel
216+
.iter_mut()
217+
.zip(offset.iter().cycle())
218+
.for_each(|(o, &value)| {
219+
if current_time < self.start_time || current_time >= self.stop_time {
220+
*o = 0.;
221+
} else {
222+
// as we pick values directly from the offset param which is already
223+
// computed at sub-sample accuracy, we don't need to do more than
224+
// copying the values to their right place.
225+
*o = value;
226+
}
227+
228+
current_time += dt;
229+
});
230+
}
221231

222232
// tail_time false when output has ended this quantum
223233
let still_running = self.stop_time >= next_block_time;

0 commit comments

Comments
 (0)