4

I need to find a way to get the current audio output volume while the phone is making noise on the headphones, this value will be converted to a decibel level. The android API does not appear to have any way of accessing a constant volume level other than a seemingly arbitrary volume setting level, but I dont see a way to convert that to a standard decibel level or "loudness" measurement. I have seen some ways to use the mic for this, but that wont work with headsets very well.

Does anyone know a way to measure either the maximum possible decibel (or some standard) output level to compare against, or possible the voltage being sent to the headset?

Help is welcomed.

Andy
  • 251
  • 1
  • 5
  • 15
  • Since the volume depends on the data in the file being played as well as the volume setting this seems tricky. On a desktop I'd recommend looking into getting data from a loopback-interface on your soundcard and checking the volume of that, but I haven't actually heard of anybody doing anything along those lines on Android yet. Good luck :) – dutt Jan 22 '13 at 07:50
  • Thanks, looks like I will need it... :P – Andy Jan 22 '13 at 07:52
  • 1
    Maybe something along these lines http://developer.android.com/guide/topics/media/audio-capture.html, setAudioSource. I don't know if it could capture output. – dutt Jan 22 '13 at 07:55
  • I have been looking into that, but it at least appears that this will not capture output to headsets, only stuff coming out of the phone speakers... will continue checking though to be totally sure. – Andy Jan 22 '13 at 07:58
  • My phone automatically forwards everything from the speakers to the headphones when they're plugged in, so it _might_ be the same. – dutt Jan 22 '13 at 08:11

2 Answers2

9

Be aware that there are many different meanings of the word 'deciBel'. It is a means of representing some quantity (such as intensity/power/loudness) relative to a reference point. For audio signals inside equipment, or in an audio application, there is a peak level of 0dB. When sound is emitted from a speaker, the perceived loudness is measured as a Sound Pressure Level, often described as 'dB (SPL)' (or weighted variants such as dBA). When you see the tables of values such as rock concerts at 100dB then this is the SPL that is being described. This measurement is itself relative to a reference level.

So what will have available in the API is the buffer of audio data from which you can easily obtain the audio level in terms of the raw signal (which has a maximum of 0dB). You can't however easily convert this to a physical loudness because this will be dependent on the hardware. It will be different between one model of phone and the next, and will depend on the headphones too. The only way of doing this will be to calibrate the phone by measuring with an SPL meter, but then this will give you a result which will only give reasonable results on this particular phone.

the_mandrill
  • 29,792
  • 6
  • 64
  • 93
1

I'm doing it like this:

SLmillibel gain_to_attenuation(float volume)
{
    SLmillibel volume_mb;
    if(volume>=1.0f) volume_mb=SL_MILLIBEL_MAX;
    else if(volume<=0.02f) volume_mb=SL_MILLIBEL_MIN;
    else
    {
        volume_mb=M_LN2/log(1.0f/(1.0f-volume))*-1000.0f;
        if(volume_mb>0) volume_mb=SL_MILLIBEL_MIN;
    }
    return volume_mb;
}
NoAngel
  • 1,072
  • 2
  • 18
  • 27