📄 melp_chn.c
字号:
/****************************************************************************
**
** Function: low_rate_chn_read
**
** Description: Unpacking the channel buffer for low rate ( 1200bps )
**
** Arguments:
**
** quant_param par ---- The quantization structure
**
** Return value: None
**
*****************************************************************************/
Shortword low_rate_chn_read(struct quant_param *qpar, struct melp_param *par,
struct melp_param *prev_par)
{
register Shortword i, j, k;
static Shortword prev_uv = 1;
static Shortword prev_fsmag[NUM_HARM];
static Shortword qplsp[LPC_ORD], prev_gain[2*NF*NUM_GAINFR];
static Shortword firstTime = TRUE;
const Shortword *codebook;
Shortword erase = 0, lsp_check[NF] = {0,0,0};
Shortword bit_cntr, bit_cntr1, cnt, last, index, dontcare;
Shortword prot_bp1, prot_bp2, prot_lsp;
Shortword uv1, uv2, cuv, uv_index, uv_parity;
unsigned char *bit_ptr, *bit_ptr1;
Shortword ilsp1[LPC_ORD], ilsp2[LPC_ORD], res[2*LPC_ORD];
Shortword temp1, temp2, p_value, q_value;
Shortword intfact;
Shortword weighted_fsmag[NUM_HARM]; /* Q13 */
Shortword erase_uuu = 0, erase_vvv = 0;
Shortword flag_parity = 0, flag_dec_lsp = 1, flag_dec_pitch = 1;
Shortword melp_v_cb_size[4] = {256, 64, 32, 32};
Shortword res_cb_size[4] = {256, 64, 64, 64};
Shortword melp_uv_cb_size[1] = {512};
Longword L_acc, L_sum1, L_sum2;
/* In previous versions we use unweighted_fsmag[] and prev_fsmag[] to */
/* keep track of a previous par[].fs_mag array. They were obtained by */
/* multiplying the w_fs_inv[] arrays with par[].fs_mag, and they are */
/* weighted by w_fs[] when they are used later. In floating point */
/* version this is straightforward but in fixed point the multiplication */
/* of w_fs_inv[] and w_fs[] do not yield the original data. Modifica- */
/* tions are made to remove this to and fro inversions. */
if (firstTime){ /* Initialization */
temp2 = shl(LPC_ORD, 10); /* Q10 */
temp1 = X08_Q10; /* Q10 */
for (i = 0; i < LPC_ORD; i++){
/* qplsp[i] = (i + 1)*0.8/LPC_ORD; */
qplsp[i] = divide_s(temp1, temp2);
temp1 = add(temp1, X08_Q10);
}
fill(prev_gain, 2560, 2*NF*NUM_GAINFR);
fill(prev_fsmag, ONE_Q13, NUM_HARM);
firstTime = FALSE;
}
/* ======== Read channel output buffer into bit buffer ======== */
bit_ptr = bit_buffer;
qpar->chptr = chbuf;
qpar->chbit = 0;
for (i = 0; i < bitNum12; i++){
erase |= unpack_code(&qpar->chptr, &qpar->chbit, &index, 1,
chwordsize, ERASE_MASK);
bit_buffer[i] = (unsigned char) index;
bit_ptr++;
}
bit_ptr = bit_buffer;
bit_cntr = 0;
/* ====== Read sync bit ====== */
unpack_code(&bit_ptr, &bit_cntr, &dontcare, 1, 1, 0);
/* ====== Unpacking Global U/V dicision ====== */
unpack_code(&bit_ptr, &bit_cntr, &uv_index, UV_BITS, 1, 0);
/* ====== Unpacking parity bit ====== */
unpack_code(&bit_ptr, &bit_cntr, &uv_parity, 1, 1, 0);
/* ====== Unpacking pitch information ====== */
unpack_code(&bit_ptr, &bit_cntr, &qpar->pitch_index, PITCH_VQ_BITS, 1, 0);
/* error check in U/V pattern */
bit_ptr1 = bit_ptr;
bit_cntr1= bit_cntr;
/* unpack_code(&bit_ptr1, &bit_cntr1, &dontcare, 39, 1, 0); LSP */
bit_cntr1 = 0; bit_ptr1 += 39;
unpack_code(&bit_ptr1, &bit_cntr1, &prot_lsp, 3, 1, 0); /* LSP */
unpack_code(&bit_ptr1, &bit_cntr1, &dontcare, 10, 1, 0); /* GAIN */
unpack_code(&bit_ptr1, &bit_cntr1, &dontcare, 2, 1, 0); /* BP */
unpack_code(&bit_ptr1, &bit_cntr1, &prot_bp2, 2, 1, 0); /* BP */
unpack_code(&bit_ptr1, &bit_cntr1, &prot_bp1, 2, 1, 0); /* BP */
if (uv_parity != parity(uv_index, 3))
flag_parity |= 1;
/* Mode checking */
if (uv_index == 0){
if (!flag_parity){
j = qpar->pitch_index;
qpar->pitch_index = low_rate_pitch_dec[qpar->pitch_index];
if (qpar->pitch_index == UV_PIND){
qpar->uv_flag[0] = par[0].uv_flag = 1;
qpar->uv_flag[1] = par[1].uv_flag = 1;
qpar->uv_flag[2] = par[2].uv_flag = 1;
if (prot_bp2 != 0){
erase_uuu |= 1;
flag_dec_lsp = 0;
flag_dec_pitch = 0;
}
} else if (qpar->pitch_index == INVAL_PIND){
erase_uuu |= 1;
flag_dec_lsp = 0;
flag_dec_pitch = 0;
} else {
qpar->pitch_index -= 2;
for (i = k = 0; i < PITCH_VQ_BITS; i++){
if ((j & 0x1) == 1) k++;
j >>= 1;
}
if (k == 6 || k == 7){
qpar->uv_flag[0] = par[0].uv_flag = 1;
qpar->uv_flag[1] = par[1].uv_flag = 1;
qpar->uv_flag[2] = par[2].uv_flag = 0;
if (prot_bp2 != 1){
erase_uuu |= 1;
flag_dec_lsp = 0;
flag_dec_pitch = 0;
}
} else if (k == 4){
qpar->uv_flag[0] = par[0].uv_flag = 1;
qpar->uv_flag[1] = par[1].uv_flag = 0;
qpar->uv_flag[2] = par[2].uv_flag = 1;
if (prot_bp2 != 2){
erase_uuu |= 1;
flag_dec_lsp = 0;
flag_dec_pitch = 0;
}
} else if (k == 5){
qpar->uv_flag[0] = par[0].uv_flag = 0;
qpar->uv_flag[1] = par[1].uv_flag = 1;
qpar->uv_flag[2] = par[2].uv_flag = 1;
if (prot_bp2 != 3){
erase_uuu |= 1;
flag_dec_lsp = 0;
flag_dec_pitch = 0;
}
}
}
} else if (prot_bp1 == 0){
j = qpar->pitch_index;
qpar->pitch_index = low_rate_pitch_dec[qpar->pitch_index];
if (qpar->pitch_index == UV_PIND){
qpar->uv_flag[0] = par[0].uv_flag = 1;
qpar->uv_flag[1] = par[1].uv_flag = 1;
qpar->uv_flag[2] = par[2].uv_flag = 1;
if (prot_bp2 != 0){
erase_uuu |= 1;
flag_dec_lsp = 0;
flag_dec_pitch = 0;
}
} else if (qpar->pitch_index == INVAL_PIND){
erase_uuu |= 1;
flag_dec_lsp = 0;
flag_dec_pitch = 0;
} else {
qpar->pitch_index -= 2;
for (i = k = 0; i < PITCH_VQ_BITS; i++){
if ((j & 0x1) == 1) k++;
j >>= 1;
}
if (k == 6 || k == 7){
qpar->uv_flag[0] = par[0].uv_flag = 1;
qpar->uv_flag[1] = par[1].uv_flag = 1;
qpar->uv_flag[2] = par[2].uv_flag = 0;
if (prot_bp2 != 1){
erase_uuu |= 1;
flag_dec_lsp = 0;
flag_dec_pitch = 0;
}
} else if (k == 4){
qpar->uv_flag[0] = par[0].uv_flag = 1;
qpar->uv_flag[1] = par[1].uv_flag = 0;
qpar->uv_flag[2] = par[2].uv_flag = 1;
if (prot_bp2 != 2){
erase_uuu |= 1;
flag_dec_lsp = 0;
flag_dec_pitch = 0;
}
} else if (k == 5){
qpar->uv_flag[0] = par[0].uv_flag = 0;
qpar->uv_flag[1] = par[1].uv_flag = 1;
qpar->uv_flag[2] = par[2].uv_flag = 1;
if (prot_bp2 != 3){
erase_uuu |= 1;
flag_dec_lsp = 0;
flag_dec_pitch = 0;
}
}
}
} else {
if (prot_bp2 == 1 && prot_lsp == 7){
qpar->uv_flag[0] = par[0].uv_flag = 0;
qpar->uv_flag[1] = par[1].uv_flag = 0;
qpar->uv_flag[2] = par[2].uv_flag = 1;
} else if (prot_bp2 == 2){
qpar->uv_flag[0] = par[0].uv_flag = 0;
qpar->uv_flag[1] = par[1].uv_flag = 1;
qpar->uv_flag[2] = par[2].uv_flag = 0;
} else if (prot_bp2 == 3){
qpar->uv_flag[0] = par[0].uv_flag = 1;
qpar->uv_flag[1] = par[1].uv_flag = 0;
qpar->uv_flag[2] = par[2].uv_flag = 0;
} else {
erase_vvv |= 1;
flag_dec_lsp = 0;
flag_dec_pitch = 2;
}
}
} else if (uv_index == 1 || uv_index == 2 || uv_index == 4){
if (!flag_parity){
if (uv_index == 1){
qpar->uv_flag[0] = par[0].uv_flag = 0;
qpar->uv_flag[1] = par[1].uv_flag = 0;
qpar->uv_flag[2] = par[2].uv_flag = 1;
} else if (uv_index == 2){
qpar->uv_flag[0] = par[0].uv_flag = 0;
qpar->uv_flag[1] = par[1].uv_flag = 1;
qpar->uv_flag[2] = par[2].uv_flag = 0;
} else if (uv_index == 4){
qpar->uv_flag[0] = par[0].uv_flag = 1;
qpar->uv_flag[1] = par[1].uv_flag = 0;
qpar->uv_flag[2] = par[2].uv_flag = 0;
}
} else {
if (prot_bp1 == 0){
j = qpar->pitch_index;
qpar->pitch_index = low_rate_pitch_dec[qpar->pitch_index];
if (qpar->pitch_index == UV_PIND){
qpar->uv_flag[0] = par[0].uv_flag = 1;
qpar->uv_flag[1] = par[1].uv_flag = 1;
qpar->uv_flag[2] = par[2].uv_flag = 1;
if (prot_lsp != 0){
erase_uuu |= 1;
flag_dec_lsp = 0;
flag_dec_pitch = 0;
}
} else if (qpar->pitch_index == INVAL_PIND){
erase_uuu |= 1;
flag_dec_lsp = 0;
flag_dec_pitch = 0;
} else {
qpar->pitch_index -= 2;
for (i = k = 0; i < PITCH_VQ_BITS; i++){
if ((j & 0x1) == 1) k++;
j >>= 1;
}
if (k == 6 || k == 7){
qpar->uv_flag[0] = par[0].uv_flag = 1;
qpar->uv_flag[1] = par[1].uv_flag = 1;
qpar->uv_flag[2] = par[2].uv_flag = 0;
if (prot_bp2 != 1){
erase_uuu |= 1;
flag_dec_lsp = 0;
flag_dec_pitch = 0;
}
} else if (k == 4){
qpar->uv_flag[0] = par[0].uv_flag = 1;
qpar->uv_flag[1] = par[1].uv_flag = 0;
qpar->uv_flag[2] = par[2].uv_flag = 1;
if (prot_bp2 != 2){
erase_uuu |= 1;
flag_dec_lsp = 0;
flag_dec_pitch = 0;
}
} else if (k == 5){
qpar->uv_flag[0] = par[0].uv_flag = 0;
qpar->uv_flag[1] = par[1].uv_flag = 1;
qpar->uv_flag[2] = par[2].uv_flag = 1;
if (prot_bp2 != 3){
erase_uuu |= 1;
flag_dec_lsp = 0;
flag_dec_pitch = 0;
}
}
}
} else if (prot_bp1 == 1 && prot_lsp == 7){
qpar->uv_flag[0] = par[0].uv_flag = 0;
qpar->uv_flag[1] = par[1].uv_flag = 0;
qpar->uv_flag[2] = par[2].uv_flag = 1;
} else {
erase_vvv |= 1;
}
}
} else if (uv_index == 3 || uv_index == 5){
if (!flag_parity){
qpar->uv_flag[0] = par[0].uv_flag = 0;
qpar->uv_flag[1] = par[1].uv_flag = 0;
qpar->uv_flag[2] = par[2].uv_flag = 0;
if (uv_index == 3)
qpar->pitch_index = qpar->pitch_index;
else if (uv_index == 5)
qpar->pitch_index = (Shortword) (qpar->pitch_index + PITCH_VQ_SIZE);
} else {
if (prot_bp1 == 1 && prot_lsp == 7){
qpar->uv_flag[0] = par[0].uv_flag = 0;
qpar->uv_flag[1] = par[1].uv_flag = 0;
qpar->uv_flag[2] = par[2].uv_flag = 1;
} else {
erase_vvv |= 1;
if (uv_index == 3)
qpar->pitch_index = qpar->pitch_index;
else if (uv_index == 5)
qpar->pitch_index = (Shortword) (qpar->pitch_index + PITCH_VQ_SIZE);
}
}
} else if (uv_index == 6){
if (!flag_parity){
qpar->uv_flag[0] = par[0].uv_flag = 0;
qpar->uv_flag[1] = par[1].uv_flag = 0;
qpar->uv_flag[2] = par[2].uv_flag = 0;
qpar->pitch_index = (Shortword) (qpar->pitch_index + 2*PITCH_VQ_SIZE);
} else {
if (prot_bp1 == 2){
qpar->uv_flag[0] = par[0].uv_flag = 0;
qpar->uv_flag[1] = par[1].uv_flag = 1;
qpar->uv_flag[2] = par[2].uv_flag = 0;
}
if (prot_bp1 == 3){
qpar->uv_flag[0] = par[0].uv_flag = 1;
qpar->uv_flag[1] = par[1].uv_flag = 0;
qpar->uv_flag[2] = par[2].uv_flag = 0;
} else {
erase_vvv |= 1;
qpar->pitch_index = (Shortword) (qpar->pitch_index + 2*PITCH_VQ_SIZE);
}
}
} else if (uv_index == 7){
if (!flag_parity){
qpar->uv_flag[0] = par[0].uv_flag = 0;
qpar->uv_flag[1] = par[1].uv_flag = 0;
qpar->uv_flag[2] = par[2].uv_flag = 0;
qpar->pitch_index = (Shortword) (qpar->pitch_index + 3*PITCH_VQ_SIZE);
} else {
erase_vvv |= 1;
qpar->pitch_index = (Shortword) (qpar->pitch_index + 3*PITCH_VQ_SIZE);
}
}
if (erase_uuu){
qpar->uv_flag[0] = par[0].uv_flag = 1;
qpar->uv_flag[1] = par[1].uv_flag = 1;
qpar->uv_flag[2] = par[2].uv_flag = 1;
}
if (erase_vvv){
qpar->uv_flag[0] = par[0].uv_flag = 0;
qpar->uv_flag[1] = par[1].uv_flag = 0;
qpar->uv_flag[2] = par[2].uv_flag = 0;
}
/* ====== Unpacking LSF information ====== */
last = -1;
cnt = 0;
for (i = 0; i < NF; i++){
if (!qpar->uv_flag[i]){
cnt++;
last = i;
}
}
uv1 = qpar->uv_flag[0];
uv2 = qpar->uv_flag[1];
cuv = qpar->uv_flag[2];
if ((uv1 == 1) && (uv2 == 1) && (cuv == 1)){
unpack_code(&bit_ptr, &bit_cntr, &(qpar->lsf_index[0][0]), 9, 1, 0);
unpack_code(&bit_ptr, &bit_cntr, &(qpar->lsf_index[1][0]), 9, 1, 0);
unpack_code(&bit_ptr, &bit_cntr, &(qpar->lsf_index[2][0]), 9, 1, 0);
unpack_code(&bit_ptr, &bit_cntr, &(qpar->lsf_index[0][1]), 4, 1, 0);
unpack_code(&bit_ptr, &bit_cntr, &(qpar->lsf_index[1][1]), 4, 1, 0);
unpack_code(&bit_ptr, &bit_cntr, &(qpar->lsf_index[2][1]), 4, 1, 0);
unpack_code(&bit_ptr, &bit_cntr, &dontcare, 3, 1, 0);
} else if ((uv1 == 1) && (uv2 == 1) && (cuv != 1)){
unpack_code(&bit_ptr, &bit_cntr, &(qpar->lsf_index[0][0]), 9, 1, 0);
unpack_code(&bit_ptr, &bit_cntr, &(qpar->lsf_index[1][0]), 9, 1, 0);
unpack_code(&bit_ptr, &bit_cntr, &(qpar->lsf_index[2][0]), 8, 1, 0);
unpack_code(&bit_ptr, &bit_cntr, &(qpar->lsf_index[2][1]), 6, 1, 0);
unpack_code(&bit_ptr, &bit_cntr, &(qpar->lsf_index[2][2]), 5, 1, 0);
unpack_code(&bit_ptr, &bit_cntr, &(qpar->lsf_index[2][3]), 5, 1, 0);
} else if ((uv1 == 1) && (uv2 != 1) && (cuv == 1)){
unpack_code(&bit_ptr, &bit_cntr, &(qpar->lsf_index[0][0]), 9, 1, 0);
unpack_code(&bit_ptr, &bit_cntr, &(qpar->lsf_index[1][0]), 8, 1, 0);
unpack_code(&bit_ptr, &bit_cntr, &(qpar->lsf_index[1][1]), 6, 1, 0);
unpack_code(&bit_ptr, &bit_cntr, &(qpar->lsf_index[1][2]), 5, 1, 0);
unpack_code(&bit_ptr, &bit_cntr, &(qpar->lsf_index[1][3]), 5, 1, 0);
unpack_code(&bit_ptr, &bit_cntr, &(qpar->lsf_index[2][0]), 9, 1, 0);
} else if ((uv1 != 1) && (uv2 == 1) && (cuv == 1)){
unpack_code(&bit_ptr, &bit_cntr, &(qpar->lsf_index[0][0]), 8, 1, 0);
unpack_code(&bit_ptr, &bit_cntr, &(qpar->lsf_index[0][1]), 6, 1, 0);
unpack_code(&bit_ptr, &bit_cntr, &(qpar->lsf_index[0][2]), 5, 1, 0);
unpack_code(&bit_ptr, &bit_cntr, &(qpar->lsf_index[0][3]), 5, 1, 0);
unpack_code(&bit_ptr, &bit_cntr, &(qpar->lsf_index[1][0]), 9, 1, 0);
unpack_code(&bit_ptr, &bit_cntr, &(qpar->lsf_index[2][0]), 9, 1, 0);
} else {
if ((uv1 != 1) && (uv2 != 1) && (cuv == 1)){
/* ---- Interpolation [4 inp + (8+6+6+6) res + 9 uv] ---- */
unpack_code(&bit_ptr, &bit_cntr, &(qpar->lsf_index[0][0]),
9, 1, 0);
} else {
unpack_code(&bit_ptr, &bit_cntr, &(qpar->lsf_index[0][0]),
8, 1, 0);
unpack_code(&bit_ptr, &bit_cntr, &(qpar->lsf_index[0][1]),
6, 1, 0);
unpack_code(&bit_ptr, &bit_cntr, &(qpar->lsf_index[0][2]),
5, 1, 0);
unpack_code(&bit_ptr, &bit_cntr, &(qpar->lsf_index[0][3]),
5, 1, 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -