mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-11-03 20:38:59 +00:00 
			
		
		
		
	git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@7221 65c4cc65-6c06-0410-ace0-fbb531ad65f3
		
			
				
	
	
		
			153 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			153 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
 | 
						|
/******************************************************************
 | 
						|
 | 
						|
    iLBC Speech Coder ANSI-C Source Code
 | 
						|
 | 
						|
    LPC_decode.c 
 | 
						|
 | 
						|
    Copyright (C) The Internet Society (2004). 
 | 
						|
    All Rights Reserved.
 | 
						|
 | 
						|
******************************************************************/
 | 
						|
 | 
						|
#include <math.h>
 | 
						|
#include <string.h>
 | 
						|
 | 
						|
#include "helpfun.h"
 | 
						|
#include "lsf.h"
 | 
						|
#include "iLBC_define.h"
 | 
						|
#include "LPCdecode.h"
 | 
						|
#include "constants.h"
 | 
						|
 | 
						|
/*---------------------------------------------------------------*
 | 
						|
 *  interpolation of lsf coefficients for the decoder
 | 
						|
 *--------------------------------------------------------------*/
 | 
						|
 | 
						|
void LSFinterpolate2a_dec( 
 | 
						|
    float *a,           /* (o) lpc coefficients for a sub-frame */
 | 
						|
    float *lsf1,    /* (i) first lsf coefficient vector */
 | 
						|
 | 
						|
 | 
						|
    float *lsf2,    /* (i) second lsf coefficient vector */
 | 
						|
    float coef,         /* (i) interpolation weight */
 | 
						|
    int length          /* (i) length of lsf vectors */
 | 
						|
){
 | 
						|
    float  lsftmp[LPC_FILTERORDER];
 | 
						|
    
 | 
						|
    interpolate(lsftmp, lsf1, lsf2, coef, length);
 | 
						|
    lsf2a(a, lsftmp);
 | 
						|
}
 | 
						|
 | 
						|
/*---------------------------------------------------------------*
 | 
						|
 *  obtain dequantized lsf coefficients from quantization index 
 | 
						|
 *--------------------------------------------------------------*/
 | 
						|
 | 
						|
