Вопрос

I want to get the volume level from recording microphone data in 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;
}

But in this method, the volume depends on the sum of each data in data[]. At the beginning, when sum is low, when we speak loudly the sum is larger, but when the sound decreases, the sum doesn't change, so the volume which calculated by the GetMicrophoneVolume doesn't change.

Anyone knows how to correctly get the microphone volume?
Or is there some problem with my solution?
Also why doesn't the sum of data decreases when the sound decreases?
A better way to solve the problem will be greatly appreciated.

Это было полезно?

Решение

Thank you guys, Finally I got a solution that calculated by 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));
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top