Search Unity

Question Procedural 3D audio

Discussion in 'Audio & Video' started by z_bulon, May 17, 2020.

  1. z_bulon

    z_bulon

    Joined:
    Oct 7, 2018
    Posts:
    9
    Hi,

    I have found the following way for procedural audio generation:
    1. Create an empty AudioSource
    2. Attach a script and implement void OnAudioFilterRead(float[] data, int channels)
    3. OnAudioFilterRead can insert any kind of procedural samples into the empty audio stream
    Problem:
    As I see every 3D effects (dopler, etc) are implemented in AudioSource, so 3D effects won't be applied for the above procedural audio chain (of course theoretically it would be possible to implement 3D effects in the audio filter script.

    Isn't there a simpler solution?
    e.g. feed AudioSource with procedural samples? Or to insert an existing 3D audio filter component into the end of the above procedural samples?
     
    NathBar likes this.
  2. Davide

    Davide

    Joined:
    Sep 19, 2012
    Posts:
    13
    Hi,
    i think you didn't understand how OnAudioFilterRead works or i didn't understand what's your question.

    OnAudioFilterRead actually FEEDS the AudioSource, so any effect applied on the audiosource will be applied to your procedural samples as well.

    You can also form a chain and add audio effect components (like reverb, highpass/lowpass filter) and they will be applied too.
     
  3. jay_luxus

    jay_luxus

    Joined:
    Oct 6, 2021
    Posts:
    1
    That is only partly true. Using the OnAudioFilterRead Method to generate procedural sound out of nothing, OnAudioFilterRead gets empty audio data from the audio source and fills it for example with a procedural noise sound on both channels (for stereo). When you try to adjust the balance of the channels now in the audio source, nothing happens. That's because stereo pan is applied before any effect. The same applies to spatial blending (3D-Effects). So, while the distance to the emitting object is still taken into account (The sound is louder the nearer the listener is to the emitter), actual spatial audio (where you here whether an emitter is left or right of the listener and doppler effect comes into account ect.) does not work for the same reason the balance of stereo channels doesn't work. It's applied before any effect or filter is applied.

    In this Case The Audio Source Component applies the Spatial Blending to the empty audio source (so, essentially, nothing happens), then OnAudioFilterRead gets the empty audio source data (with 3d effect, that has no impact, because the sound is still just flat nothingness) and fills the empty data on both channels with a generated sound. That sound is what the listener hears. Spatial Blending is not going to be applied to it since it was applied before streaming the data to OnAudioFilterRead. The only properties of audio source that apply to OnAudioFilterRead are those that address generall attributes for the whole audio stream like volume, pitch and distance. Channel specific properties like stereo pan and 3D-sound-direction do not apply.

    The solution is to either implement your own Spatial Blending in a custom Script or to use a Spatializer Plugin, which is actually encouraged by Unity. There is an Example Custom Spatializer SDK out there, that's part of the native audio SDK (https://docs.unity3d.com/Manual/AudioSpatializerSDK.html). The Download link there is unfortunately dead, but you can find the Source Files on github, Pack it in Unity and then import it into your project. The example seems to work only for pc though and not for iPhone or Android, which is a bit weird. So you might need to make adjustments to the script.

    Another solution is to use 3rd Party plugins such as Resonance Audio for Unity (didn't work for me though and seems a bit glitchy and not up to date, but maybe I did something wrong) or the HP VR Spatial Audio Unity Plugin which is part of the omnicept VR SDK and can also be used as standalone. It specifically targets XR-Applications but also works for Non-XR-Applications. The catch is however, that it costs money, unless you are an academic user and don't want to monetize your application. For me this Plugin works perfectly, it's easy to use and doesn't come with much clutter.

    YOu might find other plugins or sdks out there or you can just implement your own with Unity's custom spatializer API, that also includes the possibility to enable Spatializing after effects and filters.

    This thread doesn't seem to be very active, but still, maybe this helps someone :)
     
    Last edited: Jan 22, 2022
    NathBar likes this.