实现思路
在Unity当中,是没有直接获取麦克风的音量大小的方法的,但是,它提供了一种录制音频的方法,那么我们就可以从录制的音频当中去获取音量的大小了。
实现细节
在Unity的API当中,存在着录制的方法
Microphone.Start(string deviceName,bool loop,int lengthSrc,int frequency);
第一个自然是马克风设备的名称,第二个是指要不要重复录制,第三个是指录制时长,第四个指的是录制时候的码率(一般是44100)
在利用这个方法实现了录制音频之后,我们就可以对音频进行分析了。
/// <summary>
/// 获取一段时间内的最大的音量
/// </summary>
///
/// <returns>
/// 音量大小
/// </returns>
private float GetMaxVolume()
{
float maxVolum = 0f;
//用于储存一段时间内的音频信息
float[] volumeData = new float[VOLUME_DATA_LENGTH];
int offset;
//获取录制的音频的开头位置
offset = Microphone.GetPosition(mDeviceName) - VOLUME_DATA_LENGTH + 1;
if(offset < 0)
{
return 0f;
}
//获取数据
mMicrophoneRecode.GetData(volumeData, offset);
//解析数据
for(int i = 0;i < VOLUME_DATA_LENGTH; i++)
{
float tempVolume = volumeData[i];
if(tempVolume > maxVolume)
{
maxVolume = tempVolume;
}
}
return maxVolume;
}
在这里Microphone.GetPosition(string deviceName);
方法是获取当前录制到的位置的方法,减去我用于储存声音的数组的大小(VOLUME_DATA_LENGTH)则是刚好是我用于储存数组的开头所需要的坐标
然后利用音频(AudioClip)当中的GetData(float[] data,int offsetSample)方法,获取了一段时间内的音频数据,然后再根据数据进行分析,获取当前时间段内的最大音频即可
具体实现代码
using UnityEngine;
public class MicrophoneInput : MonoBehaviour {
private static int VOLUME_DATA_LENGTH = 128; //录制的声音长度
public float volume; //音量
private AudioClip mMicrophoneRecode; //录制的音频
private string mDeviceName; //设备名称
private const int frequency = 44100; //码率
private const int lengthSec = 999; //录制时长
// Use this for initialization
void Start () {
//获取设备名称
mDeviceName = Microphone.devices[0];
//录制一段音频
mMicrophoneRecode = Microphone.Start(mDeviceName, true, lengthSec, frequency);
}
// Update is called once per frame
void Update () {
volume = GetMaxVolume();
}
/// <summary>
/// 获取最大的音量
/// </summary>
///
/// <returns>
/// 音量大小
/// </returns>
private float GetMaxVolume()
{
float maxVolume = 0f;
//用于储存一段时间内的音频信息
float[] volumeData = new float[VOLUME_DATA_LENGTH];
int offset;
//获取录制的音频的开头位置
offset = Microphone.GetPosition(mDeviceName) - VOLUME_DATA_LENGTH + 1;
if(offset < 0)
{
return 0f;
}
//获取数据
mMicrophoneRecode.GetData(volumeData, offset);
//解析数据
for(int i = 0;i < VOLUME_DATA_LENGTH; i++)
{
float tempVolume = volumeData[i];
if(tempVolume > maxVolume)
{
maxVolume = tempVolume;
}
}
return maxVolume;
}
}