op25/op25/gr-op25_repeater/lib/imbe_vocoder/ch_decode.cc

186 lines
5.1 KiB
C++

/*
* 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;
}