Calling AudioClip.GetData() in AssetPostprocessor returns "false"

I’m calling AudioClip.GetData() in a script derived from AssetPostprocessor, but the array to be filled with samples stays empty. I checked with MonoDevelop Debugger to see that the line returns “false” and the array audioClipSamples is still empty. The file I’m importing is a wave file and the import settings have been set to “PCM” and “Decompress on Load”. Do you have an idea how to get the samples?

using System;
using UnityEngine;
using UnityEditor;
using System.Collections;
using Assets.Scripts.Audio;

namespace Assets.Editor.Audio
{
    class MyAudioPostprocessor : AssetPostprocessor
    {
        public void OnPostprocessAudio (AudioClip audioClip)
        {
            var audioImporter = (AudioImporter)assetImporter;
            audioClip = AssetDatabase.LoadAssetAtPath(audioImporter.assetPath, typeof(AudioClip)) as AudioClip; // meaningless if this is turned on or off
            float[] audioClipSamples = new float[audioClip.samples * audioClip.channels];
            audioClip.GetData (audioClipSamples, 0); // FIXME: returns "false"?
        }
    }
}

Unfortunately, you cannot read the data of an AudioClip during OnPostprocessAudio. You should ideally check that the AudioClip’s loadState is AudioDataLoadState.Loaded to be sure GetData will return true.

My workaround was to have a static list. On OnPostprocessAudio, I add the clip to this list which schedules it to be processed. However, I don’t process the clips during OnPostprocessAudio - instead I subscribed to EditorApplication.update to run a method every frame, which, if the list is not empty checks (once every second) for load states and processes all the entries it can, and sets the dirty flag.

I plan to add a timeout (if a clip has not loaded for too long, it’s removed from the list and considered “failed to process”), but it works very nicely like this.

Thanks a lot, that was really helpful.

Is there a reason that Unity cannot use GetData during OnPostprocessAudio? It shouldn’t be a problem to actually load the clip …

The data of an AudioClip doesn’t load instantly. When processing an AudioClip, first there’s the step of converting the audio data to the selected asset compression format (even PCM needs to be resaved) and then that needs to be loaded (exactly when that occurs depends on the asset settings). It works that way so that the editor/game can still run while audio is loading. I’m not sure exactly where in the chain OnPostprocessAudio happens in relationship to these other things, but say it’d be after the full import, the entire import would need to happen again if the processor changed any of the import settings.

1 Like