You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
186 lines
5.1 KiB
C++
186 lines
5.1 KiB
C++
1 year ago
|
/*
|
||
|
* Project 25 IMBE Encoder/Decoder Fixed-Point implementation
|
||
|
* Developed by Pavel Yazev E-mail: pyazev@gmail.com
|
||
|
* Version 1.0 (c) Copyright 2009
|
||
|
*
|
||
|
* This is free software; you can redistribute it and/or modify it
|
||
|
* under the terms of the GNU General Public License as published by
|
||
|
* the Free Software Foundation; either version 3, or (at your option)
|
||
|
* any later version.
|
||
|
*
|
||
|
* The software is distributed in the hope that it will be useful, but
|
||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||
|
* See the GNU General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU General Public License
|
||
|
* along with this; see the file COPYING. If not, write to the Free
|
||
|
* Software Foundation, Inc., 51 Franklin Street, Boston, MA
|
||
|
* 02110-1301, USA.
|
||
|
*/
|
||
|
|
||
|
#include "typedef.h"
|
||
|
#include "globals.h"
|
||
|
#include "imbe.h"
|
||
|
#include "basic_op.h"
|
||
|
#include "ch_decode.h"
|
||
|
#include "aux_sub.h"
|
||
|
|
||
|
|
||
|
void decode_frame_vector(IMBE_PARAM *imbe_param, Word16 *frame_vector)
|
||
|
{
|
||
|
Word16 bit_stream[BIT_STREAM_LEN];
|
||
|
Word16 i, vec_num, tmp, tmp1, tmp2, bit_thr, shift;
|
||
|
Word16 *b_ptr, *ba_ptr, index0;
|
||
|
Word32 L_tmp;
|
||
|
|
||
|
imbe_param->b_vec[0] = (shr(frame_vector[0], 4) & 0xFC) | (shr(frame_vector[7], 1) & 0x3);
|
||
|
|
||
|
if (imbe_param->b_vec[0] < 0 || imbe_param->b_vec[0] > 207)
|
||
|
return; // If we return here IMBE parameters from previous frame will be used (frame repeating)
|
||
|
|
||
|
tmp = ((imbe_param->b_vec[0] & 0xFF) << 1) + 0x4F; // Convert b_vec[0] to unsigned Q15.1 format and add 39.5
|
||
|
|
||
|
//imbe_param->ff = 4./((double)imbe_param->b_vec[0] + 39.5);
|
||
|
|
||
|
// Calculate fundamental frequency with higher precession
|
||
|
shift = norm_s(tmp);
|
||
|
tmp1 = tmp << shift;
|
||
|
|
||
|
tmp2 = div_s(0x4000, tmp1);
|
||
|
imbe_param->fund_freq = L_shr(L_deposit_h(tmp2), 11 - shift);
|
||
|
|
||
|
L_tmp = L_sub(0x40000000, L_mult(tmp1, tmp2));
|
||
|
tmp2 = div_s(extract_l(L_shr(L_tmp, 2)), tmp1);
|
||
|
L_tmp = L_shr(L_deposit_l(tmp2), 11 - shift - 2);
|
||
|
imbe_param->fund_freq = L_add(imbe_param->fund_freq, L_tmp);
|
||
|
|
||
|
//printf("%X %X \n", imbe_param->fund_freq, (Word32)(imbe_param->ff * (double)((UWord32)1<<31)));
|
||
|
|
||
|
tmp = (tmp + 0x2) >> 3; // Calculate (b0 + 39.5 + 1)/4
|
||
|
imbe_param->num_harms = ((UWord32)CNST_0_9254_Q0_16 * tmp) >> 16;
|
||
|
|
||
|
if(imbe_param->num_harms <= 36)
|
||
|
imbe_param->num_bands = extract_h((UWord32)(imbe_param->num_harms + 2) * CNST_0_33_Q0_16); // fix((L+2)/3)
|
||
|
else
|
||
|
imbe_param->num_bands = NUM_BANDS_MAX;
|
||
|
|
||
|
// Convert input vector (from b_3 to b_L+1) to bit stream
|
||
|
bit_stream[0] = (frame_vector[0] & 0x4)?1:0;
|
||
|
bit_stream[1] = (frame_vector[0] & 0x2)?1:0;
|
||
|
bit_stream[2] = (frame_vector[0] & 0x1)?1:0;
|
||
|
|
||
|
bit_stream[BIT_STREAM_LEN - 3] = (frame_vector[7] & 0x40)?1:0;
|
||
|
bit_stream[BIT_STREAM_LEN - 2] = (frame_vector[7] & 0x20)?1:0;
|
||
|
bit_stream[BIT_STREAM_LEN - 1] = (frame_vector[7] & 0x10)?1:0;
|
||
|
|
||
|
|
||
|
index0 = 3 + 3 * 12 - 1;
|
||
|
for(vec_num = 3; vec_num >= 1; vec_num--)
|
||
|
{
|
||
|
tmp = frame_vector[vec_num];
|
||
|
for(i = 0; i < 12; i++)
|
||
|
{
|
||
|
bit_stream[index0] = (tmp & 0x1)?1:0;
|
||
|
tmp >>= 1;
|
||
|
index0--;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
index0 = 3 + 3 * 12 + 3 * 11 - 1;
|
||
|
for(vec_num = 6; vec_num >= 4; vec_num--)
|
||
|
{
|
||
|
tmp = frame_vector[vec_num];
|
||
|
for(i = 0; i < 11; i++)
|
||
|
{
|
||
|
bit_stream[index0] = (tmp & 0x1)?1:0;
|
||
|
tmp >>= 1;
|
||
|
index0--;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Rebuild b1
|
||
|
index0 = 3 + 3 * 12;
|
||
|
tmp = 0;
|
||
|
for(i = 0; i < imbe_param->num_bands; i++)
|
||
|
tmp = (tmp << 1) | bit_stream[index0++];
|
||
|
|
||
|
imbe_param->b_vec[1] = tmp;
|
||
|
|
||
|
// Rebuild b2
|
||
|
tmp = 0;
|
||
|
tmp |= bit_stream[index0++] << 1;
|
||
|
tmp |= bit_stream[index0++];
|
||
|
imbe_param->b_vec[2] = (frame_vector[0] & 0x38) | (tmp << 1) | (shr(frame_vector[7], 3) & 0x01);
|
||
|
|
||
|
// Shift the rest of sequence
|
||
|
tmp = imbe_param->num_bands + 2; // shift
|
||
|
for(; index0 < BIT_STREAM_LEN; index0++)
|
||
|
bit_stream[index0 - tmp] = bit_stream[index0];
|
||
|
|
||
|
// Priority ReScanning
|
||
|
b_ptr = &imbe_param->b_vec[3];
|
||
|
ba_ptr = imbe_param->bit_alloc;
|
||
|
for(i = 0; i < B_NUM; i++)
|
||
|
ba_ptr[i] = b_ptr[i] = 0;
|
||
|
|
||
|
|
||
|
// Unpack bit allocation table's item
|
||
|
get_bit_allocation(imbe_param->num_harms, imbe_param->bit_alloc);
|
||
|
|
||
|
index0 = 0;
|
||
|
bit_thr = (imbe_param->num_harms == 0xb)?9:ba_ptr[0];
|
||
|
|
||
|
while(index0 < BIT_STREAM_LEN - imbe_param->num_bands - 2)
|
||
|
{
|
||
|
for(i = 0; i < imbe_param->num_harms - 1; i++)
|
||
|
if(bit_thr && bit_thr <= ba_ptr[i])
|
||
|
b_ptr[i] = (b_ptr[i] << 1) | bit_stream[index0++];
|
||
|
bit_thr--;
|
||
|
}
|
||
|
|
||
|
// Synchronization Bit Decoding
|
||
|
imbe_param->b_vec[imbe_param->num_harms + 2] = frame_vector[7] & 1;
|
||
|
}
|
||
|
|
||
|
|
||
|
void v_uv_decode(IMBE_PARAM *imbe_param)
|
||
|
{
|
||
|
Word16 num_harms;
|
||
|
Word16 num_bands;
|
||
|
Word16 vu_vec, *p_v_uv_dsn, mask, i, uv_cnt;
|
||
|
|
||
|
num_harms = imbe_param->num_harms;
|
||
|
num_bands = imbe_param->num_bands;
|
||
|
vu_vec = imbe_param->b_vec[1];
|
||
|
|
||
|
p_v_uv_dsn = imbe_param->v_uv_dsn;
|
||
|
|
||
|
mask = 1 << (num_bands - 1);
|
||
|
|
||
|
v_zap(p_v_uv_dsn, NUM_HARMS_MAX);
|
||
|
|
||
|
i = 0; uv_cnt = 0;
|
||
|
while(num_harms--)
|
||
|
{
|
||
|
if(vu_vec & mask)
|
||
|
*p_v_uv_dsn++ = 1;
|
||
|
else
|
||
|
{
|
||
|
*p_v_uv_dsn++ = 0;
|
||
|
uv_cnt++;
|
||
|
}
|
||
|
|
||
|
if(++i == 3)
|
||
|
{
|
||
|
if(num_bands > 1)
|
||
|
{
|
||
|
num_bands--;
|
||
|
mask >>= 1;
|
||
|
}
|
||
|
i = 0;
|
||
|
}
|
||
|
}
|
||
|
imbe_param->l_uv = uv_cnt;
|
||
|
}
|