www.pudn.com > T-REC-G.722.1-200505-I!!SOFT-ZST-E.zip > sam2coef.c


/************************************************************************************ 
************************************************************************************* 
** 
**   ITU-T 7/14kHz Audio Coder Candidate (G.722.1 Annex C) Source Code 
** 
**   © 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(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	*new_ptr, *old_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(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 = 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 = 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 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(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 0)  
    {
        for(index=0;index