/*************************************************************************** ** ** 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 #include #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= 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 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 0) { temp = extract_l(L_mult0(region,REGION_SIZE)); raw_mlt_ptr = &mlt_coefs[temp]; for (i=0; i 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 0) { absolute_region_power_index[region] = temp1; move16(); } } for (region=1; region 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 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); }