I am trying to make a game in which my character shoots when a loud enough sound is heard true the mic (in Unity). I have however no idea how to start.
Thank you for your help!
I am trying to make a game in which my character shoots when a loud enough sound is heard true the mic (in Unity). I have however no idea how to start.
Thank you for your help!
You can get the decibels from a Microphone by retrieving the block of the currently playing Microphone's output data with the AudioSource.GetOutputData
function. To get the dB from this data, you need sum the data samples then calculate the RMS. That's RMS value you can use to calculate the dB with 20 * Mathf.Log10 (RMS / refVal)
.
There is a complete example on about this on Unity's post. You can read that for more information and the code below is based on that:
public float rmsVal;
public float dbVal;
public float pitchVal;
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();
Debug.Log("RMS: " + rmsVal.ToString("F2"));
Debug.Log(dbVal.ToString("F1") + " dB");
Debug.Log(pitchVal.ToString("F0") + " Hz");
}
void AnalyzeSound()
{
GetComponent<AudioSource>().GetOutputData(_samples, 0); // fill array with samples
int i;
float sum = 0;
for (i = 0; i < QSamples; i++)
{
sum += _samples[i] * _samples[i]; // sum squared samples
}
rmsVal = Mathf.Sqrt(sum / QSamples); // rms = square root of average
dbVal = 20 * Mathf.Log10(rmsVal / RefValue); // calculate dB
if (dbVal < -160) dbVal = -160; // clamp it to -160dB min
// get sound spectrum
GetComponent<AudioSource>().GetSpectrumData(_spectrum, 0, FFTWindow.BlackmanHarris);
float maxV = 0;
var maxN = 0;
for (i = 0; i < QSamples; i++)
{ // find max
if (!(_spectrum[i] > maxV) || !(_spectrum[i] > Threshold))
continue;
maxV = _spectrum[i];
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);
}
pitchVal = freqN * (_fSample / 2) / QSamples; // convert index to frequency
}