我想从windows 8中记录麦克风数据中获得音量级别。
microphone = Microphone.Default;
microphone.BufferDuration = TimeSpan.FromMilliseconds(150);
microphone.BufferReady += microphone_BufferReady;
private void microphone_BufferReady(object sender, EventArgs e)
{
// Get buffer from microphone and add to collection
int size = microphone.GetSampleSizeInBytes(microphone.BufferDuration);
byte[] buffer = new byte[size];
int bytes = microphone.GetData(buffer);
MicrophoneDuration += microphone.GetSampleDuration(size);
bufferCollection.Add(buffer);
//Get the volume of microphone
MicrophoneVolume = GetMicrophoneVolume(buffer);
}
/// <summary>
/// Get the microphone volume, from 0 up to 100.
///
/// The sum of data[i] square divided by the total length of the data.
/// volume = sum(data[i] * data[i])/Length/10000
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public static double GetMicrophoneVolume(byte[] data)
{
double value = 0;
for (int i = 0; i < data.Length; i++)
{
value += data[i] * data[i];
}
return ConvertTo(value / data.Length / 10000);
}
/// <summary>
/// x/100 = value/MaxiMicrophoneVolume/// </summary>
/// <param name="value"></param>
/// <returns></returns>
private static double ConvertTo(double value)
{
if (value > MaxiMicrophoneVolume)
value = MaxiMicrophoneVolume;
if (value < 0)
value = 0;
return (100 * value) / MaxiMicrophoneVolume;
}但是在这种方法中,体积取决于data[]中每个数据的和。在开始时,当和低时,当我们大声说话时,和是大的,但是当声音变小时,和没有变化,所以由GetMicrophoneVolume计算的体积没有变化。
有人知道如何正确获得麦克风音量吗?
还是我的解决方案有什么问题?
另外,为什么当声音变小时,数据的总和不减少呢?
更好的解决这个问题的方法将会受到极大的赞赏。
发布于 2014-01-07 02:56:09
谢谢各位,我终于找到了一个由均方根计算出来的解决方案
/// <summary>
/// Detecting volume changes, the RMS Mothod.
///
/// RMS(Root mean square)
/// </summary>
/// <param name="data">RAW datas</param>
/// <returns></returns>
public static void MicrophoneVolume(byte[] data)
{
//RMS Method
double rms = 0;
ushort byte1 = 0;
ushort byte2 = 0;
short value = 0;
int volume = 0;
rms = (short)(byte1 | (byte2 << 8));
for (int i = 0; i < data.Length - 1; i += 2)
{
byte1 = data[i];
byte2 = data[i + 1];
value = (short)(byte1 | (byte2 << 8));
rms += Math.Pow(value, 2);
}
rms /= (double)(data.Length / 2);
volume = (int)Math.Floor(Math.Sqrt(rms));
}https://stackoverflow.com/questions/20943469
复制相似问题