tags:

views:

588

answers:

4
+1  Q: 

Android PCM Bytes

Hi

I am using the AudioRecord class to analize raw pcm bytes as it comes in the mic.

So thats working nicely. Now i need convert the pcm bytes into decibel.

I have a formula that takes sound presure in Pa into db.

db = 20 * log10(Pa/ref Pa)

So the question is the bytes i am getting from audiorecorder from the buffer what is it is it amplitude pascal sound pressure or what.

I tried to putting the value into te formula but it comes back with very hight db so i do not think its right

thanks

A: 

The problem is likely the definition of the "reference" sound pressure at the mic. I have no idea what it would be or if it's available.

The only audio application I've ever used, defined 0db as "full volume", when the samples were at + or - max value (in unsigned 16 bits, that'd be 0 and 65535). To get this into db I'd probably do something like this:

// assume input_sample is in the range 0 to 65535
sample = (input_sample * 10.0) - 327675.0
db = log10(sample / 327675.0)

I don't know if that's right, but it feels right to the mathematically challenged me. As the input_sample approaches the "middle", it'll look more and more like negative infinity.

Now that I think about it, though, if you want a SPL or something that might require different trickery like doing RMS evaluation between the zero crossings, again something that I could only guess at because I have no idea how it really works.

dash-tom-bang
Close, except PCM samples are *signed* 16-bit (so you don't need the offset subtraction). Also - in my universe at least - you can't take the log of a negative number. :)
MusiGenesis
Ha hah good points all. They're always signed? I thought for sure I once had to deal with PCM data that was unsigned (could be misremembering, of course).
dash-tom-bang
I should have said that PCM is *usually* signed - 1-byte-per-sample PCM and RAW PCM formats (like what you probably worked with) are unsigned, but they're pretty rare in the wild (CD audio is signed).
MusiGenesis
A: 

Disclaimer: I know nothing about Android (other than the fact that it's one of the stupidest product names in history, given that android literally means "automaton that resembles a human being").

Your device is probably recording in mono at 44,100 samples per second (maybe less) using two bytes per sample. So your first step is to combine pairs of bytes in your original data into two-byte integers (I don't know how this is done in Android).

You can then compute the decibel value (relative to the peak) of each sample by first taking the normalized absolute value of the sample and passing it to your Db function:

float Db = 20 * log10(ABS(sampleVal) / 32768)

A value near the peak (e.g. +32767 or -32768) will have a Db value near 0. A value of 3277 (0.1) will have a Db value of -20; a value of 327 (.01) will have a Db value of -40 etc.

MusiGenesis
HiTHanks all it seems to work with this formula. The values are +32767 or -32768 range.
Pintac
One question just to put my mind to res. What unit of measure is the sampleValue
Pintac
Strictly speaking, the sample value represents the instantaneous voltage output from a microphone (where +32767 represents the maximum positive voltage and -32768 represents the minimum negative voltage). Because of how microphones work, this voltage is related to *changes* in sound pressure from the local average - when a microphone records a sound, the air pressure around the mic goes up and down slightly, which moves a membrane back and forth producing an alternating positive then negative voltage. An ADC (analog-to-digital-converter) samples this voltage 44100 times per second ...
MusiGenesis
... and converts it to a signed short value (-32768 to +32767) which is saved in the data.
MusiGenesis
A: 

The reference pressure in Leq (sound pressure level) calculations is 20 micro-Pascal (rms). To measure absolute Leq levels, you need to calibrate your microphone using a calibrator. Most calibrators fit 1/2" or 1/4" microphone capsules, so I have my doubts about calibrating the microphone on an Android phone. Alternatively you may be able to use the microphone sensitivity (Pa/mV) and then calibrate the voltage level going into the ADC. Even less reliable results could be had from comparing the Android values with the measured sound level of a diffuse stationary sound field using a sound level meter. Note that in Leq calculations you normally use the RMS values. A single sample's value doesn't mean much.

Han
What i actually want to do with the db is to figure out the volume(loadness) of the audio if it goes higher than a certain volume(loadness in db) i want t do something. i have a reference table of db'shttp://en.wikipedia.org/wiki/Sound_pressure#Examples_of_sound_pressure_and_sound_pressure_levels
Pintac
One way or another you will need to calibrate the system. At least you would need to compare your calculated values to a known sound level.The values given in the Wikipedia entry are most likely A-weighted sound levels, where the sound level in each octave band is weighted to result in an overall value. The Leq is usually given for each octave band.
Han
the sample value i am getting is +32767 to -32768 what unit is this is it amplitude sound pressure volt wats...
Pintac
It is neither. It is an arbitrary unit, proportional to both voltage at the ADC input and Pascal through the pressure to voltage conversion of the microphone. To get the conversion factor from the dimensionless sample value to voltage or pressure you need to compare these sample values to known voltage or sound pressure levels. This is what calibration does.
Han
i assume there is fixed values say in the spec of the microphone that i will need to work out the presure or voltage.
Pintac
The microphone spec will tell you how many mV/Pa, but without knowing the ADC spec (and intermediate circuitry) this still doesn't give you the conversion from pressure (Pa) to sample values. I think you best bet is to implement your dB measurement and to compare your value with a known value from say a sound level meter. Then you can incorporate the correct conversion factor in your code.
Han
A: 

I held my sound level meter right next to the mic on my google ion and went 'Woooooo!' and noted that clipping occurred about 105 db spl. Hope this helps.

BobG