How to Make an Audio Spectrum Analyzer in Unity
Like a prism that separates light into its constituent colors, an audio spectrum analyzer separates a sound into different frequency components. The most common way to do audio spectrum analysis is using a mathematical operation called a Forier transform. In this tutorial, we are going to use Unity’s GetSpectrumData() function to repeatedly apply the Forier transform to an Audio Clip and then scale a set of objects according to the frequency contend of the clip.
Begin by importing any audio clip into unity.
Create an empty game object, named SpectrumObject and add a new C# script, named SpectrumAnalyzer to it.
Add a new AudioSource component to the SpectrumObject and drag the audio clip from the assets folder into the Audio clip field of the Audio source.
Next we will start building the script by creating a reference to the audio source and filling it during the start function. We will also create some code to handle the refresh timing of the spectrum analyzer.
using UnityEngine; public class SpectrumAnalyzer : MonoBehaviour { AudioSource source; public float SpectrumRefreshTime; private float lastUpdate = 0; void Start() { source = GetComponent<AudioSource>(); } void Update() { if (Time.time - lastUpdate > SpectrumRefreshTime) { //display spectrum lastUpdate = Time.time; } } }
After this we will create a function that will generate a line of cubes and populate an array with these cubes.
using UnityEngine; public class SpectrumAnalyzer : MonoBehaviour { AudioSource source; GameObject [] cubes; public float SpectrumRefreshTime; private float lastUpdate = 0; void Start() { source = GetComponent<AudioSource>(); cubes = new GameObject[1024]; createDisplayObjects(); } void Update() { if (Time.time - lastUpdate > SpectrumRefreshTime) { //display spectrum lastUpdate = Time.time; } } void createDisplayObjects() { for (int i = 0; i < 1024; i++) { Debug.Log(i); GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube); cube.transform.position = new Vector3(i, 0, 0); cubes[i] = cube; } } }
The last step is to implement the spectral analysis. This will be accomplished in the following way:
using UnityEngine; public class SpectrumAnalyzer : MonoBehaviour { AudioSource source; GameObject [] cubes; public float SpectrumRefreshTime; private float lastUpdate = 0; private float[] spectrum = new float[1024]; public float scaleFactor = 10000; void Start() { source = GetComponent<AudioSource>(); cubes = new GameObject[1024]; createDisplayObjects(); } void Update() { if (Time.time - lastUpdate > SpectrumRefreshTime) { source.GetSpectrumData(spectrum, 0, FFTWindow.Rectangular); for (int i = 0;i < spectrum.Length; i++) { cubes[i].transform.localScale = new Vector3(1, spectrum[i] * scaleFactor, 1); } lastUpdate = Time.time; } } void createDisplayObjects() { for (int i = 0; i < 1024; i++) { GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube); cube.transform.position = new Vector3(i, 0, 0); cubes[i] = cube; } } }