【蓝牙sbc协议】sbc源码阅读笔记(二)——sbc_struct详解(上)[通俗易懂]

2022-10-01 12:01:10 浏览数 (1)

大家好,又见面了,我是你们的朋友全栈君。

sbc_struct结构详解

sbc_struct结构的定义:
代码语言:javascript复制
// sbc.h
struct sbc_struct { 
   
	unsigned long flags;

	uint8_t frequency;
	uint8_t blocks;
	uint8_t subbands;
	uint8_t mode;
	uint8_t allocation;
	uint8_t bitpool;
	uint8_t endian;

	void *priv;
	void *priv_alloc_base;
};
typedef struct sbc_struct sbc_t;

flags

unsigned long类型。在调用sbc_init(&sbc, 0L);sbc_init_msbc(&sbc, 0);的时候作为第二个参数传入,并在函数中,继续传递给sbc_set_defaults函数,在sbc_set_defaults中赋值给sbc->flags

待补充:作用

代码语言:javascript复制
/* sbcenc.c */
// !msbc
sbc_init(&sbc, 0L);
// msbc
sbc_init_msbc(&sbc, 0);

/* sbc.c */
// sbc_init()与sbc_init_msbc()均调用此方法
sbc_set_defaults(sbc, flags);	
// sbc_set_defaults()
static void sbc_set_defaults(sbc_t *sbc, unsigned long flags)
{ 
     
	···
	sbc->flags = flags;
	···
}

frequency

uint8_t类型,用来表示采样率,取值有16k,32k,44.1k,48k。

代码语言:javascript复制
/* sbc.h */
/* sampling frequency */
#define SBC_FREQ_16000 0x00
#define SBC_FREQ_32000 0x01
#define SBC_FREQ_44100 0x02
#define SBC_FREQ_48000 0x03

sbc_init()中默认值为44.1k,在sbc_init_msbc()中默认值为16k。

代码语言:javascript复制
/* sbc.c */
// sbc
static void sbc_set_defaults(sbc_t *sbc, unsigned long flags)
{ 
     
	···
	sbc->frequency = SBC_FREQ_44100;
	···
}
// msbc
···
sbc_set_defaults(sbc, flags);		// 先调用了sbc_set_defaults
sbc->frequency = SBC_FREQ_16000;// 随后修改默认值为16k
···

encode()中,sbc编码可以根据文件采样率对frequency赋值,msbc只能使用16k。

代码语言:javascript复制
/* sbcenc.c */
// msbc必须为16k
static void encode(char *filename, int subbands, int bitpool, int 								joint, int dualchannel, int snr, int blocks, bool msbc)
{ 

···
if (!msbc) { 

sbc_init(&sbc, 0L);
switch (BE_INT(au_hdr.sample_rate)) { 

case 16000:
sbc.frequency = SBC_FREQ_16000;
break;
case 32000:
sbc.frequency = SBC_FREQ_32000;
break;
case 44100:
sbc.frequency = SBC_FREQ_44100;
break;
case 48000:
sbc.frequency = SBC_FREQ_48000;
break;
}
···
} else { 

if (BE_INT(au_hdr.sample_rate) != 16000 ||
BE_INT(au_hdr.channels) != 1 ||
BE_INT(au_hdr.channels) != 1) { 

fprintf(stderr, "mSBC requires 16 bits, 16kHz, mono "
"inputn");
goto done;
}
···
}
···
}

blocks

类型为uint8_t,sbc编码的取值有4,8,12,16,msbc为15。

待补充:作用

代码语言:javascript复制
/* sbc.h */
/* blocks */
#define SBC_BLK_4 0x00
#define SBC_BLK_8 0x01
#define SBC_BLK_12 0x02
#define SBC_BLK_16 0x03
/* sbc.c */
#define MSBC_BLOCKS 15

sbc_set_defaults()中默认设置为16,msbc则修改为15。

代码语言:javascript复制
/* sbc.c */
// sbc
static void sbc_set_defaults(sbc_t *sbc, unsigned long flags)
{ 

···
sbc->blocks = SBC_BLK_16;
···
}
// msbc
···
sbc_set_defaults(sbc, flags);		// 先调用了sbc_set_defaults
sbc->blocks = MSBC_BLOCKS;			// 随后修改为15
···

encode()中进行赋值。

代码语言:javascript复制
/* sbcenc.c */
static void encode(char *filename, int subbands, int bitpool, int 								joint, int dualchannel, int snr, int blocks, bool msbc)
{ 

···
if (!msbc) { 

sbc_init(&sbc, 0L);
···
sbc.blocks = blocks == 4 ? SBC_BLK_4 :
blocks == 8 ? SBC_BLK_8 :
blocks == 12 ? SBC_BLK_12 : SBC_BLK_16;
} else { 

···
sbc_init_msbc(&sbc, 0);		// 设置为15
···
}
···
}