void SimplelsfDEQ(
 | 
						|
    float *lsfdeq,    /* (o) dequantized lsf coefficients */
 | 
						|
    int *index,         /* (i) quantization index */
 | 
						|
    int lpc_n           /* (i) number of LPCs */
 | 
						|
){  
 | 
						|
    int i, j, pos, cb_pos;
 | 
						|
 | 
						|
    /* decode first LSF */
 | 
						|
    
 | 
						|
    pos = 0;
 | 
						|
    cb_pos = 0;
 | 
						|
    for (i = 0; i < LSF_NSPLIT; i++) {
 | 
						|
        for (j = 0; j < dim_lsfCbTbl[i]; j++) {
 | 
						|
            lsfdeq[pos + j] = lsfCbTbl[cb_pos + 
 | 
						|
                (long)(index[i])*dim_lsfCbTbl[i] + j];
 | 
						|
        }       
 | 
						|
        pos += dim_lsfCbTbl[i];
 | 
						|
        cb_pos += size_lsfCbTbl[i]*dim_lsfCbTbl[i];
 | 
						|
    }
 | 
						|
 | 
						|
    if (lpc_n>1) {
 | 
						|
 | 
						|
        /* decode last LSF */
 | 
						|
 | 
						|
        pos = 0;
 | 
						|
        cb_pos = 0;
 | 
						|
        for (i = 0; i < LSF_NSPLIT; i++) {
 | 
						|
            for (j = 0; j < dim_lsfCbTbl[i]; j++) {
 | 
						|
                lsfdeq[LPC_FILTERORDER + pos + j] = 
 | 
						|
                    lsfCbTbl[cb_pos + 
 | 
						|
                    (long)(index[LSF_NSPLIT + i])*
 | 
						|
                    dim_lsfCbTbl[i] + j];
 | 
						|
            }       
 | 
						|
            pos += dim_lsfCbTbl[i];
 | 
						|
            cb_pos += size_lsfCbTbl[i]*dim_lsfCbTbl[i];
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/*----------------------------------------------------------------*
 | 
						|
 | 
						|
 | 
						|
 *  obtain synthesis and weighting filters form lsf coefficients 
 | 
						|
 *---------------------------------------------------------------*/
 | 
						|
 | 
						|
void DecoderInterpolateLSF( 
 | 
						|
    float *syntdenum, /* (o) synthesis filter coefficients */
 | 
						|
    float *weightdenum, /* (o) weighting denumerator 
 | 
						|
                               coefficients */
 | 
						|
    float *lsfdeq,       /* (i) dequantized lsf coefficients */
 | 
						|
    int length,         /* (i) length of lsf coefficient vector */
 | 
						|
    iLBC_Dec_Inst_t *iLBCdec_inst 
 | 
						|
                        /* (i) the decoder state structure */
 | 
						|
){
 | 
						|
    int    i, pos, lp_length;
 | 
						|
    float  lp[LPC_FILTERORDER + 1], *lsfdeq2;
 | 
						|
        
 | 
						|
    lsfdeq2 = lsfdeq + length;
 | 
						|
    lp_length = length + 1;
 | 
						|
    
 | 
						|
    if (iLBCdec_inst->mode==30) {
 | 
						|
        /* sub-frame 1: Interpolation between old and first */
 | 
						|
 | 
						|
        LSFinterpolate2a_dec(lp, iLBCdec_inst->lsfdeqold, lsfdeq, 
 | 
						|
            lsf_weightTbl_30ms[0], length);
 | 
						|
        memcpy(syntdenum,lp,lp_length*sizeof(float));
 | 
						|
        bwexpand(weightdenum, lp, LPC_CHIRP_WEIGHTDENUM, 
 | 
						|
            lp_length);
 | 
						|
 | 
						|
        /* sub-frames 2 to 6: interpolation between first 
 | 
						|
           and last LSF */
 | 
						|
    
 | 
						|
        pos = lp_length;
 | 
						|
        for (i = 1; i < 6; i++) {
 | 
						|
            LSFinterpolate2a_dec(lp, lsfdeq, lsfdeq2, 
 | 
						|
                lsf_weightTbl_30ms[i], length);
 | 
						|
            memcpy(syntdenum + pos,lp,lp_length*sizeof(float));
 | 
						|
            bwexpand(weightdenum + pos, lp, 
 | 
						|
                LPC_CHIRP_WEIGHTDENUM, lp_length);
 | 
						|
            pos += lp_length;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    else {
 | 
						|
        pos = 0;
 | 
						|
        for (i = 0; i < iLBCdec_inst->nsub; i++) {
 | 
						|
            LSFinterpolate2a_dec(lp, iLBCdec_inst->lsfdeqold, 
 | 
						|
                lsfdeq, lsf_weightTbl_20ms[i], length);
 | 
						|
            memcpy(syntdenum+pos,lp,lp_length*sizeof(float));
 | 
						|
            bwexpand(weightdenum+pos, lp, LPC_CHIRP_WEIGHTDENUM, 
 | 
						|
                lp_length);
 | 
						|
            pos += lp_length;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    
 | 
						|
    /* update memory */
 | 
						|
 | 
						|
 | 
						|
 | 
						|
    if (iLBCdec_inst->mode==30)
 | 
						|
        memcpy(iLBCdec_inst->lsfdeqold, lsfdeq2, 
 | 
						|
                    length*sizeof(float));
 | 
						|
    else
 | 
						|
        memcpy(iLBCdec_inst->lsfdeqold, lsfdeq, 
 | 
						|
                    length*sizeof(float));
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
 |