Android蓝牙协议栈fluoride(十) - 音乐播放(3)

上一篇文章介绍了btif层中A2DP角色管理以及状态机,本文将介绍A2DP音频相关的内容,包括音频流、解码等。

概述

音频流向如下图:
在这里插入图片描述

建立AVDTP协议连接之后,当Source端需要播放时会通过AVDTP协议发送通过RTP格式封装的音频数据包,收到数据包之后协议栈中选用连接时约定的编码器以及参数进行解码,解码成PCM数据之后写入到音频模块进行播放。A2DP Profile连接建立过程如下:

  1. Source端会获取Sink端支持几个解码器(SEP, Stream End Point)。
  2. Source端获取每个SEP的配置(Capabilites)。
  3. 根据Source端支持的配置情况选择一个配置设置给Sink端。
    此时,已经为后面传输音频流做好了准备,需要播放时即可发送音频流进行播放。
    在这里插入图片描述
    有播放时,Source端向Sink端发送音频流。

编解码器

管理

在Fluoride协议栈中,解码器配置、解码等的实现在stack/a2dp目录中。A2DP Profile中规定蓝牙播放必须支持SBC编解码器,其他的可以选,现在常见的有编解码器有:SBC、AAC、APTx、LDAC、LHDC等,除SBC和AAC在profile协议中有定义,其他都都是自定义编解码器。不同编解码器由不同的人/厂商实现,因此在A2DP协议上使用以下类型区分不同的编解码器:

// SBC codec
#define A2DP_MEDIA_CT_SBC 0x00
// AAC codec
#define A2DP_MEDIA_CT_AAC 0x02
// 自定义codec
#define A2DP_MEDIA_CT_NON_A2DP 0xFF

所有自定义的codec都是FF,具体细分在自定义的capabilities中用vendor id和codec id区分,capabilities结构中,前面两个字段为vendor id和codec id,如下图:
在这里插入图片描述

其中每个厂商的vendor id不能重复,一个厂商多个codec的codec id也不能重复,如LDAC:

static const tA2DP_LDAC_CIE a2dp_ldac_source_caps = {
   
    A2DP_LDAC_VENDOR_ID,  // vendorId
    A2DP_LDAC_CODEC_ID,   // codecId
    ...
};

在代码逻辑中为了区分不同角色的编解码器,使用以下枚举表示不同的codec(每个codec的index的值应该是不同的):

typedef enum {
   
  BTAV_A2DP_CODEC_INDEX_SOURCE_MIN = 0,
  // Add an entry for each source codec here.
  // NOTE: The values should be same as those listed in the following file:
  //   BluetoothCodecConfig.java
  BTAV_A2DP_CODEC_INDEX_SOURCE_SBC = 0,
  BTAV_A2DP_CODEC_INDEX_SOURCE_AAC,
  BTAV_A2DP_CODEC_INDEX_SOURCE_APTX,
  BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD,
  BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC,
  BTAV_A2DP_CODEC_INDEX_SOURCE_MAX,

  BTAV_A2DP_CODEC_INDEX_SINK_MIN = BTAV_A2DP_CODEC_INDEX_SOURCE_MAX,
  // Add an entry for each sink codec here
  BTAV_A2DP_CODEC_INDEX_SINK_SBC = BTAV_A2DP_CODEC_INDEX_SINK_MIN,
  BTAV_A2DP_CODEC_INDEX_SINK_AAC,
  BTAV_A2DP_CODEC_INDEX_SINK_LDAC,
  BTAV_A2DP_CODEC_INDEX_SINK_MAX,

  BTAV_A2DP_CODEC_INDEX_MIN = BTAV_A2DP_CODEC_INDEX_SOURCE_MIN,
  BTAV_A2DP_CODEC_INDEX_MAX = BTAV_A2DP_CODEC_INDEX_SINK_MAX
} btav_a2dp_codec_index_t;

核心的类之间的关系如下:
在这里插入图片描述
A2dpCodecs是管理编解码器的核心数据结构,管理所有编辑器的配置,初始化A2dpCodecs时,根据btav_a2dp_codec_index_t中定义的枚举调用A2dpCodecConfig中的工厂方法createCodec创建各个编解码器的配置,然后添加列表中,其中indexed_codecs_是所有未被禁用的编解码器的配置,ordered_source_codecs_是所有source使用的编码器的配置,ordered_sink_codecs_是所有sink使用的解码器的配置。

API接口

