Skip to content

Commit b86ee1a

Browse files
committed
Improve HRTF panner initialization time by caching the HRIR sphere
relates to #371
1 parent 74b58e0 commit b86ee1a

File tree

1 file changed

+21
-2
lines changed

1 file changed

+21
-2
lines changed

src/node/panner.rs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use std::any::Any;
2+
use std::collections::HashMap;
23
use std::f32::consts::PI;
4+
use std::sync::{Mutex, OnceLock};
35

46
use float_eq::float_eq;
57
use hrtf::{HrirSphere, HrtfContext, HrtfProcessor, Vec3};
@@ -13,6 +15,24 @@ use super::{
1315
AudioNode, ChannelConfig, ChannelConfigOptions, ChannelCountMode, ChannelInterpretation,
1416
};
1517

18+
/// Load the HRIR sphere for the given sample_rate
19+
///
20+
/// The included data contains the impulse responses at 44100 Hertz, so it needs to be resampled
21+
/// for other values (which can easily take 100s of milliseconds). Therefore cache the result (per
22+
/// sample rate) in a global variable and clone it every time a new panner is created.
23+
fn load_hrir_sphere(sample_rate: u32) -> HrirSphere {
24+
static INSTANCE: OnceLock<Mutex<HashMap<u32, HrirSphere>>> = OnceLock::new();
25+
let cache = INSTANCE.get_or_init(|| Mutex::new(HashMap::new()));
26+
let mut guard = cache.lock().unwrap();
27+
guard
28+
.entry(sample_rate)
29+
.or_insert_with(|| {
30+
let resource = include_bytes!("../../resources/IRC_1003_C.bin");
31+
HrirSphere::new(&resource[..], sample_rate).unwrap()
32+
})
33+
.clone()
34+
}
35+
1636
/// Spatialization algorithm used to position the audio in 3D space
1737
#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)]
1838
pub enum PanningModelType {
@@ -549,9 +569,8 @@ impl PannerNode {
549569
let hrtf_option = match value {
550570
PanningModelType::EqualPower => None,
551571
PanningModelType::HRTF => {
552-
let resource = include_bytes!("../../resources/IRC_1003_C.bin");
553572
let sample_rate = self.context().sample_rate() as u32;
554-
let hrir_sphere = HrirSphere::new(&resource[..], sample_rate).unwrap();
573+
let hrir_sphere = load_hrir_sphere(sample_rate);
555574
Some(HrtfState::new(hrir_sphere))
556575
}
557576
};

0 commit comments

Comments
 (0)