1125 lines
38 KiB
C
1125 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 = ®ion_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,
|
|
®ion_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,
|
|
®ion_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,
|
|
®ion_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);
|
|
}
|
|
|
|
|