- Home /
Music Visualiser Help
Hi there, I'm working on a music visualiser and I would like to take a sample from an audiosource and obtain a volume sample for multiple frequencies.
I'm currently obtaining a sample using
AudioSource.GetOutputData(); AudioSource.GetSpectrumData();
I assume the first is volume(amplitude) while the second is frequency
I'm currently taking a sample size of 256 and applying the information I retrieve from the samples to the scale of the cubes to create a wave form. however I would like to have samples of specific frequencies so I can apply them to different objects and effectively have different dynamic objects responding to different frequencies.
If anyone has done this before/Has seen this somewhere before/has an Idea on how to do this I'd appreciate your assistance
Thanks in advance :)
Answer by zombience · Nov 04, 2013 at 05:19 PM
Hey, I've actually done a bit of work with this.
Here's the code I used to use to analyze audio in Unity. It was originally intended to analyze live audio input from your microphone. This ended up being a poor choice and extremely inefficient in Unity.
However, if you use this code to analyze playback of samples and files within Unity, it works just fine.
I haven't looked at this in a while as I've moved on to using external analysis, so some code cleanup might be necessary. But this should work for the most part.
using UnityEngine;
using System.Collections;
public class FFT : MonoBehaviour {
#region vars
private struct AudioObj{
public GameObject player;
public AudioClip clip;
public void SetClip(AudioClip c)
{
player.audio.clip = null;
clip = null;
clip = c;
player.audio.clip = c;
}
}
private AudioObj[] audioObj = new AudioObj[2];
private const int BANDS = 4;
public float[] curve = new float[BANDS];
public float[] output = new float[BANDS];
public string[] inputDevices;
private int[] crossovers = new int[BANDS];
private float[] freqData = new float[8192];
private float[] band;
private bool swap;
public GameObject playerPrefab;
private int index = 0;
public static FFT Instance;
private bool doSound = true;
private int deviceNum= 0;
#endregion
#region Unity Methods
void Start ()
{
Instance = this;
crossovers[0] = 30;
crossovers[1] = 50;
crossovers[2] = 600;
crossovers[3] = freqData.Length;
band = new float[BANDS];
output = new float[BANDS];
for(int i = 0; i < 2; i ++)
{
audioObj[i].player = (GameObject)Instantiate(playerPrefab);
audioObj[i].player.transform.parent = transform;
audioObj[i].player.transform.position = Vector3.zero;
audioObj[i].clip = new AudioClip();
}
InvokeRepeating("Check", 0, 1.0f/15.0f);
StartCoroutine(StartRecord());
inputDevices = new string[Microphone.devices.Length];
for (int i = 0; i < Microphone.devices.Length; i ++)
inputDevices[i] = Microphone.devices[i].ToString();
}
void Update()
{
KeyInput();
}
#endregion
#region Actions
private void Check()
{
if(!doSound)
return;
AudioListener.GetSpectrumData(freqData, 0, FFTWindow.Hamming);
bool cutoff = false;
int k = 0;
for(int i = 0; i < freqData.Length; i ++)
{
if(k > BANDS - 1)
break;
float d = freqData[i];
float b = band[k];
band[k] = (d>b) ? d : b;
if(i > crossovers[k] - 10)
{
if(cutoff)
break;
output[k] = band[k];
band[k] = 0;
k++;
if(i > crossovers[BANDS - 1] - 10)
cutoff = true;
}
}
}
private IEnumerator StartRecord()
{
audioObj[index].SetClip(null);
audioObj[index].clip = Microphone.Start(Microphone.devices[deviceNum], false, 2, 48000);
print ("recording to audioObj " + index);
StartCoroutine(StartPlay (audioObj[index].clip));
yield return new WaitForSeconds(2);
Microphone.End(Microphone.devices[deviceNum]);
StartCoroutine(StartRecord());
}
private IEnumerator StartPlay(AudioClip buffer)
{
audioObj[index].SetClip(buffer);
yield return new WaitForSeconds(.05f);
audioObj[index].player.SetActive(true);
audioObj[index].player.audio.Play();
audioObj[Mathf.Abs((index % 2) - 1)].player.audio.Stop();
audioObj[Mathf.Abs((index % 2) - 1)].player.SetActive(false);
index++;
if(index > 1)
index = 0;
}
private void KeyInput()
{
if(Input.GetKeyDown(KeyCode.A))
{
doSound = !doSound;
}
if(Input.GetKeyDown(KeyCode.Equals))
{
deviceNum ++;
if(deviceNum > Microphone.devices.Length - 1)
deviceNum = 0;
}
}
#endregion
}
Thanks for the help zombience! there is a lot of stuff here and I'm about to head out but when I come back i'll give it a thorough read. Thanks again! :)
definitely! use whatever works for you.
also, it bears mentioning that i was using this to split up the inco$$anonymous$$g data into only 4 bands (lows, low mids, high mids, and highs).
if you want something more like a 16 band EQ, you can do that with this code, but you'll have to do some work to figure out how to split the spectrum for analysis. There is a lot of help out there for this though, so you should be ok.
I chose my bands by listening, not by math, so your mileage may vary.
This is great I got something working! Thanks a lot!
I'm definitely going to try and get more bands and get that working :) Hopefully I can find out somewhere else online how to go about doing that haha :)
Answer by tanoshimi · Nov 04, 2013 at 02:38 PM
Like this?:
http://karllim.weebly.com/unity3d-simple-visualizer.html
(warning - turn your speaker volume down before clicking the link. You'll see why...)
The webpage takes a very very very long time to load :\
I'll have a look when it loads at a decent speed.
Thanks in advance it looks promising
It's got a 5$$anonymous$$b Unity Webplayer demo embedded in it, but that's all.
Your answer
Follow this Question
Related Questions
Audio controls disabled??! 0 Answers
Stereo Mix as Input? 1 Answer
IEnumerator issues 3 Answers
How To Turn Off Sound For Certain Objects? 1 Answer
Stop audio/background music from pausing when showing ads 1 Answer