What does getStreamVolumedB in Android AudioManager return?

Viewed 446

I have been trying to get some sort of db SPL conversion for the output volume coming from the android device. I know it is pretty much impossible for it to be a perfect db SPL level because of hardware and calibrations and stuff, but I just need a rough cut off so that I can give the user a warning when the volume of the media they are playing is too loud.

I found the getStreamVolumedB function in AudioManager, but I cannot interpret the results. All floats returned seem to be on a scale from 0 to 1 or 0 to 0.7ish, with 0 to 1 applying to voice calls, and 0 to 0.7 applying to media. I used my galaxy s8 to test it by playing spotify while I run the function, and instead of changing its float db calculation based on what is being outputted, it only seems to change based on the volume settings on the device.

Can someone help me interpret what exactly the function is outputting and how I can somehow convert that to db SPL, or get a safe hearing threshold? Also I'm totally new to android programming and also Java, so I could be using the function wrong or something. If so, please let me know. Thanks!

I have attached code to the relevant class below

public class AudioStream {
private AudioManager audioManager;
//private AudioStream audioStreamVol;
private static final String TAG = "AudioStream";

private Set<Integer> deviceTypes =
        new HashSet<>(Arrays.asList(AudioDeviceInfo.TYPE_BUILTIN_EARPIECE,
        AudioDeviceInfo.TYPE_BUILTIN_SPEAKER,
        AudioDeviceInfo.TYPE_WIRED_HEADSET,
        AudioDeviceInfo.TYPE_WIRED_HEADPHONES,
        AudioDeviceInfo.TYPE_LINE_ANALOG,
        AudioDeviceInfo.TYPE_LINE_DIGITAL,
        AudioDeviceInfo.TYPE_BLUETOOTH_SCO,
        AudioDeviceInfo.TYPE_BLUETOOTH_A2DP,
        AudioDeviceInfo.TYPE_HDMI,
        AudioDeviceInfo.TYPE_HDMI_ARC,
        AudioDeviceInfo.TYPE_USB_DEVICE,
        AudioDeviceInfo.TYPE_USB_ACCESSORY,
        AudioDeviceInfo.TYPE_DOCK,
        AudioDeviceInfo.TYPE_FM,
        AudioDeviceInfo.TYPE_BUILTIN_MIC,
        AudioDeviceInfo.TYPE_TELEPHONY,
        AudioDeviceInfo.TYPE_AUX_LINE,
        AudioDeviceInfo.TYPE_IP,
        AudioDeviceInfo.TYPE_BUS,
        AudioDeviceInfo.TYPE_USB_HEADSET,
        AudioDeviceInfo.TYPE_HEARING_AID));

public int findDeviceType() {
    final AudioDeviceInfo[] devices = audioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS);
    for (AudioDeviceInfo device : devices) {
        final int type = device.getType();
        if (deviceTypes.contains(type)) {
            return type;
        }
    }
    return -1;

}

public float audioStreamVol(Context context){
    audioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
    int curType = (int) audioManager.STREAM_MUSIC;
    int vol = audioManager.getStreamVolume(curType);
    int deviceType = findDeviceType();
    float volumedB = audioManager.getStreamVolumeDb(curType, vol, deviceType);
    return volumedB;
}

}

1 Answers

I saw a similar range on my Galaxy S10, 0.0 to 1.0 dB corresponding to the volume 0 to 15, for music stream. This contradicted with the documentation:

A volume expressed in dB. A negative value indicates the audio signal is attenuated. A typical maximum value at the maximum volume index is 0 dB (no attenuation nor amplification). Muting is reflected by a value of Float#NEGATIVE_INFINITY.

While on emulator with one official image I tested, it returns float from -Infinity to 0.0, as per document.

I guess there is a bug on Samsung's OS.

Back to your question, how to calculate the output SPL:

Output dB SPL = amplitude of original audio(1) + gains(2) + max output of device(3)

  1. Amplitude of original audio, in dB. It's a negative or zero value, e.g. -10. Zero means the max amplitude, i.e. loudest sound.
  2. Gains in dB, usually also a negative or zero value. The system's volume control is a gain. App may also apply their own gain on audio, independent with system's. In this case, two gains accumulated: gain_total = gain_system + gain_app. AudioManager.getStreamVolumedB() tells the system's audio gain.
  3. Max output of device, in dB. This depends on the devices, such as phone and earphone. The value is usually a positive number, e.g. 110dB.

For example, if you has a audio file with very loud sound, say 0dB of its amplitude. And the volume control is set to -20dB. Device's max output is 100dB. The output dB SPL will be 0 - 20 + 100 = 80dB SPL.

Related