藍牙音樂(A2DP)音頻延遲的一些感想跟分析,讓你對A2DP體驗更佳深入

?零.聲明

最近做藍牙協議棧的過程中遇到一些客戶偶爾提報音頻延遲的問題,所以引發了一些感想,跟大家分享下,音頻延遲主要的影響范圍是對一些要求實時性比較高的場景有比較差的體驗

  • 連接藍牙看視頻的過程中,發現音畫不同步,比如看電影,看抖音等一些視頻類的內容
  • 游戲過程中,需要對聲音有實時判斷的,比如競技類游戲之類的
  • 導航過程中,聲音延遲,影響比較大,尤其是我直觀的體驗一個場景的痛點,就是在高速交叉口的時候,有的時候開車并不會一直盯著屏幕看,反而會聽語音播報,但是有的時候交叉口很近的才出來播報,導致措手不及

當然還有其他場景,我只是列舉了幾個我能想到的。說完這些,那我就從理論的角度給大家分析下這個問題,首先我想公布結論:對于藍牙連接,沒辦法完全消除延遲,只能盡量讓這個延遲變小。

本專欄文章我們會以連載的方式持續更新,本專欄計劃更新內容如下:

第一篇:藍牙綜合介紹 ,主要介紹藍牙的一些概念,產生背景,發展軌跡,市面藍牙介紹,以及藍牙開發板介紹。

第二篇:Transport層介紹,主要介紹藍牙協議棧跟藍牙芯片之前的硬件傳輸協議,比如基于UART的H4,H5,BCSP,基于USB的H2等

第三篇:傳統藍牙controller介紹,主要介紹傳統藍牙芯片的介紹,包括射頻層(RF),基帶層(baseband),鏈路管理層(LMP)等

第四篇:傳統藍牙host介紹,主要介紹傳統藍牙的協議棧,比如HCI,L2CAP,SDP,RFCOMM,HFP,SPP,HID,AVDTP,AVCTP,A2DP,AVRCP,OBEX,PBAP,MAP等等一系列的協議吧。

第五篇:低功耗藍牙controller介紹,主要介紹低功耗藍牙芯片,包括物理層(PHY),鏈路層(LL)

第六篇:低功耗藍牙host介紹,低功耗藍牙協議棧的介紹,包括HCI,L2CAP,ATT,GATT,SM等

第七篇:藍牙芯片介紹,主要介紹一些藍牙芯片的初始化流程,基于HCI vendor command的擴展

第八篇:附錄,主要介紹以上常用名詞的介紹以及一些特殊流程的介紹等。

另外,開發板如下所示,對于想學習藍牙協議棧的最好人手一套。以便更好的學習藍牙協議棧,相信我,學完這一套視頻你將擁有修改任何協議棧的能力(比如Linux下的bluez,Android下的bluedroid)。

-------------------------------------------------------------------------------------------------------------------------

藍牙視頻教程(跟韋東山老師合作):

https://item.taobao.com/item.htm?spm=a1z10.1-c-s.w4004-22329603896.20.5aeb41f98e267j&id=693788592796

藍牙交流扣扣群:765961169

入手開發板:https://shop220811498.taobao.com/category-1542116976.htm?spm=a1z10.5-c-s.w4010-22329603913.7.39ca7dbe2EA0K3&search=y&catName=%C0%B6%D1%C0%BF%AA%B7%A2%B0%E5#bd

藍牙學習目錄一篇文章足夠你學習藍牙技術,提供史上最全的藍牙技術(傳統藍牙/低功耗藍牙)文章總結,文檔下載總結(2020/12/11更新)_Wireless_Link的博客-CSDN博客_藍牙eir

--------------------------------------------------------------------------------------------------------------------------

一. A2DP的架構

我們先來介紹下整個A2DP audio path的框架

A2DP source的發送流程

UL(Upper Layer)收集到PCM數據,然后發送到A2DP,A2DP經過codec算法(SBC/AAC/APTX/LDAC/LHDC..)壓縮成特定的音頻格式,然后交給AVDTP,AVDTP轉交給L2CAP,L2CAP通過ACL格式轉交給HCI,然后到達BT chip,通過RF射頻出去。

A2DP sink的接收流程

