Created
October 29, 2018 22:19
-
-
Save fuzzblob/f87ab206852deff2edb2726fc89472f0 to your computer and use it in GitHub Desktop.
Unity Waveform UI with customizable resolution
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
// 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