【藍牙sbc協議】sbc源碼閱讀筆記(二)——sbc_struct詳解(下)

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;
	}
  ···
}

以上完成了兩個指針的初始化。


待補充內容:
  • 數據寫入過程
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章