[audio] 基础知识

参考

  ​​​​​https://source.android.com/docs/core/audio/attributes

  https://source.android.com/docs/core/audio/terminology 


channelConfig:单双声道

audioFormat:采样格式位数 ENCODING_PCM_16BIT  |  ENCODING_PCM_8BIT

帧大小计算

frame_size = sample * channles

sample:对应不同格式的位数,PCM_16_BIT 就是 2字节

channles:声道数,双声道就是 2

sampleRate:采样率,每秒采集的数据量

数据量每秒

frame_size = sampleRate(44100) * sample(PCM_16_BIT) * channles

           = 44100 * 2 * 2 = 176400 B = 172 KB

streamType版本中用来表示音频使用场景,(音乐、通话、通知) AUDIO_STREAM_MUSIC

        base/media/java/android/media/AudioSystem.java

        system/media/audio/include/system/audio-hal-enums.h

    /* These values must be kept in sync with system/media/audio/include/system/audio-hal-enums.h */
    /*
     * If these are modified, please also update Settings.System.VOLUME_SETTINGS
     * and attrs.xml and AudioManager.java.
     */
    /** @hide Used to identify the default audio stream volume */
    @TestApi
    public static final int STREAM_DEFAULT = -1;
    /** @hide Used to identify the volume of audio streams for phone calls */
    public static final int STREAM_VOICE_CALL = 0;
    /** @hide Used to identify the volume of audio streams for system sounds */
    public static final int STREAM_SYSTEM = 1;
    /** @hide Used to identify the volume of audio streams for the phone ring and message alerts */
    public static final int STREAM_RING = 2;
    /** @hide Used to identify the volume of audio streams for music playback */
    public static final int STREAM_MUSIC = 3;
    /** @hide Used to identify the volume of audio streams for alarms */
    public static final int STREAM_ALARM = 4;
    /** @hide Used to identify the volume of audio streams for notifications */
    public static final int STREAM_NOTIFICATION = 5;
    /** @hide
     *  Used to identify the volume of audio streams for phone calls when connected on bluetooth
     *  @deprecated use {@link #STREAM_VOICE_CALL} instead */
    public static final int STREAM_BLUETOOTH_SCO = 6;
    /** @hide Used to identify the volume of audio streams for enforced system sounds in certain
     * countries (e.g camera in Japan) */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    public static final int STREAM_SYSTEM_ENFORCED = 7;
    /** @hide Used to identify the volume of audio streams for DTMF tones */
    public static final int STREAM_DTMF = 8;
    /** @hide Used to identify the volume of audio streams exclusively transmitted through the
     *  speaker (TTS) of the device */
    public static final int STREAM_TTS = 9;
    /** @hide Used to identify the volume of audio streams for accessibility prompts */
    public static final int STREAM_ACCESSIBILITY = 10;
    /** @hide Used to identify the volume of audio streams for virtual assistant */
    public static final int STREAM_ASSISTANT = 11;
    /**
     * @hide
     * @deprecated Use {@link #numStreamTypes()} instead
     */
    public static final int NUM_STREAMS = 5;

AudioAttributes 新版本的音频属性,新版本中对老版本的streamType有做兼容

AudioAttributes {
    mUsage
    mContentType
    mSource
    mFlags
    mTags / mFormattedTags / mBundle    (key value pairs)
}

系统仅基于 STREAM_MUSIC、STREAM_NOTIFICATION 等固定流类型进行混音和音量控制。

例如,Google Maps 的导航语音和音乐播放器都被归类为 STREAM_MUSIC,导致:

无法区分优先级:导航语音和音乐在混音时被同等对待,无法自动降低音乐音量以突出导航提示。

音量控制耦合:用户在调节音量时只能统一控制所有 STREAM_MUSIC 流,无法单独调节导航或音乐。

音频路由混乱:车载系统无法识别 STREAM_MUSIC 中的导航语音和音乐差异,导致两者共用同一逻辑通道。

// 导航应用的正确配置
AudioAttributes attributes = new AudioAttributes.Builder()
    .setUsage(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE) // 明确用途
    .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)            // 内容类型为语音
    .build();
mediaPlayer.setAudioAttributes(attributes);

USAGE:明确音频的“使用场景

        USAGE_ASSISTANCE_NAVIGATION_GUIDANCE 表示导航语音

    /**
     * Usage value to use when the usage is media, such as music, or movie
     * soundtracks.
     */
    public final static int USAGE_MEDIA = 1;
    /**
     * Usage value to use when the usage is voice communications, such as telephony
     * or VoIP.
     */
    public final static int USAGE_VOICE_COMMUNICATION = 2;
    /**
     * Usage value to use when the usage is in-call signalling, such as with
     * a "busy" beep, or DTMF tones.
     */
    public final static int USAGE_VOICE_COMMUNICATION_SIGNALLING = 3;
    /**
     * Usage value to use when the usage is an alarm (e.g. wake-up alarm).
     */
    public final static int USAGE_ALARM = 4;
    /**
     * Usage value to use when the usage is notification. See other
     * notification usages for more specialized uses.
     */
    public final static int USAGE_NOTIFICATION = 5;