不同编解码器的接口都不相同,为了调用方的接口统一,fluoride中定义了编解码器的API,有新的编解码器需要适配时只需要实现这些API即可,API原型定义如下:

// 编码器API
typedef struct {
   
  // 编码器初始化
  void (*encoder_init)(const tA2DP_ENCODER_INIT_PEER_PARAMS* p_peer_params, A2dpCodecConfig* a2dp_codec_config, a2dp_source_read_callback_t read_callback, a2dp_source_enqueue_callback_t enqueue_callback);
  // 清理编码器资源
  void (*encoder_cleanup)(void);
  
### 回答1: Linux 系统中有几种常见的蓝牙协议栈: 1. BlueZ:这是 Linux 系统中默认的蓝牙协议栈,它由 Linux 基金会开发并维护。BlueZ 提供了蓝牙的高级功能,并且可以让用户通过命令行或脚本来控制蓝牙设备。 2. Bluedroid:这是 Android 系统中的蓝牙协议栈,也可以在其他基于 Linux 的系统中使用。Bluedroid 提供了丰富的蓝牙功能,包括蓝牙协议栈、配对、连接、传输数据等。 3. BlueZ for Android:这是一个基于 BlueZ 的蓝牙协议栈,专门为 Android 系统开发。它兼容 BlueZ 命令行工具,可以让用户在 Android 系统中使用 BlueZ 命令行来控制蓝牙设备。 4. hciattach:这是 Linux 中用于驱动蓝牙硬件的工具,它可以将蓝牙硬件附加到蓝牙协议栈中,使蓝牙硬件可以与其他蓝牙设备通信。 总的来说,Linux 系统中的蓝牙协议栈主要有 BlueZ 和 Bluedroid 两种,其中 BlueZ 是 Linux 系统中的默认蓝牙协议栈,Bluedroid 则是 Android 系统中的蓝牙协议栈。 ### 回答2: Linux操作系统中有两种蓝牙协议栈可供选择。 1. BlueZ协议栈:BlueZ是Linux操作系统上最常用的蓝牙协议栈。它提供API和工具,用于在Linux设备上实现蓝牙功能。BlueZ支持几乎所有的蓝牙协议,包括传统的蓝牙核心规范(Bluetooth Core Specification)和最新的蓝牙低功耗(Bluetooth Low Energy)规范。BlueZ协议栈被广泛应用于各种Linux设备,包括智能手机、平板电脑、智能手表等。 2. Affix协议栈:Affix是一个开源的Linux蓝牙协议栈。它提供了蓝牙通信的基本功能,并可以在嵌入式系统上运行。Affix协议栈支持蓝牙核心规范,但对于蓝牙低功耗规范的支持相对有限。它适用于资源受限的嵌入式设备,如物联网设备、传感器等。 总结起来,Linux操作系统上有两种常用的蓝牙协议栈:BlueZ协议栈和Affix协议栈。其中,BlueZ协议栈是最常用和功能最全面的蓝牙协议栈,被广泛应用于各种Linux设备。而Affix协议栈则适用于资源受限的嵌入式设备。 ### 回答3: Linux操作系统支持多种蓝牙协议栈,以下是其中一些常见的蓝牙协议栈: 1. BlueZ:BlueZ是Linux操作系统上最为广泛使用的开源蓝牙协议栈。它提供了一套完整的蓝牙协议栈实现,包括蓝牙核心协议、蓝牙硬件驱动和一系列用户空间的工具和库。BlueZ支持众多的蓝牙协议和功能,如蓝牙文件传输、蓝牙耳机、蓝牙键盘等。 2. Affix:Affix是一种轻量级的蓝牙协议栈,旨在提供更小的内存占用和更低的功耗。它适用于嵌入式设备和资源受限的系统。Affix支持核心蓝牙协议,但不支持所有BlueZ的高级功能。 3. Bluedroid:Bluedroid最初是由Android平台使用的蓝牙协议栈,后来也被移植到了Linux操作系统中。Bluedroid基于BlueZ协议栈,但做了一些定制化的修改和优化,以适应移动设备的需求。 4. FluorideFluoride是谷歌开发的蓝牙协议栈,最初用于Android平台,后来也支持了Linux操作系统。Fluoride提供了一套用于开发蓝牙应用的API和工具,并且与BlueZ相比有一些特有的优化和功能。 这些蓝牙协议栈都有各自的特点和适用场景,开发者可以根据不同的需求选择合适的协议栈来进行蓝牙应用程序的开发和调试。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值