subbands

uint8_t类型,表示子带数量,取值范围为4,8。

代码语言:javascript复制
/* sbc.h */
/* subbands */
#define SBC_SB_4 0x00
#define SBC_SB_8 0x01

sbc_set_defaults()中默认设置为8。

encode()中进行赋值。

代码语言:javascript复制
/* sbcenc.c */
static void encode(char *filename, int subbands, int bitpool, int 								joint, int dualchannel, int snr, int blocks, bool msbc)
{ 

···
if (!msbc) { 

sbc_init(&sbc, 0L);
···
sbc.subbands = subbands == 4 ? SBC_SB_4 : SBC_SB_8;
···
} else { 

···
sbc_init_msbc(&sbc, 0);		// 默认8
···
}
···
}

mode

uint8_t类型,表示声道模式,支持单声道、双声道、立体声和联合立体声。

代码语言:javascript复制
/* sbc.h */
/* channel mode */
#define SBC_MODE_MONO 0x00
#define SBC_MODE_DUAL_CHANNEL 0x01
#define SBC_MODE_STEREO 0x02
#define SBC_MODE_JOINT_STEREO 0x03

sbc_set_defaults()中默认设置为立体声,msbc编码则默认是单声道。

encode()中进行赋值。

代码语言:javascript复制
/* sbcenc.c */
static void encode(char *filename, int subbands, int bitpool, int 								joint, int dualchannel, int snr, int blocks, bool msbc)
{ 

···
if (!msbc) { 

sbc_init(&sbc, 0L);
···
if (BE_INT(au_hdr.channels) == 1) { 

sbc.mode = SBC_MODE_MONO;	// 单声道
// 音频为单声道但指定了联合或双声道模式
if (joint || dualchannel) { 

fprintf(stderr, "Audio is mono but joint or "
"dualchannel mode has been specifiedn");
goto done;
}
} else if (joint && !dualchannel)
sbc.mode = SBC_MODE_JOINT_STEREO;	// 立体声
else if (!joint && dualchannel)
sbc.mode = SBC_MODE_DUAL_CHANNEL;	// 双声道
else if (!joint && !dualchannel)
sbc.mode = SBC_MODE_STEREO;				// 联合立体声
else { 

fprintf(stderr, "Both joint and dualchannel "
"mode have been specifiedn");
goto done;
}
···
} else { 

···
sbc_init_msbc(&sbc, 0);		// msbc默认单声道
···
}
···
}

allocation

uint8_t类型,表示每个子频段幅值比特数的分配方法,有响度和信噪比。

代码语言:javascript复制
/* sbc.h */
/* allocation method */
#define SBC_AM_LOUDNESS 0x00
#define SBC_AM_SNR 0x01

默认为SBC_AM_LOUDNESS,在encode()中赋值。

代码语言:javascript复制
/* sbcenc.c */
static void encode(char *filename, int subbands, int bitpool, int 								joint, int dualchannel, int snr, int blocks, bool msbc)
{ 

···
if (!msbc) { 

sbc_init(&sbc, 0L);
···
sbc.allocation = snr ? SBC_AM_SNR : SBC_AM_LOUDNESS;
···
} else { 

···
sbc_init_msbc(&sbc, 0);		// msbc默认SBC_AM_LOUDNESS
···
}
···
}

bitpool

uint8_t类型,表示幅值的比特数,默认为32,msbc默认为26。

代码语言:javascript复制
/* sbcenc.c */
static void encode(char *filename, int subbands, int bitpool, int 								joint, int dualchannel, int snr, int blocks, bool msbc)
{ 

···
if (!msbc) { 

sbc_init(&sbc, 0L);
···
sbc.bitpool = bitpool;		// sbc默认32
···
} else { 

···
sbc_init_msbc(&sbc, 0);		// msbc默认26
···
}
···
}

endian

uint8_t类型,用来表示主机字节序(大端、小端),默认为大端。

代码语言:javascript复制
/* sbc.h */
/* data endianess */
#define SBC_LE 0x00
#define SBC_BE 0x01

sbc_set_defaults()中判断并赋值。

代码语言:javascript复制
/* sbc.c */
// sbc_set_defaults()
static void sbc_set_defaults(sbc_t *sbc, unsigned long flags)
{ 

···
#if __BYTE_ORDER == __LITTLE_ENDIAN
sbc->endian = SBC_LE;
#elif __BYTE_ORDER == __BIG_ENDIAN
sbc->endian = SBC_BE;
#else
#error "Unknown byte order"
#endif
}

待补充:sbc与msbc执行sbc_set_defaults()后,都又将endian赋值为SBC_BE

待补充内容:
  • flags 的作用
  • blocks 的作用
  • endian 判断赋值后,又重新赋值为 SBC_BE
  • *priv 与 *priv_alloc_base

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/194983.html原文链接:https://javaforall.cn

0 人点赞