Skip to content

Commit 7e9c18c

Browse files
uklotzdeorottier
authored andcommitted
Avoid repeated access to sine table behind OnceLock
1 parent c365ede commit 7e9c18c

File tree

2 files changed

+24
-11
lines changed

2 files changed

+24
-11
lines changed

src/node/oscillator.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ impl OscillatorNode {
222222
started: false,
223223
periodic_wave: None,
224224
ended_triggered: false,
225+
sine_table: sine_table(),
225226
};
226227

227228
let node = Self {
@@ -327,6 +328,8 @@ struct OscillatorRenderer {
327328
periodic_wave: Option<PeriodicWave>,
328329
/// defines if the `ended` events was already dispatched
329330
ended_triggered: bool,
331+
/// Precomputed sine table
332+
sine_table: &'static [f32],
330333
}
331334

332335
impl AudioProcessor for OscillatorRenderer {
@@ -467,8 +470,7 @@ impl OscillatorRenderer {
467470

468471
// linear interpolation into lookup table
469472
let k = (position - floored) as f32;
470-
let sine_table = sine_table();
471-
sine_table[prev_index].mul_add(1. - k, sine_table[next_index] * k)
473+
self.sine_table[prev_index].mul_add(1. - k, self.sine_table[next_index] * k)
472474
}
473475

474476
#[inline]

src/node/stereo_panner.rs

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,9 @@ fn assert_valid_channel_count_mode(mode: ChannelCountMode) {
6969
/// - `gain_left = (x * PI / 2.).cos()`
7070
/// - `gain_right = (x * PI / 2.).sin()`
7171
#[inline(always)]
72-
fn get_stereo_gains(x: f32) -> [f32; 2] {
72+
fn get_stereo_gains(sine_table: &[f32], x: f32) -> [f32; 2] {
7373
let idx = (x * TABLE_LENGTH_BY_4_F32) as usize;
7474

75-
let sine_table = sine_table();
7675
let gain_left = sine_table[idx + TABLE_LENGTH_BY_4_USIZE];
7776
let gain_right = sine_table[idx];
7877

@@ -185,7 +184,7 @@ impl StereoPannerNode {
185184

186185
pan_param.set_value(options.pan);
187186

188-
let renderer = StereoPannerRenderer { pan: pan_proc };
187+
let renderer = StereoPannerRenderer::new(pan_proc);
189188

190189
let node = Self {
191190
registration,
@@ -209,6 +208,16 @@ struct StereoPannerRenderer {
209208
/// Position of the input in the output’s stereo image.
210209
/// -1 represents full left, +1 represents full right.
211210
pan: AudioParamId,
211+
sine_table: &'static [f32],
212+
}
213+
214+
impl StereoPannerRenderer {
215+
fn new(pan: AudioParamId) -> Self {
216+
Self {
217+
pan,
218+
sine_table: sine_table(),
219+
}
220+
}
212221
}
213222

214223
impl AudioProcessor for StereoPannerRenderer {
@@ -241,7 +250,7 @@ impl AudioProcessor for StereoPannerRenderer {
241250
if pan_values.len() == 1 {
242251
let pan = pan_values[0];
243252
let x = (pan + 1.) * 0.5;
244-
let [gain_left, gain_right] = get_stereo_gains(x);
253+
let [gain_left, gain_right] = get_stereo_gains(self.sine_table, x);
245254

246255
left.iter_mut()
247256
.zip(right.iter_mut())
@@ -257,7 +266,7 @@ impl AudioProcessor for StereoPannerRenderer {
257266
.zip(input.channel_data(0).iter())
258267
.for_each(|(((l, r), pan), input)| {
259268
let x = (pan + 1.) * 0.5;
260-
let [gain_left, gain_right] = get_stereo_gains(x);
269+
let [gain_left, gain_right] = get_stereo_gains(self.sine_table, x);
261270

262271
*l = input * gain_left;
263272
*r = input * gain_right;
@@ -268,7 +277,7 @@ impl AudioProcessor for StereoPannerRenderer {
268277
if pan_values.len() == 1 {
269278
let pan = pan_values[0];
270279
let x = if pan <= 0. { pan + 1. } else { pan };
271-
let [gain_left, gain_right] = get_stereo_gains(x);
280+
let [gain_left, gain_right] = get_stereo_gains(self.sine_table, x);
272281

273282
left.iter_mut()
274283
.zip(right.iter_mut())
@@ -292,13 +301,13 @@ impl AudioProcessor for StereoPannerRenderer {
292301
.for_each(|((((l, r), &pan), &input_left), &input_right)| {
293302
if pan <= 0. {
294303
let x = pan + 1.;
295-
let [gain_left, gain_right] = get_stereo_gains(x);
304+
let [gain_left, gain_right] = get_stereo_gains(self.sine_table, x);
296305

297306
*l = input_right.mul_add(gain_left, input_left);
298307
*r = input_right * gain_right;
299308
} else {
300309
let x = pan;
301-
let [gain_left, gain_right] = get_stereo_gains(x);
310+
let [gain_left, gain_right] = get_stereo_gains(self.sine_table, x);
302311

303312
*l = input_left * gain_left;
304313
*r = input_left.mul_add(gain_right, input_right);
@@ -347,11 +356,13 @@ mod tests {
347356

348357
#[test]
349358
fn test_get_stereo_gains() {
359+
let sine_table = sine_table();
360+
350361
// check correctness of wavetable lookup
351362
for i in 0..1001 {
352363
let x = i as f32 / 1000.;
353364

354-
let [gain_left, gain_right] = get_stereo_gains(x);
365+
let [gain_left, gain_right] = get_stereo_gains(sine_table, x);
355366

356367
assert_float_eq!(
357368
gain_left,

0 commit comments

Comments
 (0)