272 lines
7.6 KiB
C
272 lines
7.6 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)
|
|||
|
**
|
|||
|
** <EFBFBD> 2004 Polycom, Inc.
|
|||
|
**
|
|||
|
** All rights reserved.
|
|||
|
**
|
|||
|
******************************************************************************/
|
|||
|
|
|||
|
/******************************************************************************
|
|||
|
* Filename: samples_to_rmlt_coefs.c
|
|||
|
*
|
|||
|
* Purpose: Convert Samples to Reversed MLT (Modulated Lapped Transform)
|
|||
|
* Coefficients
|
|||
|
*
|
|||
|
* The "Reversed MLT" is an overlapped block transform which uses
|
|||
|
* even symmetry * on the left, odd symmetry on the right and a
|
|||
|
* Type IV DCT as the block transform. * It is thus similar to a
|
|||
|
* MLT which uses odd symmetry on the left, even symmetry * on the
|
|||
|
* right and a Type IV DST as the block transform. In fact, it is
|
|||
|
* equivalent * to reversing the order of the samples, performing
|
|||
|
* an MLT and then negating all * the even-numbered coefficients.
|
|||
|
*
|
|||
|
******************************************************************************/
|
|||
|
|
|||
|
/***************************************************************************
|
|||
|
Include files
|
|||
|
***************************************************************************/
|
|||
|
#include "defs.h"
|
|||
|
#include "tables.h"
|
|||
|
#include "count.h"
|
|||
|
|
|||
|
/***************************************************************************
|
|||
|
Function: samples_to_rmlt_coefs
|
|||
|
|
|||
|
Syntax: Word16 samples_to_rmlt_coefs(new_samples,
|
|||
|
old_samples,
|
|||
|
coefs,
|
|||
|
dct_length)
|
|||
|
Word16 *new_samples;
|
|||
|
Word16 *old_samples;
|
|||
|
Word16 *coefs;
|
|||
|
Word16 dct_length;
|
|||
|
|
|||
|
Description: Convert samples to MLT coefficients
|
|||
|
|
|||
|
Design Notes:
|
|||
|
|
|||
|
WMOPS: 7kHz | 24kbit | 32kbit
|
|||
|
-------|--------------|----------------
|
|||
|
AVG | 1.40 | 1.40
|
|||
|
-------|--------------|----------------
|
|||
|
MAX | 1.40 | 1.40
|
|||
|
-------|--------------|----------------
|
|||
|
|
|||
|
14kHz | 24kbit | 32kbit | 48kbit
|
|||
|
-------|--------------|----------------|----------------
|
|||
|
AVG | 3.07 | 3.07 | 3.07
|
|||
|
-------|--------------|----------------|----------------
|
|||
|
MAX | 3.10 | 3.10 | 3.10
|
|||
|
-------|--------------|----------------|----------------
|
|||
|
|
|||
|
***************************************************************************/
|
|||
|
|
|||
|
Word16 samples_to_rmlt_coefs(const Word16 *new_samples,Word16 *old_samples,Word16 *coefs,Word16 dct_length)
|
|||
|
{
|
|||
|
|
|||
|
Word16 index, vals_left,mag_shift,n;
|
|||
|
Word16 windowed_data[MAX_DCT_LENGTH];
|
|||
|
Word16 *old_ptr;
|
|||
|
const Word16 *new_ptr, *sam_low, *sam_high;
|
|||
|
Word16 *win_low, *win_high;
|
|||
|
Word16 *dst_ptr;
|
|||
|
Word16 neg_win_low;
|
|||
|
Word16 samp_high;
|
|||
|
Word16 half_dct_size;
|
|||
|
|
|||
|
Word32 acca;
|
|||
|
Word32 accb;
|
|||
|
Word16 temp;
|
|||
|
Word16 temp1;
|
|||
|
Word16 temp2;
|
|||
|
Word16 temp5;
|
|||
|
|
|||
|
half_dct_size = shr_nocheck(dct_length,1);
|
|||
|
|
|||
|
/*++++++++++++++++++++++++++++++++++++++++++++*/
|
|||
|
/* Get the first half of the windowed samples */
|
|||
|
/*++++++++++++++++++++++++++++++++++++++++++++*/
|
|||
|
|
|||
|
dst_ptr = windowed_data;
|
|||
|
move16();
|
|||
|
|
|||
|
/* address arithmetic */
|
|||
|
test();
|
|||
|
if (dct_length==DCT_LENGTH)
|
|||
|
{
|
|||
|
win_high = samples_to_rmlt_window + half_dct_size;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
win_high = max_samples_to_rmlt_window + half_dct_size;
|
|||
|
}
|
|||
|
|
|||
|
win_low = win_high;
|
|||
|
move16();
|
|||
|
|
|||
|
/* address arithmetic */
|
|||
|
sam_high = old_samples + half_dct_size;
|
|||
|
|
|||
|
sam_low = sam_high;
|
|||
|
move16();
|
|||
|
|
|||
|
for (vals_left = half_dct_size;vals_left > 0;vals_left--)
|
|||
|
{
|
|||
|
acca = 0L;
|
|||
|
move32();
|
|||
|
|
|||
|
acca = L_mac(acca,*--win_low, *--sam_low);
|
|||
|
acca = L_mac(acca,*win_high++, *sam_high++);
|
|||
|
temp = itu_round(acca);
|
|||
|
|
|||
|
*dst_ptr++ = temp;
|
|||
|
move16();
|
|||
|
}
|
|||
|
|
|||
|
/*+++++++++++++++++++++++++++++++++++++++++++++*/
|
|||
|
/* Get the second half of the windowed samples */
|
|||
|
/*+++++++++++++++++++++++++++++++++++++++++++++*/
|
|||
|
|
|||
|
sam_low = new_samples;
|
|||
|
move16();
|
|||
|
|
|||
|
/* address arithmetic */
|
|||
|
sam_high = new_samples + dct_length;
|
|||
|
|
|||
|
for (vals_left = half_dct_size; vals_left > 0; vals_left--)
|
|||
|
{
|
|||
|
acca = 0L;
|
|||
|
move32();
|
|||
|
|
|||
|
acca = L_mac(acca,*--win_high, *sam_low++);
|
|||
|
neg_win_low = negate(*win_low++);
|
|||
|
samp_high = *--sam_high;
|
|||
|
acca = L_mac(acca, neg_win_low, samp_high);
|
|||
|
temp = itu_round(acca);
|
|||
|
|
|||
|
*dst_ptr++=temp;
|
|||
|
move16();
|
|||
|
}
|
|||
|
|
|||
|
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
|
|||
|
/* Save the new samples for next time, when they will be the old samples */
|
|||
|
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
|
|||
|
|
|||
|
new_ptr = new_samples;
|
|||
|
move16();
|
|||
|
|
|||
|
old_ptr = old_samples;
|
|||
|
move16();
|
|||
|
|
|||
|
for (vals_left = dct_length;vals_left > 0;vals_left--)
|
|||
|
{
|
|||
|
*old_ptr++ = *new_ptr++;
|
|||
|
move16();
|
|||
|
}
|
|||
|
|
|||
|
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
|
|||
|
/* Calculate how many bits to shift up the input to the DCT. */
|
|||
|
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
|
|||
|
|
|||
|
temp1=0;
|
|||
|
move16();
|
|||
|
|
|||
|
for(index=0;index<dct_length;index++)
|
|||
|
{
|
|||
|
temp2 = abs_s(windowed_data[index]);
|
|||
|
temp = sub(temp2,temp1);
|
|||
|
test();
|
|||
|
if(temp > 0)
|
|||
|
{
|
|||
|
move16();
|
|||
|
temp1 = temp2;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
mag_shift=0;
|
|||
|
move16();
|
|||
|
|
|||
|
temp = sub(temp1,14000);
|
|||
|
test();
|
|||
|
if (temp >= 0)
|
|||
|
{
|
|||
|
mag_shift = 0;
|
|||
|
move16();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
temp = sub(temp1,438);
|
|||
|
test();
|
|||
|
if(temp < 0)
|
|||
|
temp = add(temp1,1);
|
|||
|
else
|
|||
|
{
|
|||
|
temp = temp1;
|
|||
|
move16();
|
|||
|
}
|
|||
|
accb = L_mult(temp,9587);
|
|||
|
acca = L_shr_nocheck(accb,20);
|
|||
|
temp5 = extract_l(acca);
|
|||
|
temp = norm_s(temp5);
|
|||
|
test();
|
|||
|
if (temp == 0)
|
|||
|
{
|
|||
|
mag_shift = 9;
|
|||
|
move16();
|
|||
|
}
|
|||
|
else
|
|||
|
mag_shift = sub(temp,6);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
acca = 0L;
|
|||
|
move32();
|
|||
|
for(index=0; index<dct_length; index++)
|
|||
|
{
|
|||
|
temp = abs_s( windowed_data[index]);
|
|||
|
acca = L_add(acca,temp);
|
|||
|
}
|
|||
|
|
|||
|
acca = L_shr_nocheck(acca,7);
|
|||
|
|
|||
|
test();
|
|||
|
if (temp1 < acca)
|
|||
|
{
|
|||
|
mag_shift = sub(mag_shift,1);
|
|||
|
}
|
|||
|
|
|||
|
test();
|
|||
|
if (mag_shift > 0)
|
|||
|
{
|
|||
|
for(index=0;index<dct_length;index++)
|
|||
|
{
|
|||
|
windowed_data[index] = shl_nocheck(windowed_data[index],mag_shift);
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
test();
|
|||
|
if (mag_shift < 0)
|
|||
|
{
|
|||
|
n = negate(mag_shift);
|
|||
|
for(index=0;index<dct_length;index++)
|
|||
|
{
|
|||
|
windowed_data[index] = shr_nocheck(windowed_data[index],n);
|
|||
|
move16();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
|
|||
|
/* Perform a Type IV DCT on the windowed data to get the coefficients */
|
|||
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
|
|||
|
|
|||
|
dct_type_iv_a(windowed_data, coefs, dct_length);
|
|||
|
|
|||
|
return(mag_shift);
|
|||
|
}
|