BT chip通過RF接收進來數據,然后通過ACL交給HCI,然后交給L2CAP,L2CAP交給AVDTP,AVDTP交給A2DP,A2DP收到的是remote經過壓縮的數據,此時通過codec算法(SBC/AAC/APTX/LDAC/LHDC..)解壓成PCM數據,然后交于聲卡播放

我們在拿一個Source設備(手機)跟一個Sink設備(車載/耳機/音箱)來舉例子看下整個結構

整個流程跟上面的A2DP類似,所以我們就不介紹了

二. 延遲原因分析

所以從這個框架中就可以總結歸納出來整個音頻延遲可能原因

NOTED: 在這里注意下,音頻延遲跟音頻卡頓分析思路完全不同,有的人可能會混淆,有機會我再通過另外一篇文章來介紹下音頻卡頓的分析思路。

大體的可能得原因如下:

另外,市面上大部分的實測數據如下:

當然這個是多方面原因造成的音頻延遲,我們就來拆解下。

1. codec算法本身造成的音頻延遲

編解碼器

開發廠商

理論單幀延遲

關鍵設計原理

幀尺寸(典型值)

SBC

SIG

15~30 ms

固定分幀(4/8子帶)

4~6 ms音頻數據

AAC

Fraunhofer IIS

5~20 ms

可變分幀(1024/960樣本)

20~24 ms音頻數據

aptX

高通

1.92 ms

固定4樣本塊處理(16kHz子帶)

1.92 ms音頻數據

aptX HD

高通

2.6 ms

增強量化精度(24bit)

2.6 ms音頻數據

aptX LL

高通

0.67 ms

超小幀(80樣本@48kHz)

1.67 ms音頻數據

aptX

Adaptive

高通

1~2 ms

動態幀調整(80~512樣本)

1~6 ms音頻數據

LDAC

Sony

8~10 ms

大幀優化音質(512/1024樣本)

5~10 ms音頻數據

LC3

SIG

0.125 ms

超短幀(10樣本@48kHz)

0.25 ms音頻數據

LHDC

Savitech

3~5 ms

可變分幀(256/512樣本)

3~6 ms音頻數據

?? 注意

  • 理論延遲 ≠ 實際端到端延遲(需疊加傳輸/緩沖/渲染等環節)
  • 幀尺寸越小延遲越低,但抗丟包能力下降(需更頻繁傳輸)

當然上面的數據也不一定是絕對的哈·,也要結合多方面因素來考慮

我們來算一個SBC的理論延遲吧,比如一個AVDTP package是1K的數據,然后4-5倍壓縮率,所以解壓后大概一幀是5K數據,而44.1Khz + 16bit位深 + 2Channel的1S的數據量173Kbyte,是28ms的理論延遲。

也就是你當下要發的數據,必須要等著5K數據壓縮完畢才能發送給對方。所以對方收到的第一包數據一定是28ms以前的數據,這個就是理論延遲

2. Sink原因

a. 緩沖buffer過大

為什么會有緩沖buffer呢,在介紹這個之前,我們就要介紹下jitter的概念了,什么是jitter呢?就是比如上面我們介紹了一包數據是28ms的延遲,也可以理解為每包duration如果所有都恒定,那么duration都應該是28ms,但是由于是無線,所以肯定會存在干擾等因素,導致包肯定有重傳等,所以在空口的duration肯定不是那么恒定的,比如來了28ms的數據,你就直接播放,那么由于空口有干擾,導致下個包是50ms來(這個是假定制),那么你本應該在29ms播放的時候發現沒有數據了,所以這時候會存在22ms的空檔沒有數據期,所以就會卡存,比如這種空口包

可以看到只要有duration增大的情況,那么后面一定會有duration小的數據過來來補充,我們就成為這種現象為jitter.

為了避免這種情況,所以sink端一定會有緩沖buffer來降低這個卡頓風險,但是談到這里學問就大了·,你增大緩沖buffer是解決了卡頓的風險,但是就帶來了我們本章的問題了,就是莫名其妙多了延遲了,比如你緩沖buffer緩沖100ms,那么就額外多了100ms的延遲。這時候我們就要在特定的平臺來權衡這個數值了,這個方面在不同的平臺調整的值策略不同,要實測

b. 協議棧調度異常

