【问题标题】:What does getStreamVolumedB in Android AudioManager return?Android AudioManager 中的 getStreamVolumedB 返回什么?
【发布时间】:2020-06-17 20:41:23
【问题描述】:

我一直在尝试对来自 android 设备的输出音量进行某种 db SPL 转换。我知道由于硬件和校准之类的原因,它几乎不可能成为完美的 db SPL 级别,但我只需要粗略的切断,这样我就可以在用户正在播放的媒体音量时向用户发出警告声音太大。

我在 AudioManager 中找到了 getStreamVolumedB 函数,但我无法解释结果。返回的所有浮点数似乎都在从 0 到 1 或 0 到 0.7ish 的范围内,其中 0 到 1 应用于语音呼叫,0 到 0.7 应用于媒体。我使用我的galaxy s8通过在运行该功能时播放spotify来对其进行测试,而不是根据输出的内容更改其浮动数据库计算,它似乎只是根据设备上的音量设置而更改。

谁能帮我解释一下这个函数到底输出了什么,以及我如何能以某种方式将它转换为 db SPL,或者获得一个安全的听力阈值? 此外,我对 android 编程和 Java 都是全新的,所以我可能使用错误的函数或其他东西。如果是这样,请告诉我。谢谢!

我已将代码附加到下面的相关类中

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;
}

}

【问题讨论】:

    标签: android audio android-audiomanager


    【解决方案1】:

    我在我的 Galaxy S10 上看到了类似的范围,0.01.0 dB 对应于音量 015,用于音乐流。这与the documentation相矛盾:

    以 dB 表示的音量。负值表示音频信号被衰减。最大音量指数的典型最大值为 0 dB(无衰减也无放大)。静音由 Float#NEGATIVE_INFINITY 的值反映。

    根据我测试的一张官方图片在模拟器上,它会根据文档返回从-Infinity0.0 的浮点数。

    我猜三星的操作系统存在错误。

    回到你的问题,如何计算输出声压级:

    输出 dB SPL = 原始音频幅度 (1) + 增益 (2) + 设备最大输出 (3)

    1. 原始音频的幅度,以 dB 为单位。这是一个负值或零值,例如-10。零表示最大幅度,即声音最大。
    2. 增益以 dB 为单位,通常也是负值或零值。系统的音量控制是一种增益。应用程序也可以在音频上应用自己的增益,与系统无关。在这种情况下,累积了两个增益:gain_total = gain_system + gain_app。 AudioManager.getStreamVolumedB() 告诉系统的音频增益。
    3. 设备的最大输出,以 dB 为单位。这取决于设备,例如电话和耳机。该值通常是一个正数,例如110 分贝。

    例如,如果您有一个声音很大的音频文件,请说出它的振幅 0dB。并且音量控制设置为-20dB。设备的最大输出为100dB。输出 dB SPL 将为 0 - 20 + 100 = 80dB SPL

    【讨论】:

      猜你喜欢
      • 2021-12-23
      • 1970-01-01
      • 1970-01-01
      • 2011-03-13
      • 2022-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-16
      • 1970-01-01
      相关资源
      最近更新 更多