GetOutputData and GetSpectrumData, what represent the values returned?

Hello forum people

Excuse my English. My question is this, I am using GetOutputData and GetSpectrumData in a AudioSource. As I was reading represent the amplitude and frequency of my AudioSource, but my problem is knowing how to convert these values ​​returned in decibels (GetOutputData) or Hertz (GetSpectrumData). If someone can give me a hand with this, I’d be very grateful. Of course, thank you very much

Getting the audio volume in dB is the easiest part: you must allocate a float array of suitable size and pass it to [GetOutputData][1], then sum all squared sample values, calculate the average and get its square root; that’s the RMS value, which you can convert to dB with a log operation. In a PC, the sound is usually sampled at 48000Hz (the actual sampling frequency can be read from [AudioSettings.outputSampleRate][2]); if you set the array size to 1024, for instance, you’ll get the average sound level of the last 21.3mS (1024/48000) each time you do this procedure. dB values are calculated by 20 * Log10(rmsValue / refValue) - adjust Ref Value in the Inspector if you need a different 0 dB reference.

Extracting the sound frequency is more complicated. You must allocate a float array
with a power-of-two size and pass it to [GetSpectrumData][3]. The size (lets call it Q ) defines the frequency resolution: each element shows the relative amplitude (0…1) of a the frequency equal to N * 24000 / Q Hertz (where N is the element index, and 24000 is half the PC sampling rate - see AudioSettings.outputSampleRate for other machines). With a 1024 array, for instance, you will have a resolution of 23.4 hertz (each element refers to a frequency 23.4 Hz higher than the previous one). This array shows all frequencies in the interval 0 - 24000 Hz. To know which is the dominant frequency, you must find the max amplitude element and multiply its index by the frequency resolution. Since the actual frequency may fall between two elements, some kind of interpolation can give a more precise result. This works for simple sounds like sinusoids, square wave, triangle, etc. but may fail for more complex real world sounds like guitar notes or voice, because sometimes the harmonics are higher than the fundamental (harmonics are integral multiples of the fundamental frequency). And this will surely fail if you try to get the pitch of a CD song, because it’s composed of several instruments and voices sounding together.

The function AnalyzeSound below measures the volume of the sound currently being played in RMS and dB, and find its pitch in Hertz. Create a GUIText and drag it to the variable display to show these values. Unity generates the audio spectrum incredibly fast, so this whole script consumes less than 1 mS at Update in my machine (a 1.8GHz Intel Core Duo PC). If you want to try this script with a reference sound, download [this][4] - it’s a test sound which goes from 200Hz to 1000Hz in 100Hz steps at each second; it also reduces the volume in 3dB each step, then repeat the sequence with a different waveform (square, triangle and sin waves are used).

var qSamples: int = 1024;  // array size
var refValue: float = 0.1; // RMS value for 0 dB
var threshold = 0.02;      // minimum amplitude to extract pitch
var rmsValue: float;   // sound level - RMS
var dbValue: float;    // sound level - dB
var pitchValue: float; // sound pitch - Hz

private var samples: float[]; // audio samples
private var spectrum: float[]; // audio spectrum
private var fSample: float;

function Start () {
	samples = new float[qSamples];
	spectrum = new float[qSamples];
    fSample = AudioSettings.outputSampleRate;
}

function AnalyzeSound(){
	audio.GetOutputData(samples, 0); // fill array with samples
	var i: int;
	var sum: float = 0;
	for (i=0; i < qSamples; i++){
		sum += samples_*samples*; // sum squared samples*_

* }*
* rmsValue = Mathf.Sqrt(sum/qSamples); // rms = square root of average*
_ dbValue = 20Mathf.Log10(rmsValue/refValue); // calculate dB_
_
if (dbValue < -160) dbValue = -160; // clamp it to -160dB min*_
* // get sound spectrum*
* audio.GetSpectrumData(spectrum, 0, FFTWindow.BlackmanHarris);*
* var maxV: float = 0;*
* var maxN: int = 0;*
* for (i=0; i < qSamples; i++){ // find max*
if (spectrum > maxV && spectrum > threshold){
_ maxV = spectrum*;
maxN = i; // maxN is the index of max*

* }
}
var freqN: float = maxN; // pass the index to a float variable*

* if (maxN > 0 && maxN < qSamples-1){ // interpolate index using neighbours*
* var dL = spectrum[maxN-1]/spectrum[maxN];
var dR = spectrum[maxN+1]/spectrum[maxN];
freqN += 0.5(dRdR - dLdL);

* }
pitchValue = freqN(fSample/2)/qSamples; // convert index to frequency_

}

