pjsip-pjproject/third_party/g7221/encode/encoder.c

1126 lines
38 KiB
C

/***************************************************************************
**
** ITU-T G.722.1 (2005-05) - Fixed point implementation for main body and Annex C
** > Software Release 2.1 (2008-06)
** (Simple repackaging; no change from 2005-05 Release 2.0 code)
**
** © 2004 Polycom, Inc.
**
** All rights reserved.
**
***************************************************************************/
/***************************************************************************
Filename: encoder.c
Purpose: Contains files used to implement the G.722.1 Annex C encoder
Design Notes:
***************************************************************************/
/***************************************************************************
Include files
***************************************************************************/
#include <stdio.h>
#include <math.h>
#include "defs.h"
#include "huff_def.h"
#include "tables.h"
#include "count.h"
/***************************************************************************
Function: encoder
Syntax: void encoder(Word16 number_of_available_bits,
Word16 number_of_regions,
Word16 mlt_coefs,
Word16 mag_shift,
Word16 out_words)
inputs: number_of_available_bits
number_of_regions
mag_shift
mlt_coefs[DCT_LENGTH]
outputs: out_words[MAX_BITS_PER_FRAME/16]
Description: Encodes the mlt coefs into out_words using G.722.1 Annex C
WMOPS: 7kHz | 24kbit | 32kbit
-------|--------------|----------------
AVG | 0.93 | 1.04
-------|--------------|----------------
MAX | 1.20 | 1.28
-------|--------------|----------------
14kHz | 24kbit | 32kbit | 48kbit
-------|--------------|----------------|----------------
AVG | 1.39 | 1.71 | 2.01
-------|--------------|----------------|----------------
MAX | 2.00 | 2.30 | 2.52
-------|--------------|----------------|----------------
***************************************************************************/
void encoder(Word16 number_of_available_bits,
Word16 number_of_regions,
Word16 *mlt_coefs,
Word16 mag_shift,
Word16 *out_words)
{
Word16 num_categorization_control_bits;
Word16 num_categorization_control_possibilities;
Word16 number_of_bits_per_frame;
Word16 number_of_envelope_bits;
Word16 categorization_control;
Word16 region;
Word16 absolute_region_power_index[MAX_NUMBER_OF_REGIONS];
Word16 power_categories[MAX_NUMBER_OF_REGIONS];
Word16 category_balances[MAX_NUM_CATEGORIZATION_CONTROL_POSSIBILITIES-1];
Word16 drp_num_bits[MAX_NUMBER_OF_REGIONS+1];
UWord16 drp_code_bits[MAX_NUMBER_OF_REGIONS+1];
Word16 region_mlt_bit_counts[MAX_NUMBER_OF_REGIONS];
UWord32 region_mlt_bits[4*MAX_NUMBER_OF_REGIONS];
Word16 mag_shift_offset;
Word16 temp;
/* initialize variables */
test();
if (number_of_regions == NUMBER_OF_REGIONS)
{
num_categorization_control_bits = NUM_CATEGORIZATION_CONTROL_BITS;
move16();
num_categorization_control_possibilities = NUM_CATEGORIZATION_CONTROL_POSSIBILITIES;
move16();
}
else
{
num_categorization_control_bits = MAX_NUM_CATEGORIZATION_CONTROL_BITS;
move16();
num_categorization_control_possibilities = MAX_NUM_CATEGORIZATION_CONTROL_POSSIBILITIES;
move16();
}
number_of_bits_per_frame = number_of_available_bits;
move16();
for (region=0; region<number_of_regions; region++)
{
region_mlt_bit_counts[region] = 0;
move16();
}
/* Estimate power envelope. */
number_of_envelope_bits = compute_region_powers(mlt_coefs,
mag_shift,
drp_num_bits,
drp_code_bits,
absolute_region_power_index,
number_of_regions);
/* Adjust number of available bits based on power envelope estimate */
temp = sub(number_of_available_bits,number_of_envelope_bits);
number_of_available_bits = sub(temp,num_categorization_control_bits);
/* get categorizations */
categorize(number_of_available_bits,
number_of_regions,
num_categorization_control_possibilities,
absolute_region_power_index,
power_categories,
category_balances);
/* Adjust absolute_region_category_index[] for mag_shift.
This assumes that REGION_POWER_STEPSIZE_DB is defined
to be exactly 3.010299957 or 20.0 times log base 10
of square root of 2. */
temp = shl_nocheck(mag_shift,1);
mag_shift_offset = add(temp,REGION_POWER_TABLE_NUM_NEGATIVES);
for (region=0; region<number_of_regions; region++)
{
absolute_region_power_index[region] = add(absolute_region_power_index[region],mag_shift_offset);
move16();
}
/* adjust the absolute power region index based on the mlt coefs */
adjust_abs_region_power_index(absolute_region_power_index,mlt_coefs,number_of_regions);
/* quantize and code the mlt coefficients based on categorizations */
vector_quantize_mlts(number_of_available_bits,
number_of_regions,
num_categorization_control_possibilities,
mlt_coefs,
absolute_region_power_index,
power_categories,
category_balances,
&categorization_control,
region_mlt_bit_counts,
region_mlt_bits);
/* stuff bits into words */
bits_to_words(region_mlt_bits,
region_mlt_bit_counts,
drp_num_bits,
drp_code_bits,
out_words,
categorization_control,
number_of_regions,
num_categorization_control_bits,
number_of_bits_per_frame);
}
/***************************************************************************
Function: bits_to_words
Syntax: bits_to_words(UWord32 *region_mlt_bits,
Word16 *region_mlt_bit_counts,
Word16 *drp_num_bits,
UWord16 *drp_code_bits,
Word16 *out_words,
Word16 categorization_control,
Word16 number_of_regions,
Word16 num_categorization_control_bits,
Word16 number_of_bits_per_frame)
Description: Stuffs the bits into words for output
WMOPS: 7kHz | 24kbit | 32kbit
-------|--------------|----------------
AVG | 0.09 | 0.12
-------|--------------|----------------
MAX | 0.10 | 0.13
-------|--------------|----------------
14kHz | 24kbit | 32kbit | 48kbit
-------|--------------|----------------|----------------
AVG | 0.12 | 0.15 | 0.19
-------|--------------|----------------|----------------
MAX | 0.14 | 0.17 | 0.21
-------|--------------|----------------|----------------
***************************************************************************/
void bits_to_words(UWord32 *region_mlt_bits,
Word16 *region_mlt_bit_counts,
Word16 *drp_num_bits,
UWord16 *drp_code_bits,
Word16 *out_words,
Word16 categorization_control,
Word16 number_of_regions,
Word16 num_categorization_control_bits,
Word16 number_of_bits_per_frame)
{
Word16 out_word_index = 0;
Word16 j;
Word16 region;
Word16 out_word;
Word16 region_bit_count;
Word16 current_word_bits_left;
UWord16 slice;
Word16 out_word_bits_free = 16;
UWord32 *in_word_ptr;
UWord32 current_word;
Word32 acca = 0;
Word32 accb;
Word16 temp;
/* First set up the categorization control bits to look like one more set of region power bits. */
out_word = 0;
move16();
drp_num_bits[number_of_regions] = num_categorization_control_bits;
move16();
drp_code_bits[number_of_regions] = (UWord16)categorization_control;
move16();
/* These code bits are right justified. */
for (region=0; region <= number_of_regions; region++)
{
current_word_bits_left = drp_num_bits[region];
move16();
current_word = (UWord32)drp_code_bits[region];
move16();
j = sub(current_word_bits_left,out_word_bits_free);
test();
if (j >= 0)
{
temp = extract_l(L_shr_nocheck(current_word,j));
out_word = add(out_word,temp);
out_words[out_word_index++] = out_word;
move16();
out_word_bits_free = 16;
move16();
out_word_bits_free = sub(out_word_bits_free,j);
acca = (current_word << out_word_bits_free);
out_word = extract_l(acca);
}
else
{
j = negate(j);
acca = (current_word << j);
accb = L_deposit_l(out_word);
acca = L_add(accb,acca);
out_word = extract_l(acca);
out_word_bits_free = sub(out_word_bits_free,current_word_bits_left);
}
}
/* These code bits are left justified. */
for (region=0;region<number_of_regions; region++)
{
accb = L_deposit_l(out_word_index);
accb = L_shl_nocheck(accb,4);
accb = L_sub(accb,number_of_bits_per_frame);
test();
if(accb < 0)
{
temp = shl_nocheck(region,2);
in_word_ptr = &region_mlt_bits[temp];
region_bit_count = region_mlt_bit_counts[region];
move16();
temp = sub(32,region_bit_count);
test();
if(temp > 0)
current_word_bits_left = region_bit_count;
else
current_word_bits_left = 32;
current_word = *in_word_ptr++;
acca = L_deposit_l(out_word_index);
acca = L_shl_nocheck(acca,4);
acca = L_sub(acca,number_of_bits_per_frame);
/* from while loop */
test();
test();
logic16();
while ((region_bit_count > 0) && (acca < 0))
{
/* from while loop */
test();
test();
logic16();
temp = sub(current_word_bits_left,out_word_bits_free);
test();
if (temp >= 0)
{
temp = sub(32,out_word_bits_free);
accb = LU_shr(current_word,temp);
slice = (UWord16)extract_l(accb);
out_word = add(out_word,slice);
test();
current_word <<= out_word_bits_free;
current_word_bits_left = sub(current_word_bits_left,out_word_bits_free);
out_words[out_word_index++] = extract_l(out_word);
move16();
out_word = 0;
move16();
out_word_bits_free = 16;
move16();
}
else
{
temp = sub(32,current_word_bits_left);
accb = LU_shr(current_word,temp);
slice = (UWord16)extract_l(accb);
temp = sub(out_word_bits_free,current_word_bits_left);
test();
accb = slice << temp;
acca = L_deposit_l(out_word);
acca = L_add(acca,accb);
out_word = extract_l(acca);
out_word_bits_free = sub(out_word_bits_free,current_word_bits_left);
current_word_bits_left = 0;
move16();
}
test();
if (current_word_bits_left == 0)
{
current_word = *in_word_ptr++;
region_bit_count = sub(region_bit_count,32);
/* current_word_bits_left = MIN(32,region_bit_count); */
temp = sub(32,region_bit_count);
test();
if(temp > 0)
current_word_bits_left = region_bit_count;
else
current_word_bits_left = 32;
}
acca = L_deposit_l(out_word_index);
acca = L_shl_nocheck(acca,4);
acca = L_sub(acca,number_of_bits_per_frame);
}
accb = L_deposit_l(out_word_index);
accb = L_shl_nocheck(accb,4);
accb = L_sub(accb,number_of_bits_per_frame);
}
}
/* Fill out with 1's. */
test();
while (acca < 0)
{
test();
current_word = 0x0000ffff;
move32();
temp = sub(16,out_word_bits_free);
acca = LU_shr(current_word,temp);
slice = (UWord16)extract_l(acca);
out_word = add(out_word,slice);
out_words[out_word_index++] = out_word;
move16();
out_word = 0;
move16();
out_word_bits_free = 16;
move16();
acca = L_deposit_l(out_word_index);
acca = L_shl_nocheck(acca,4);
acca = L_sub(acca,number_of_bits_per_frame);
}
}
/***************************************************************************
Function: adjust_abs_region_power_index
Syntax: adjust_abs_region_power_index(Word16 *absolute_region_power_index,
Word16 *mlt_coefs,
Word16 number_of_regions)
inputs: *mlt_coefs
*absolute_region_power_index
number_of_regions
outputs: *absolute_region_power_index
Description: Adjusts the absolute power index
WMOPS: 7kHz | 24kbit | 32kbit
-------|--------------|----------------
AVG | 0.03 | 0.03
-------|--------------|----------------
MAX | 0.12 | 0.12
-------|--------------|----------------
14kHz | 24kbit | 32kbit | 48kbit
-------|--------------|----------------|----------------
AVG | 0.03 | 0.03 | 0.03
-------|--------------|----------------|----------------
MAX | 0.14 | 0.14 | 0.14
-------|--------------|----------------|----------------
***************************************************************************/
void adjust_abs_region_power_index(Word16 *absolute_region_power_index,Word16 *mlt_coefs,Word16 number_of_regions)
{
Word16 n,i;
Word16 region;
Word16 *raw_mlt_ptr;
Word32 acca;
Word16 temp;
for (region=0; region<number_of_regions; region++)
{
n = sub(absolute_region_power_index[region],39);
n = shr_nocheck(n,1);
test();
if (n > 0)
{
temp = extract_l(L_mult0(region,REGION_SIZE));
raw_mlt_ptr = &mlt_coefs[temp];
for (i=0; i<REGION_SIZE; i++)
{
acca = L_shl_nocheck(*raw_mlt_ptr,16);
acca = L_add(acca,32768L);
acca = L_shr_nocheck(acca,n);
acca = L_shr_nocheck(acca,16);
*raw_mlt_ptr++ = extract_l(acca);
}
temp = shl_nocheck(n,1);
temp = sub(absolute_region_power_index[region],temp);
absolute_region_power_index[region] = temp;
move16();
}
}
}
/***************************************************************************
Function: compute_region_powers
Syntax: Word16 compute_region_powers(Word16 *mlt_coefs,
Word16 mag_shift,
Word16 *drp_num_bits,
UWord16 *drp_code_bits,
Word16 *absolute_region_power_index,
Word16 number_of_regions)
mlt_coefs[DCT_LENGTH];
mag_shift;
drp_num_bits[MAX_NUMBER_OF_REGIONS];
drp_code_bits[MAX_NUMBER_OF_REGIONS];
absolute_region_power_index[MAX_NUMBER_OF_REGIONS];
number_of_regions;
Description: Computes the power for each of the regions
WMOPS: 7kHz | 24kbit | 32kbit
-------|--------------|----------------
AVG | 0.09 | 0.09
-------|--------------|----------------
MAX | 0.13 | 0.13
-------|--------------|----------------
14kHz | 24kbit | 32kbit | 48kbit
-------|--------------|----------------|----------------
AVG | 0.20 | 0.20 | 0.20
-------|--------------|----------------|----------------
MAX | 0.29 | 0.29 | 0.29
-------|--------------|----------------|----------------
***************************************************************************/
Word16 compute_region_powers(Word16 *mlt_coefs,
Word16 mag_shift,
Word16 *drp_num_bits,
UWord16 *drp_code_bits,
Word16 *absolute_region_power_index,
Word16 number_of_regions)
{
Word16 *input_ptr;
Word32 long_accumulator;
Word16 itemp1;
Word16 power_shift;
Word16 region;
Word16 j;
Word16 differential_region_power_index[MAX_NUMBER_OF_REGIONS];
Word16 number_of_bits;
Word32 acca;
Word16 temp;
Word16 temp1;
Word16 temp2;
input_ptr = mlt_coefs;
for (region=0; region<number_of_regions; region++)
{
long_accumulator = L_deposit_l(0);
for (j=0; j<REGION_SIZE; j++)
{
itemp1 = *input_ptr++;
move16();
long_accumulator = L_mac0(long_accumulator,itemp1,itemp1);
}
power_shift = 0;
move16();
acca = (long_accumulator & 0x7fff0000L);
logic32();
test();
while (acca > 0)
{
test();
long_accumulator = L_shr_nocheck(long_accumulator,1);
acca = (long_accumulator & 0x7fff0000L);
logic32();
power_shift = add(power_shift,1);
}
acca = L_sub(long_accumulator,32767);
temp = add(power_shift,15);
test();
test();
logic16();
while ((acca <= 0) && (temp >= 0))
{
test();
test();
logic16();
long_accumulator = L_shl_nocheck(long_accumulator,1);
acca = L_sub(long_accumulator,32767);
power_shift--;
temp = add(power_shift,15);
}
long_accumulator = L_shr_nocheck(long_accumulator,1);
/* 28963 corresponds to square root of 2 times REGION_SIZE(20). */
acca = L_sub(long_accumulator,28963);
test();
if (acca >= 0)
power_shift = add(power_shift,1);
acca = L_deposit_l(mag_shift);
acca = L_shl_nocheck(acca,1);
acca = L_sub(power_shift,acca);
acca = L_add(35,acca);
acca = L_sub(acca,REGION_POWER_TABLE_NUM_NEGATIVES);
absolute_region_power_index[region] = extract_l(acca);
}
/* Before we differentially encode the quantized region powers, adjust upward the
valleys to make sure all the peaks can be accurately represented. */
temp = sub(number_of_regions,2);
for (region = temp; region >= 0; region--)
{
temp1 = sub(absolute_region_power_index[region+1],DRP_DIFF_MAX);
temp2 = sub(absolute_region_power_index[region],temp1);
test();
if (temp2 < 0)
{
absolute_region_power_index[region] = temp1;
move16();
}
}
/* The MLT is currently scaled too low by the factor
ENCODER_SCALE_FACTOR(=18318)/32768 * (1./sqrt(160).
This is the ninth power of 1 over the square root of 2.
So later we will add ESF_ADJUSTMENT_TO_RMS_INDEX (now 9)
to drp_code_bits[0]. */
/* drp_code_bits[0] can range from 1 to 31. 0 will be used only as an escape sequence. */
temp1 = sub(1,ESF_ADJUSTMENT_TO_RMS_INDEX);
temp2 = sub(absolute_region_power_index[0],temp1);
test();
if (temp2 < 0)
{
absolute_region_power_index[0] = temp1;
move16();
}
temp1 = sub(31,ESF_ADJUSTMENT_TO_RMS_INDEX);
/*
* The next line was corrected in Release 1.2
*/
temp2 = sub(absolute_region_power_index[0], temp1);
test();
if (temp2 > 0)
{
absolute_region_power_index[0] = temp1;
move16();
}
differential_region_power_index[0] = absolute_region_power_index[0];
move16();
number_of_bits = 5;
move16();
drp_num_bits[0] = 5;
move16();
drp_code_bits[0] = (UWord16)add(absolute_region_power_index[0],ESF_ADJUSTMENT_TO_RMS_INDEX);
move16();
/* Lower limit the absolute region power indices to -8 and upper limit them to 31. Such extremes
may be mathematically impossible anyway.*/
for (region=1; region<number_of_regions; region++)
{
temp1 = sub(-8,ESF_ADJUSTMENT_TO_RMS_INDEX);
temp2 = sub(absolute_region_power_index[region],temp1);
test();
if (temp2 < 0)
{
absolute_region_power_index[region] = temp1;
move16();
}
temp1 = sub(31,ESF_ADJUSTMENT_TO_RMS_INDEX);
temp2 = sub(absolute_region_power_index[region],temp1);
test();
if (temp2 > 0)
{
absolute_region_power_index[region] = temp1;
move16();
}
}
for (region=1; region<number_of_regions; region++)
{
j = sub(absolute_region_power_index[region],absolute_region_power_index[region-1]);
temp = sub(j,DRP_DIFF_MIN);
test();
if (temp < 0)
{
j = DRP_DIFF_MIN;
}
j = sub(j,DRP_DIFF_MIN);
move16();
differential_region_power_index[region] = j;
move16();
temp = add(absolute_region_power_index[region-1],differential_region_power_index[region]);
temp = add(temp,DRP_DIFF_MIN);
absolute_region_power_index[region] = temp;
move16();
number_of_bits = add(number_of_bits,differential_region_power_bits[region][j]);
drp_num_bits[region] = differential_region_power_bits[region][j];
move16();
drp_code_bits[region] = differential_region_power_codes[region][j];
move16();
}
return (number_of_bits);
}
/***************************************************************************
Function: vector_quantize_mlts
Syntax: void vector_quantize_mlts(number_of_available_bits,
number_of_regions,
num_categorization_control_possibilities,
mlt_coefs,
absolute_region_power_index,
power_categories,
category_balances,
p_categorization_control,
region_mlt_bit_counts,
region_mlt_bits)
Word16 number_of_available_bits;
Word16 number_of_regions;
Word16 num_categorization_control_possibilities;
Word16 mlt_coefs[DCT_LENGTH];
Word16 absolute_region_power_index[MAX_NUMBER_OF_REGIONS];
Word16 power_categories[MAX_NUMBER_OF_REGIONS];
Word16 category_balances[MAX_NUM_CATEGORIZATION_CONTROL_POSSIBILITIES-1];
Word16 *p_categorization_control;
Word16 region_mlt_bit_counts[MAX_NUMBER_OF_REGIONS];
Word32 region_mlt_bits[4*MAX_NUMBER_OF_REGIONS];
Description: Scalar quantized vector Huffman coding (SQVH)
WMOPS: 7kHz | 24kbit | 32kbit
-------|--------------|----------------
AVG | 0.57 | 0.65
-------|--------------|----------------
MAX | 0.78 | 0.83
-------|--------------|----------------
14kHz | 24kbit | 32kbit | 48kbit
-------|--------------|----------------|----------------
AVG | 0.62 | 0.90 | 1.11
-------|--------------|----------------|----------------
MAX | 1.16 | 1.39 | 1.54
-------|--------------|----------------|----------------
***************************************************************************/
void vector_quantize_mlts(Word16 number_of_available_bits,
Word16 number_of_regions,
Word16 num_categorization_control_possibilities,
Word16 *mlt_coefs,
Word16 *absolute_region_power_index,
Word16 *power_categories,
Word16 *category_balances,
Word16 *p_categorization_control,
Word16 *region_mlt_bit_counts,
UWord32 *region_mlt_bits)
{
Word16 *raw_mlt_ptr;
Word16 region;
Word16 category;
Word16 total_mlt_bits = 0;
Word16 temp;
Word16 temp1;
Word16 temp2;
/* Start in the middle of the categorization control range. */
temp = shr_nocheck(num_categorization_control_possibilities,1);
temp = sub(temp,1);
for (*p_categorization_control = 0; *p_categorization_control < temp; (*p_categorization_control)++)
{
region = category_balances[*p_categorization_control];
move16();
power_categories[region] = add(power_categories[region],1);
move16();
}
for (region=0; region<number_of_regions; region++)
{
category = power_categories[region];
move16();
temp = extract_l(L_mult0(region,REGION_SIZE));
raw_mlt_ptr = &mlt_coefs[temp];
move16();
temp = sub(category,(NUM_CATEGORIES-1));
test();
if (temp < 0)
{
region_mlt_bit_counts[region] =
vector_huffman(category, absolute_region_power_index[region],raw_mlt_ptr,
&region_mlt_bits[shl_nocheck(region,2)]);
}
else
{
region_mlt_bit_counts[region] = 0;
move16();
}
total_mlt_bits = add(total_mlt_bits,region_mlt_bit_counts[region]);
}
/* If too few bits... */
temp = sub(total_mlt_bits,number_of_available_bits);
test();
test();
logic16();
while ((temp < 0) && (*p_categorization_control > 0))
{
test();
test();
logic16();
(*p_categorization_control)--;
region = category_balances[*p_categorization_control];
move16();
power_categories[region] = sub(power_categories[region],1);
move16();
total_mlt_bits = sub(total_mlt_bits,region_mlt_bit_counts[region]);
category = power_categories[region];
move16();
raw_mlt_ptr = &mlt_coefs[region*REGION_SIZE];
move16();
temp = sub(category,(NUM_CATEGORIES-1));
test();
if (temp < 0)
{
region_mlt_bit_counts[region] =
vector_huffman(category, absolute_region_power_index[region],raw_mlt_ptr,
&region_mlt_bits[shl_nocheck(region,2)]);
}
else
{
region_mlt_bit_counts[region] = 0;
move16();
}
total_mlt_bits = add(total_mlt_bits,region_mlt_bit_counts[region]);
temp = sub(total_mlt_bits,number_of_available_bits);
}
/* If too many bits... */
/* Set up for while loop test */
temp1 = sub(total_mlt_bits,number_of_available_bits);
temp2 = sub(*p_categorization_control,sub(num_categorization_control_possibilities,1));
test();
test();
logic16();
while ((temp1 > 0) && (temp2 < 0))
{
/* operations for while contitions */
test();
test();
logic16();
region = category_balances[*p_categorization_control];
move16();
power_categories[region] = add(power_categories[region],1);
move16();
total_mlt_bits = sub(total_mlt_bits,region_mlt_bit_counts[region]);
category = power_categories[region];
move16();
temp = extract_l(L_mult0(region,REGION_SIZE));
raw_mlt_ptr = &mlt_coefs[temp];
move16();
temp = sub(category,(NUM_CATEGORIES-1));
test();
if (temp < 0)
{
region_mlt_bit_counts[region] =
vector_huffman(category, absolute_region_power_index[region],raw_mlt_ptr,
&region_mlt_bits[shl_nocheck(region,2)]);
}
else
{
region_mlt_bit_counts[region] = 0;
move16();
}
total_mlt_bits = add(total_mlt_bits,region_mlt_bit_counts[region]);
(*p_categorization_control)++;
temp1 = sub(total_mlt_bits,number_of_available_bits);
temp2 = sub(*p_categorization_control,sub(num_categorization_control_possibilities,1));
}
}
/***************************************************************************
Function: vector_huffman
Syntax: Word16 vector_huffman(Word16 category,
Word16 power_index,
Word16 *raw_mlt_ptr,
UWord32 *word_ptr)
inputs: Word16 category
Word16 power_index
Word16 *raw_mlt_ptr
outputs: number_of_region_bits
*word_ptr
Description: Huffman encoding for each region based on category and power_index
WMOPS: 7kHz | 24kbit | 32kbit
-------|--------------|----------------
AVG | 0.03 | 0.03
-------|--------------|----------------
MAX | 0.04 | 0.04
-------|--------------|----------------
14kHz | 24kbit | 32kbit | 48kbit
-------|--------------|----------------|----------------
AVG | 0.03 | 0.03 | 0.03
-------|--------------|----------------|----------------
MAX | 0.04 | 0.04 | 0.04
-------|--------------|----------------|----------------
***************************************************************************/
Word16 vector_huffman(Word16 category,
Word16 power_index,
Word16 *raw_mlt_ptr,
UWord32 *word_ptr)
{
Word16 inv_of_step_size_times_std_dev;
Word16 j,n;
Word16 k;
Word16 number_of_region_bits;
Word16 number_of_non_zero;
Word16 vec_dim;
Word16 num_vecs;
Word16 kmax, kmax_plus_one;
Word16 index,signs_index;
Word16 *bitcount_table_ptr;
UWord16 *code_table_ptr;
Word32 code_bits;
Word16 number_of_code_bits;
UWord32 current_word;
Word16 current_word_bits_free;
Word32 acca;
Word32 accb;
Word16 temp;
Word16 mytemp; /* new variable in Release 1.2 */
Word16 myacca; /* new variable in Release 1.2 */
/* initialize variables */
vec_dim = vector_dimension[category];
move16();
num_vecs = number_of_vectors[category];
move16();
kmax = max_bin[category];
move16();
kmax_plus_one = add(kmax,1);
move16();
current_word = 0L;
move16();
current_word_bits_free = 32;
move16();
number_of_region_bits = 0;
move16();
/* set up table pointers */
bitcount_table_ptr = (Word16 *)table_of_bitcount_tables[category];
code_table_ptr = (UWord16 *) table_of_code_tables[category];
/* compute inverse of step size * standard deviation */
acca = L_mult(step_size_inverse_table[category],standard_deviation_inverse_table[power_index]);
acca = L_shr_nocheck(acca,1);
acca = L_add(acca,4096);
acca = L_shr_nocheck(acca,13);
/*
* The next two lines are new to Release 1.2
*/
mytemp = (Word16)(acca & 0x3);
acca = L_shr_nocheck(acca,2);
inv_of_step_size_times_std_dev = extract_l(acca);
for (n=0; n<num_vecs; n++)
{
index = 0;
move16();
signs_index = 0;
move16();
number_of_non_zero = 0;
move16();
for (j=0; j<vec_dim; j++)
{
k = abs_s(*raw_mlt_ptr);
acca = L_mult(k,inv_of_step_size_times_std_dev);
acca = L_shr_nocheck(acca,1);
/*
* The next four lines are new to Release 1.2
*/
myacca = (Word16)L_mult(k,mytemp);
myacca = (Word16)L_shr_nocheck(myacca,1);
myacca = (Word16)L_add(myacca,int_dead_zone_low_bits[category]);
myacca = (Word16)L_shr_nocheck(myacca,2);
acca = L_add(acca,int_dead_zone[category]);
/*
* The next two lines are new to Release 1.2
*/
acca = L_add(acca,myacca);
acca = L_shr_nocheck(acca,13);
k = extract_l(acca);
test();
if (k != 0)
{
number_of_non_zero = add(number_of_non_zero,1);
signs_index = shl_nocheck(signs_index,1);
test();
if (*raw_mlt_ptr > 0)
{
signs_index = add(signs_index,1);
}
temp = sub(k,kmax);
test();
if (temp > 0)
{
k = kmax;
move16();
}
}
acca = L_shr_nocheck(L_mult(index,(kmax_plus_one)),1);
index = extract_l(acca);
index = add(index,k);
raw_mlt_ptr++;
}
code_bits = *(code_table_ptr+index);
number_of_code_bits = add((*(bitcount_table_ptr+index)),number_of_non_zero);
number_of_region_bits = add(number_of_region_bits,number_of_code_bits);
acca = code_bits << number_of_non_zero;
accb = L_deposit_l(signs_index);
acca = L_add(acca,accb);
code_bits = acca;
move32();
/* msb of codebits is transmitted first. */
j = sub(current_word_bits_free,number_of_code_bits);
test();
if (j >= 0)
{
test();
acca = code_bits << j;
current_word = L_add(current_word,acca);
current_word_bits_free = j;
move16();
}
else
{
j = negate(j);
acca = L_shr_nocheck(code_bits,j);
current_word = L_add(current_word,acca);
*word_ptr++ = current_word;
move16();
current_word_bits_free = sub(32,j);
test();
current_word = code_bits << current_word_bits_free;
}
}
*word_ptr++ = current_word;
move16();
return (number_of_region_bits);
}