Search Unity

Memory problems with AudioClip - And I thought I was clever!

Discussion in 'iOS and tvOS' started by gregzo, Mar 28, 2012.

  1. gregzo

    gregzo

    Joined:
    Dec 17, 2011
    Posts:
    795
    Hi to all!

    Finishing my first iOS app (iPad 1+), of a musical nature. It heavily relies on Unity 3.5's AudioClip.Get/SetData functions, so much so that the AudioClips are never played as such.

    Memory is an issue (on iPad 1), starting to get level 2 warnings... So I figured why not ditch the AudioClips alltogether, and use Resources.Load to store the audio data only (49 1s mono wavs, and 49 10s mono wavs). Got it to work, but memory wise it made things much worse - the app crashes after loading about half of the 10s wavs. I really don't understand why this is the case... Here are the steps I followed:

    1) Change the extension of my wav files to .bytes
    2) Placed'em in Resources folder
    3) Load them as text asset, remove the header, convert bytes[] to Int16[] and then Int16[] to float[].

    Here is my load function, any help would be great!

    Code (csharp):
    1. function LoadAudioFloatsFromResources(filePath:String)
    2. {
    3.    
    4.     var tempAsset : TextAsset = UnityEngine.Resources.Load(filePath) as TextAsset;
    5.  
    6.     var bytes = tempAsset.bytes;
    7.  
    8.     var floats = new floats[bytes.length/2-headerSize/2];
    9.  
    10.     for(var i:int=0;i<bytes.length-headerSize;i+=2)
    11.     {
    12.         floats[i/2] = BitConverter.ToInt16(bytes,i+headerSize)/32767.0; //rescale factor to convert Int16 to float
    13.     }
    14.         return floats;
    15. }
     
    Last edited: Mar 28, 2012
  2. gregzo

    gregzo

    Joined:
    Dec 17, 2011
    Posts:
    795
    Nobody on this? I could really do with some help...
     
  3. Mantas-Puida

    Mantas-Puida

    Joined:
    Nov 13, 2008
    Posts:
    1,864
    You probably want to add following code at the end of your function:
    Code (csharp):
    1.  
    2. tempAsset = null;
    3. UnityEngine.Resources.UnloadUnusedAssets();
    4.  
     
  4. gregzo

    gregzo

    Joined:
    Dec 17, 2011
    Posts:
    795
    @Mantas Thanks for your reply! Of course, I forgot to unload, silly... But my app still gets killed by the OS after loading above 30 assets (800 kb each). I tried loading them one by one, unloading unused assets every time (the log confirms the assets are indeed unloaded).

    I don't understand why loading at runtime would eat up much more memory than having the audioclips in the scene already...

    I have the iOS basic license, would pro's stripping mean less of the engine is loaded in ram, therefore giving me more room for assets?

    Thanks for your help!
     
  5. gregzo

    gregzo

    Joined:
    Dec 17, 2011
    Posts:
    795
    Bumpy bump!
     
  6. Mantas-Puida

    Mantas-Puida

    Joined:
    Nov 13, 2008
    Posts:
    1,864
    Are you doing these conversions to float[] when loading sounds as part of the scene?
     
  7. gregzo

    gregzo

    Joined:
    Dec 17, 2011
    Posts:
    795
    No, it would be counter productive... What I am trying to do is have only the float[]s in memory, so that instead of having to call both AudioClip.GetData() and AudioClip.SetData(), i could use the latter only, thereby saving quite a bit of ram...

    I understand my function allocates a lot of temp floats, but I thought the garbage collector would clean that up if I give it enough time. But even if I load and convert 800k every 5s, my app's getting killed by the OS. And to be of any practical use, I would need to load and convert much faster anyway...

    Thanks for your advice!
     
  8. gregzo

    gregzo

    Joined:
    Dec 17, 2011
    Posts:
    795
    Bump, bump bmp!
     
  9. Mantas-Puida

    Mantas-Puida

    Joined:
    Nov 13, 2008
    Posts:
    1,864
    There isn't much information on what your code does after loading (especially if compared to the code path which is not using Resources.Load). I can just hint that first of all - float takes 2x memory if compared to Int16 and secondly the code you provided does not reuse float array, for every clip new one is allocated.