var display: GUIText; // drag a GUIText here to show results

function Update () {
* if (Input.GetKeyDown(“p”)){*
* audio.Play();*
* }*
* AnalyzeSound();*
* if (display){*
* display.text = "RMS: "+rmsValue.ToString(“F2”)+*
* " (“+dbValue.ToString(“F1”)+” dB)
"+*

* “Pitch: “+pitchValue.ToString(“F0”)+” Hz”;*
* }*
}
*[1]: http://unity3d.com/support/documentation/ScriptReference/AudioSource.GetOutputData.html*_
[2]: http://docs.unity3d.com/Documentation/ScriptReference/AudioSettings-outputSampleRate.html*_
_[3]: http://unity3d.com/support/documentation/ScriptReference/AudioSource.GetSpectrumData.html*_

_*[4]: http://www.draldo.com.br/data/WaveSweep.wav*_

Converted to C#:

using UnityEngine;

public class AudioMeasureCS : MonoBehaviour
{
    public float RmsValue;
    public float DbValue;
    public float PitchValue;

    private const int QSamples = 1024;
    private const float RefValue = 0.1f;
    private const float Threshold = 0.02f;

    float[] _samples;
    private float[] _spectrum;
    private float _fSample;

    void Start()
    {
        _samples = new float[QSamples];
        _spectrum = new float[QSamples];
        _fSample = AudioSettings.outputSampleRate;
    }

    void Update()
    {
        AnalyzeSound();
    }

    void AnalyzeSound()
    {
        GetComponent<AudioSource>().GetOutputData(_samples, 0); // fill array with samples
        int i;
        float sum = 0;
        for (i = 0; i < QSamples; i++)
        {
            sum += _samples <em>* _samples*; // sum squared samples*</em>

}
RmsValue = Mathf.Sqrt(sum / QSamples); // rms = square root of average
DbValue = 20 * Mathf.Log10(RmsValue / RefValue); // calculate dB
if (DbValue < -160) DbValue = -160; // clamp it to -160dB min
// get sound spectrum
GetComponent().GetSpectrumData(_spectrum, 0, FFTWindow.BlackmanHarris);
float maxV = 0;
var maxN = 0;
for (i = 0; i < QSamples; i++)
{ // find max
if (!(spectrum > maxV) || !(spectrum > Threshold))
continue;

maxV = spectrum*;*
maxN = i; // maxN is the index of max
}
float freqN = maxN; // pass the index to a float variable
if (maxN > 0 && maxN < QSamples - 1)
{ // interpolate index using neighbours
var dL = _spectrum[maxN - 1] / _spectrum[maxN];
var dR = _spectrum[maxN + 1] / _spectrum[maxN];
freqN += 0.5f * (dR * dR - dL * dL);
}
PitchValue = freqN * (fSample / 2) / QSamples; // convert index to frequency
}

}

Found this at kaappine.fi

public float sensitivity = 100;
public float loudness = 0;
private AudioSource _audio;

void Awake()
{
    _audio = GetComponent<AudioSource>();
}

void Start()
{
    _audio.clip = Microphone.Start(null, true, 10, 44100);
    _audio.loop = true;
    _audio.mute = false;
    while (!(Microphone.GetPosition(null) > 0)) { }
    _audio.Play();
}

void Update()
{
    loudness = GetAveragedVolume() * sensitivity;
    if(loudness > 1)
    {
       //DO SOMETHING
    }
}

float GetAveragedVolume()
{
    float[] data = new float[256];
    float a = 0;
    _audio.GetOutputData(data, 0);
    foreach (float s in data)
    {
        a += Mathf.Abs(s);
    }
    return a / 256;
}

,dfg