From 97f6b060f8dce5c0b25a45cfe21faac5e523ab95 Mon Sep 17 00:00:00 2001 From: Max Heimbrock <43608204+MaxHeimbrock@users.noreply.github.com> Date: Mon, 10 Aug 2026 11:34:33 +0200 Subject: [PATCH] Audio boost script --- .../Meet/Assets/Runtime/AudioBoostFilter.cs | 54 +++++++++++++++++++ .../Assets/Runtime/AudioBoostFilter.cs.meta | 11 ++++ Samples~/Meet/Assets/Runtime/MeetManager.cs | 12 +++++ 3 files changed, 77 insertions(+) create mode 100644 Samples~/Meet/Assets/Runtime/AudioBoostFilter.cs create mode 100644 Samples~/Meet/Assets/Runtime/AudioBoostFilter.cs.meta diff --git a/Samples~/Meet/Assets/Runtime/AudioBoostFilter.cs b/Samples~/Meet/Assets/Runtime/AudioBoostFilter.cs new file mode 100644 index 00000000..18b07046 --- /dev/null +++ b/Samples~/Meet/Assets/Runtime/AudioBoostFilter.cs @@ -0,0 +1,54 @@ +using UnityEngine; + +/// +/// Boosts the audio of the on this GameObject by a linear +/// gain multiplier, e.g. for devices that play WebRTC audio at very low volume. +/// Values above 1 are hard-clipped at full scale, so expect distortion on loud +/// passages at higher settings. +/// +/// Must be added AFTER the for this source has been +/// created: Unity runs audio filters in component order and the SDK's probe overwrites +/// the buffer, so this filter only has an effect while it sits below the probe. +/// +public class AudioBoostFilter : MonoBehaviour +{ + [Tooltip("Linear gain applied to the audio. 1 = unchanged.")] + [Range(1f, 10f)] + public float multiplier = 1f; + + private void OnEnable() + { + AudioSettings.OnAudioConfigurationChanged += OnAudioConfigurationChanged; + } + + private void OnDisable() + { + AudioSettings.OnAudioConfigurationChanged -= OnAudioConfigurationChanged; + } + + // AudioStream reacts to this same event by destroying and re-adding its probe, + // which appends the new probe below this filter — the probe would then overwrite + // the boosted output. Re-adding this component moves the gain back to the end of + // the filter chain. AudioStream subscribed to the event before this component + // existed, so the new probe is already in place when this handler runs. + private void OnAudioConfigurationChanged(bool deviceWasChanged) + { + var replacement = gameObject.AddComponent(); + replacement.multiplier = multiplier; + Destroy(this); + } + + // Called by Unity on the audio thread. + private void OnAudioFilterRead(float[] data, int channels) + { + var gain = multiplier; + if (gain == 1f) + return; + + for (int i = 0; i < data.Length; i++) + { + var boosted = data[i] * gain; + data[i] = boosted > 1f ? 1f : (boosted < -1f ? -1f : boosted); + } + } +} diff --git a/Samples~/Meet/Assets/Runtime/AudioBoostFilter.cs.meta b/Samples~/Meet/Assets/Runtime/AudioBoostFilter.cs.meta new file mode 100644 index 00000000..f08ce2ac --- /dev/null +++ b/Samples~/Meet/Assets/Runtime/AudioBoostFilter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ceba6fcb200fd43deb998fefd5af0d60 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Samples~/Meet/Assets/Runtime/MeetManager.cs b/Samples~/Meet/Assets/Runtime/MeetManager.cs index 1dc27c71..f5f801f4 100644 --- a/Samples~/Meet/Assets/Runtime/MeetManager.cs +++ b/Samples~/Meet/Assets/Runtime/MeetManager.cs @@ -44,6 +44,13 @@ public class MeetManager : MonoBehaviour [Tooltip("Prefer hardware audio processing (e.g., iOS VPIO). Lower latency but may have different quality characteristics.")] [SerializeField] private bool preferHardwareProcessing = true; + [Header("Audio Playback (Unity Audio mode only)")] + [Tooltip("Linear gain applied to remote audio played through Unity AudioSources, " + + "for devices with very low playout volume. 1 = unchanged. " + + "Can also be tweaked per track at runtime on the AudioTrack GameObjects.")] + [Range(1f, 10f)] + [SerializeField] private float remoteAudioBoost = 1f; + private const string PlaceholderTextureResourceName = "PlaceholderTileSquare"; private Texture _placeholderTexture; @@ -375,6 +382,11 @@ private void AddRemoteAudioTrack(RemoteAudioTrack audioTrack) var audiostream = new AudioStream(audioTrack, source); _audioStreams.Add(sid, audiostream); + // Must be added after the AudioStream so the boost filter runs after the + // SDK's probe in Unity's filter chain. + var boost = audioObject.AddComponent(); + boost.multiplier = remoteAudioBoost; + _audioObjects[sid] = audioObject; }