這個沒有啥好介紹的,就是協議棧的調度問題,協議棧的接收或者playback倍其他task或者thread搶占,拿不到資源,這個可能會引起音頻卡頓,也可能會引起來音頻延遲。

c. 平臺驅動問題

平臺驅動也會有音頻緩沖

ⅰ. Linux驅動緩沖原理

關鍵參數:

參數

內核結構字段

影響

典型值

buffer_size

runtime->buffer_size

總緩沖區大小

1024-8192幀

period_size

runtime->period_size

單次傳輸量

256-1024幀

period_count

由buffer_size/period_size推導

中斷頻率

2-8個周期

ⅱ. Android緩沖原理

AudioFlinger 混合緩沖區

  • FastMixer線程:專用于低延遲場景(游戲/錄音)
  • 混合緩沖區大小默認20ms(可動態調節)

AAudio 直通模式

[App] → [AAudio API] → [HAL層] → [DMA Buffer]

  • 繞過AudioFlinger,減少>40ms延遲
  • 要求:Android 8.0+,支持 MMAP 的硬件

層級

延遲范圍

可優化極限

應用層緩沖

10-100ms

1ms (AAudio)

AudioFlinger混合

20-40ms

0ms (Bypass)

內核環形緩沖

5-30ms

2ms (MMAP)

DMA傳輸

0.5-2ms

硬件固定

Codec處理

1-10ms

硬件固定

Android總延遲

36-182ms

<15ms

ⅲ. RTOS

RTOS等就要看SDK的編寫源碼了

3. Source原因

a. Delay report

Delay report是藍牙SIG在AVDTP/A2DP提出來的協議規范,就是為了解決音畫不同步的問題,但是這個要依賴于sink跟source都支持,什么原理呢?很簡單

在連線的時候A2DP sink會告知Source我的delay report時間是多少,Source收到后,在處理視頻的時候本來應該當下發送視頻,但是因為他知道sink的延遲是多少,所以音頻先于視頻delay report的時間發送,也就是 音頻先于視頻早達到delay report的時間,所以就規避了音畫不同步的問題·

但是目前看下來支持的Source設備還是比較少,加上現在的一些視頻類的APP也不會關注這個點,所以生態個人感覺還不是那么好!

b. UL層送數據延遲

這個也沒啥好解釋的哈,看標題就能看出來,由于系統問題,Source數據就是送的慢,所以導致到了sink端沒有那么及時

三. 未來方向

音頻延遲一直在無線領域是一個比較大的課題,想真正解決或者說讓end user無感知,還是比較難得,所以百花齊放,有幾個點可能要重點關注下。

1. LC3編解碼器(LE Audio核心)

通過0.25ms超短幀 + 前向糾錯實現端到端<30ms

突破性設計

參數

傳統SBC/AAC

LC3

優勢

幀長度

5~30ms

0.25ms

降低基礎延遲10倍

處理復雜度

50 MIPS

<15 MIPS

功耗降低60%

抗丟包能力

需20%重傳

FEC冗余

容忍15%丟包不中斷

動態碼率范圍

固定

64-1024kbps

自適應網絡環境

實測延遲表現

場景

端到端延遲

對比傳統編解碼

語音通話

18-22ms

比aptX LL低40%

游戲音頻

25-28ms

比LDAC低85%

多設備廣播

32ms

首支持≤50ms同步

2. 雙通道直傳

如蘋果H2芯片的并行串流,規避中繼延遲

  1. 異構計算架構
    • 主處理器:處理降噪/空間音頻(占用<5% CPU)
    • 射頻模塊:獨立管理雙通道時序同步(精度±2μs)
  1. 私有協議優化
    • 頻段:2.402-2.481GHz動態避讓Wi-Fi
    • 時隙:將傳統藍牙32時隙壓縮至8時隙

3. AI預測緩沖

高通S7平臺可預測下一幀內容,減少20%緩沖時間

ⅰ. 核心技術創新

模塊

功能描述

延遲優化效果

音頻特征提取

20ms內識別音樂/語音/槍聲

減少分析延遲

LSTM預測模型

預測未來80ms音頻內容

緩沖降低20%

動態碼率適配

根據網絡質量切換aptX Adaptive

避免重傳延遲

端側推理引擎

Hexagon NPU加速(15TOPS)

推理耗時<1ms

