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, Default)]
49pub enum Renderer {
50 #[default]
52 Default,
53
54 HrtfRenderer(HrtfRenderer),
57}
58
59uuid_provider!(Renderer = "13bf8432-987a-4216-b6aa-f5c0e8914a31");
60
61fn render_with_params(
62 source: &mut SoundSource,
63 left_gain: f32,
64 right_gain: f32,
65 mix_buffer: &mut [(f32, f32)],
66) {
67 let last_left_gain = *source.last_left_gain.get_or_insert(left_gain);
68 let last_right_gain = *source.last_right_gain.get_or_insert(right_gain);
69
70 if last_left_gain != left_gain || last_right_gain != right_gain {
71 let step = 1.0 / mix_buffer.len() as f32;
72 let mut t = 0.0;
73 for ((out_left, out_right), &(raw_left, raw_right)) in
74 mix_buffer.iter_mut().zip(source.frame_samples())
75 {
76 *out_left += math::lerpf(last_left_gain, left_gain, t) * raw_left;
79 *out_right += math::lerpf(last_right_gain, right_gain, t) * raw_right;
80
81 t += step;
82 }
83 } else {
84 for ((out_left, out_right), &(raw_left, raw_right)) in
85 mix_buffer.iter_mut().zip(source.frame_samples())
86 {
87 *out_left += left_gain * raw_left;
89 *out_right += right_gain * raw_right;
90 }
91 }
92}
93
94pub(crate) fn render_source_default(
95 source: &mut SoundSource,
96 listener: &Listener,
97 distance_model: DistanceModel,
98 mix_buffer: &mut [(f32, f32)],
99) {
100 let distance_gain = lerpf(
101 1.0,
102 source.calculate_distance_gain(listener, distance_model),
103 source.spatial_blend(),
104 );
105 let panning = lerpf(
106 source.panning(),
107 source.calculate_panning(listener),
108 source.spatial_blend(),
109 );
110 let gain = distance_gain * source.gain();
111 let left_gain = gain * (1.0 + panning);
112 let right_gain = gain * (1.0 - panning);
113 render_with_params(source, left_gain, right_gain, mix_buffer);
114 source.last_left_gain = Some(left_gain);
115 source.last_right_gain = Some(right_gain);
116}
117
118pub(crate) fn render_source_2d_only(source: &mut SoundSource, mix_buffer: &mut [(f32, f32)]) {
119 let gain = (1.0 - source.spatial_blend()) * source.gain();
120 let left_gain = gain * (1.0 + source.panning());
121 let right_gain = gain * (1.0 - source.panning());
122 render_with_params(source, left_gain, right_gain, mix_buffer);
123 source.last_left_gain = Some(left_gain);
124 source.last_right_gain = Some(right_gain);
125}