机器翻译结果,仅用于学习,不喜勿喷,原文档链接。
如果您过去曾使用过蓝牙® 应用程序,那么您可能专注于profile,而几乎没有看过 Core spec。这是可能的,因为蓝牙经典音频profile使用与核心设置绑定的明确传输配置,因此无需了解profile或其关联协议下发生的事情。使用蓝牙 LE audio profile,情况会发生变化,因为与使用任何蓝牙经典音频profile相比,您更有可能影响 Core 的工作方式。
为了尝试使最灵活的系统成为可能,它不仅可以满足当今的音频需求,还可以满足我们甚至还没有考虑过的需求,spec必须允许更大程度的灵活性。为了实现这一点,做出了一个基本的架构决策,将音频平面和控制平面分开。这意味着已经定义了新的同步物理通道来传输音频流。它们并排放置,但与蓝牙 LE 的现有 ACL 链接分开。 Core 中的等时物理通道可让您建立多个等时音频流,这些音频流能够传输所有类型的音频,从非常低的语音质量到令人难以置信的高音乐质量。除了我们稍后会看到的一个例外,等时流不包含控制信息——它们纯粹是为了传输音频。随附的 ACL 通道用于设置等时流、打开、关闭它们、添加音量和媒体控制,以及我们需要的所有其他功能,使用属于低功耗蓝牙的标准 GATT程序.
为了提供不同延迟、不同音频质量和不同稳健性级别所需的灵活性,开发人员需要能够控制这些等时流的配置方式。这在通用音频框架的profile堆栈中完成得相当高。这意味着当您开始使用蓝牙 LE audio应用程序时,即使您只是使用顶层 profile,您仍然需要相当多地了解底层等时流的工作方式。这与您在大多数以前的蓝牙应用程序中所经历的不同。为了帮助理解蓝牙 LE audio的整体架构,我们需要了解这些等时流是如何开发的、它们的作用以及如何使用它们。
4.1 LE audio拓扑
到目前为止,蓝牙spec主要是点对点连接:Central 设备与peripheral建立连接,然后交互数据。这是一个非常受限的拓扑。正如我们在无线立体声耳机中看到的那样,许多公司已经开发了专有扩展来增加灵活性,但isochronous stream的开发是为了应对比这些专有解决方案所能提供的更广泛的拓扑。除了将手机连接到一对耳机或单个扬声器之外,蓝牙 LE audio还需要能够将单独的左右信号发送到左耳塞和右耳塞。它还需要能够将相同的信息发送到一组以上的耳塞,并增加设备和流的数量。
有两种类型的等时流——单播和广播(unicast and broadcast )。单播连接,称为 Connected Isochronous Streams (CIS),是最接近现有蓝牙音频用例的。从这个意义上说,“已连接”意味着它们正在两个设备之间传输音频数据,并在两个设备之间使用确认方案来提供流量控制。 Connected Isochronous Streams 需要有一个 ACL 控制通道,该通道在传输音频数据的 CIS 的整个生命周期内启动并运行。
广播等时流 (BIS) 的结构非常相似,用于广播,但有一个主要区别。通过广播,传输等时流的设备不知道有多少设备可能在那里接收音频。设备之间没有连接,也不需要 ACL 链接。简而言之,广播纯粹是混杂的。但是,可以将控制链接添加到广播。在核心级别,连接和广播等时流之间有明显的区别,它基于数据是否被确认。但是,许多应用程序将在单播和广播之间切换以实现不同的用例,而用户并不知道正在发生什么。但就目前而言,我们将专注于基础知识。
广播允许多个设备以与 FM 收音机或广播电视相同的方式听到相同的内容。对蓝牙 LE audio广播能力的要求最初是由感应线圈的助听器应用驱动的,在这种应用中,在公共场所佩戴助听器的多个人可以收听相同的信号。 Telecoil 的音频质量相对较低,主要用于语音。凭借蓝牙 LE audio的更高质量以及显着降低的安装成本,业界设想了更广泛的应用和用途。传统的电话线圈位置,如会议中心、剧院和礼拜场所;公共信息,例如航班公告、火车发车时间和巴士时刻表,将可供佩戴耳机和耳塞的每个人获取,而不仅仅是佩戴助听器的人。广播也适用于更多的个人应用,一群人可以收听同一台电视,或分享手机上的音乐。最后一个示例展示了蓝牙 LE audio应用程序如何在不可见的情况下来回切换底层协议。如果您将音乐从手机流式传输到耳塞,则可能使用的是 Connected Isochronous Stream。当你的朋友过来问他们“你也想听这个吗?”时,你的音乐共享应用程序会将你的手机从私人的单播连接切换到加密的广播连接,这样你们都可以听到相同的音乐,无论是在耳塞、助听器、耳机还是扬声器上。在应用层,聆听音乐并与任何数量的其他人共享应该是无缝的——用户不需要了解广播或单播。但在过渡期间,下面会发生很多事情。
这些不同用例的构建块本质上是相同的。用于单播用例的 Connected Isochronous Streams 和用于广播用例的 Broadcast Isochronous Streams 之间存在一些差异,但基本原理非常相似。我们现在准备好看看它们是如何组合在一起的,这意味着潜入核心。
4.2 Isochronous Streams and Roles
Core 5.2 版本中的等时流功能是低功耗蓝牙中一个全新的概念。如果您熟悉Hands-Free profile或 A2DP,您就会知道它们的拓扑结构非常受限。 HFP 具有双向一对一链接,通常在电话和耳机或Hands-Free 设备之间。它有两个角色:AG和HF。 A2DP 是一个更简单的单播链接,指定生成音频的 Source 设备和接收该音频的 Sink 设备,它可以是您的耳机、扬声器、放大器或录音设备。
LE audio 建立在BLE spec中存在的基本不对称性之上,其中一个设备 - central负责设置和控制等时流。 Central 可以连接到许多外围设备,这些外围设备使用这些等时流来发送和接收音频数据。不对称意味着外围设备的功率可以低得多。对于 CIS,他们对如何配置等时流有发言权,这将影响音频质量、延迟和电池寿命,与蓝牙经典音频profile相比,他们可以更好地控制音频流。对于 BIS,Central 做出所有决定,Peripheral 决定它想要接收哪些 Broadcast Isochronous Streams。
重复我们在第 3.3 节的术语概述中所说的内容,当我们向上移动LE audio spec的堆栈时,我们会遇到许多不同的名称来表示设备所执行的角色。在core spec中,它被定义为central和peripheral。在 BAPS spec集中,它们被称为client和server,而在 CAP 中,它们成为initiator和Acceptor。initiator角色始终存在于负责调度等时流的central中。Acceptor是参与这些流的设备。总是有一个 Initiator,但可以有多个 Acceptor。
当我们进入顶层 profile时,会出现大量新角色名称,包括发送者、广播者和acceptor。我将忽略所有这些并在大多数时间使用initiator和Acceptor名称(即使它们在技术上是角色),因为我认为它们最能解释LE audio 流的工作方式。当不涉及音频流时(控制spec就是这种情况),我将退回到使用client和server。
在这个阶段我想指出的一件事是,除了广播之外,任何一个设备都可以充当音频源,生成音频数据,或充当音频接收器,接收该数据。 Initiator 和 Acceptor 都可以同时是源和接收器,并且它们每个都可以包含多个LE audio 接收器和源。谁生成音频以及谁接收和呈现音频的概念与initiator和Acceptor的概念是正交的。要记住的重要一点是,initiator是负责计算每次发送的音频数据传输时间的设备。该任务称为调度。 Acceptor 是接受这些流的设备。该概念适用于单播和广播。 Acceptor 还可以生成音频数据,例如从头戴式耳机的麦克风中捕获您的声音,但 Initiator 负责告诉它何时需要发回该数据。
由于initiator角色远比Acceptor角色复杂,initiator通常是具有更大电池和更多资源的手机、电视和平板电脑等设备。调度必须考虑对 Initiator 无线电的其他需求,其中可能包括其他蓝牙连接,通常还包括 Wi-Fi。这是由芯片设计人员处理的复杂操作。但是,正如我们稍后将看到的,LE audio profile为应用程序提供了相当大的范围来影响该调度,这就是为什么开发人员需要清楚地了解等时流的工作原理。
对于单播低功耗蓝牙音频,我们在拓扑方面有很大的灵活性,如图 4.3 所示。我们可以复制我们在 HFP 或 A2DP 中的相同拓扑,其中我们有一个设备 - 通常是您的手机和一个外围设备,例如您的耳机,它们之间有一个音频链接。在此基础上,蓝牙技术现在可以支持与两个或多个 Acceptor 对话的 Initiator。其主要应用是让您的手机与左右一对耳塞或助听器通话。它们不再需要来自同一制造商,因为LE audio 是一种可互操作的标准。
我们可以通过添加额外的单播流来扩展这一点,以支持一对以上的耳塞,或者连接多个扬声器以支持环绕声系统,图 4.3 的示例显示了添加中央低音单元。
理论上,该spec可以支持多达 31 个独立的单播等时流,可以连接 31 个不同的设备。这对于音频来说实际上是不现实的,因为我们在三个或四个流之后开始耗尽带宽。核心spec中限制 31 个流的原因是等时流功能旨在支持许多不同的时间关键型应用程序,而不仅仅是音频。其中一些需要比音频少得多的带宽。当我们查看 LC3 编解码器时,我们会发现我们必须在延迟、音频质量和稳健性之间做出一些权衡,这限制了我们实际可以支持的音频流的数量。
对单播可以支持的流数量的广播时间限制是使用广播的原因之一。如图 4.4 所示,单个 Broadcaster 可以与多个 Acceptor 对话,这些 Acceptor 通常配置为成对的设备,接收单个单声道或单独的左右音频通道。根据音频质量(通常设置采样率,因此设置广播时间使用和最大流数),Broadcasters可能能够提供更多功能,例如以不同语言同时传输音频流。这些是在设计LE audio 应用程序时需要了解的权衡取舍,我们将在接下来的章节中更详细地介绍。
4.3 Connected Isochronous Streams
要了解核心同步功能,我们将从单播和连接的等时流开始,它们被称为 CIS。它们的结构相当复杂,但它建立在一些非常简单的原则之上。我将首先描述 Connected Isochronous Streams 是如何设计的,解释组成部分及其工作原理,然后看看 Broadcast 的不同之处。这为您进入通用音频框架奠定了基础,我们在其中使用了等时流。
4.3.1 CIS 结构和时序
当您为数字音频进行设计时,您通常会受到限制,即您将以标准、一致的速率对传入的音频进行采样。一旦传入的音频被采样和编码,它就会被发送到蓝牙发射器以发送到接收设备。系统是重复的,音频数据是有时间限制的,传输之间有一个恒定的间隔,称为等时间隔或 ISO_Interval。 CIS 中每个等时间隔的开始称为其锚点。如图 4.5 所示,传输开始于initiator向acceptor发送包含音频数据 (D) 的数据包。当 Acceptor 收到它时,它会发回一个确认,并且该过程会定期重复。图 4.5 中的第三个数据包没有确认,所以initiator会假定它没有被接收到。
大多数现代编解码器都经过优化,以 10 毫秒的帧速率运行,即它们一次采样 10 毫秒的音频,这在音频质量和延迟之间提供了很好的折衷。这是 LC3 的首选设置,它是LE audio 的强制编解码器。除非我另有说明,否则我们将假设在本书中使用 10 毫秒的采样间隔,因此等时间隔将始终为 10 毫秒,或 10 毫秒的倍数。
4.3.1.1 Isochronous Payloads
设备间发送的空口包(D)的PDU中的数据结构如图4.5所示,非常简单,如图4.6所示。
编码的 ISO PDU 前面是前导码和访问地址,后面是 CRC。在通过 LE 1M PHY25 传输时,它们会增加 10 或 14 个八位字节(取决于 ISO PDU 有效负载中是否包含消息完整性检查 (MIC)26),而在使用 LE 2M PHY 时会增加 11 或 15 个八位字节。
对于 CIS,ISO PDU 称为 CIS PDU,其结构如图 4.7 所示。
ISO PDU 有一个报头,后面跟着一个高达 251 个八位字节的有效载荷。如果需要加密音频,则在该数据包的末尾有一个可选的 MIC。在 CIS PDU 标头中,有五个控制元素:
- LLID(链路层ID),表示它是framed的还是unframed的
- NESN和SN,Next Expected Sequence Number和Sequence Number,用于链路层级别的确认和流量控制,
- CIE,关闭同步事件位,以及
- NPI。 Null Payload Indicator,指示有效负载是空 PDU,标识没有数据要发送。
4.3.1.2 Subevents和重传
我们将介绍 ISO PDU 标头中的控制位,因为它们与解释 CIS 的工作原理相关。在此之前,我们需要看一下 Connected Isochronous Stream 的结构。我们已经讨论过等时间隔,它是 CIS 的连续锚点之间的时间。锚点是发起方传输 CIS 的第一个数据包的点,也是每个连续同步间隔的开始点。在 CIS 中,如果需要,我们可以重新传输 CIS PDU,因为 CIS 结构支持多个subevent。每个 Subevent 都以 Initiator 的传输开始,并以 Acceptor 的预期响应的最后一点结束。一个 CIS 中的所有subevent形成一个 CIS 事件,该事件从 CIS 的锚点开始,在接收到从acceptor接收到的最后一个传输位时结束。
连续subevent之间的时间定义为 Sub_Interval 间隔,它是该 CIS 的subevent的最大持续时间,加上帧间间隔,定义为 150µs。子间隔间隔在 CIS 配置时确定,并且在 CIS 的生命周期内不会改变。
4.3.1.3 跳频
定义subevent的一个重要原因是低功耗蓝牙音频会更改每个subevent的传输通道,如图 4.9 所示,以防止干扰。
Core 5.2 spec引入了一种新的频道选择算法,比 Core 4.0 中的更高效。这适用于每个subevent。如果没有发送subevent,则Channel跳频方案假定它已经发送并移动到下一个频率Channel以用于下一个subevent。
4.3.1.4 关闭subevent
当我们查看isochronous PDU 报头时,我们看到有一个关闭isochronous事件位 - CIE。 Initiator 使用它来表示它已收到来自 Acceptor 的确认,确认其数据包已被 Acceptor 成功接收,因此它将停止对该特定 PDU 的进一步重传。在图 4.10 中,Initiator 已经发送了它的第一个 PDU 并得到了确认,因此它发送了一个 CIE 位设置为 1 的数据包,以告诉 Acceptor 将不会有进一步的传输,因为它正在关闭事件.它通常不会费心在该传输中包含音频数据,因此它还会设置 Null Packet Indicator 位,允许它缩短传输的数据包。 (图 4.10 显示了原始 CIS 事件的持续时间以进行比较。)
这允许acceptor进入睡眠状态,直到下一个isochronous间隔。initiator可以利用这段时间做其他事情。由于许多initiator还将与其他蓝牙设备进行交互,并可能与 Wi-Fi 共享他们的无线电和天线,这可能很有用。对于 Acceptor 而言,关闭其接收器直到它准备好再次执行某些操作可以带来显着的节能效果。
如果 Acceptor 没有收到带有 CIE 位的 header,它会继续监听每个调度的 Subevent 中的数据,但不会收到任何来自 Initiator 的数据包进行响应。
4.3.2 控制音频质量和鲁棒性
在介绍了 CIS 中传输的基本时序之后,我们现在可以查看用于控制音频质量和链路稳健性的参数。对于许多音频应用来说,延迟很重要。对于某些应用程序,例如当您收听实时流时,将延迟最小化很重要,特别是如果您也可以听到环境声音。另一方面,如果您通过手机流式传输音乐并且听不到或看不到源,则延迟并不重要。其他应用程序,例如游戏,有不同的优先级,如果你在看电影的同时听音频,口型同步就变得很重要。
基本音频profile (BAP) 可以使用 LE_Set_CIG_Parameters HCI 命令设置许多影响音频质量和延迟的参数。我们将在第 7 章了解它是如何做出这些选择的,但现在,我们需要了解如何配置同步通道结构。应用程序可以请求以影响延迟和稳健性的关键项目是:
- Maximum Transport Latency,它设置发起方可以花费在传输特定 CIS 的 PDU 上的最长时间。
- CIS 两个方向的最大 SDU 大小
- 两个方向的 SDU 间隔
最大传输延迟会影响整体延迟,尽管它只是其中的一个元素。尽管许多应用程序都希望最大限度地减少延迟,但在现实的无线世界中,您还需要解决无线链路固有的脆弱性,其中可能会丢失数据包。为了确保足够的鲁棒性(转化为呈现的语音和音乐流而不会丢失、点击和静音),我们需要使用各种技术来帮助确保音频数据在可接受的时间范围内通过。
4.3.2.1 Flush Timeout and Number of Subevents
上面列出的三个参数是controller的输入。controller采用它们并使用它们来计算三个参数,这些参数会影响该 CIS 的LE audio 链路的稳健性,它们是:
- NSE - subevent的数量。这指定将在每个isochronous间隔中安排的subevent的数量。它们用于 CIS 的初始传输
- PDU 及其随后的重传。它们可能不会全部使用,但它是预定的固定数量。
- FT – 刷新超时。 Flush Timeout 定义了在丢弃 PDU 之前可以使用多少个连续的isochronous间隔来传输 PDU。不再传输的点称为冲洗点。
- BN – 突发数量,它是在每个 CIS 事件中为传输提供的有效负载数量。
这些可能很难掌握,因此查看一些简单的示例很有用。
subevent数量 (NSE) 是三者中最直接的。它只是在每个等时间隔内可用的传输等时 PDU 的机会数。在最简单的示例中,在每个等时间隔中仅提供一个 PDU 用于传输,该 PDU 将在第一个subevent中传输,然后可以在同一等时间隔内重传最多 (NSE-1) 次。如果是单向 CIS,一旦 PDU 的传输被 Acceptor 确认,controller可以在其下一次传输(可以有一个空的 PDU 有效负载)的标头中设置 Close Isochronous Event (CIE) 位,以及剩余的subevent在该 CIS 事件中,让出给其他无线电应用做数据交互。
这就是 Flush Timeout 为 1 的情况,因为 Flush 点与等时间隔的 CIS 事件的结束重合。这个简单的例子如图 4.11 所示。为了清楚起见,以下示例仅涉及一个 Acceptor。
在此示例中,NSE 设置为 4,因此每个数据包有四次传输的机会。在第一个 CIS 事件中,四次尝试都没有成功,因此数据包 P0 被刷新,acceptor将需要尝试使用某种形式的数据包丢失校正来重建它。
第二个数据包 (P1) 在第二次尝试后成功,之后发起方关闭事件。第三个数据包(P2)第一次成功。
如果 Flush Timeout 增加,则数据包的传输可以在更多的isochronous间隔内继续。图 4.12 说明了一个示例,其中 NSE 保持为 4,但 Flush Timeout 增加到 3。
如果您只使用 NSE 和 FT 这两个参数,这说明了一个问题。它允许一个数据包支配传输时隙,直到它到达它的刷新点。在图 4.12 中,第一个有效载荷 P0 无法通过,它占用了前三个isochronous间隔中的所有subevent,让 P1 和 P2 一直等到冲洗点 FP0 之后。尽管这种情况不常见,但它会使后续的有效载荷更加暴露,直到有足够多的有效载荷通过以使系统恢复平衡。
4.3.2.2 Burst Number
解决此问题的方法是允许在单个isochronous间隔中传输多个有效载荷,以便每个isochronous间隔中的subevent可以在多个 PDU 之间共享,而不会被其中一个独占使用。这可以通过利用突发数量 (BN) 来实现,BN 是为在 CIS 事件中传输而提供的有效载荷数量。在上面的示例中,CIS 事件中仅传送了一个数据包,这是 SDU 和 PDU 生成的节奏与等时间隔相同的情况——这意味着每个 10 毫秒等时间隔有一个编码的 10 毫秒音频帧可用.如果我们想使用 BN 并且我们继续每 10ms 对传入的音频通道进行采样,我们需要将 Isochronous Interval 增加到它的倍数,以便我们在每个 Isochronous Interval 中有更多可用的数据包。这意味着通过解决一个问题,我们可能会创建另一个问题,这会增加延迟。
在图 4.13 中,等时间隔已加倍,允许在每个间隔中提供两个数据包。 10ms 编解码器帧和 20ms isochronous间隔的组合意味着发起方有两个可用于在每个isochronous间隔内传输的 PDU。其结果是现在每个等时间隔中有两个冲洗点。在我们的简单示例中,每个冲洗点发生在两个subevent之后。对于 FT 和 NSE 参数的更复杂组合,可以根据核心 [第 8 卷,B 部分,4.5.13.5] 中的方程式计算冲洗点的位置。
回到图 4.13,我们看到 Initiator 在第一个 Subevent 中发送数据包 P0,该数据包被确认,因此 Controller 立即继续发送数据包 P1,在确认之前发送了 3 次。
在第二个isochronous间隔中,数据包 P2 被传输,但acceptor发送 NACK 以指示接收到的数据包中的错误。由于 Flush Timeout 设置为 1 且 BN=2,数据包 P2 的 Flush Point 处于相同的isochronous间隔中,经过两次进一步的传输尝试之后,Acceptor 都没有成功接收到。
此时,发起方开始传输 P3,尽管在此示例中,接收方再次以 NACK 响应以指示其接收的数据包存在问题。在两次尝试之后,P3 被initiator刷新。
在图 4.13 的最后一个等时间隔中,P4 传输成功,给 P5 留下 3 次机会,均未成功。在每种情况下,发起方都将尝试在该 PDU 的刷新点之前的每个可用subevent中传输 PDU。在每次确认传输后,它将继续处理下一个可用数据包,或者,如果没有更多可用数据包,则关闭同步事件。
在本例中,P2、P3 和 P5 将被丢弃。在现实生活中,我们期望更高的确认率——这只是说明原理的一个例子。
作为最后一个示例,图 4.14 显示了将 Flush Timeout 增加到 2 的效果,Burst Number 为 2,它提供了在两个连续的isochronous间隔中传输的机会。在这个例子中,没有数据包被刷新。
使用 Flush Timeout 和 Burst Number 可以非常有用地提供更多的重传机会,跨越多个isochronous间隔。如果您在嘈杂的环境中,它们特别有用。但是,它们对延迟有影响。 ==Flush Timeout 的每一个增量都会增加延迟,因为重传会分布在更多的isochronous间隔上,而 Burst Number 会增加isochronous间隔的持续时间。==请注意,Burst Number 仅限于以isochronous间隔到达的多个有效载荷。它不能被起诉来解决我们在图 4.12 中看到的单个有效载荷占用传输机会的问题。
这些参数不能由Host直接设置。它仅限于设置最大传输延迟的值,然后在controller中计算最大 SDU 大小和 SDU 间隔 BN、NSE 和 FT,其中考虑了芯片中的任何其他无线电要求。然而,了解这些参数对等时通道结构的潜在影响是非常有用的。 TMAP 的表 3.19 提供了controller如何解释 CIS 的host值以适应不同操作条件的示例,例如优先考虑共存的通话时间或最小化延迟。参数的准确分配总是由调度程序中的算法决定的,这将由芯片供应商设置。
NSE应该是BN的整数倍
4.3.3 Framing
CIS PDU头中另一个需要理解的参数是一对LLID(链路层ID)比特,它表示CIS是framed的还是unframed的。unframed是指 PDU 由一个或多个完整的编解码器帧组成的情况。它用于isochronous间隔是编解码器帧长度的整数倍的情况。相反,framed是您在编解码器帧长度和isochronous间隔之间存在不匹配的情况,这会导致编解码器帧在多个 SDU 中被分段。这开始变得复杂,但在initiator可能需要支持具有不同时序的蓝牙连接时很重要。当我们查看一个称为 ISOAL 的功能时,我们将重新审视这一点,它是等时适应层,旨在应对这种不匹配。 (LLID 位还指示何时没有 ISO PDU,这与 ISO PDU 标头中的 NPI 不同。)
4.3.4 多路CIS
涵盖了单个单向 CIS 的所有功能后,下一步是添加更多功能。最常见的应用是当initiator向左右耳塞发送音频时。在这种情况下,Initiator 将使用两个不同的 Acceptor 设置单独的 Isochronous Streams。在图 4.15 中,我们可以看到它是我们之前看到的内容的直接扩展——initiator发送并接收来自第一个Acceptor的确认,然后对第二个Acceptor重复此操作。
需要注意的重要一点是,虽然左右音频通道是同时采样的,但 ISO PDU 是串行发送的。
请注意,如果我们有多个 CIS,它们总是具有相同的等时间隔。它们的锚点不同,因为数据是串行发送的,但是对于每个 CIS,它们的锚点之间的 ISO 间隔相同。每个锚点代表该 CIS 从initiator到Acceptor的第一次传输点。如图 4.16 所示,每个 CIS 都有一个关联的 ACL 链接。 ACL 链接始终需要存在,因为它用于设置 CIS 并对其进行控制。如果 Initiator 和 Acceptor 之间有多个 CIS,它们可以共享同一个 ACL。如果 ACL 因任何原因丢失,则任何关联的 CIS 都将终止。然后,应用程序需要决定如何处理与该 CIG 中的其他 Acceptor 建立的任何剩余 CIS。
当一个 Initiator 调度两个或多个音频通道时,它们的传输方式有两种选择,无论它们是连接到一个还是多个 Acceptor。显而易见的方法是按顺序传输它们,以便您在 CIS 0 上发送所有数据,然后在 CIS 1 上发送所有数据,直到initiator处理完两个 CIS 的所有数据包。这在图 4.17 中进行了说明,其中 NSE 为 3。它显示了 CIS 0 中的所有subevent在 CIS 1 的subevent之前传输。
这种方法的缺点是,如果您有一个可靠的连接,即第一次传输的数据包得到确认,那么您最终会在每个 CIS 之间产生间隙。在手机等设备中,通常共享蓝牙和 Wi-Fi 无线电,这是浪费的通话时间,可以用于其他用途。为了解决这个问题,controller可以选择交错 CIS 作为替代方法,如图 4.18 所示。
在这种情况下,CIS 0 的每个subevent后面跟着一个 CIS 1 的subevent,其余的 CIS 依此类推。该图重复了图 4.17 的示例,NSE 为 3,并显示 CIS 0 发送和接收它的第一个subevent,然后是 CIS 1。如果两个acceptor都接收到这些第一个传输并确认它们,它们可以关闭它们的 CIS 事件。它会在传输后导致更大的差距,从而腾出可用于其他目的的通话时间。
4.3.5 双向 CIS
我们上面定义的多个单向连接的等时流复制了 A2DP 的用例。对于耳塞和许多其他音频应用,我们也希望获取数据,这需要双向性。一种方法是在相反方向设置第二个 CIS,以便我们使用一个 CIS 从手机传输到耳塞,另一个从耳塞传输到手机。然而,这是低效的。核心spec通过将返回数据添加到确认包中来提供优化。它仍然是一个 CIS,但它现在被用于两个单独的音频流。
在图 4.19 所示的示例中,Initiator 设置了具有左 Acceptor 和右 Acceptor 的各个 CIS。两者都从 Initiator 接收数据,但左侧也将数据从其麦克风发送回手机。我们之前看到的相同原则也适用。数据由 Initiator 发送,Acceptor 立即响应确认收到(或没有),如果有数据,则将其包含在返回的 CIS PDU 中。如果返回的 PDU 以良好的 CRC 返回,initiator将确认它,关闭事件,并将数据传输到正确的Acceptor CIS。
双向确认使用 ISO PDU 报头中的 NESN 和 SN 位,当数据包被确认时翻转位。在图 4.19 中,所有传输的数据包都具有相同的 ISO PDU 格式。标记为“Ack”的那些不包含音频数据,因此会将 NPI 位设置为 1,以指示它们具有空 CIS PDU。来自左侧acceptor的数据包将与initiator的“L”和“R”数据包格式相同,但包含来自acceptor麦克风的数据。initiator对左侧acceptor数据的“确认”将包括 CIE 位,发生在它将数据传输到右侧acceptor之前,这表明它正在以顺序模式传输 CIS。这些“Acks”也将设置 CIE 位。
NSE 的值适用于 CIS 中的两个方向,因为相同的subevent用于将 PDU 传输到acceptor和从acceptor传输。一旦确认了一个方向的有效载荷,未来的传输可以用空有效载荷替换该 PDU 的有效载荷。 (这对subevent的时间没有影响,但会节省少量的电量。)
只有发起方可以设置双向 CIS 中 ISO PDU 报头中的 CIE 位,以指示它们不会在当前 CIS 事件中传输任何进一步的有效载荷数据。除非已确认两个方向的有效负载,否则它不应关闭 CIS 事件。如果initiator已经确认了它的数据包,但还没有收到acceptor的数据包,它应该在每个可用的subevent中继续发送空 PDU 数据包,给acceptor重新发送的机会。
双向 CIS 中的两个方向可以具有不同的属性,例如编解码器和 PHY,甚至可以由不同的应用程序使用。甚至一些结构参数对于两个方向也可能不同。 FT 和 BN 可以不同,Max_PDU 和 Max_SDU 值也可以不同,这也意味着 SDU_Intervals 可以不同,尽管其中一个需要是另一个的整数倍。但是,ISO_Interval、Packing、Framing 和 NSE 必须相同。
4.3.6 CIS 中的同步
一旦我们添加了第二个 Acceptor,这两个 Acceptor 就会彼此独立,但在 Initiator 的控制之下。如果他们是一个 Coordinated Set,他们会知道另一个 Coordinated Set 的存在,因为他们知道 Coordinated Set 中有多少成员。但是,您的左耳塞和右耳塞不一定知道另一个存在、打开或接收数据。用户可能会拿出一个与朋友分享,或者一个电池可能会耗尽。即使他们有交流的方式,也不能保证他们会一直保持联系。为了解决这个问题并使它们能够精确地同时渲染或捕获音频流,Core Isochronous Channels 设计包括一种同步方法,该方法允许微秒级的渲染精度,而 Acceptor 不需要了解存在(或其他情况) ) 的任何其他Acceptor。图 4.20 说明了这是如何完成的。
在 CIG 中,为该 CIG 中的每个 CIS 安排 CIS 事件。对于将是两个 CIS 事件的一对耳塞 - 一个用于左耳塞,一个用于右耳塞。它可能更多,例如多声道音响系统。这些 CIS 事件构成了一个 CIG 事件。在图 4.20 中,为简单起见,多个 CIS 显示为连续的。它们同样可以交错。
core spec定义了一个 CIG 参考点,该参考点可能与第一个 CIS 的锚点重合,但不能晚于第一个 CIS 的锚点。通常,它会在此之前发生。它还定义了一个 CIG 同步点,该点发生在该 CIG 内最后一个 CIS 事件的最后一个可能接收事件之后。此时,Initiator 知道每个 Acceptor 将有一切可能的机会接收发送给它的每个 PDU,并有时间为 Initiator 返回任何数据。
为了重建这个共同点,每个设备都被告知其支持的每个 CIS 的单独 CIS 同步延迟,这是根据与该 CIS 关联的 ACL 链接的 Instant 计算得出的。这允许它计算 CIG 同步点,这是每个设备的通用时间戳。有了这些知识,每个设备都可以确定它应该何时开始解码音频。 BAP 添加了一个称为 Presentation Delay 的功能,它告诉 Acceptor 何时渲染解码的流。当我们向上移动层并开始深入研究 QoS 和延迟的基本概念的细节时,我们将看到如何使用 Presentation Delay 来增加渲染时间的灵活性。
如果您有带麦克风的设备,则存在相同的同步问题,但在这种情况下,您需要协调接收器捕获音频的点。如果它使用双向 CIS 的上行链路,它将使用相同的 CIG 同步点,但可能需要与用于呈现来自发起方的下行链路音频数据的值不同的 Presentation Delay 值,因为它需要额外的时间来捕获和编码音频流。
同步定时以微秒精度定义。这意味着 CIG 中所有Acceptor的controller都分配了一个时间戳,该时间戳将在几微秒内。这需要传达给呈现音频流的应用程序层,尽管这样做的方法取决于实现。但是,该spec意着左右耳塞可以将两个音频流呈现给耳朵,其距离比大脑所能识别的更近一个数量级。
4.3.7 CIG 状态机
在介绍了构成连接的等时流的所有功能之后,我们可以看看如何将它们组合在一起以配置和建立连接的同步组。
有一个相当简单的状态机用于配置和建立 CIG 及其组成的 CIS,如图 4.21 所示。它包含三个状态:
- Configurable CIG 状态,这是定义构成 CIG 的所有 CIS 的位置。这是通过一组称为 LE Set CIG 参数命令的 HCI 命令完成的。一旦这些信息被发送到controller,initiator就拥有了制定调度和优化其通话时间使用所需的所有信息。
- Active CIG 状态,其中启用了一个或多个已配置的 CIS。通过使用 LE Create CIS HCI 命令启用至少一个已配置的 CIS,CIG 进入活动状态。它不需要启用所有已配置的 CIS。一旦 CIG 处于活动状态,它就可以断开各个 CIS,并且可以使用 LE Create CIS 命令启用它之前配置的其他 CIS。理论上,这允许它在 CIG 处于活动状态时交换 CIS。如果只是偶尔需要 CIS,例如语音命令的返回路径,这将很有用。 CIS 可以根据需要打开和关闭。一旦 CIG 处于活动状态,您就无法配置其他 CIS。这只能通过断开所有 CIS、停用 CIG 并重新启动来完成。
- Inactive CIG 状态,通过断开所有已建立的 CIS,CIG 进入非活动状态。在此状态下不能更改任何CIS的配置,也不能添加新的配置,但可以通过使用LE Create CIS HCI命令重新建立CIS返回到Active状态。这允许重新激活 CIG,而无需controller返回开始并重新调度其配置的一个或多个 CIS。
当所有已建立的 CIS 都已断开连接时,可以通过发出 LE Remove CIG HCI 命令来移除 CIG。
4.3.8 CIS 的 HCI 命令
core spec定义了五个 HCI 命令,用于通知controller有关每个 CIG 的信息。第一个是 LE Set CIG 参数命令 [Vol 4, Part E, 7.8.97],它创建一个 CIG 并在其中配置一个 CIS 数组。 CIG 中的每个 CIS 可以是单向的或双向的。每个方向都可以使用不同的 PHY。
第一次使用 LE Set CIG 参数命令创建 CIG,将其移动到已配置 CIG 状态,其中 CIS 的数量在阵列中定义。该命令可以多次使用,以向 CIG 添加更多的 CIS,或修改已定义的 CIS。每个 CIS 都分配有一个连接句柄。
每次发出命令时,controller都应尝试为 CIG 中的所有 CIS 计算时间表,以满足 HCI 参数指定的要求,如果成功,将使用 HCI 完成命令确认这一点。请注意,Host 发送的两个参数——Packing 和 RTN(重传次数)仅是推荐值。controller在制定时间表时应尽量适应它们,但可以忽略它们,或尝试由它们指导的最佳情况时间表。 Burst Number、Flush Timeout 和 NSE 的 Link Layer 参数由 Controller 的调度算法决定,不能由更上层spec显式设置。一些profile spec提供了针对特定用例建议最佳设置的建议,但取决于特定芯片实现是否可以通过应用程序访问这些设置,或者是调度程序选择的一部分。
从host发送的 HCI 参数与controller设置的参数之间的这种不匹配可能看起来很奇怪,但有一个很好的理由,即防止顶层 profile或应用程序尝试优先考虑整体无线电操作。许多蓝牙芯片都包含 Wi-Fi,它们通常共享一个天线。因此,controller需要弄清楚如何适应两者的需求。蓝牙技术实现也可能运行多个profile。智能手机没有理由不能接收LE audio 广播流,然后将其作为一对连接的等时流重新传输到一对助听器(除了可用通话时间和处理资源的物理限制)。但是,在profile级别,这些应用程序中没有一个可能知道另一个存在。如果每一个都可以规定 BN、FT 和 NSE 的确切值,那么它们很可能无法与其他应用程序的约束共存。这就是为什么 HCI 命令会阻止这种级别的控制,从而允许controller找出如何最好地将所有东西组合在一起。应用程序开发人员无法访问调度算法——它们是蓝牙芯片的关键部分。然而,重要的是要理解为什么你不能决定你想要什么,并意识到过度指定音频应用程序需求的危险。
配置完所有 CIS 后,使用 LE Create CIS 命令创建每个所需的 CIS,这会导致 CIG 移动到活动 CIG 状态。此时不需要创建所有 CIS。一个 CIS 可以断开连接,并在任何时候创建另一个 CIS,当应用程序决定从使用耳塞中的麦克风转移到智能手机上的麦克风时,这可能很有用。但是,这确实假设controller设法调度了所有 CIS。
CIG 保持在 Active CIG 状态,直到最后一个 CIS 断开。此时它移动到非活动 CIG 状态。它可以使用 LE Remove CIG 命令永久删除,也可以通过在至少一个 CIS 上再次使用 LE Create 命令返回到活动 CIG 状态。
由于每个 CIS 都是由 Initiator 创建的,因此每个 Acceptor 将通过链路层命令获知连接参数,从而将 HCI LE CIS Request 事件 [7.7.65.26] 发送到其host。如果它接受请求,它将以 HCI LE 接受 CIS 请求命令 [7.8.101] 进行响应,从而导致发起方和接受方host都接收到 HCI LE CIS 已建立事件 [7.7.65.25]。当我们到达 ASCS 时,我们将看到它们如何与 Isochronous Stream 状态机一起工作。
这完成了对 CIG 和 CIS 的所有组成部分以及我们如何将单播连接的等时流放在一起的回顾。现在,我们将看看广播的类似物,我们必须做同样的事情,但没有在两个设备之间建立连接以允许他们协商他们正在做的事情的奢侈。
4.4 广播等时流
广播音频是蓝牙技术的全新概念。正如我们在前几章中看到的那样,过去,音频总是直接从一个设备流式传输到另一个设备。这个概念现在已经通过 Connected Isochronous Streams 进行了扩展,因此我们可以将音频流式传输到多个设备。但这些设备仍处于连接状态,并且正确接收到的每个数据包都会得到确认。使用广播,没有连接。广播发射器范围内的任何设备都可以拾取和渲染广播音频流。与蓝牙经典音频profile的最大区别在于它是单向的 - 没有确认。这意味着在技术上可以构建一个不包含接收器但仅传输的广播源。这些广播可以被范围内的任何广播接收器接收。
没有确认有一个实际优势,即它通常会产生更大的范围。发生这种情况是因为连接上的链路预算通常非常不对称。广播发射机通常由电源供电,因此可以轻松地以最大允许功率进行发射。这为它提供了一个很好的耳塞链接预算。但是,耳塞不太可能以超过 0dBm (1mW) 的速度回传确认信息,这既是为了节省电池,也是因为它的小天线可能会获得低于 0dB 的增益。这意味着耳塞接收广播传输的链路预算可能比返回确认路径高 10 – 20dB。后者决定了 CIS 的最大范围。对于公共覆盖,Broadcasters可以覆盖相当大的区域——远远超过连接的等时流传输所能达到的范围。
4.4.1BIS结构
Broadcast Isochronous Streams 和 Groups 的结构定义与我们刚刚看到的 Connected Isochronous Streams 非常相似。
图 4.22 显示了广播等时流具有相同的基本 PDU 结构,包括报头、有效负载和一个可选的 MIC(如果您想要加密)。但是,BIS 的标头要简单得多,因为它不需要 CIS PDU 标头中的 SN 和 NESN 流控制位。它以相同的两个链路层 ID (LLID) 位开始。这些指示 PDU 是framed的还是unframed的。然后是 CSSN 和 CSTF,它们用于表示控制subevent的存在。 CSSN 是控制subevent序列号,CSTF 是控制subevent传输标志,表示该 BIS 事件中存在控制subevent。这些是新的,在 Connected Isochronous Streams 中不存在。在 BIG 中,有一个控制subevent,可用于为每个Acceptor提供控制信息。我们在广播中需要这些,因为没有 ACL 通知Acceptor诸如跳跃序列的变化之类的事情。标头中唯一的其他信息是有效负载的长度。
如果我们看一下图 4.23 中的 Broadcast Isochronous Stream 的结构,也会非常熟悉。 BIS 和 CIS 之间的根本区别在于没有确认。 BIS 纯粹由包含由发起方发送的数据的subevent组成。没有双向数据——一切都是从广播源传输的。和以前一样,我们看到每个subevent都在不同的频道上传输。
BIG(广播同步组,由一个或多个 BIS 组成)和 CIG 之间的显着区别是控制subevent的潜在存在,如图 4.23 中的虚线所示。当它发生时(在 BIS 事件中,ISO PDU 的标头包含 CSTF 标志),控制subevent在最后一个 BIS 的最终subevent之后传输,并提供了将控制信息发送到每个设备的机会它正在接收广播流。我们将在 4.4.3 节介绍它的作用。
如图 4.23 所示,广播等时流具有相同的基本元素,即isochronous间隔和 BIS 和 BIG 事件的锚点。由于没有确认或返回数据包,因此定义了一个 Sub_Interval 时间,它是单个 BIS 内连续subevent开始之间的时间。它也是最后一个 BIS 的最终subevent开始与控制subevent(如果存在)之间的时间。
如果 BIG 包含多个 BIS,则每个 BIS 由 BIS_Spacing 分隔。通过调整 Sub_Interval 和 BIS_Spacing 的值,BIS 可以按顺序或交错方式排列,如图 4.24 和图 4.25 所示。如果 BIS_Spacing 大于 Sub_Interval,它们将按顺序排列。如果它更小,它们将被交错。
两个图都显示了两个 BIS,每个 BIS 都将 NSE 设置为两个(即,每个都有两个subevent)。从这些数字可以得出一些重要的观察结果。首先是控制subevent从不计入 NSE——它是一个完全独立的subevent。第二个是当控制subevent出现时,它不会影响任何其他数据包或锚点。它安排在最后一个 BIS 的最后一个subevent之后。但它确实为包含控制subevent的等时间隔扩展了 BIG 事件。
CIS 可以在设备接收到音频数据包后停止传输,而广播源不知道它们是否已被接收,因此它必须重复每次传输。但是,一旦接收器收到一个数据包,它就可以关闭它的无线电并等待下一个预定的 BIS。这再次突出了我们在BLE 中的不对称性。因为广播源总是在传输,它通常比接收器具有更高的功耗,接收器很可能是耳塞。一般来说,这意味着广播源需要更大的电池或永久电源。由于它们通常是公共场所的电话或基础设施发射器,这通常是一个问题。但是,如果广播传输被嵌入到手表或腕带等小型设备中,则应牢记这一点。
与 CIS 不同,所有 BIS 都具有相同的时序结构。尽管每个单独的 CIS 的结构通常根据其编解码器配置进行调整,优化subevent以适应 PDU 的大小,但每个 BIS subevent的长度相同,必须适合正在传输的最大 PDU。该约束是因为 BIGInfo 中定义了整体 BIS 时序结构,该 BIGInfo 包含在 Periodic Advertisements 中。 BIGInfo 结构的大小是有限的,因此没有粒度来为不同的 BIS 指定不同的时间——它指定了“一刀切”。这意味着如果您想以 48kHz 采样率广播一个频道,而以 24kHz 播放第二个频道,较小的 24kHz 频道仍将分配给较大的 48kHz 数据包的 BIS subevent计时,这会浪费广播时间。如果这导致问题,另一种方法是在单独的 BIG 中传输数据包。在这种情况下,这意味着一个 BIG 用于 48kHz 采样数据包,另一个用于 24kHz 采样数据包。不利的一面是,这增加了复杂性并使广告量翻倍,因为每个人都需要自己的广告集。实施者需要决定哪一个最适合他们的特定应用。
4.4.2 BIS 的稳健性
BIS 参数的定义方式略有不同,因为在没有确认的情况下,我们需要采用一些不同的策略来最大化接收传输的机会。
BIS 仍然具有突发数 (BN) 和subevent数量 (NSE),其定义方式与 CIS 相同。为了弥补确认的不足,核心引入了isochronous间隔内的组计数的概念,即 NSE 与突发数 (NSE/BN) 的比率。组计数用于确定在 BIS 中安排重传的方式,将它们分配给组,这些组用于将分集添加到传输方案中。 (这些组与广播同步组无关——不幸的是,对于两个完全不同的概念使用同一个词。)
图 4.26 显示了 BIS 的两个示例,每个示例包含 6 个subevent,因此 NSE = 6。在第一种情况下,我们将突发数设置为 3。这意味着可用于该 BIS 事件的三个有效负载中的每一个被发送两次。在第二个示例中,右侧有相同数量的 Subevents,但 Burst Number 为 2,因此我们对两个有效负载进行了 3 次重传。每个单独的subevent都有一个从 0 到 (Group Count-1) 的组号 (g)。因此,在左图中,我们的组计数为 2,包括组 0 和组 1。在右侧示例中,有三个组:组 0、组 1 和组 2。
需要注意的重要一点是,尽管这两个示例看起来相同,但它们将具有不同的等时间隔。假设我们的帧为 10 毫秒,左边的示例将具有 20 毫秒的isochronous间隔,因为它包含两个有效载荷 - P0 和 P1。右侧的示例将具有 30 毫秒的isochronous间隔,因为有三个有效负载,P0、P1 和 P2。
组计数与另外两个新参数一起使用:
- 立即重复计数 (IRC),它定义了携带与当前事件相关的数据的组的数量,1 ≤ IRC ≤ NSE÷BN 以及
- 预传输偏移(PTO)。 Pre-transmission 的概念是允许提前传输数据包,希望接收设备能够提前接收音频数据包,使其断电,然后在最后的传输机会出现时准备好渲染它们。
这些由 Controller 中的调度程序计算的参数代替了 Flush Timeout。对于 CIS,Flush Timeout 本质上是终止,终止 PDU 的传输。在大多数情况下,它是不需要的,因为一旦initiator收到其数据已被接收的确认,它就可以关闭事件并停止传输。
Broadcasters不能这样做——它必须继续传输。因此,最大化数据包传输的多样性以使每个 Acceptor 有最佳机会找到数据包是有利的。他们越早做到这一点,他们就可以越早入睡,直到下一个到来。
Pre-Transmission Offset 通过引入与当前事件关联的subevent以及与未来事件关联的subevent的概念来工作。这种将subevent分配给 PDU 的方法比 CIS 的方案还要复杂,因此最好通过一系列示例来说明更改值的效果。这一切都由controller解决,应用程序无法访问,但是当您设置 HCI 参数来配置流时,它有助于理解它。
为了说明未来subevent的概念,图 4.27 演示了一个 BIS 事件,其中我们有一个包含八个subevent的 NSE;其中前五个与当前的 BIS 事件相关联,后三个用于来自未来 BIS 事件的数据。
我们现在可以将所有内容与更多示例放在一起。
我们首先在图 4.26 中看到的这些组编号 (g) 与立即重复计数 (IRC) 一起根据以下规则确定在每个传输时隙中发送哪些有效负载:
- 如果 g < IRC,组 g 应包含与当前 BIS 事件相关的数据。
- 如果 g ≥ IRC,组 g 应包含与未来 BIS 事件相关的数据,是当前 BIS 事件之后的 PTO × (g - IRC + 1) BIS 事件。
我们现在将看几个示例,这些示例说明这些不同的参数如何导致各种不同的重传方案。
在图 4.28 中,我们有四个 NSE 为 4 的subevent。Burst Number 为 1 意味着在每个 BIS 事件中提供一个新的有效负载(因此本示例的isochronous间隔为 10 毫秒)。立即重复计数为三,这意味着与每个事件相关的数据在前三个时隙中传输。上面显示的条件表明,该 BIS 事件中的最后一个传输来自下一个 BIS 事件。使用这种方案,在每个 BIS 事件中,总是有 3 次当前数据传输加上 1 次来自下一个事件的数据传输。
如果看起来我们已经发明了时间旅行,我们还没有。我们只是稍微改变了我们的定义。在 p0 和 p1 PDU 都可用之前,事件 x 不会发生。所以 p1 确实是 Event x 中的当前数据。这表明只要 PTO 大于 0,延迟就会开始增加,因为 Sync 参考点要到最后一次可能的数据传输之后才会出现,对于 p0 来说,这在事件 x+1 中。
图 4.29 显示了当我们将subevent的数量增加到 5 时会发生什么。这里,IRC 保持为 3,但 NSE 为 5,这提供了两个与未来 BIS 事件的数据相关联的subevent。这些用于预传输来自事件 x+1 和事件 x+2 的数据包。这意味着传输正在跨越更多的isochronous间隔,数据来自三个连续的 BIS 事件。这有助于提供对可能持续超过一个isochronous间隔的宽带干扰突发的鲁棒性,但其代价是更大的延迟,延迟增加了 10 毫秒。
图 4.30 通过将 Pre-Transmission Offset 增加到 2 来查看我们进一步传播的情况。这导致包含来自 x+2 BIS 事件和 x+4 BIS 事件的数据,有效地传播了音频数据在五个事件上传输,与 PTO = 0 的情况相比,延迟总共增加了 40 毫秒。在此图中,我们仅显示第一个 BIS 事件 x 中第 3 组和第 4 组的箭头,否则图变得非常混乱,难以阅读。
最后,在图 4.31 中,我们将 NSE 设置为 6,将 Burst Number 和 IRC 设置为 2,并且 Pre-Transmission Offset 也是 2。通过这些设置,每个 BIS 事件都包括传输两次的“当前”事件的两个数据包,一个接一个,如图 4.26 所示,最后两个 Subevents 用于包未来的两个事件。因为 BN 为 2,所以等时间隔将为 20ms。由于 PTO 为 2,p4 和 p5 来自未来的两个 Isochronous Interval,因此延迟比图 4.28 的简单示例大 50ms。
如果IRC等于GC,PTO将被忽略。
这些 BIS 参数允许一些非常灵活的传输方案,以应对延迟和鲁棒性方面的不同要求。在下一章中,我们将看到如何将它们用于不同的广播情况。
总之,Flush Timeout 和 Pre-Transmission Offset 都会增加延迟。对于 CIS,Flush Timeout 有助于在 Initiator 和 Acceptor 之间共享电池节省,因为使用确认意味着可以关闭事件。对于没有确认的 BIS,广播发送器必须在每个subevent中发送。 PTO 有效地为acceptor节省了所有功率,通过提供多种传输方式,使其获得数据包的最佳机会。
4.4.3 控制subevent
控制subevent [Core, Vol 6, B, 4.4.6.7] 不需要包含在每个 BIG 事件中。通常,控制subevent用于频道映射更新等项目,因此仅在需要向所有接收广播音频流的设备提供该信息时偶尔发生。使用控制subevent的优点是设备不再需要扫描来找出基本的 BIG 信息,例如正在使用的跳频Channel。这最大限度地减少了接收器必须做的工作量,以确保它与 BIG 和其中的 BIS 保持同步。如果没有它们,Broadcast Sink 将需要继续接收 Periodic Advertising 列车并定期检查 BIGInfo 以发现任何变化。
控制subevent在六个连续的 BIG 事件中传输。然后它可以在任何后续的 BIG 事件中传输,但一次只能传输一个控制事件。包含控制subevent的 BIG 事件中的 BIS subevent的每个 BIS 标头必须将控制subevent传输标志 (CSTF) 设置为 1,以表示该 BIG 事件中存在控制subevent。它的控制subevent序列号 (CSSN) 将告诉acceptor它是否与他们已经收到的相同。控制事件使用与每个其他subevent相同的跳频方案,采用相同 BIG 事件中的第一个 BIS 事件的索引。
4.4.4 BIG同步
与 Connected Isochronous Streams 一样,单个接收设备(通常是一对耳塞或助听器)不一定知道彼此的存在。为了使他们的音频保持同步,他们需要使用 BIG 中包含的信息来了解何时需要渲染它。为了使他们能够做到这一点,定义了一个大同步点,它与音频数据传输的结束相吻合。因为我们在广播中没有要考虑的确认,所以 BIG 同步点正好位于 BIG 中最后一个 BIS 的最后一个 BIS 传输的末尾。通常,这将与 BIG 活动的结束同时进行。但是,对于存在控制subevent的情况,BIG 同步点保持在最后一次 BIS subevent传输的末尾,而 BIG 事件延伸到控制subevent的末尾,如图 4.32 所示。
在 BIG 同步点,正在监听该 BIG 内任何广播等时流的每个设备都将知道每个其他设备都已收到其数据;因此,BIG 同步点是他们可以应用Presentation Delay的固定时间点。这是在堆栈的较高层定义的,并指示需要渲染音频的点。这里重要的一点是音频不是在 BIG 同步点呈现的——它是在呈现延迟结束时呈现的,它从 BIG 同步点开始。由于广播仅包含来自广播源的传输,因此没有将Presentation Delay的概念应用于从acceptor返回的捕获数据。
BIG Synchronization Point 的推导对于广播来说也略有不同。与单播不同,每个 BIS 都具有相同的基本时序参数——这是因为它们需要在 BIGInfo 中定义,并且没有足够的空间允许对各个 BIS 进行不同的设置。这意味着 BIG 同步点与 BIG 锚点之间是一个固定的间隔,这两者都是每个 Acceptor 都知道的,因为它们在 BIGInfo 中。 (相比之下,每个 CIS 使用基于其自己的锚点的 CIS_Sync_Delay,因为它不知道任何其他 CIS 的相对时间,并且不能假设它们与自己的相同)。
4.4.5 BIS 的 HCI 命令
与连接的等时流一样,host应用程序可以定义 SDU 间隔、最大 SDU 大小和最大传输延迟,这是允许传输 BIS 数据 PDU 的最大时间。对于具有 CIG 的 AS,由controller中的调度程序使用这些来指导它定义实际的链路层参数,即 NSE、BN、IRC 和 PTO。
设置 BIG 比 CIS 简单得多,主要是因为没有与任何接收设备通信,因此只需要两个 HCI 命令。 LE_Create_BIG 配置并创建一个 BIG,其中包含 Num_BIS 数量的 BIS,LE_Terminate_BIG 命令结束并删除它。没有添加或删除 BIS 的选项 - 一切都在一次操作中完成。这两个命令仅适用于正在传输一个或多个 BIG 的initiator。
对于想要从 BIG 中接收一个或多个 BIS 的 Acceptor 有两个类似的命令,这个过程称为与 BIS 同步。它们是 LE_BIG_Create_Sync 命令和 LE_BIG_Terminate_Sync 命令。但在我们开始之前,我们需要看看 Acceptor 如何找到 Broadcaster 并连接到它。
4.4.6 查找广播音频流
当我们查看连接的等时流时,我们没有谈论设备如何启动连接。原因是使用 Connected Isochronous Streams 的设备以与所有其他BLE 设备完全相同的方式连接,使用正常的广告和扫描程序。他们配对、绑定、设置 ACL 链接、发现彼此的功能,然后继续设置流。如果它们是一个 Coordinated Set,CAP 过程确保该集合的所有成员都应用相同的过程。使用广播音频流,不会发生任何配对和协商过程,因为没有连接。相反,接收设备需要找到一种方法来发现正在传输的内容、传输时间,并弄清楚如何与之同步。
执行此操作的方法称为Extended Adv,并已添加到 Core 5.1。暂时回到基础,图 4.34 显示了用于BLE 的通道。对于低功耗蓝牙,2.4 GHz 频谱分为 40 个通道,每个通道宽 2 MHz。其中三个是为固定频率的广告保留的——频道 37、38 和 39,被称为主要广告频道。
选择这三个通道的位置是为了避开 Wi-Fi 频谱中最常用的部分。在三个广告频道之间有 37 个通用频道,编号从 0 到 36。
如果其他设备能够接收他们的传输,Broadcasters需要提供大量信息。他们不仅需要根据跳频Channel告诉接收器传输的位置,而且还需要提供有关 BIG 结构及其组成 BIS 的所有详细信息,这些都是我们刚刚介绍的。在许多情况下,Acceptor 范围内可能有多个广播发射器,特别是在公共场所使用它们时,因此有多个广播等时流可供选择。Acceptor需要能够区分它们,这意味着广播广告包含有关每个广播流内容的信息。所有这些都需要Broadcasters传达大量信息。三个主要的广告渠道,即渠道 37、38 和 39,如果没有超载的风险,那就太多了。
为了克服这个限制,Core 5.1 的Extended Adv方案允许将广告信息移动到通用频道 - 频道 0 到 36。为了实现这一点,Broadcasters在其主要广告中包含一个辅助指针 (AuxPtr),它通知在通用渠道(现在用作辅助广告渠道)中提供更多广告信息的设备。辅助指针提供扫描设备确定这些辅助广告所在位置所需的信息。此时扫描仪不知道 AuxPtr 是否用于广播。只有当它找到并阅读Extended Adv时,这一点才会变得明显。图 4.35 说明了该方案的基本结构。
Extended Adv流程是使用三种类型的广告 PDU 构建的:
- ADV_EXT_IND:Extended Adv指示,使用主要广告渠道。每个 BIG 都需要自己的广告集和 ADV_EXT_IND 。每个 ADV_EXT_IND 的标头包括广告地址 (AdvA)、ADI(包括此Extended Adv集的集 ID)和指向以下内容的辅助指针:
- AUX_ADV_IND:辅助广告指示。这些在 37 个通用Channel上传输。它们包含特定于 BIG 的广告数据。 AUX_ADV_IND 还包括一个 SyncInfo 字段,它为扫描仪提供有关如何定位的信息:
- AUX_SYNC_IND:辅助同步信息。这些广告包含两条重要信息。第一个是附加controller广告数据字段 (ACAD)。这是接收设备的controller所需的信息,描述了 BIG 的结构及其组成的 BIS。第二个是接收设备的host信息,包含在 AdvData 字段中。这包含基本音频公告服务 UUID 和 BASE,其中包含 BIG 中流的详细定义,包括编解码器配置和metadata,以用户可读格式描述音频流的用例和内容。
ADV_EXT_IND数据包中存在辅助指针 (AuxPtr) 表示可以在Extended Adv中找到部分或全部广告数据。但是,描述和定位广播流所需的信息量仍然大于正常的Extended Advertising packet的信息量。为了适应这种情况,Extended Adv可以通过将 AuxPtr 包含到 Auxiliary AUX_CHAIN_IND PDU 来链接更多数据包,但事实并非如此。相反,它设置了一个 Periodic Advertising train,其中包括有关 AUX_SYNC_IND PDU 中的 BIG 及其 BIS 的所有信息。 Periodic Advertising train中的 AUX_SYNC_IND 数据包会定期传输,因此一旦扫描设备找到它们,它就可以继续跟踪它们,而无需返回 Primary Advertisements 或 Extended Advertisements。Broadcasters甚至可以关闭其Extended Adv,但保持Periodic Advertising train运行。
此周期性广告序列的存在由Extended Adv的 AUX_ADV_IND PDU 中的 Syncinfo 字段指示,该字段提供有关在何处找到它的信息。如果周期性广告序列的信息量太大而无法放入单个 PDU,则 AUX_ADV_IND 也可以使用 AdvPtr 指向辅助 AUX_CHAIN_IND PDU。通常,不需要 AUX_CHAIN_IND PDU。
此 Periodic Advertising train的存在由Extended Adv的 AUX_ADV_IND PDU 中的 Syncinfo 字段指示,该字段提供有关在何处找到它的信息。如果 Periodic Advertising train的信息量太大而无法放入单个 PDU,则 AUX_ADV_IND 也可以使用 AdvPtr 指向辅助 AUX_CHAIN_IND PDU。通常,不需要 AUX_CHAIN_IND PDU。
定位和接收广播音频流所需的数据从Extended Adv开始。 AUX_ADV_IND 包含广播音频公告服务 UUID,它将Extended Adv标识为属于特定广播音频流,并使用 3 个八位字节的 Broadcast_ID 来标识它。 Broadcast_ID 在 BIG 的生命周期内保持静态。 AUX_EXT_IND 可能包括来自顶层 profile的附加服务 UUID。这些允许扫描设备及早过滤它发现的不同广播,因此它不需要与 PA 同步并解码它携带的不感兴趣的广播的信息。该功能对于帮助选择公共广播特别有用,公共广播在公共广播profile (PBP) 中定义,该profile定义了公共广播公告 UUID。
确定它喜欢 BIG 的外观后,扫描仪将与 Periodic Advertising train同步。这些广告使用通用通道 0 到 36。与Extended Adv一样,如果需要,可以使用另一个 AuxPtr 将它们链接起来以包含更多数据。对于广播音频,它们包含两个重要的信息。
第一个是附加controllerAdvertising数据字段,即 ACAD。 ACAD 包含Advertising数据结构。这些是包含Advertising数据 (AD) 类型及其相应数据的数据结构。所有主动广播的设备都将使用 ACAD 发送 BIGInfo 结构,该结构提供接收设备检测广播和了解 BIS 时序所需的所有信息。这是将在 CIG 中的链路层传递给Acceptor的信息,但在广播中没有直接连接,这是不可能的。因此,这种替代方法。
图 4.36 显示了 BIGInfo 的结构。它从 BIG_Offset 开始,它准确地通知设备它们可以在哪里找到与此 AUX_SYNC_IND PDU 相关的 BIG。随后,BIGInfo 描述了该 BIG 的结构:
- 基本间距 – ISO_Interval、Sub_Interval 和 BIS 间距
- BIG 中的 BIS 数量(Num_BIS)及其特征 - NSE、Burst Number、PTO、IRC 和 Framing,
- 数据包信息 - Max_PDU、SDU_Interval、Max_SDU 和 bisPayloadCount。
- 物理Channel访问信息,形式为 SeedAccessAddress、BaseCRCInit、Channel Map (ChM) 和 PHY,以及
- 组初始化向量 (GIV) 和组会话密钥推导 (GSKD) 以允许对加密的广播流进行解码。如果存在最后两个字段,则扫描设备知道广播已加密,这意味着它将需要获取 Broadcast_Code(如下所述)来解密音频流。
GIV 和 GSKD 的存在是判断 BIG 是否包含加密 BIS 的简单方法。如果它们不存在,则 BIGInfo 较短,表明 BIS 未加密。
在我们离开 BIGInfo 之前,需要重复一件重要的事情,那就是所有 BIS 都具有完全相同的参数。这与 CIG 不同,其中多个 CIS 可以具有不同的参数。在 BIG 中,一个设置适用于正在使用的每个 BIS,必须指定该设置以满足不同 BIS 的最大要求。
4.4.7 同步广播音频流
获得 BIGInfo 后,设备可以使用此信息找出这些 BIS 所在的位置。 BIG_Offset 与 BIG_Offset_Units 一起告诉接收器在 BIGInfo 数据包开始后第一个 BIS 的锚点将位于何处(请记住,对于广播,没有 ACL 来提供时间瞬间,就像 CIS 一样) . Acceptor 可以在一个 BIG 中接收任意数量的 BIS。在LE audio 中,这称为与 BIG 或 BIS 同步。图 4.37 显示了如何使用这些信息。
在大多数现实生活中,Broadcast Sink 不希望与所有 BIS 同步。耳塞或助听器通常只想与包含立体声流的 BIG 的左侧或右侧音频流同步,而耳机则希望与左右声道同步。为了确定要连接到哪个 BIS 或 BIS,扫描设备需要查看包含在周期性Advertising AUX_SYNC_IND PDU 中的第二条重要信息。这是广播音频源端点结构 (BASE),它包含在每个 AUX_SYNC_IND PDU 的 AdvData 字段中,位于基本音频公告服务 UUID 之后。
4.4.8 BASE——广播音频源endpoint结构
要了解 BASE,我们需要进入基本音频profile,这是我们将在通用音频框架 (GAF) 中遇到的第一个profile。它是配置和管理音频流的关键profile,适用于连接的等时流和广播等时流。
BIGInfo 描述了 BIS 的结构,告诉设备它包含多少 BIS 以及在哪里可以找到它们,但这只是实用信息。它不提供有关广播音频流中内容的任何信息。 BASE 提供该详细信息,告诉设备每个 BIS 中包含哪些音频信息以及它是如何配置的。如果范围内有多个广播器,那么接收器是否能够选择它收听的广播器是至关重要的。 BASE由三个级别的信息组成,如图 4.38 所示。当我们查看如何设置广播流时,我们将更详细地重新审视这一点。
最高级别 - 级别 1,提供对 BIG 中的每个 BIS 有效的信息 - 单个呈现延迟和组成 BIS 划分的子组的数量。这些子组包含具有共同特征的 BIS,这可能是它们的编码方式或音频流的语言。
在 BASE 的第 2 层更详细地描述了每个子组,其中为该子组中的 BIS 提供编解码器信息,以及 LTV 结构形式的流metadata。其中大部分是人类可读形式的数据字符串,例如节目信息,建议metadata至少包含 ProgramInfo LTV,以便能够显示它的扫描设备可以使用它来帮助用户在不同的音频流。这也是提供语言 LTV 的地方。
最后,BASE 的第 3 级为每个 BIS 提供了具体信息。这包括它的 BIS_Index,它标识它在 BIG 中出现的顺序,以及它的 Channel_Allocation,它标识它所代表的音频位置,例如左或右。级别 3 可以包含特定 BIS 的一组不同的编解码器信息,这将覆盖级别 2 的子组值。这仅可能在 BIG 的一个成员使用与其他 BIS 不同的设置时使用。
BASE 中包含的信息允许广播接收器确定它是否想要接收 BIG,以及它想要同步到该 BIG 中包含的哪些 BIS,以及告诉它该特定 BIS 在整个 BIG 中的位置.一旦它解析了 BIGInfo 和 BASE,设备就拥有了同步到任何 BIS 所需的所有信息
大多数情况下,Broadcast Source 只会传输一个 BIG,但它可以传输多个 BIG。这可能发生在公共信息广播中,其中不同类型的消息可能包含在不同的 BIG 中。例如,一个机场可能使用一个 BIG 用于航班公告,第二个用于一般安全公告,第三个加密用于工作人员公告。在这种情况下,每个 BIG 将有自己的一组主要Advertising,每个都有不同的Advertising集 ID (SID),以及包含其特定 Broadcast_ID、BIGInfo 和 BASE 的Extended Adv序列(参见图 4.39)。
SID 不应经常更改——它通常在设备经历电源循环之前是静态的,并且通常在整个生命周期内都是静态的。 Broadcast_ID 在 BIG 的生命周期内是静态的。广播接收器可以利用这些 ID 重新连接到他们知道是否识别 SID 和 Broadcast_ID 的广播器。
4.4.9 帮助找广播
期望广播音频将以与单播音频截然不同的方式使用。助听器行业热衷于使用LE audio 广播来补充和扩展当前的感应线圈基础设施,从而使安装在场地中更具成本效益。今天,大多数 Telecoil 用于扩声,特别是对于佩戴助听器的人。未来,由于消费者耳塞和耳机可以接收相同的广播传输,因此可能会部署更多的公共音频信息服务。LE audio 广播也很可能成为电视的标准,无论是在健身房和酒吧等公共场所,还是在家里。 Bluetooth SIG 的音频共享计划正在推广广播作为咖啡馆共享音乐和个人音乐的解决方案。
如果市场以这种方式发展,用户通常会发现自己处于多个广播源的范围内,这意味着他们需要选择接收哪个。 AUX_ADV_IND 数据包中的profile UUID 可以提供第一级选择,但设备仍需要检测和解析每个 BIG 的 BASE 信息以做出决定。 (在早期,可能会选择你找到的第一个 BIG,然后按一个按钮移动到下一个,但从长远来看,这不是可扩展的用户体验。)这给产品设计师带来了一个问题,因为像耳塞这样的设备没有显示空间,而且通常几乎没有任何按钮的空间。此外,扫描过程相对耗电——持续扫描会对耳塞或助听器的电池寿命产生显着影响。
为了解决这个限制,LE audio spec引入了commander的概念——一个执行扫描操作的角色,允许用户选择广播,然后指示接收设备与所选的 BIS 或 BIS 同步。commander角色可以作为手机、智能手表、耳塞盒或专用远程控制设备中的应用程序的一部分来实现。事实上,任何与广播接收器连接的BLE 设备都可以充当commander。实现commander角色的设备称为广播助手,并在广播音频扫描服务 (BASS) 中定义。它们可以集成到电视等设备中,以帮助自动连接到耳塞和耳机。
4.4.10 Periodic Advertising同步传输 – PAST
广播助手以与任何其他扫描设备完全相同的方式扫描指示存在Extended Adv的Advertising。一旦发现它们,它就可以同步到相关的 Periodic Advertising train,其中包含广播音频公告服务 UUID,然后发现随附的 BIGInfo 和 BASE 结构。它可以在读取和解析它找到的基本metadata之前对其扫描应用过滤器,之后它通常通过显示人类可读的 ProgramInfo 向用户提供可用广播流的列表。
一旦用户做出选择,广播助手将使用 PAST 程序向广播接收器提供查找相关Periodic Advertising train所需的信息。这允许广播接收器直接跳转到那些Advertising数据包,获取 BIGInfo 和 BASE 并与适当的 BIS 同步,而无需在扫描中消耗能量。此过程称为Periodic Advertising同步传输或 PAST。
广播助手向用户提供的信息级别完全取决于实现。手机应用程序可以列出范围内的每个广播员;它可以根据用户偏好限制显示的信息量,或者使用从一组耳塞读取的预配置设置。广播助手同样可以是手表或健身手环上的一个按钮,它从它找到的广播源列表中选择最后一个已知的等时流。广播助手还可以包括应用程序来获取所需的 Broadcast_Code 以解密私有、加密的广播,方法是与广播器或代理建立蓝牙连接,或者使用带外 (OOB) 方法。
4.4.11 Broadcast_Code
加密流在蓝牙技术中并不新鲜。安全性和保密性一直是spec的重要组成部分。然而,在发送和接收设备之间没有连接的情况下实施加密,就像LE audio 中的广播流一样,引入了一个新问题,即如何应对加密。
许多广播流不会被加密;它们将被公开广播,以便任何人都可以拿起它们。但是,这会产生一些问题。首先,范围内的任何人都可以接收它们。由于蓝牙技术在穿透墙壁方面非常有效,这在会议室、酒店房间甚至家庭中可能是一个问题,在这些房间中,相邻房间的某人可能会无意中从您的电视中拾取音频。这可能从烦人到尴尬,取决于内容是什么。在商业环境中,它很可能是机密的,因此添加加密至关重要。基本的保密性在感应线圈系统中是固有的,因为音频传输只能在感应线圈的范围内被拾取。为了在LE audio 广播中提供相同级别的身份验证,需要对音频数据进行加密,这需要接收方获取解密密钥,即广播代码。
寻找广播的设备可以通过检查周期性广播链中 BIGInfo 的长度来检测广播音频流是否被加密。如果流被加密,则数据包将包含额外的 24 个八位字节,其中包含组初始化向量 (GIV) 和组会话密钥分散器 (GSKD)。扫描器将检测它们的存在,并结合其他metadata,确定是否与此类流同步,具体取决于它们是否能够检索 Broadcast_Code。
尽管广播不需要配对广播源和接收器,但在许多情况下,将存在 ACL 连接。这听起来可能很奇怪,但这种安排允许加密连接的数量远远超出单播的可能,而不会达到通话时间限制。预计这将是大多数家用电视的工作方式,这样邻居就听不到你在听什么了。在这种情况下,用户将与电视配对,使用 BASS 的功能来获取 Broadcast_Code。 Broadcast_Code 是host应用程序的一个属性。host在设置 BIS 时将其提供给controller,并且它可以同样将其提供给受信任的设备。在公共场所、会议室和酒店,可能会使用带外方法,可能类似于用于连接到 Wi-Fi 接入点的打印信息。 Broadcast_Codes 也可以通过其他带外方法获得,例如扫描二维码、点击 NFC 终端,甚至包含在可下载的剧院门票中。我们将在第 12 章中更详细地探讨这些配置
请注意,用于描述Advertising包内广播的metadata未加密。因此,应注意确保其不包含机密或可能令人尴尬的信息。
4.4.12 广播拓扑
LE audio 中包含的功能为查找广播提供了广泛的选项。我们将在后面的章节中更详细地介绍它们,但下图显示了一些常见的。在大多数情况下,它们显示单个“广播信息”流,其中包含所有Advertising信息
图 4.40 显示了最简单的情况,一副耳机通过自己的扫描来查找和选择广播音频流。
图 4.41 基本相同,但指出广播接收器也可以是电话。在这里,它可以扫描广播者,向用户显示广播音频流的可用选择,然后将音频渲染到一对有线耳机。它同样可以使用蓝牙(蓝牙经典音频或LE audio )传输流,尽管这不太可能有效利用通话时间。
图 4.42 显示了最常见的用例,其中手机、手表或远程遥控等设备充当广播助手,扫描并向用户展示选择的广播音频流,然后使用 PAST 允许用户的耳机或耳塞连接到选定的流。正如我们将看到的,广播助手还可以用于音量控制和静音,允许用户查找、选择和控制广播音频流的呈现。如图 4.43 所示。
尽管音频流的广播源和广播接收器之间没有连接,但设备可以使用 ACL 连接来帮助同步到 BIS,以便在您进入房间时电视可以自动同步到音频流。在这种情况下,广播源通常还包含一个广播助手,它将与用户的耳机配对。当用户选择连接到广播助手时,它将使用 PAST 提供如何与 BIS 和 BASS 同步以传输 Broadcast_Code 的详细信息。
这是构成音频共享基础的拓扑结构之一,许多朋友可以通过一部手机共享音乐。第 12 章更详细地解释了这些选项。
4.5 ISOAL——同步适配层
ISOAL [Core Vol 6, Part G] 是 Core Isochronous Streams 功能中最复杂的方面之一。好消息是,它在蓝牙芯片中已经为您处理好了,但了解它为什么是必要的以及它的作用是有用的。 ISOAL 用于广播和单播音频流。
ISOAL 的存在是为了解决帧大小不匹配时发生的问题。最常见的原因是 Acceptor 只支持 10ms 的帧大小,但 Initiator 需要使用 7.5ms 的帧,因为它正在与其他蓝牙经典设备(例如旧的鼠标和键盘)连接,这些
设备只能以 7.5 毫秒的时间间隔运行。随着新的外围设备变得更加灵活,这将随着时间的推移而改变,但在此之前,ISOAL 提供了一种方法来适应它们,同时整个蓝牙生态系统迁移到 10 毫秒的时间间隔。
ISOAL 层位于编解码器和链路层之间的数据路径中。如果编解码器在host中实现,则来自编解码器的编码 SDU 可以通过 HCI 传递,或者通过专有接口(无论编解码器位于何处)。如图 4.44 所示,ISOAL 提供分段和重组或分段和重组,并负责在framed或unframed的 PDU 中发送编码的音频数据。
根据host层提供的设置,controller可以决定是使用framed的还是unframed的 PDU。对于unframed的 PDU,如果 SDU 可以容纳在单个 PDU 中,则等时自适应管理器可以将它们分段,但在没有分段报头的情况下发送它们。这是传输同步数据的最有效、最低延迟的方式。如果 SDU 大于最大 PDU 大小,它将被分段并在多个unframed的 SDU 中发送。重组或重新组装过程将它们重新组装成 SDU。只有当 ISO_Interval 等于或为 SDU_Interval 的整数倍时,才能使用unframed PDU,而 SDU_Interval 本身等于或为采样帧的整数倍。这意味着 SDU 的生成需要与传输时间同步,这样它们就不会相互漂移。否则,您需要使用framed的 SDU。
对于framed的 SDU,Isochronous Adaptation Manager 添加一个分段报头和一个可选的 Time_Offset。 Time_Offset 允许跨 PDU 对多个 SDU 进行分段,提供一个参考时间,以保持 SDU 生成和传输时序之间的关联。如果您需要更多详细信息,ISOAL 的完整spec包含在第 6 卷,G 部分,核心第 6 节中。
设计人员需要注意的 ISOAL 的主要方面是它包含定义 Transport_Delay 的一组方程。 Transport_Delay 是 SDU 被呈现以供传输和它在适当的同步参考处准备好解码的点之间的时间。
对于framed的 SDU,CIG 传输延迟为:
Transport_Latency = CIG_Sync_Delay + FT × ISO_Interval + SDU_Interval
对于 Central 到 Peripheral 和 Peripheral 到 Central 方向,需要使用 CIG_Sync_Delay、FT 和 SDU_Interval 的各自值进行单独计算。
对于使用framed SDU 的 BIG,
Transport_Latency = BIG_Sync_Delay + (PTO × (NSE÷BN–IRC)) × ISO_Interval
+ ISO_Interval + SDU_Interval
对于unframed的 SDU,计算略有不同。对于 CIG:Transport_Latency = CIG_Sync_Delay + FT × ISO_Interval - SDU_Interval
同样,您需要将 CIG_Sync_Delay、FT 和 SDU_Interval 的值分别用于 Central 到 Peripheral 和 Peripheral 到 Central 方向。
对于无框的 BIG,
Transport_Latency = BIG_Sync_Delay + (PTO × (NSE÷BN-IRC) + 1) × ISO_Interval - SDU_Interval
--oOo--
到此结束了等时流的基础知识。现在我们需要查看 LC3 并了解 QoS 选择如何影响鲁棒性和延迟。