ⅱ. 實測數據(Snapdragon Sound Gen 2)

場景

傳統方案延遲

AI預測方案

提升幅度

地鐵中游戲音頻

142ms

89ms

-37%

擁擠WiFi環境

210ms

121ms

-42%

設備跨房間傳輸

185ms

98ms

-47%

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/83955.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/83955.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/83955.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

MySQL 8.0 綠色版安裝和配置過程

MySQL作為云計算時代&#xff0c;被廣泛使用的一款數據庫&#xff0c;他的安裝方式有很多種&#xff0c;有yum安裝、rpm安裝、二進制文件安裝&#xff0c;當然也有本文提到的綠色版安裝&#xff0c;因綠色版與系統無關&#xff0c;且可快速復制生成&#xff0c;具有較強的優勢。…

AGV|無人叉車工業語音播報器|預警提示器LBE-LEX系列性能與接線說明

LBE-LEX系列AGV|無人叉車工業語音播報器|預警提示器&#xff0c;涵蓋LBE-LEI-M-00、LBE-LESM-00、LBE-LES-M-01、LBE-LEC-M-00、LBE-KEI-M-00、LBE-KES-M-00、LBE-KES-M-01、LBE-KEC-M-00等型號&#xff0c;適用于各種需要語音提示的場景&#xff0c;主要有AGV、AMR機器人、無人…

行為型設計模式之Interpreter(解釋器)

行為型設計模式之Interpreter&#xff08;解釋器&#xff09; 前言&#xff1a; 自己的話理解&#xff1a;自定義一個解釋器用來校驗參數或數據是否合法。 1&#xff09;意圖 給定一個語言&#xff0c;定義它的文法的一種表示&#xff0c;并定義一個解釋器&#xff0c;這個解…

C++常用的企業級日志庫

黃老師跟大家推薦幾款在企業開發中最受歡迎的C++日志庫! 1. spdlog spdlog 是一個非常流行的開源C++日志庫,以其高性能和易用性著稱。它支持多線程、異步日志記錄以及多種格式化選項。 安裝 可以通過包管理器安裝,例如 vcpkg: vcpkg install spdlog示例代碼 #include…

Python讀取PDF:文本、圖片與文檔屬性

在日常的數據采集、文檔歸檔與信息挖掘過程中&#xff0c;PDF格式因其版式固定、內容穩定而被廣泛使用。Python 開發者若希望實現 PDF 內容的自動化提取&#xff0c;選擇一個易用且功能完善的庫至關重要。本文將介紹如何用Python實現 PDF文本讀取、圖片提取 以及 文檔屬性讀取 …

excel中數字不滿六位在左側前面補0的方法

如下圖“代碼”列&#xff0c;想要實現統一的六位&#xff0c;如果不足六位&#xff0c;在前面&#xff08;左側&#xff09;補0。 實現方法&#xff1a; 使用公式TEXT(A2,"000000")注意務必是用雙引號。 目標實現&#xff1a; 如果想要脫離原數據&#xff0c;復制…

軟考 系統架構設計師系列知識點之雜項集萃(82)

接前一篇文章&#xff1a;軟考 系統架構設計師系列知識點之雜項集萃&#xff08;81&#xff09; 第148題 “41”視圖主要用于描述系統邏輯架構&#xff0c;最早由Philippe Kruchten于1995年提出。其中&#xff08; &#xff09;視圖用于描述對象模型&#xff0c;并說明系統應該…

Langgraph實戰--自定義embeding

概述 在Langgraph中我想使用第三方的embeding接口來實現文本的embeding。但目前langchain只提供了兩個類&#xff0c;一個是AzureOpenAIEmbeddings&#xff0c;一個是&#xff1a;OpenAIEmbeddings。通過ChatOpenAI無法使用第三方的接口&#xff0c;例如&#xff1a;硅基流平臺…

(附實例代碼及圖示)混合策略實現 doc-doc 對稱檢索

HyDE 混合策略 在前面的文章中&#xff0c;學習的優化策略都是將對應的 查詢 生成 新查詢&#xff0c;通過 新查詢 來執行相應的檢索&#xff0c;但是在數據庫中存儲的數據一般都是 文檔 層面上的&#xff0c;數據會遠遠比 查詢 要大很多&#xff0c;所以 query 和 doc 之間是…

