sbc_struct結構詳解
*priv、*priv_alloc_base
priv指針與priv_alloc_base指針。
在初始化過程sbc_init(&sbc, 0L)
中,給兩個指針分配空間:
/* sbc.c */
// sbc
SBC_EXPORT int sbc_init(sbc_t *sbc, unsigned long flags)
{
if (!sbc)
return -EIO;
memset(sbc, 0, sizeof(sbc_t));
// struct sbc_priv 見下方
sbc->priv_alloc_base = malloc(sizeof(struct sbc_priv) + SBC_ALIGN_MASK);
if (!sbc->priv_alloc_base)
return -ENOMEM;
// typedef unsigned long uintptr_t;
// m&~n 爲m/n所剩餘數據的起始位置
// SBC_ALIGN_MASK 爲15
sbc->priv = (void *) (((uintptr_t) sbc->priv_alloc_base +
SBC_ALIGN_MASK) & ~((uintptr_t) SBC_ALIGN_MASK));
memset(sbc->priv, 0, sizeof(struct sbc_priv));
sbc_set_defaults(sbc, flags);
return 0;
}
SBC_ALIGN_MASK
:
/* sbc_tables.h */ /* * Enforce 16 byte alignment for the data, which is supposed to be used * with SIMD optimized code. */ #define SBC_ALIGN_BITS 4 #define SBC_ALIGN_MASK ((1 << (SBC_ALIGN_BITS)) - 1) #ifdef __GNUC__ #define SBC_ALIGNED __attribute__((aligned(1 << (SBC_ALIGN_BITS)))) #else #define SBC_ALIGNED #endif
sbc_priv
的定義:
/* sbc.c */ // 各個屬性詳細信息見下方 struct sbc_priv { bool init; bool msbc; struct SBC_ALIGNED sbc_frame frame; struct SBC_ALIGNED sbc_decoder_state dec_state; struct SBC_ALIGNED sbc_encoder_state enc_state; // 兩個函數指針 int (*unpack_frame)(const uint8_t *data, struct sbc_frame *frame, size_t len); ssize_t (*pack_frame)(uint8_t *data, struct sbc_frame *frame, size_t len, int joint); };
// sbc_frame /* This structure contains an unpacked SBC frame. Yes, there is probably quite some unused space herein */ struct sbc_frame { uint8_t frequency; uint8_t block_mode; uint8_t blocks; enum { MONO = SBC_MODE_MONO, DUAL_CHANNEL = SBC_MODE_DUAL_CHANNEL, STEREO = SBC_MODE_STEREO, JOINT_STEREO = SBC_MODE_JOINT_STEREO } mode; uint8_t channels; enum { LOUDNESS = SBC_AM_LOUDNESS, SNR = SBC_AM_SNR } allocation; uint8_t subband_mode; uint8_t subbands; uint8_t bitpool; uint16_t codesize; uint16_t length; /* bit number x set means joint stereo has been used in subband x */ uint8_t joint; /* only the lower 4 bits of every element are to be used */ uint32_t SBC_ALIGNED scale_factor[2][8]; /* raw integer subband samples in the frame */ int32_t SBC_ALIGNED sb_sample_f[16][2][8]; /* modified subband samples */ int32_t SBC_ALIGNED sb_sample[16][2][8]; /* original pcm audio samples */ int16_t SBC_ALIGNED pcm_sample[2][16*8]; };
// sbc_decoder_state struct sbc_decoder_state { int subbands; int32_t V[2][170]; int offset[2][16]; };
// sbc_encoder_state struct sbc_encoder_state { int position; // 編碼器處理的連續塊數 /* Number of consecutive blocks handled by the encoder */ uint8_t increment; int16_t SBC_ALIGNED X[2][SBC_X_BUFFER_SIZE]; // 4子帶多項濾波器 /* Polyphase analysis filter for 4 subbands configuration, * it handles "increment" blocks at once */ void (*sbc_analyze_4s)(struct sbc_encoder_state *state, int16_t *x, int32_t *out, int out_stride); // 8子帶多項濾波器 /* Polyphase analysis filter for 8 subbands configuration, * it handles "increment" blocks at once */ void (*sbc_analyze_8s)(struct sbc_encoder_state *state, int16_t *x, int32_t *out, int out_stride); // 根據子帶數量和輸入數據字節順序,處理輸入數據(逐行掃描、尾數轉換、重新排序) /* Process input data (deinterleave, endian conversion, reordering), * depending on the number of subbands and input data byte order */ int (*sbc_enc_process_input_4s_le)(int position, const uint8_t *pcm, int16_t X[2][SBC_X_BUFFER_SIZE], int nsamples, int nchannels); int (*sbc_enc_process_input_4s_be)(int position, const uint8_t *pcm, int16_t X[2][SBC_X_BUFFER_SIZE], int nsamples, int nchannels); int (*sbc_enc_process_input_8s_le)(int position, const uint8_t *pcm, int16_t X[2][SBC_X_BUFFER_SIZE], int nsamples, int nchannels); int (*sbc_enc_process_input_8s_be)(int position, const uint8_t *pcm, int16_t X[2][SBC_X_BUFFER_SIZE], int nsamples, int nchannels); // 計算比例因子 /* Scale factors calculation */ void (*sbc_calc_scalefactors)(int32_t sb_sample_f[16][2][8], uint32_t scale_factor[2][8], int blocks, int channels, int subbands); // 聯合立體聲的比例因子計算 /* Scale factors calculation with joint stereo support */ int (*sbc_calc_scalefactors_j)(int32_t sb_sample_f[16][2][8], uint32_t scale_factor[2][8], int blocks, int subbands); const char *implementation_info; };
// unpack_frame、pack_frame static void sbc_set_defaults(sbc_t *sbc, unsigned long flags) { ··· if (priv->msbc) { priv->pack_frame = msbc_pack_frame; priv->unpack_frame = msbc_unpack_frame; } else { priv->pack_frame = sbc_pack_frame; priv->unpack_frame = sbc_unpack_frame; } ··· }
以上完成了兩個指針的初始化。
待補充內容:
- 數據寫入過程