//...

CONTENT_TYPE :定义音频内容的类型

        CONTENT_TYPE_SPEECH 表示语音内容                base/media/java/android/media/AudioAttributes.java

    /**
     * Content type value to use when the content type is speech.
     */
    public final static int CONTENT_TYPE_SPEECH = 1;
    /**
     * Content type value to use when the content type is music.
     */
    public final static int CONTENT_TYPE_MUSIC = 2;
    /**
     * Content type value to use when the content type is a soundtrack, typically accompanying
     * a movie or TV program.
     */
    public final static int CONTENT_TYPE_MOVIE = 3;
//...

AUDIO_OUTPUT_FLAG:定义音频流特性的标志位,直接影响音频数据的处理方式、设备路由和性能优化。这些标志决定了音频流的优先级、延迟要求和硬件兼容性。

        av/media/libaudioclient/include/media/AudioTrack.h

        audio_output_flags_t

AudioTrack( audio_stream_type_t streamType,
                uint32_t sampleRate,
                audio_format_t format,
                audio_channel_mask_t channelMask,
                size_t frameCount    = 0,
                audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
                const wp<IAudioTrackCallback>& callback = nullptr,
                int32_t notificationFrames = 0,
                audio_session_t sessionId  = AUDIO_SESSION_ALLOCATE,
                transfer_type transferType = TRANSFER_DEFAULT,
                const audio_offload_info_t *offloadInfo = nullptr,
                const AttributionSourceState& attributionSource =
                AttributionSourceState(),
                const audio_attributes_t* pAttributes = nullptr,
                bool doNotReconnect = false,
                float maxRequiredSpeed = 1.0f,
                audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE);
AUDIO_OUTPUT_FLAG_FAST
低延迟模式,优先选择低延迟硬件路径(如 low_latency 设备)
游戏音效、按键音、实时语音通话等对延迟敏感的场景

AUDIO_OUTPUT_FLAG_PRIMARY
主音频流,用于系统铃声、通知等基础声音
系统级音频(如来电铃声)

AUDIO_OUTPUT_FLAG_DEEP_BUFFER
高缓冲模式,适合高音质但对延迟不敏感的场景
音乐播放、视频背景音

AUDIO_OUTPUT_FLAG_DIRECT 直输模式,绕过软件混音,直接输出到硬件(如 USB 声卡)
专业音频设备、Hi-Fi 播放

AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD
硬件解码模式,数据不经软件解码直接传输到硬件解码器
压缩音频格式(如 MP3、AAC)的高效播放

STRATEGY:对streamType做一次细致的划分         av/services/audiopolicy/common/include/policy.h

/**
 * Legacy audio policy product strategies IDs. These strategies are supported by the default
 * policy engine.
 * IMPORTANT NOTE: the order of this enum is important as it determines the priority
 * between active strategies for routing decisions: lower enum value => higher priority
 */
#define AUDIO_LEGACY_STRATEGY_LIST_DEF(V)      \
    V(STRATEGY_NONE, -1)                       \
    V(STRATEGY_PHONE, 0)                       \
    V(STRATEGY_SONIFICATION, 1)                \
    V(STRATEGY_ENFORCED_AUDIBLE, 2)            \
    V(STRATEGY_ACCESSIBILITY, 3)               \
    V(STRATEGY_SONIFICATION_RESPECTFUL, 4)     \
    V(STRATEGY_MEDIA, 5)                       \
    V(STRATEGY_DTMF, 6)                        \
    V(STRATEGY_CALL_ASSISTANT, 7)              \
    V(STRATEGY_TRANSMITTED_THROUGH_SPEAKER, 8) \
    V(STRATEGY_REROUTING, 9)                   \
    V(STRATEGY_PATCH, 10)

enum legacy_strategy {
    AUDIO_LEGACY_STRATEGY_LIST_DEF(AUDIO_DEFINE_ENUM_SYMBOL_V)
};


module:指音频硬件接口,也称为HwModule‌,定义在 audio_policy_configuration.xml 文件中

主要包括以下几种类型:primary、a2dp、usb、r_submix

每个 module 都被描述为 HwModule,保存在 mHwModules 中‌

<audioPolicyConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
    <!-- ... -->
    <globalConfiguration speaker_drc_enabled="true"/>
    <!-- ... -->
        <!-- Usb Audio HAL -->
        <module name="usb" halVersion="2.0">
            <mixPorts>
                <mixPort name="usb_accessory output" role="source">
                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                             samplingRates="44100,48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                </mixPort>
            </mixPorts>
            <devicePorts>
                <devicePort tagName="USB Host Out" type="AUDIO_DEVICE_OUT_USB_ACCESSORY" role="sink">
                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                             samplingRates="44100,48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                </devicePort>
            </devicePorts>
            <routes>
                <route type="mix" sink="USB Host Out"
                       sources="usb_accessory output"/>
            </routes>
        </module>
</audioPolicyConfiguration>

output:音频数据的输出通道。每个output可以路由到不同的设备,如speaker、蓝牙、HDMI等‌

一个 output 对应一个或多个设备节点,比如/dev/snd/pcmC0D0p。

一个设备节点只由一个 Thread 操作。

一个 output 是多个 device 的组合,比如声卡上有喇叭(dev1)和耳机(dev2),这些 device 属于同一个硬件上不同的端口。这些 device 需支持同样的参数,如采样率和通道。

<mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_FAST|AUDIO_OUTPUT_FLAG_PRIMARY">
        <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                             samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</mixPort>

device:具体出声设备,比如手机喇叭、耳机,录制设备,比如mic设备         media/audio/include/system/audio-hal-enums.h

#define AUDIO_DEVICE_LIST_UNIQUE_DEF(V) \
    V(AUDIO_DEVICE_NONE, 0x0u) \
    V(AUDIO_DEVICE_OUT_EARPIECE, 0x1u) \
    V(AUDIO_DEVICE_OUT_SPEAKER, 0x2u) \
    V(AUDIO_DEVICE_OUT_WIRED_HEADSET, 0x4u) \
    V(AUDIO_DEVICE_OUT_WIRED_HEADPHONE, 0x8u) \
    V(AUDIO_DEVICE_OUT_BLUETOOTH_SCO, 0x10u) \
    V(AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET, 0x20u) \
    V(AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT, 0x40u) \
    V(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP, 0x80u) \
    V(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES, 0x100u) \
    V(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER, 0x200u) \
    V(AUDIO_DEVICE_OUT_HDMI, 0x400u) \
    V(AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET, 0x800u) \
    V(AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET, 0x1000u) \
    V(AUDIO_DEVICE_OUT_USB_ACCESSORY, 0x2000u) \
    V(AUDIO_DEVICE_OUT_USB_DEVICE, 0x4000u) \
    V(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, 0x8000u) \
    V(AUDIO_DEVICE_OUT_TELEPHONY_TX, 0x10000u) \
    V(AUDIO_DEVICE_OUT_LINE, 0x20000u) \
    V(AUDIO_DEVICE_OUT_HDMI_ARC, 0x40000u) \
    V(AUDIO_DEVICE_OUT_HDMI_EARC, 0x40001u) \
    V(AUDIO_DEVICE_OUT_SPDIF, 0x80000u) \
    V(AUDIO_DEVICE_OUT_FM, 0x100000u) \
    V(AUDIO_DEVICE_OUT_AUX_LINE, 0x200000u) \
    V(AUDIO_DEVICE_OUT_SPEAKER_SAFE, 0x400000u) \
    V(AUDIO_DEVICE_OUT_IP, 0x800000u) \
    V(AUDIO_DEVICE_OUT_MULTICHANNEL_GROUP, 0x800001u) \
    V(AUDIO_DEVICE_OUT_BUS, 0x1000000u) \
    V(AUDIO_DEVICE_OUT_PROXY, 0x2000000u) \
    V(AUDIO_DEVICE_OUT_USB_HEADSET, 0x4000000u) \
    V(AUDIO_DEVICE_OUT_HEARING_AID, 0x8000000u) \
    V(AUDIO_DEVICE_OUT_ECHO_CANCELLER, 0x10000000u) \
    V(AUDIO_DEVICE_OUT_BLE_HEADSET, 0x20000000u) \
    V(AUDIO_DEVICE_OUT_BLE_SPEAKER, 0x20000001u) \
    V(AUDIO_DEVICE_OUT_BLE_BROADCAST, 0x20000002u) \
    V(AUDIO_DEVICE_OUT_DEFAULT, AUDIO_DEVICE_BIT_DEFAULT) \
    V(AUDIO_DEVICE_IN_COMMUNICATION, AUDIO_DEVICE_BIT_IN | 0x1u) \
    V(AUDIO_DEVICE_IN_AMBIENT, AUDIO_DEVICE_BIT_IN | 0x2u) \
    V(AUDIO_DEVICE_IN_BUILTIN_MIC, AUDIO_DEVICE_BIT_IN | 0x4u) \
    V(AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET, AUDIO_DEVICE_BIT_IN | 0x8u) \
    V(AUDIO_DEVICE_IN_WIRED_HEADSET, AUDIO_DEVICE_BIT_IN | 0x10u) \
    V(AUDIO_DEVICE_IN_HDMI, AUDIO_DEVICE_BIT_IN | 0x20u) \
    V(AUDIO_DEVICE_IN_TELEPHONY_RX, AUDIO_DEVICE_BIT_IN | 0x40u) \
    V(AUDIO_DEVICE_IN_BACK_MIC, AUDIO_DEVICE_BIT_IN | 0x80u) \
    V(AUDIO_DEVICE_IN_REMOTE_SUBMIX, AUDIO_DEVICE_BIT_IN | 0x100u) \
    V(AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET, AUDIO_DEVICE_BIT_IN | 0x200u) \
    V(AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET, AUDIO_DEVICE_BIT_IN | 0x400u) \
    V(AUDIO_DEVICE_IN_USB_ACCESSORY, AUDIO_DEVICE_BIT_IN | 0x800u) \
    V(AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_DEVICE_BIT_IN | 0x1000u) \
    V(AUDIO_DEVICE_IN_FM_TUNER, AUDIO_DEVICE_BIT_IN | 0x2000u) \
    V(AUDIO_DEVICE_IN_TV_TUNER, AUDIO_DEVICE_BIT_IN | 0x4000u) \
    V(AUDIO_DEVICE_IN_LINE, AUDIO_DEVICE_BIT_IN | 0x8000u) \
    V(AUDIO_DEVICE_IN_SPDIF, AUDIO_DEVICE_BIT_IN | 0x10000u) \
    V(AUDIO_DEVICE_IN_BLUETOOTH_A2DP, AUDIO_DEVICE_BIT_IN | 0x20000u) \
    V(AUDIO_DEVICE_IN_LOOPBACK, AUDIO_DEVICE_BIT_IN | 0x40000u) \
    V(AUDIO_DEVICE_IN_IP, AUDIO_DEVICE_BIT_IN | 0x80000u) \
    V(AUDIO_DEVICE_IN_BUS, AUDIO_DEVICE_BIT_IN | 0x100000u) \
    V(AUDIO_DEVICE_IN_PROXY, AUDIO_DEVICE_BIT_IN | 0x1000000u) \
    V(AUDIO_DEVICE_IN_USB_HEADSET, AUDIO_DEVICE_BIT_IN | 0x2000000u) \
    V(AUDIO_DEVICE_IN_BLUETOOTH_BLE, AUDIO_DEVICE_BIT_IN | 0x4000000u) \
    V(AUDIO_DEVICE_IN_HDMI_ARC, AUDIO_DEVICE_BIT_IN | 0x8000000u) \
    V(AUDIO_DEVICE_IN_HDMI_EARC, AUDIO_DEVICE_BIT_IN | 0x8000001u) \
    V(AUDIO_DEVICE_IN_ECHO_REFERENCE, AUDIO_DEVICE_BIT_IN | 0x10000000u) \
    V(AUDIO_DEVICE_IN_BLE_HEADSET, AUDIO_DEVICE_BIT_IN | 0x20000000u) \
    V(AUDIO_DEVICE_IN_DEFAULT, AUDIO_DEVICE_BIT_IN | AUDIO_DEVICE_BIT_DEFAULT)
