🎧 蓝牙耳机

基于经典蓝牙 A2DP + HFP Profile 的音频设备,支持立体声音乐和通话功能。

📐 系统架构

flowchart TB subgraph Headset["蓝牙耳机"] MIC[麦克风] --> CODEC[音频 Codec] CODEC --> BT[BLE+ 经典双模芯片] BT --> ANT[天线] BT --> AMP[功放] AMP --> SPK[扬声器] end subgraph Phone["手机"] APP[音乐 App] --> AUDIO[音频系统] AUDIO --> BT2[BLE+ 经典双模芯片] BT2 --> ANT2[天线] end ANT <-->|A2DP 音频流 | ANT2 ANT <-->|HFP 通话 | ANT2 ANT -.->|BLE 控制 | ANT2 style Headset fill:#e3f2fd,stroke:#007bff style Phone fill:#d4edda,stroke:#28a745

📋 蓝牙音频 Profile

flowchart TB subgraph Classic["经典蓝牙 Profile"] A2DP["A2DP
音频传输"] AVRCP["AVRCP
远程控制"] HFP["HFP/HSP
免提通话"] end subgraph BLE["低功耗蓝牙"] BATTERY["电池服务"] FINDME["查找耳机"] FWUPD["固件升级"] end A2DP --> CODEC1{音频编码} CODEC1 --> SBC[SBC] CODEC1 --> AAC[AAC] CODEC1 --> APTX[aptX] CODEC1 --> LDAC[LDAC] style Classic fill:#fff3cd,stroke:#ffc107 style BLE fill:#e3f2fd,stroke:#007bff

📊 A2DP 音频传输流程

sequenceDiagram participant Phone as 手机 participant Headset as 蓝牙耳机 Note over Phone,Headset: 1. 经典蓝牙连接 Phone->>Headset: Inquiry/Page Headset-->>Phone: 连接完成 Note over Phone,Headset: 2. 服务发现 (SDP) Phone->>Headset: SDP 查询 A2DP Headset-->>Phone: 返回 A2DP/AVRCP UUID Note over Phone,Headset: 3. A2DP 信令 Phone->>Headset: L2CAP 连接 (信令通道) Phone->>Headset: 配置 Codec (SBC) Headset-->>Phone: 配置确认 Note over Phone,Headset: 4. 音频流传输 Phone->>Headset: L2CAP 连接 (媒体通道) loop 持续传输 Phone->>Headset: RTP 音频包 (10ms) end Note over Phone,Headset: 5. 播放控制 Phone->>Headset: AVRCP Play/Pause Headset-->>Phone: 执行确认

📦 A2DP 数据包结构

// A2DP 音频数据包结构
// 基于 L2CAP ACL 数据

typedef struct {
    // L2CAP Header (4 bytes)
    uint16_t l2cap_len;      // L2CAP 数据长度
    uint16_t l2cap_cid;      // Channel ID (媒体通道)
    
    // RTP Header (12 bytes)
    uint8_t  rtp_v_p_x_cc;   // Version, Padding, Extension, CC
    uint8_t  rtp_m_pt;       // Marker, Payload Type
    uint16_t rtp_seq;        // Sequence Number
    uint32_t rtp_timestamp;  // Timestamp
    uint32_t rtp_ssrc;       // SSRC
    
    // AVDTP Media Payload
    uint8_t  frame_count;    // 帧数量
    uint8_t  frame_len[4];   // 每帧长度
    uint8_t  audio_data[];   // SBC/AAC 音频数据
} a2dp_packet_t;

// SBC 音频帧头
typedef struct {
    uint8_t  sync_word;      // 同步字 0x9C
    uint8_t  freq_samp;      // 采样率 + 块数 + 声道 + 分配方法
    uint8_t  subbands;       // 子带数 + 联合声道
    uint8_t  snr_alloc;      // 信噪比 + 比特池
    uint8_t  scale_factor[]; // 缩放因子
    uint8_t  audio_data[];   // 音频数据
} sbc_frame_t;

// 典型配置:44.1kHz, 立体声,SBC
// 每包约 120-150 bytes,每 10ms 发送一次

📈 完整连接流程

flowchart TD A[开机] --> B[BLE 广播] B --> C{手机连接?} C -->|是 | D[BLE 配对] C -->|否 | B D --> E[经典蓝牙可发现] E --> F{经典蓝牙连接?} F -->|是 | G[建立 A2DP+HFP] F -->|否 | E G --> H{音频播放?} H -->|是 | I[A2DP 流传输] H -->|否 | J{来电?} I --> K[播放音乐] J -->|是 | L[HFP 通话] J -->|否 | M[待机] K --> N{暂停/结束?} L --> N N -->|是 | M N -->|否 | I M --> O{断开?} O -->|是 | B O -->|否 | M style A fill:#28a745,color:#fff style I fill:#007bff,color:#fff style L fill:#ffc107,color:#000 style B fill:#dc3545,color:#fff

💻 HFP 通话控制

// HFP AT 命令交互
// 通过 RFCOMM 通道传输

// 耳机发送 AT 命令
const char *hfp_at_commands[] = {
    "AT+BRSF=1023\r\n",      // 支持的功能
    "AT+CIND=?",             // 查询指示器
    "AT+CLCC=?",             // 查询当前通话
    "ATA\r\n",               // 接听电话
    "AT+CHUP\r\n",           // 挂断电话
    "AT+CKPD=200\r\n",       // 按键按下 (多功能键)
};

// 手机响应
const char *hfp_responses[] = {
    "+BRSF: 1023",           // 功能确认
    "+CIND: (\"batt\",(0-5))", // 电池指示器
    "OK",                    // 命令成功
   "RING",                   // 来电提醒
    "+CLCC: 1,1,4,0,\"123456789\"", // 通话列表
};

// HFP 事件处理
void hfp_event_handler(hfp_event_t event) {
    switch (event) {
        case HFP_EVENT_CALL_INCOMING:
            // 来电:播放铃声
            play_ringtone();
            break;
            
        case HFP_EVENT_CALL_CONNECTED:
            // 通话建立:切换音频路由
            audio_route_to_speaker();
            break;
            
        case HFP_EVENT_CALL_ENDED:
            // 通话结束:恢复待机
            audio_route_to_idle();
            break;
            
        case HFP_EVENT_AUDIO_CONNECTED:
            // A2DP 音频连接
            a2dp_streaming_start();
            break;
    }
}

🎵 音频编码对比

编码 码率 延迟 音质 兼容性
SBC 328 kbps ~150ms ★★★☆☆ 100% (强制支持)
AAC 256 kbps ~100ms ★★★★☆ iOS/Android
aptX 352 kbps ~70ms ★★★★☆ Qualcomm 芯片
aptX HD 576 kbps ~150ms ★★★★★ 高端设备
LDAC 990 kbps ~150ms ★★★★★ Sony/Android
LC3 160-345 kbps ~40ms ★★★★☆ LE Audio (蓝牙 5.2+)

🔋 低功耗设计

功耗模式

  • 播放中: 30-50mA
  • 通话中: 40-60mA
  • 待机: 3-5mA
  • 休眠: <50μA

省电策略

  • 无音频时进入 Sniff 模式
  • BLE 广播替代经典蓝牙
  • 自动关机 (30 分钟无操作)
  • 入耳检测暂停播放

🔍 调试要点

常见问题

  • 连接失败:清除配对重试
  • 音频卡顿:干扰/距离过远
  • 不同步:重新配对
  • 通话无声:检查 HFP 路由

推荐工具

  • Frontline: 协议分析仪
  • Ellisys: 蓝牙分析仪
  • Wireshark: HCI 抓包
  • Audio Tester: 音质测试

🆕 LE Audio (蓝牙 5.2+)

flowchart TB subgraph LEA["LE Audio 特性"] LC3[LC3 编码
低功耗高音质] MULTI[多设备连接
同时播放] BROADCAST[广播音频
公共场所] HEARING[助听器支持
低功耗] end subgraph Classic["经典音频"] A2DP2[A2DP] HFP2[HFP] end LEA --> BENEFIT[优势
低功耗 + 多设备 + 广播] Classic --> LIMIT[限制
功耗高 + 单连接] style LEA fill:#d4edda,stroke:#28a745 style Classic fill:#fff3cd,stroke:#ffc107