How to accurately calculate audio decibels

Hi, everybody.
Situation is that the current I got an audio file, put it in to the AudioSource, and then I by calling the AudioSource. GetOutputData (myClip. Samples, 0);Get it broadcast spectrum, then the call Mathf. Log (spectrum );, the data is not ready to db. Could you tell me what is the formula can accurately calculate audio decibels ? thanks!

I would like to know also. No idea.

Little gift:

using UnityEngine;

public static class AudioPower
{
    public static float ComputeRMS( float[] buffer, int offset, ref int length )
    {
        // sum of squares
        float sos = 0f;
        float val;

        if( offset + length > buffer.Length )
        {
            length = buffer.Length - offset;
        }

        for( int i = 0; i < length; i++ )
        {
            val = buffer[ offset ];
            sos += val * val;
            offset ++;
        }

        // return sqrt of average
        return Mathf.Sqrt( sos / length );
    }

    public static float ComputeDB( float[] buffer, int offset, ref int length )
    {
        float rms;

        rms = ComputeRMS( buffer, offset, ref length );

        // could divide rms by reference power, simplified version here with ref power of 1f.
        // will return negative values: 0db is the maximum.
        return 10 * Mathf.Log10( rms );
    }
}

Bear in mind that db is a relative measurement. Here, we assume an average power of 1f to be the maximum, 0db level. The method will return negative values.

This particular piece of code is untested, let me know if there are issues. I’ve used a ref parameter for length to simplify use when computing a power graph of a larger chunk of audio. To get realtime power, the methods can be simplified. For use with OnAudioFilterRead(), one should also de-interleave first, and compute the power for both channels separately.

Cheers,

Gregzo

Edit: fixed rms loop logic

3 Likes

Thank you Gregzo. For audio data I’m so worried , and not have any idea about the audio data processing , too bad

I am also

@gregzo Can u help me out I really do not know how to process the negative values

Edit: My Code

        int length = (int)Recording.length;
        float[] buffer = new float[128];

        Recording.GetData(buffer, 0);

        DB = AudioPower.ComputeDB(buffer, 0, ref length);

This is awesome code and it’s working perfectly. I needed it to trim the silence at the beginning and the end of the audio clip. However, I would like to know… what is the reference power? When I read documentation, they used it to describe how much voice is lost in phone line after 1mile of distance. However… all audio editing tools actively using decibels. Human ear cannot hear anything bellow -40dB. Any practical example and information would be awesome. Thanks!

UPD: There is a bug related to 0 sample. I have no time to dig deeper but float values close to zero cause this algorithm to fail. So here is the fix (I ignore samples with 0.1% of the max rate):

      for (int i = 0; i < length; i++) {
        val = buffer[offset];
        if (val > -0.001f && val < 0.001f) continue;
        sos += val * val;
        offset++;
      }
1 Like

Common issue with floats, you could use Mathf.Approximately.