Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice

Audio Changes to in-editor waveform generation in 5.4?

Discussion in '5.4 Beta' started by Rtyper, Apr 15, 2016.

  1. Rtyper

    Rtyper

    Joined:
    Aug 7, 2010
    Posts:
    452
    My Unity plugin, LipSync Pro, uses the AudioUtil class through reflection to get a waveform preview texture of AudioClips to display in the editor, but I've noticed this is broken in the 5.4 beta. The GetWaveForm method seems to have gone entirely, and all I could find in the release notes is this:
    I get that quiet changes to internal, hidden classes like AudioUtil are to be expected so I'm not complaining, but the ability to get this waveform texture is pretty vital for me - is there any way I could get some info on how the new waveform previews are generated?

    Thanks!
     
  2. janm_unity3d

    janm_unity3d

    Unity Technologies

    Joined:
    Jun 12, 2012
    Posts:
    36
    You could try this which displays the selected audioclip in a separate window, but it still relies on reflection, so no guarantees this won't change at some point:

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3. using System.Collections;
    4. using System.Reflection;
    5.  
    6. public class RenderWave : EditorWindow
    7. {
    8.     [MenuItem("Window/Waveform")]
    9.     public static void ShowWindow()
    10.     {
    11.         EditorWindow.GetWindow(typeof(RenderWave));
    12.     }
    13.  
    14.     void OnGUI()
    15.     {
    16.         var clip = Selection.activeObject as AudioClip; if (clip == null) return;
    17.         var path = AssetDatabase.GetAssetPath (clip); if (path == null) return;
    18.         var importer = AssetImporter.GetAtPath (path); if (importer == null) return;
    19.         var assembly = Assembly.GetAssembly (typeof (AssetImporter)); if (assembly == null) return;
    20.         var type = assembly.GetType ("UnityEditor.AudioUtil"); if (type == null) return;
    21.         var AudioUtil_GetMinMaxData = type.GetMethod ("GetMinMaxData"); if (AudioUtil_GetMinMaxData == null) return;
    22.         var minMaxData = AudioUtil_GetMinMaxData.Invoke (null, new object[] { importer }) as float[]; if (minMaxData == null) return;
    23.  
    24.         var r = EditorGUILayout.GetControlRect (GUILayout.ExpandWidth (true), GUILayout.ExpandHeight (true));
    25.         var curveColor = new Color (255 / 255f, 168 / 255f, 7 / 255f);
    26.         int numChannels = clip.channels;
    27.         int numSamples = minMaxData.Length / (2 * numChannels);
    28.         float h = (float)r.height / numChannels;
    29.         for (int channel = 0; channel < numChannels; channel++)
    30.         {
    31.             var channelRect = new Rect (r.x, r.y + channel * h, r.width, h);
    32.             AudioCurveRendering.DrawMinMaxFilledCurve(
    33.                 channelRect,
    34.                 delegate(float x, out Color col, out float minValue, out float maxValue)
    35.                 {
    36.                     col = curveColor;
    37.                     float p = Mathf.Clamp(x * (numSamples - 2), 0.0f, numSamples - 2);
    38.                     int i = (int)Mathf.Floor(p);
    39.                     int offset1 = (i * numChannels + channel) * 2;
    40.                     int offset2 = offset1 + numChannels * 2;
    41.                     minValue = Mathf.Min(minMaxData[offset1 + 1], minMaxData[offset2 + 1]);
    42.                     maxValue = Mathf.Max(minMaxData[offset1 + 0], minMaxData[offset2 + 0]);
    43.                     if (minValue > maxValue) { float tmp = minValue; minValue = maxValue; maxValue = tmp; }
    44.                 }
    45.             );
    46.         }
    47.     }
    48. }
    49.  
     
  3. Rtyper

    Rtyper

    Joined:
    Aug 7, 2010
    Posts:
    452
    Brilliant, thanks for that! Looks like a move towards making this more easily accessible too, so that's good.