webui無法注冊如何配置

1. 初始登陸界面 docker部署的腳本為&#xff1a; docker run -d \ -p 8180:8080 --gpusall \ -v ollama:/root/.ollama \ -v /home/pretrained_model/output:/app/backend/output \ --name open-webui \ --restart always ghcr.io/open-webui/open-webui:ollama 2. 新增注冊入…

力扣 88.合并兩個有序數組

文章目錄 題目介紹題解 題目介紹 題解 法一&#xff1a;暴力法 class Solution {public void merge(int[] nums1, int m, int[] nums2, int n) {for(int i 0; i < n; i){nums1[mi] nums2[i];}Arrays.sort(nums1);} }法二&#xff1a;倒序雙指針 時間復雜度為O(mn) 從右…

conda入門

目錄 1. Conda 是什么&#xff1f;2. 為什么需要 Conda&#xff1f;它能解決什么問題&#xff1f;3. Conda 的核心組件和概念4. Conda 基本工作流程和常用命令5. Conda 的主要優勢6. Conda 與 Pip 的關系7. 何時使用 Conda&#xff1f; 1. Conda 是什么&#xff1f; 包管理器&…

UE 5 和simulink聯合仿真,如果先在UE5這一端結束Play,過一段時間以后**Unreal Engine 5** 中會出現顯存不足錯誤

提問 UE5報錯如圖。解析原因 回答 你遇到的這個錯誤提示是&#xff1a; “Out of video memory trying to allocate a rendering resource. Make sure your video card has the minimum required memory, try lowering the resolution and/or closing other applications tha…

第七十三篇 從電影院售票到停車場計數:生活場景解析Java原子類精髓

目錄 一、原子類基礎&#xff1a;電影院售票系統1.1 傳統售票的并發問題1.2 原子類解決方案 二、原子類家族&#xff1a;超市收銀系統2.1 基礎類型原子類2.2 數組類型原子類 三、CAS機制深度解析&#xff1a;停車場管理系統3.1 CAS工作原理3.2 車位計數器實現 四、高性能實踐&a…

Linux(線程控制)

一 線程的操作 1. 創建線程&#xff1a;pthread_create int pthread_create(pthread_t *thread, // 線程 idconst pthread_attr_t *attr, // 線程屬性設置void *(*start_routine) (void *), // 回調函數void *arg // 傳遞…

PL/SQLDeveloper中數值類型字段查詢后顯示為科學計數法的處理方式

PL/SQLDeveloper中數值類型字段查詢后顯示為科學計數法的處理方式 文章目錄 PL/SQLDeveloper中數值類型字段查詢后顯示為科學計數法的處理方式1. 查詢效果2. 處理方式3. 再次查詢 1. 查詢效果 2. 處理方式 3. 再次查詢

centos 9/ubuntu 一次性的定時關機

方法一 # 15 表示15分鐘以后自動關機 sudo shutdown -h 15方法二&#xff1a; sudo dnf install at -y # 晚上十點半關機 echo "shutdown -h now" | at 22:30 # 檢查是否設置成功命令 atq [rootdemo-192 ~]# atq 1 Wed Jun 4 11:12:00 2025 a root # 取消定時計劃…

Riverpod與GetX的優缺點對比

Riverpod 與 GetX 的優缺點對比 在 Flutter 開發領域,Riverpod 和 GetX 都是備受關注的狀態管理與依賴注入框架,它們各有優劣,適用于不同的開發場景。以下從多個維度詳細對比二者的優缺點。 一、Riverpod 的優缺點 (一)優點 架構清晰,數據流向明確:基于 Provider 模…

day 47

注意力可視化 訓練模型 包含通道注意力模塊和CNN模型的定義&#xff08;通道注意力的插入&#xff09; import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import ma…

《Vuejs設計與實現》第 8 章(掛載與更新)

目錄 8.1 掛載子節點與屬性 8.2 HTML Attributes 與 DOM Properties 8.3 設置元素屬性的正確方式 8.4 處理 class 屬性 8.5 卸載操作 8.6 區分 vnode 類型 8.7 事件處理優化 8.8 事件冒泡與更新時機問題 8.9 子節點的更新 8.10 文本節點和注釋節點 8.11 片段&#xf…