-
-
Save fuzzblob/f87ab206852deff2edb2726fc89472f0 to your computer and use it in GitHub Desktop.
/* | |
// 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; | |
} | |
} |
My first thought (not having seen this code in a long time) is that it might be multi channel audio not being handled correctly. Like in line 46 is clip.samples referring to all samples or just the count of one channel? I'm not sure what exactly is wrong but thats my first guess...
Looks like that was the case after all, tysm! I changed it to int resolution = (clip.samples * clip.channels) / width;
and it's working now! Having only two channels to work with definitely made it simpler lol
amazing! another alternative would be to render whichever channel is louder at that sample. So reading the amount of channels worth of samples to compare and select the largest abs(), or to render them in different colours at the same location. Thanks for reaching out and raising the issue :)
I'm kinda amazed that this still works after 6 years. This is exactly what I needed... or, it would be, if it didn't draw exactly half of the audioclip I put in. I can't tell myself why it's getting exactly half the length, so if you're still active, would you have any idea?