Skip to content

Commit 5a14057

Browse files
committed
PannerNode: cache the entire HRTFProcessor (not just the HRIR sphere)
This reduces panner node HRTF setting time to ~1ms
1 parent b86ee1a commit 5a14057

File tree

1 file changed

+14
-14
lines changed

1 file changed

+14
-14
lines changed

src/node/panner.rs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,27 @@ use super::{
1515
AudioNode, ChannelConfig, ChannelConfigOptions, ChannelCountMode, ChannelInterpretation,
1616
};
1717

18-
/// Load the HRIR sphere for the given sample_rate
18+
/// Load the HRTF processor for the given sample_rate
1919
///
2020
/// The included data contains the impulse responses at 44100 Hertz, so it needs to be resampled
2121
/// for other values (which can easily take 100s of milliseconds). Therefore cache the result (per
2222
/// 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();
23+
fn load_hrtf_processor(sample_rate: u32) -> (HrtfProcessor, usize) {
24+
static INSTANCE: OnceLock<Mutex<HashMap<u32, (HrtfProcessor, usize)>>> = OnceLock::new();
2525
let cache = INSTANCE.get_or_init(|| Mutex::new(HashMap::new()));
2626
let mut guard = cache.lock().unwrap();
2727
guard
2828
.entry(sample_rate)
2929
.or_insert_with(|| {
3030
let resource = include_bytes!("../../resources/IRC_1003_C.bin");
31-
HrirSphere::new(&resource[..], sample_rate).unwrap()
31+
let hrir_sphere = HrirSphere::new(&resource[..], sample_rate).unwrap();
32+
let len = hrir_sphere.len();
33+
34+
let interpolation_steps = 1; // TODO?
35+
let samples_per_step = RENDER_QUANTUM_SIZE / interpolation_steps;
36+
let processor = HrtfProcessor::new(hrir_sphere, interpolation_steps, samples_per_step);
37+
38+
(processor, len)
3239
})
3340
.clone()
3441
}
@@ -187,14 +194,7 @@ struct HrtfState {
187194
}
188195

189196
impl HrtfState {
190-
fn new(hrir_sphere: HrirSphere) -> Self {
191-
let len = hrir_sphere.len();
192-
193-
let interpolation_steps = 1;
194-
let samples_per_step = RENDER_QUANTUM_SIZE / interpolation_steps;
195-
196-
let processor = HrtfProcessor::new(hrir_sphere, interpolation_steps, samples_per_step);
197-
197+
fn new(processor: HrtfProcessor, len: usize) -> Self {
198198
Self {
199199
len,
200200
processor,
@@ -570,8 +570,8 @@ impl PannerNode {
570570
PanningModelType::EqualPower => None,
571571
PanningModelType::HRTF => {
572572
let sample_rate = self.context().sample_rate() as u32;
573-
let hrir_sphere = load_hrir_sphere(sample_rate);
574-
Some(HrtfState::new(hrir_sphere))
573+
let (processor, len) = load_hrtf_processor(sample_rate);
574+
Some(HrtfState::new(processor, len))
575575
}
576576
};
577577

0 commit comments

Comments
 (0)