Reputation: 247
While recording user voice, i want to know when he/she stopped talking to end the recording and send the audio file to google speech recognition API.
I found this thread here and tried to use it's solution but i am always getting the same value from the average of spectrum data which is 5.004574E-08: Unity - Microphone check if silent
This is the code i am using for getting the GetSpectrumData value:
public void StartRecordingSpeech()
{
//If there is a microphone
if (micConnected)
{
if (!Microphone.IsRecording(null))
{
goAudioSource.clip = Microphone.Start(null, true, 10, 44100); //Currently set for a 10 second clip max
goAudioSource.Play();
StartCoroutine(StartRecordingSpeechCo());
}
}
else
{
Debug.LogError("No microphone is available");
}
}
IEnumerator StartRecordingSpeechCo()
{
while (Microphone.IsRecording(null))
{
float[] clipSampleData = new float[128];
goAudioSource.GetSpectrumData(clipSampleData, 0, FFTWindow.Rectangular);
Debug.Log(clipSampleData.Average());
yield return null;
}
}
PS: I am able to record the users voice, save it and get the right response from the voice recognition api.
Upvotes: 0
Views: 1432
Reputation: 247
The following method is what worked for me. it detect the volume of the microphone, turn it into decibels. It does not need to play the recorded audio or anything. (credit goes to this old thread in the unity answers: https://forum.unity.com/threads/check-current-microphone-input-volume.133501/).
public float LevelMax()
{
float levelMax = 0;
float[] waveData = new float[_sampleWindow];
int micPosition = Microphone.GetPosition(null) - (_sampleWindow + 1); // null means the first microphone
if (micPosition < 0) return 0;
goAudioSource.clip.GetData(waveData, micPosition);
// Getting a peak on the last 128 samples
for (int i = 0; i < _sampleWindow; i++)
{
float wavePeak = waveData[i] * waveData[i];
if (levelMax < wavePeak)
{
levelMax = wavePeak;
}
}
float db = 20 * Mathf.Log10(Mathf.Abs(levelMax));
return db;
}
In my case, if the value is bigger then -40 then the user is talking!if its 0 or bigger then there is a loud noise, other then that, its silence!
Upvotes: 1
Reputation: 90580
If you are interested in a volume then GetSpectrumData
is actually not really what you want. This is used for frequency analysis and returns - as the name says - a frequency spectrum so how laud is which frequency in a given frequency range.
What you rather want to use is GetOutputData
which afaik returns an array with amplitudes from -1
to 1
. So you have to square all values, get the average and take the square root of this result (source)
float[] clipSampleData = new float[128];
goAudioSource.GetOutputData(clipSampleData, 0);
Debug.Log(Mathf.Sqrt(clipSampleData.Select(f => f*f).Average()));
Upvotes: 0