I want to get the average decibels over a period of time (lets say 1 second). Edit: This is to detect loud noises.
I have a ByteArray of audio, at 16khz sample rate and 16 bit depth.
I convert it to a ShortArray to get the amplitude of over time, like so:
fun bytesToShort(byteArray: ByteArray): ShortArray {
val shortOut = ShortArray(byteArray.size / 2)
val byteBuffer: ByteBuffer = ByteBuffer.wrap(byteArray)
byteBuffer.order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(shortOut)
return shortOut
}
From what I gather, this is the correct way to get the amplitude.
Now my converting algorithm:
val amplitudeValues = bytesToShort(bytesForDecibels)
val rms = sqrt(amplitudeValues.sumOf { it * it } / amplitudeValues.size.toDouble())
val decibels = 20 * log10(rms)
It spits out apparent decibel values. However, I tried a recording where I literally scream in the microphone, and can't reach an average of over 51 decibels. Is my algorithm correct and the microphone simply cannot pick up louder sounds then 51db, or is the algorithm incomplete/incorrect?
Edit: I didn't mention I wanted to detect loud noises. Reading from @GabeSechan's comment, I need to check amplitude spikes over a baseline amplitude to detect a loud noise. So I will set a baseline according to microphone activity and any large spikes over baselines are loud noises.