Search Unity

Audio Asynchronously loading AudioClip from file

Discussion in 'Audio & Video' started by Brady, Jun 19, 2020.

  1. Brady

    Brady

    Joined:
    Sep 25, 2008
    Posts:
    2,474
    I'm loading user-provided OGG files from disk using the following:

    UnityWebRequestMultimedia.GetAudioClip()
    and
    DownloadHandlerAudioClip.GetContent();

    In an average case, this results in a ~500ms pause, and the culprit appears to be SoundManager.LoadFMODSound() as shown in my deep profiling screenshot.
    upload_2020-6-19_3-6-24.png

    This is all inside a coroutine that has a:

    Code (csharp):
    1.  
    2. while (!operation.isDone)
    3.     yield return null;
    4.  
    But somewhere there seems to be a blocking operation. This is an absolute deal-breaker on Quest where you're not allowed to drop frames, much less completely freeze for half a second. Surely there is a way to asynchronously and smoothly load AudioClips from disk?
     
  2. Nomabond

    Nomabond

    Joined:
    Apr 9, 2013
    Posts:
    1
    Did you ever find a solution to this, Brady?

    Welp, shortly after asking here I found a solution that works in my case. Figured I'd share in case anyone else stumbles here.


    Code (CSharp):
    1. public IEnumerator LoadSong(string url)
    2.     {
    3.         using (UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip(url, AudioType.MPEG))
    4.         {
    5.             yield return www.SendWebRequest();
    6.  
    7.             if (www.isNetworkError)
    8.             {
    9.                 Debug.LogError(www.error);
    10.                 yield break;
    11.             }
    12.  
    13.            // this allows for streaming audio which may not be your solution but it works in my case
    14.             ((DownloadHandlerAudioClip)www.downloadHandler).streamAudio = true;
    15.  
    16.             if (www.isNetworkError)
    17.             {
    18.                 Debug.Log(www.error);
    19.             }
    20.             else
    21.             {
    22.                   // do whatever you need to with the clip
    23.                   AudioClip clip = ((DownloadHandlerAudioClip)www.downloadHandler).audioClip;
    24.             }
    25.         }
    26.     }
     
    Last edited: Nov 9, 2020
    Goodlyay and arufolo like this.
  3. melterx12

    melterx12

    Joined:
    Jan 20, 2019
    Posts:
    16
    Sorry to bring this thread back up but has anyone found a solution for this that does not involve setting the clip as streaming? I need to get samples from the clip which is not supported if streaming is enabled.
     
  4. Brady

    Brady

    Joined:
    Sep 25, 2008
    Posts:
    2,474
    I don't think that's possible, since to get the samples for the entire song, you'd need to have it fully loaded. You can, however, get some frequency data from the current buffer of the playing AudioSource. See here:

    https://docs.unity3d.com/ScriptReference/AudioSource.GetSpectrumData.html