fyrox_sound/renderer/
mod.rs1#![allow(clippy::float_cmp)]
29
30use crate::{
31 context::DistanceModel, listener::Listener, math, renderer::hrtf::HrtfRenderer,
32 source::SoundSource,
33};
34use fyrox_core::math::lerpf;
35use fyrox_core::{
36 reflect::prelude::*,
37 uuid_provider,
38 visitor::{Visit, VisitResult, Visitor},
39};
40use strum_macros::{AsRefStr, EnumString, VariantNames};
41
42pub mod hrtf;
43
44#[allow(clippy::large_enum_variant)]
48#[derive(Debug, Clone, AsRefStr, EnumString, VariantNames, Visit, Reflect)]
49pub enum Renderer {
50 Default,
52
53 HrtfRenderer(HrtfRenderer),
56}
57
58uuid_provider!(Renderer = "13bf8432-987a-4216-b6aa-f5c0e8914a31");
59
60impl Default for Renderer {
61 fn default() -> Self {
62 Self::Default
63 }
64}
65
66fn render_with_params(
67 source: &mut SoundSource,
68 left_gain: f32,
69 right_gain: f32,
70 mix_buffer: &mut [(f32, f32)],
71) {
72 let last_left_gain = *source.last_left_gain.get_or_insert(left_gain);
73 let last_right_gain = *source.last_right_gain.get_or_insert(right_gain);
74
75 if last_left_gain != left_gain || last_right_gain != right_gain {
76 let step = 1.0 / mix_buffer.len() as f32;
77 let mut t = 0.0;
78 for ((out_left, out_right), &(raw_left, raw_right)) in
79 mix_buffer.iter_mut().zip(source.frame_samples())
80 {
81 *out_left += math::lerpf(last_left_gain, left_gain, t) * raw_left;
84 *out_right += math::lerpf(last_right_gain, right_gain, t) * raw_right;
85
86 t += step;
87 }
88 } else {
89 for ((out_left, out_right), &(raw_left, raw_right)) in
90 mix_buffer.iter_mut().zip(source.frame_samples())
91 {
92 *out_left += left_gain * raw_left;
94 *out_right += right_gain * raw_right;
95 }
96 }
97}
98
99pub(crate) fn render_source_default(
100 source: &mut SoundSource,
101 listener: &Listener,
102 distance_model: DistanceModel,
103 mix_buffer: &mut [(f32, f32)],
104) {
105 let distance_gain = lerpf(
106 1.0,
107 source.calculate_distance_gain(listener, distance_model),
108 source.spatial_blend(),
109 );
110 let panning = lerpf(
111 source.panning(),
112 source.calculate_panning(listener),
113 source.spatial_blend(),
114 );
115 let gain = distance_gain * source.gain();
116 let left_gain = gain * (1.0 + panning);
117 let right_gain = gain * (1.0 - panning);
118 render_with_params(source, left_gain, right_gain, mix_buffer);
119 source.last_left_gain = Some(left_gain);
120 source.last_right_gain = Some(right_gain);
121}
122
123pub(crate) fn render_source_2d_only(source: &mut SoundSource, mix_buffer: &mut [(f32, f32)]) {
124 let gain = (1.0 - source.spatial_blend()) * source.gain();
125 let left_gain = gain * (1.0 + source.panning());
126 let right_gain = gain * (1.0 - source.panning());
127 render_with_params(source, left_gain, right_gain, mix_buffer);
128 source.last_left_gain = Some(left_gain);
129 source.last_right_gain = Some(right_gain);
130}