Skip to content

Instantly share code, notes, and snippets.

@fuzzblob
Created October 29, 2018 22:19
Show Gist options
  • Save fuzzblob/f87ab206852deff2edb2726fc89472f0 to your computer and use it in GitHub Desktop.
Save fuzzblob/f87ab206852deff2edb2726fc89472f0 to your computer and use it in GitHub Desktop.
Unity Waveform UI with customizable resolution
/*
// UI inspector example implementation
Rect waveformRect = GUILayoutUtility.GetRect(waveformSize.x, waveformSize.y, GUIStyle.none);
EditorUtil.Waveform(waveformRect, clip, waveformSize);
float playMarker = 0f; // replace with a 0-1 seek position
if (playMarker >= 0f) {
Rect progressRect = new Rect(waveformRect);
float width = progressRect.width * playMarker;
progressRect.width = Mathf.Clamp(width, 6, width);
GUI.Box(progressRect, "", "SelectionRect");
}
*/
// UI method implementation
public class EditorUtil
{
public static void Waveform(Rect waveformRect, AudioClip clip, Vector2 size, float playMarker = -1f, float[] beatMarkers = null, int downBeat = 0)
{
// can't load data when audio is set to streaming
if(clip.loadState != AudioDataLoadState.Loaded)
clip.LoadAudioData();
// only do expensive calcs on repaint
if (Event.current.type != EventType.Repaint)
return;
Texture2D waveformTexture = GetWaveformTexture(clip, size); // AssetPreview.GetAssetPreview(clip);
if (waveformTexture == null)
return;
GUIStyle tempStyle = new GUIStyle();
tempStyle.normal.background = waveformTexture;
tempStyle.Draw(waveformRect, GUIContent.none, false, false, false, false);
}
private static Color waveformBG = new Color(0.25f, 0.25f, 0.25f);
private static Color waveformColor = new Color(1f, 0.6f, 0.2f);
public static Texture2D GetWaveformTexture(AudioClip clip, Vector2 size) {
// get sample data
float[] samples = new float[clip.samples * clip.channels];
if (clip.GetData(samples, 0) == false)
return null;
// setup texture
int width = (int) size.x;
int height = (int) size.y;
Texture2D texture = new Texture2D(width, height);
// get sampleIntensity
int resolution = clip.samples / width;
// draw color arracy per pixel in width
Color[] colors = new Color[height];
float midHeight = height / 2f;
float sampleComp = 0f;
for (int i = 0; i < width; i++) {
// get wave intensity
float sampleChunk = 0;
for (int ii = 0; ii < resolution; ii++)
sampleChunk += Mathf.Abs(samples[(i * resolution) + ii]);
sampleChunk = sampleChunk / resolution * 1.5f;
for (int h = 0; h < height; h++) {
// get value of height relative to totalHeight
if (h < midHeight)
sampleComp = Mathf.InverseLerp(midHeight, 0, h);
else
sampleComp = Mathf.InverseLerp(midHeight, height, h);
// corralate to sample height
if (sampleComp > sampleChunk)
colors[h] = waveformBG;
else
colors[h] = waveformColor;
}
// set pixels
texture.SetPixels(i, 0, 1, height, colors);
}
// push to graphics card
texture.Apply();
// return finished texture
return texture;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment