sbc_struct結構詳解
sbc_struct結構的定義:
// 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
。待補充:作用
/* 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 " "input\n"); goto done; } ··· } ··· }
-
blocks
類型爲
uint8_t
,sbc編碼的取值有4,8,12,16,msbc爲15。待補充:作用
/* 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 specified\n"); 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 specified\n"); 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