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.
		
		
		
		
		
			
		
			
				
					
					
						
							231 lines
						
					
					
						
							6.6 KiB
						
					
					
				
			
		
		
	
	
							231 lines
						
					
					
						
							6.6 KiB
						
					
					
				| 
 | |
| 
 | |
|    /******************************************************************
 | |
| 
 | |
|        iLBC Speech Coder ANSI-C Source Code
 | |
| 
 | |
|        createCB.c
 | |
| 
 | |
|        Copyright (C) The Internet Society (2004).
 | |
|        All Rights Reserved.
 | |
| 
 | |
|    ******************************************************************/
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
|    #include "iLBC_define.h"
 | |
|    #include "constants.h"
 | |
|    #include <string.h>
 | |
|    #include <math.h>
 | |
| 
 | |
|    /*----------------------------------------------------------------*
 | |
|     *  Construct an additional codebook vector by filtering the
 | |
|     *  initial codebook buffer. This vector is then used to expand
 | |
|     *  the codebook with an additional section.
 | |
|     *---------------------------------------------------------------*/
 | |
| 
 | |
|    void filteredCBvecs(
 | |
|        float *cbvectors,   /* (o) Codebook vectors for the
 | |
|                                   higher section */
 | |
|        float *mem,         /* (i) Buffer to create codebook
 | |
|                                   vector from */
 | |
|        int lMem        /* (i) Length of buffer */
 | |
|    ){
 | |
|        int j, k;
 | |
|        float *pp, *pp1;
 | |
|        float tempbuff2[CB_MEML+CB_FILTERLEN];
 | |
|        float *pos;
 | |
| 
 | |
|        memset(tempbuff2, 0, (CB_HALFFILTERLEN-1)*sizeof(float));
 | |
|        memcpy(&tempbuff2[CB_HALFFILTERLEN-1], mem, lMem*sizeof(float));
 | |
|        memset(&tempbuff2[lMem+CB_HALFFILTERLEN-1], 0,
 | |
|            (CB_HALFFILTERLEN+1)*sizeof(float));
 | |
| 
 | |
|        /* Create codebook vector for higher section by filtering */
 | |
| 
 | |
|        /* do filtering */
 | |
|        pos=cbvectors;
 | |
|        memset(pos, 0, lMem*sizeof(float));
 | |
|        for (k=0; k<lMem; k++) {
 | |
|            pp=&tempbuff2[k];
 | |
|            pp1=&cbfiltersTbl[CB_FILTERLEN-1];
 | |
|            for (j=0;j<CB_FILTERLEN;j++) {
 | |
|                (*pos)+=(*pp++)*(*pp1--);
 | |
|            }
 | |
|            pos++;
 | |
|        }
 | |
|    }
 | |
| 
 | |
