Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Audio Audio has TOO MUCH latency.

Discussion in 'Audio & Video' started by thealbaniandude, Oct 10, 2017.

  1. thealbaniandude

    thealbaniandude

    Joined:
    Jun 19, 2017
    Posts:
    8
    I'm developing a 3-D arcade game for Android. When I press any of the buttons in the UI it actually does play the sound that I've attached to it (in an AudioSource) but it has about 800-900 milliseconds latency. That's way too much and worsens the UX.

    I've attached a script to my button. In this script I've made a "AudioSource[] audioSources;" array and in the Start() function I've written: "audioSources = GetComponents<AudioSource> ();".
    Then when the button is clicked, I've set its OnClick(); method to a public method in the Button itself. This public method has written in it: "audioSources [0].Play ();".

    Any way to lower the latency of the button's sound? Thank you :)
     
  2. sylon

    sylon

    Joined:
    Mar 5, 2017
    Posts:
    246
    Have you tried AudioSource.PlayOneShot instead of Play() ?
     
  3. thealbaniandude

    thealbaniandude

    Joined:
    Jun 19, 2017
    Posts:
    8
    Will try right now.
     
  4. thealbaniandude

    thealbaniandude

    Joined:
    Jun 19, 2017
    Posts:
    8
    Sounds good, doesn't work. Couldn't make it work. I passed it again audioSources [0] as an argument and it says cannot convert UnityEngine.AudioSource to UnityEngine.AudioClip :/
     
  5. sylon

    sylon

    Joined:
    Mar 5, 2017
    Posts:
    246
    Yeah.
    You have to pass it a AudioClip
    like this :

    audioSources[index].PlayOneShot(audioSources[index].clip);
     
  6. thealbaniandude

    thealbaniandude

    Joined:
    Jun 19, 2017
    Posts:
    8
    That worked, but still the same latency :/
     
  7. sylon

    sylon

    Joined:
    Mar 5, 2017
    Posts:
    246
    eliteforcevn likes this.
  8. thealbaniandude

    thealbaniandude

    Joined:
    Jun 19, 2017
    Posts:
    8
    I tried that too but still the same :/ Anyway, thank you for all your replies. I appreciate them :)
     
    sylon likes this.
  9. Dryn27

    Dryn27

    Joined:
    Dec 10, 2016
    Posts:
    11
    I am having lot of latency too. And I'm sure it's because of Unity. There is nothing wrong with my configuration and I've tried everything. It's just this engine.
     
    unity_f1NCBo4prTTWpw likes this.
  10. the_Bad_Brad

    the_Bad_Brad

    Joined:
    Nov 2, 2014
    Posts:
    278
    I only experience latency issues when I use any Bluetooth headphone. There is like 0.5 second delay.
     
  11. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    1,554
    Your problem came from 2 things : Unity adds audio latency and ALSO input latency. Your sound is a result of pressing a button. Audio latency is one thing but input latency also indirectly increase the perceived audio latency. (You can look at my research here : https://github.com/5argon/UnityiOSNativeAudio)

    To fix audio latency :
    Project Setting > Audio > DSP Buffer Size > set it to Best Latency (small buffer size). As of today with this settings, it make a glitched sound on Windows build while on macOS, Android, iOS is completely fine. You might want to have larger buffer size on Windows. (at the expense of more latency)

    If that is not enough you can use native methods of each platform. I just made Native Audio asset store plugins which can make a native call to both iOS and Android's fastest native way from one central interface. https://www.assetstore.unity3d.com/#!/content/107067

    There are various ways of playing audio at native side, here's my choice :

    - On iOS it uses OpenAL. It is faster than AVAudioPlayer, AudioToolbox, and SystemSound.
    - On Android it uses AudioTrack, I confirmed it to be faster than SoundPool and no meaningful difference from C++ side OpneSL ES of NDK. EDIT : v2.0 is now using OpenSL ES and there is a meaningful gain.

    I have compiled all of my findings in here : http://exceed7.com/native-audio
    PS. I have used FMOD for Unity before. The best settings that I could do. In addition to setting the best file format, requires editing FMOD Unity's source code to use very low number of buffer size. With that still the latency is just about equal to Unity's "Best Latency" (ant the sound cracks more too due to a low buffer size)

    To fix input latency :
    This is much more difficult as the path that Unity receives touch from Xcode project is almost hardwired and is not meant to be replaced easily. (Unlike audio, we just left the Unity one and use our native method)

    I made iOS Native Touch which can reduce this input latency. But you will lose many conveniences that Unity provides including finger ID tracking, stationary state, etc.

    http://exceed7.com/ios-native-touch/
     
    Last edited: Sep 4, 2018
  12. abdulraheem_taha

    abdulraheem_taha

    Joined:
    Jun 26, 2018
    Posts:
    2
    Thanks! I didn't realize that the issue was with Bluetooth headset !!!
     
    plastico77, hooman_zkh and bobbyhttk like this.
  13. nitaym

    nitaym

    Joined:
    Aug 1, 2016
    Posts:
    12
    Hey, I had the same issue when I used WAV files instead of OGG. Changing to OGG immediately made things much smoother
     
    exe2k and imranmollajoy like this.
  14. ehtchaos

    ehtchaos

    Joined:
    Apr 24, 2021
    Posts:
    1
    I develop for mac and windows, there is no delay on mac, but on windows it is, in both versions I used a bluetooth speaker, after half a day I realized that there was a delay due to the speaker, although it’s strange why it’s not on the mac.
     
  15. hooman_zkh

    hooman_zkh

    Joined:
    Aug 12, 2020
    Posts:
    2
    thanks ,That was something I did not even think about
     
  16. davidvalen95

    davidvalen95

    Joined:
    Feb 8, 2022
    Posts:
    1
    also dont use any processing audio like FxSound, equalizer, etc, itt cause delay
     
  17. kidsfab

    kidsfab

    Joined:
    Oct 16, 2018
    Posts:
    19
    Hello Everyone,
    I currently have trouble with loading a .wav file and some animations.
    It works just fine in windows (unity editor and build), but on IOS and the unity editor (Mac), upon pressing play, the sound is being played but the whole app "stops" .. until at some point the audio has finished loading ... I guess... and I can stop the animation/sound and press play again ... and they both work fine in sync.
    So I guess it is some kind of memory / buffer issue.
    I though a simple async await upon loading the sound would work but it doesn't. I have to play it ... let it freeze until something is freed and the whole thing can be reset and played.
    As you might tell from the words I'm using to describe this, I have no clue what I'm talking about.
    Any help from anyone with some understanding and a bit of time to point me on the right track is tremendously appreciated .
     
  18. Hikiko66

    Hikiko66

    Joined:
    May 5, 2013
    Posts:
    1,303
    I've never used unity on a mac. I don't think you should have this kind of discrepancy between operating systems, so it might be a bug, or some quirk about ios that I don't know about.

    for a work around and some process of elimination:

    Click on the clip in the unity editor to inspect its settings
    What is the clip load settings? Just the default?
    Compressed In Memory?
    Encoded with Ogg/Vorbis?
    https://docs.unity3d.com/Manual/class-AudioClip.html

    Is the file large? Will you be using it often? Is it possible that you will play multiple instances of that sound at the same time?

    If you answered yes, no, no, then you might try setting the file to stream.
    If you answered no, yes, yes, then you might try setting it to decompress on load, or to even use the wav file directly and not use ogg/vorbis just to see if that might be the issue.

    Try to experiment with these few settings. Loadtype and Encoding, to identify what works and what doesn't work. You can read about what each of them does. And a combination of these settings allows you to pick your priorities.

    Those priorities are:

    Size on disk (your project/exe) (wav has the highest, ogg is typical to reduce the size)

    Size in memory (streaming has the lowest, decompress on load has the highest (it decompresses a ogg to a wav at runtime and holds it in memory for example))

    Response time when play is requested (compressed has the highest as it has to decompress the entire file every time you try to play it, the others should be quick. Decompress on load should decompress on scene start, wav doesn't need to be decompressed, and streaming should be quick regardless of compressed or not, because it doesn't work with the whole file at once)

    Scene loading time (streaming has the lowest, decompressed has the highest)

    And for streaming, streaming too many things at once can start to impact your cpu, particularly on lower end devices I imagine, though if you keep the number relatively low, the impact shouldn't be significant.


    I would also be careful not to test playing a sound immediately at scene start. Wait a second or two after scene start to test how quickly a sound plays, particularly if you are synchronizing the audio with other things and the timing needs to be accurate.
     
    Last edited: Jun 15, 2022
    kidsfab likes this.
  19. kidsfab

    kidsfab

    Joined:
    Oct 16, 2018
    Posts:
    19
    Thanks a lot for your detailed answer @Hikiko66 ! I'll give your debugging approach a try. Cheers.
     
  20. kidsfab

    kidsfab

    Joined:
    Oct 16, 2018
    Posts:
    19
    Dear @Hikiko66 and all, I thought I would give a little bit more detail to my problem. Hopefully we can all learn in the process.

    The audio files I intend to play aren't available as prefabs or assets and cannot be flagged in the editor with "Preload Audio Data" or "Load in Background" flags.

    The files (.wav) are generated by the user from a microphone capture, and saved in an Application.dataPath folder.

    I have tried many ways to load the clip, but it doesn't seem to load it in memory until I actually start playing it.

    I think the flags mentioned earlier are deselected by default for external files.

    Without "Preload Audio Data" or "Load in Background" being selected the loading happens in the main thread, and as the file can be pretty heavy (6mb) its loading stalls the main thread (freezing anything else : apparently it's called a "frame hitch") while being "played" for the first time.

    When the "loading" or "partial playing" has finally been completed, the main thread is freed and everything else works as expected. I can then stop the sound that is obviously out of sync with the rest and replay it in sync, since everything is loaded in memory.

    Any idea how I can really preload the audio and play it only when it is fully in memory ?

    Thanks
     
    Last edited: Jun 16, 2022
  21. Hikiko66

    Hikiko66

    Joined:
    May 5, 2013
    Posts:
    1,303
    What code are you using to load/play the wav?
     
  22. kidsfab

    kidsfab

    Joined:
    Oct 16, 2018
    Posts:
    19
    @Hikiko66 thanks for the help here is the code I'm currently using.

    Code (CSharp):
    1.    
    2.  
    3. public class AudioManager : MonoBehaviour
    4. {
    5.     private AudioSource goAudioSource;
    6.  
    7.     private string _path;
    8.     public string SelectedFolderPath
    9.     {
    10.         get{return _path;}
    11.         set{_path = value;}
    12.     }
    13.  
    14.     public delegate void AudioLoader();
    15.     public static event AudioLoader AudioLoaded;
    16.  
    17.     private void Start()
    18.     {
    19.         goAudioSource = this.GetComponent<AudioSource>();
    20.     }
    21.    
    22.     public void StartReplaying()
    23.     {
    24.         goAudioSource.Play();
    25.     }
    26.  
    27.     public void StopReplaying()
    28.     {
    29.         goAudioSource.Stop();
    30.     }
    31.  
    32.     public void LoadFile()
    33.     {
    34.         LoadFromFile();
    35.     }
    36.  
    37.     async void LoadFromFile()
    38.     {
    39.  
    40.         string filePath= Path.Combine(SelectedFolderPath, "audio.wav");
    41.         try
    42.         {
    43.             goAudioSource.clip= await LoadClip(filePath);
    44.         }
    45.         catch (System.Exception err)
    46.         {
    47.             Debug.Log($"{err}");
    48.         }
    49.  
    50.     }
    51.  
    52.     async Task<AudioClip> LoadClip(string path)
    53.     {
    54.         AudioClip clip = null;
    55.         using (UnityWebRequest uwr = UnityWebRequestMultimedia.GetAudioClip("file://"+path, AudioType.WAV))
    56.         {
    57.            
    58.             uwr.SendWebRequest();
    59.  
    60.             try
    61.             {
    62.                 while (!uwr.isDone) await Task.Delay(5);
    63.  
    64.                 if (uwr.result == UnityWebRequest.Result.ConnectionError)
    65.                 {
    66.                     Debug.Log($"{uwr.error} file from {path}");
    67.                 }
    68.                 else
    69.                 {
    70.                     clip = DownloadHandlerAudioClip.GetContent(uwr);
    71.                     AudioFromFile = true;
    72.                 }
    73.             }
    74.             catch (System.Exception err)
    75.             {
    76.                 Debug.Log($"{err.Message}, {err.StackTrace}");
    77.             }
    78.         }
    79.  
    80.         while (!clip.LoadAudioData()) await Task.Delay(5);
    81.  
    82.         AudioLoaded?.Invoke(); //when finished
    83.  
    84.         return clip;
    85.     }
    86. }
    87.  
     
  23. kidsfab

    kidsfab

    Joined:
    Oct 16, 2018
    Posts:
    19
    ok, so I had focused entirely on the audio as the main culprit as it is the biggest file (6 MB) but it seems that some other files that I have loaded onto a memoryStream, despite being few KB, are creating the freeze problem upon reading. That brings me to a totally different thread I guess. The main problem is how to deal with several simultaneous memoryStreams and reading singleBytes from them.... if anybody has a thread dealing with such problem in mind, please feel free to post a reply. Thanks @Hikiko66 for the help !
     
  24. andrianovyaroslav27

    andrianovyaroslav27

    Joined:
    Sep 19, 2021
    Posts:
    4
    I figured the problem. In my case the problem was a big amount of active audio sources. Profiler showed that the amount was around 100, when I disabled some for testing, lag disappeared (it used to be up to 7 seconds, lol)
     
  25. Thompson654

    Thompson654

    Joined:
    Aug 9, 2023
    Posts:
    1
    You guys are awesome. MyBalanceNow like this post so much.
     
    Last edited: Aug 10, 2023