结合实例分析A2DP SBC帧结构和编解码算法

SBC也就是Sub band codec,俗称子带编码,是蓝牙A2DP必须支持的唯一编码。下面结合实例看看SBC编码数据在蓝牙传输中帧结构以及SBC的编解码算法流程:

AVDTP Frame

在这里插入图片描述
首先AVDTP Frame是基于L2CAP协议,所以会包含有4个字节的L2CAP头部,如上图看到2个字节的length = 650 bytes,两个字节的Destination CID = 0xA040 (AVDTP)。
接下来看看12个字节的AVDTP的头部:
在这里插入图片描述
这12个字节分成了三部分:

  • Padding ,Extension, Maker 和 Payload Type组成了2个字节,也就是0x8060;
  • Sequence Number 也就是0x0019, 占用2个字节,就是给AVDTP Frame一个序号,方便接收方能检查发送的数据包是不是连续的,有没有丢包。
  • Time Stamp 也就是0x00005400,占用4个字节,这个就是计算数据包播放的时间戳,接收方Audio DSP会根据时间戳来做音频播放同步以及丢包错包检查。
  • SSRC 也就是0x00000000,占用4个字节。

SBC Frame

在这里插入图片描述
从上图可以看到一个2-DH5数据包的Media Payload包含一个字节SBC头部(其中4个bit用来表示包含几个子frame),和7个frame。
根据A2DP_SPEC_V1.3,立体声和联合立体声的Frame_length计算方法:

frame_length = 4 + (4 * nrof_subbands * nrof_channels ) / 8 + (join * nrof_subbands + nrof_blocks * bitpool ) / 8.;联合立体声时,join == 1;

MONO和DUAL CHANNEL mode 的frame_length计算方法:

frame_length = 4 + (4 * nrof_subbands * nrof_channels ) / 8 + nrof_blocks * nrof_channels * bitpool / 8 .

本实例我们得到的nrof_subbands 等于8, nrof_channels 等于2,join 等于1,bitpool等于39,nrof_blocks等于16,所以:

frame_length = 4 +(4* 8 * 2) /8 +1 * 8 + 16 * 39/8 = 4 + 8 + 1 +78 = 91 byte

这样我们挑一个frame 1来看看:
在这里插入图片描述
从上图可以看出一个SBC子帧是由13个字节的Frame Header + 78个字节的audio samples组成:

第n字节参数描述
1syncword0x9C占用一个字节,这是个固定的值,标志着一个子帧的开始
2Sampling Frequency10(44.1 kHz)占用两个bit:
00表示16kHZ;
01表示32KHZ;
10表示44.1KHZ;
11表示48KHZ
2Blocks(11)16占用2个bit:
00表示4个block;
01表示8个block;
10表示12个block;
11表示16个block
2Channel ModeJoint Stereo占用2个bit:
00表示MONO;
01表示DUAL_CHANNEL;
10表示STEREO;
11表示JOINT STEREO
2Allocation MethodLoudness占用1个bit:
0表示LOUDNESS;
1表示SNR;
2Subbands1(8)占用1个bit:
0表示4个subbands;
1表示8个subbands;
3Bitpool39占用一个字节,表示bitpool大小
4crc_check0x5E占用一个字节,用作CRC校验
5join0xFE占用一个字节,一个bit为1表示一个subband编码为联合立体声,否则为立体声编码。
6-13Scale Factors比例因子,占用8个字节,4个bit表示一个通道,一个子带;此实例有2个通道,8个子带,所以需要4x2x8/8 = 8字节表示;
14-91Audio Samples78 bytes占用78个字节,量化编码后的音频数据,16x39/8 = 78,大小也就是nrf_blocks x bitpool / 8

SBC解码

在这里插入图片描述

  1. 音频接收端收到SBC帧数据会检查frame_header,然后做CRC的校验:G(X) = X8 + X4 + X3 + X2 + 1 (CRC-8).
  2. 计算真实的比例因子scalefactors : scalefactor[ch][sb] = pow(2.0, (scale _ factor[ch][sb] + 1)). 这里的scale_factor[ch][sb]就是上一节我们在帧头部的4个bit,而所谓的scale factor就是每个子段的最大幅值。
  3. Bit Allocation:这个是跟scalefactors关联的,每个子频段的幅值不一样,需要用到的bit数也不一样,但同一个子频段的幅值所用的bit数是一样的。
  4. Reconstruction of the Subband Samples:就是把每个子频段的78个字节的audio_sample和真实的比例因子scalefactor做一个乘法运算,进行采样数据的还原:sb_sample[blk][ch][sb] = scalefactor[ch][sb] * ((audio_sample[blk][ch][sb]*2.0+1.0) /levels[ch][sb]-1.0);
  5. Joint Processing :
for (blk=0;blk< nrof_blocks;blk++)
{
for (sb=0;sb<nrof_subbands;sb++)
{
if ((channel_mode==JOINT_STEREO) && (join[sb]==1))
{
sb_sample[blk][0][sb] = sb_sample[blk][0][sb] + sb_sample[blk][1][sb];
sb_sample[blk][1][sb] = sb_sample[blk][0][sb]2 * sb_sample[blk][1][sb];
}
}
}
  1. Synthesis Filter:多项滤波器组把每个子频带采样数据进行滤波器的合成为PCM数据输出给音频codec。

SBC编码

在这里插入图片描述
SBC编码过程跟解码是反过来的:

  1. Analysis Filter :把输入的PCM数据通过多项滤波器组转化为4或者8个子频带的频域数据;
  2. Scale Factors :计算每个子频段的比例因子,用4个比特表示,实际值是2的n次方,表示这个子频段的最高幅值 ;
  3. Bit Allocation:跟解码过程是一样的,跟scalefactors关联 , 每个子频段的幅值不一样,需要用到的bit数也不一样,为每个子频段分配幅值bit数的过程就是bit allocation;
  4. Quantization:量化,通过如下公式进行: quantized_sb_sample[blk][ch][sb] = ((sb_sample[blk][ch][sb] / scalefactor[ch][sb] + 1.0) * levels[ch][sb]) / 2.0
  5. BitStream packing,把每个子频段的frame_header和audio_sample打包到AVDTP数据包中。

SBC的压缩比

首先看一下SBC的比特率的计算:

bit_rate = 8 * frame_length* fs / nrof_subbands / nrof_blocks

如果不进行SBC编码,我们的bit_rate = 44100 x 16 = 705600 bit/s.
进行了SBC编码的bit_rate = 8 * 91 *44100/16/8 = 250818 bit/s
那么压缩比为:705600/250818 = 2.81

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tim_Jiangzj

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值