Measure Sound

jccorner

Centurion
Joined
Jan 31, 2004
Messages
144
Howdy folks. I've been searching and searching but have not found a suitable solution yet. My issue is that I have an array of bytes that is holding the data of a audio signal. What I want to do is simply measure the volume. Does anyone have a direction to point me in?? I would greatly appreciate the assist.
 
Thanks but I didn't see anything regarding a .net implementation. I understand that decibels can be calculated from power or even voltage, but how do I gather this information when looking at an array of bytes??
 
Amplitude and decibels

Amplitude is a measure of the magnitude of oscillation, which generally means the maximum absolute value of the wave:

Code:
maxVal = 0;

for (int i = 0; i < audioData.Length; i++) {
    if (Math.Abs(audioData[i]) > maxVal)
        maxVal = Math.Abs(audioData[i]);
}

//maxVal now contains the maximum amplitude of the sample

Decibels can be used to express amplitude, but decibels express a ratio, not an absolute value. This means that amplitudes expressed in decibels are relative to some reference amplitude. For the calculation, amplitude ratio is calculated in the same way as voltage ratio:

Code:
[size=5]X[size=1]dB[/size] = 20log[size=1]10[/size](X / X[size=1]0[/size])[/size]

The value of X can be determined using the code above, but as for the reference value X0, you need to decide what value to use - typically a very small value if you are measuring the amplitude with respect to silence.

Good luck :cool:
 
MrPaul, thank you very much. I actually didn't know I got another resopnse since I found something that gave me some estimate using a very complicated algorithm (FFT) but I will definitey look to implement when I get a chance. One question though, should I be looking in a range, because when I look at the data I see a lot of zero and 255 values (255 being the highest)?? Thanks again.
 
Audio data format?

The Fast Fourier Transform (FFT) will turn a time domain signal into its frequency domain representation, which will give you the relative amplitudes of the various frequencies in the signal, but I can't see how it would help you calculate an overall amplitude for the entire signal. The problem is that the term volume doesn't have much meaning unless you are comparing two signals for differences in amplitudes - as I said, decibels express a ratio.

Your query about zeros and 255 values raises another good point - do you know the format of the audio data? Standard PCM audio, as you'd find in a WAV file, is encoded into 16 bit samples, so to obtain useful values you have to treat it as such, using the short/Short data type.
 
Re: Audio data format?

Your query about zeros and 255 values raises another good point - do you know the format of the audio data? Standard PCM audio, as you'd find in a WAV file, is encoded into 16 bit samples, so to obtain useful values you have to treat it as such, using the short/Short data type.

I'm using 32 bit samples and you are correct, I'm using the sbyte data type.
 
BitConverter

You can use the BitConverter class to convert each four byte sequence into more the more usable Int32:

C#:
value = BitConverter.ToInt32(byteArray, index);
index += 4;

:)
 
I found this while looking for ahow to return the dB value of a captured buffer. i found the formula that is shown above and built a function to return the value.

Visual Basic:
Private function GetSample(ByVal sample As Byte()) as integer

        Dim dBValue As Double
        Dim range As Int16 = 32767.0 ' highest value as a double

        buffShort = CType(Convert.ToInt16(sample(2)), Short) 'sample(2) is a random value from the
                                                             'buffer not Peak Value.

        dBValue = (20 * Log10(buffShort / range)) + 100

        tbData.AppendText(vbCrLf & buffShort & vbCrLf & dBValue) ' this is for monitoring
        If dBValue < 0 Then ' I was getting infinity errors
            dBValue = 0
        End If

        return dBValue 

End Sub

I am having two issues. 1 how do I get the peak value in the buffer? 2. the values I am returning are not the dB value of the audio. could someone please help me?

Thanks

ZeroEffect
 
Zero, I think this is what you are looking for with getting the peak value of the sample byte

Visual Basic:
Array.Sort(sample)
Dim intPeakValue as Integer = sample(sample.GetUpperBound(0))

This will sort the data in the sample array, then you get the upperbound value as an integer.
 
Back
Top