如何在Windows Phone 8中获取麦克风音量

时间:2014-01-06 05:20:23

标签: c# windows-phone-8 windows-phone microphone

我希望通过在Windows Phone 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;
}

但是在这种方法中,音量取决于数据[]中每个数据的总和。在开始时,当和为低时,当我们大声说话时,总和较大,但当声音减小时,总和不会改变,因此GetMicrophoneVolume计算的音量不会改变。

任何人都知道如何正确获取麦克风音量? 或者我的解决方案有问题吗? 另外,为什么声音减少时数据总和不会减少? 我们将非常感谢您解决问题的更好方法。

1 个答案:

答案 0 :(得分:1)

谢谢大家,最后我得到了一个由RMS

计算的解决方案
/// <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));
}