mirror of https://github.com/asterisk/asterisk
				
				
				
			
			You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							159 lines
						
					
					
						
							4.7 KiB
						
					
					
				
			
		
		
	
	
							159 lines
						
					
					
						
							4.7 KiB
						
					
					
				| 
 | |
|    /******************************************************************
 | |
| 
 | |
|        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 "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));
 | |
| 
 | |
|    }
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 |