|    /*----------------------------------------------------------------*
 | |
|     *  Search the augmented part of the codebook to find the best
 | |
|     *  measure.
 | |
|     *----------------------------------------------------------------*/
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
|    void searchAugmentedCB(
 | |
|        int low,        /* (i) Start index for the search */
 | |
|        int high,           /* (i) End index for the search */
 | |
|        int stage,          /* (i) Current stage */
 | |
|        int startIndex,     /* (i) Codebook index for the first
 | |
|                                   aug vector */
 | |
|        float *target,      /* (i) Target vector for encoding */
 | |
|        float *buffer,      /* (i) Pointer to the end of the buffer for
 | |
|                                   augmented codebook construction */
 | |
|        float *max_measure, /* (i/o) Currently maximum measure */
 | |
|        int *best_index,/* (o) Currently the best index */
 | |
|        float *gain,    /* (o) Currently the best gain */
 | |
|        float *energy,      /* (o) Energy of augmented codebook
 | |
|                                   vectors */
 | |
|        float *invenergy/* (o) Inv energy of augmented codebook
 | |
|                                   vectors */
 | |
|    ) {
 | |
|        int icount, ilow, j, tmpIndex;
 | |
|        float *pp, *ppo, *ppi, *ppe, crossDot, alfa;
 | |
|        float weighted, measure, nrjRecursive;
 | |
|        float ftmp;
 | |
| 
 | |
|        /* Compute the energy for the first (low-5)
 | |
|           noninterpolated samples */
 | |
|        nrjRecursive = (float) 0.0;
 | |
|        pp = buffer - low + 1;
 | |
|        for (j=0; j<(low-5); j++) {
 | |
|            nrjRecursive += ( (*pp)*(*pp) );
 | |
|            pp++;
 | |
|        }
 | |
|        ppe = buffer - low;
 | |
| 
 | |
| 
 | |
|        for (icount=low; icount<=high; icount++) {
 | |
| 
 | |
|            /* Index of the codebook vector used for retrieving
 | |
|               energy values */
 | |
|            tmpIndex = startIndex+icount-20;
 | |
| 
 | |
|            ilow = icount-4;
 | |
| 
 | |
|            /* Update the energy recursively to save complexity */
 | |
|            nrjRecursive = nrjRecursive + (*ppe)*(*ppe);
 | |
|            ppe--;
 | |
|            energy[tmpIndex] = nrjRecursive;
 | |
| 
 | |
|            /* Compute cross dot product for the first (low-5)
 | |
|               samples */
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
|            crossDot = (float) 0.0;
 | |
|            pp = buffer-icount;
 | |
|            for (j=0; j<ilow; j++) {
 | |
|                crossDot += target[j]*(*pp++);
 | |
|            }
 | |
| 
 | |
|            /* interpolation */
 | |
|            alfa = (float) 0.2;
 | |
|            ppo = buffer-4;
 | |
|            ppi = buffer-icount-4;
 | |
|            for (j=ilow; j<icount; j++) {
 | |
|                weighted = ((float)1.0-alfa)*(*ppo)+alfa*(*ppi);
 | |
|                ppo++;
 | |
|                ppi++;
 | |
|                energy[tmpIndex] += weighted*weighted;
 | |
|                crossDot += target[j]*weighted;
 | |
|                alfa += (float)0.2;
 | |
|            }
 | |
| 
 | |
|            /* Compute energy and cross dot product for the
 | |
|               remaining samples */
 | |
|            pp = buffer - icount;
 | |
|            for (j=icount; j<SUBL; j++) {
 | |
|                energy[tmpIndex] += (*pp)*(*pp);
 | |
|                crossDot += target[j]*(*pp++);
 | |
|            }
 | |
| 
 | |
|            if (energy[tmpIndex]>0.0) {
 | |
|                invenergy[tmpIndex]=(float)1.0/(energy[tmpIndex]+EPS);
 | |
|            } else {
 | |
|                invenergy[tmpIndex] = (float) 0.0;
 | |
|            }
 | |
| 
 | |
|            if (stage==0) {
 | |
|                measure = (float)-10000000.0;
 | |
| 
 | |
|                if (crossDot > 0.0) {
 | |
|                    measure = crossDot*crossDot*invenergy[tmpIndex];
 | |
|                }
 | |
|            }
 | |
|            else {
 | |
|                measure = crossDot*crossDot*invenergy[tmpIndex];
 | |
|            }
 | |
| 
 | |
|            /* check if measure is better */
 | |
|            ftmp = crossDot*invenergy[tmpIndex];
 | |
| 
 | |
|            if ((measure>*max_measure) && (fabs(ftmp)<CB_MAXGAIN)) {
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
|                *best_index = tmpIndex;
 | |
|                *max_measure = measure;
 | |
|                *gain = ftmp;
 | |
|            }
 | |
|        }
 | |
|    }
 | |
| 
 | |
| 
 | |
|    /*----------------------------------------------------------------*
 | |
|     *  Recreate a specific codebook vector from the augmented part.
 | |
|     *
 | |
|     *----------------------------------------------------------------*/
 | |
| 
 | |
|    void createAugmentedVec(
 | |
|        int index,      /* (i) Index for the augmented vector
 | |
|                               to be created */
 | |
|        float *buffer,  /* (i) Pointer to the end of the buffer for
 | |
|                               augmented codebook construction */
 | |
|        float *cbVec/* (o) The constructed codebook vector */
 | |
|    ) {
 | |
|        int ilow, j;
 | |
|        float *pp, *ppo, *ppi, alfa, alfa1, weighted;
 | |
| 
 | |
|        ilow = index-5;
 | |
| 
 | |
|        /* copy the first noninterpolated part */
 | |
| 
 | |
|        pp = buffer-index;
 | |
|        memcpy(cbVec,pp,sizeof(float)*index);
 | |
| 
 | |
|        /* interpolation */
 | |
| 
 | |
|        alfa1 = (float)0.2;
 | |
|        alfa = 0.0;
 | |
|        ppo = buffer-5;
 | |
|        ppi = buffer-index-5;
 | |
|        for (j=ilow; j<index; j++) {
 | |
|            weighted = ((float)1.0-alfa)*(*ppo)+alfa*(*ppi);
 | |
|            ppo++;
 | |
|            ppi++;
 | |
|            cbVec[j] = weighted;
 | |
|            alfa += alfa1;
 | |
|        }
 | |
| 
 | |
|        /* copy the second noninterpolated part */
 | |
| 
 | |
|        pp = buffer - index;
 | |
|        memcpy(cbVec+index,pp,sizeof(float)*(SUBL-index));
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
|    }
 |