diff --git a/src/source/channel_volume.rs b/src/source/channel_volume.rs index 4398e6bf..514dcc9c 100644 --- a/src/source/channel_volume.rs +++ b/src/source/channel_volume.rs @@ -59,6 +59,11 @@ where pub fn into_inner(self) -> I { self.input } + + /// Gets the volume for a given channel number. Returns `None` if channel number is invalid. + pub fn volume(&self, channel: usize) -> Option<&Float> { + self.channel_volumes.get(channel) + } } impl Iterator for ChannelVolume diff --git a/src/source/spatial.rs b/src/source/spatial.rs index 136dad9d..0dca88fb 100644 --- a/src/source/spatial.rs +++ b/src/source/spatial.rs @@ -57,9 +57,9 @@ where let max_diff = dist_sq(left_ear, right_ear).sqrt(); let left_dist = left_dist_sq.sqrt(); let right_dist = right_dist_sq.sqrt(); - let left_diff_modifier = (((left_dist - right_dist) / max_diff + 1.0) / 4.0 + 0.5).min(1.0); + let left_diff_modifier = (((right_dist - left_dist) / max_diff + 1.0) / 4.0 + 0.5).min(1.0); let right_diff_modifier = - (((right_dist - left_dist) / max_diff + 1.0) / 4.0 + 0.5).min(1.0); + (((left_dist - right_dist) / max_diff + 1.0) / 4.0 + 0.5).min(1.0); let left_dist_modifier = (1.0 / left_dist_sq).min(1.0); let right_dist_modifier = (1.0 / right_dist_sq).min(1.0); self.input @@ -117,3 +117,67 @@ where self.input.try_seek(pos) } } + +#[cfg(test)] +mod tests { + use crate::{source::Spatial, Float}; + + const EPSILON: Float = 0.01; + + #[test] + fn equidistant_emitter_has_equal_volume() { + let emitter = [0.0, 0.0, 0.0]; + let left_ear = [-1.0, 0.0, 0.0]; + let right_ear = [1.0, 0.0, 0.0]; + let spatial = Spatial::new( + crate::source::SineWave::new(440.0), + emitter, + left_ear, + right_ear, + ); + let left = spatial.input.volume(0).expect("left channel should exist"); + let right = spatial.input.volume(1).expect("right channel should exist"); + assert!( + (left - right).abs() < EPSILON, + "Expected equal volume, got left: {left}, right: {right}" + ); + } + + #[test] + fn emitter_to_the_right_is_louder_in_right_ear() { + let emitter = [10.0, 0.0, 0.0]; + let left_ear = [-1.0, 0.0, 0.0]; + let right_ear = [1.0, 0.0, 0.0]; + let spatial = Spatial::new( + crate::source::SineWave::new(440.0), + emitter, + left_ear, + right_ear, + ); + let left = spatial.input.volume(0).expect("left channel should exist"); + let right = spatial.input.volume(1).expect("right channel should exist"); + assert!( + right > left, + "Expected right > left, got left: {left}, right: {right}" + ); + } + + #[test] + fn emitter_to_the_left_is_louder_in_left_ear() { + let emitter = [-10.0, 0.0, 0.0]; + let left_ear = [-1.0, 0.0, 0.0]; + let right_ear = [1.0, 0.0, 0.0]; + let spatial = Spatial::new( + crate::source::SineWave::new(440.0), + emitter, + left_ear, + right_ear, + ); + let left = spatial.input.volume(0).expect("left channel should exist"); + let right = spatial.input.volume(1).expect("right channel should exist"); + assert!( + left > right, + "Expected left > right, got left: {left}, right: {right}" + ); + } +}