| 
									
										
										
										
											2012-01-18 21:06:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    /******************************************************************
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        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 */ | 
					
						
							| 
									
										
										
										
											2021-10-30 21:04:43 -04:00
										 |  |  |        float *cbVec/* (o) The constructed codebook vector */ | 
					
						
							| 
									
										
										
										
											2012-01-18 21:06:29 +00:00
										 |  |  |    ) { | 
					
						
							|  |  |  |        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)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    } |