大家好,又见面了,我是你们的朋友全栈君。
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。
/* 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。
/* 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。
/* 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。
/* 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()
中进行赋值。
/* 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。
/* sbc.h */
/* subbands */
#define SBC_SB_4 0x00
#define SBC_SB_8 0x01
在sbc_set_defaults()
中默认设置为8。
在encode()
中进行赋值。
/* 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
类型,表示声道模式,支持单声道、双声道、立体声和联合立体声。
/* 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()
中进行赋值。
/* 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
类型,表示每个子频段幅值比特数的分配方法,有响度和信噪比。
/* sbc.h */
/* allocation method */
#define SBC_AM_LOUDNESS 0x00
#define SBC_AM_SNR 0x01
默认为SBC_AM_LOUDNESS
,在encode()
中赋值。
/* 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。
/* 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
类型,用来表示主机字节序(大端、小端),默认为大端。
/* sbc.h */
/* data endianess */
#define SBC_LE 0x00
#define SBC_BE 0x01
在sbc_set_defaults()
中判断并赋值。
/* 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