// Some of the device enums have aliases. They can not appear in the 'to string'
// converter as case values must be unique.
#define AUDIO_DEVICE_LIST_DEF(V) \
    AUDIO_DEVICE_LIST_UNIQUE_DEF(V) \
    V(AUDIO_DEVICE_OUT_AUX_DIGITAL, AUDIO_DEVICE_OUT_HDMI) \
    V(AUDIO_DEVICE_OUT_STUB, AUDIO_DEVICE_OUT_DEFAULT) \
    V(AUDIO_DEVICE_IN_VOICE_CALL, AUDIO_DEVICE_IN_TELEPHONY_RX) \
    V(AUDIO_DEVICE_IN_AUX_DIGITAL, AUDIO_DEVICE_IN_HDMI) \
    V(AUDIO_DEVICE_IN_STUB, AUDIO_DEVICE_IN_DEFAULT)

typedef enum : uint32_t {
    AUDIO_DEVICE_LIST_DEF(AUDIO_DEFINE_ENUM_SYMBOL_V)
} audio_devices_t;

profile:配置,用来描述 output 支持哪些设备(仅逻辑上支持,不一定有实际硬件,比如耳机 output是插上耳机就支持,不插耳机就不支持,但profile一直支持)


policy:一个 stream 终选择到哪个 device,这些stream如何互相影响(一个高优先级的声音会使得其他声音静音),等等等,统称为policy (策略)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值