Alexandre Lision | 8af73cb | 2013-12-10 14:11:20 -0500 | [diff] [blame] | 1 | |
| 2 | |
| 3 | /****************************************************************** |
| 4 | |
| 5 | iLBC Speech Coder ANSI-C Source Code |
| 6 | |
| 7 | createCB.c |
| 8 | |
| 9 | Copyright (C) The Internet Society (2004). |
| 10 | All Rights Reserved. |
| 11 | |
| 12 | ******************************************************************/ |
| 13 | |
| 14 | |
| 15 | |
| 16 | |
| 17 | |
| 18 | #include "iLBC_define.h" |
| 19 | #include "constants.h" |
| 20 | #include <string.h> |
| 21 | #include <math.h> |
| 22 | |
| 23 | /*----------------------------------------------------------------* |
| 24 | * Construct an additional codebook vector by filtering the |
| 25 | * initial codebook buffer. This vector is then used to expand |
| 26 | * the codebook with an additional section. |
| 27 | *---------------------------------------------------------------*/ |
| 28 | |
| 29 | void filteredCBvecs( |
| 30 | float *cbvectors, /* (o) Codebook vectors for the |
| 31 | higher section */ |
| 32 | float *mem, /* (i) Buffer to create codebook |
| 33 | vector from */ |
| 34 | int lMem /* (i) Length of buffer */ |
| 35 | ){ |
| 36 | int j, k; |
| 37 | float *pp, *pp1; |
| 38 | float tempbuff2[CB_MEML+CB_FILTERLEN]; |
| 39 | float *pos; |
| 40 | |
| 41 | memset(tempbuff2, 0, (CB_HALFFILTERLEN-1)*sizeof(float)); |
| 42 | memcpy(&tempbuff2[CB_HALFFILTERLEN-1], mem, lMem*sizeof(float)); |
| 43 | memset(&tempbuff2[lMem+CB_HALFFILTERLEN-1], 0, |
| 44 | (CB_HALFFILTERLEN+1)*sizeof(float)); |
| 45 | |
| 46 | /* Create codebook vector for higher section by filtering */ |
| 47 | |
| 48 | /* do filtering */ |
| 49 | pos=cbvectors; |
| 50 | memset(pos, 0, lMem*sizeof(float)); |
| 51 | for (k=0; k<lMem; k++) { |
| 52 | pp=&tempbuff2[k]; |
| 53 | pp1=&cbfiltersTbl[CB_FILTERLEN-1]; |
| 54 | for (j=0;j<CB_FILTERLEN;j++) { |
| 55 | (*pos)+=(*pp++)*(*pp1--); |
| 56 | } |
| 57 | pos++; |
| 58 | } |
| 59 | } |
| 60 | |
| 61 | /*----------------------------------------------------------------* |
| 62 | * Search the augmented part of the codebook to find the best |
| 63 | * measure. |
| 64 | *----------------------------------------------------------------*/ |
| 65 | |
| 66 | |
| 67 | |
| 68 | |
| 69 | |
| 70 | |
| 71 | void searchAugmentedCB( |
| 72 | int low, /* (i) Start index for the search */ |
| 73 | int high, /* (i) End index for the search */ |
| 74 | int stage, /* (i) Current stage */ |
| 75 | int startIndex, /* (i) Codebook index for the first |
| 76 | aug vector */ |
| 77 | float *target, /* (i) Target vector for encoding */ |
| 78 | float *buffer, /* (i) Pointer to the end of the buffer for |
| 79 | augmented codebook construction */ |
| 80 | float *max_measure, /* (i/o) Currently maximum measure */ |
| 81 | int *best_index,/* (o) Currently the best index */ |
| 82 | float *gain, /* (o) Currently the best gain */ |
| 83 | float *energy, /* (o) Energy of augmented codebook |
| 84 | vectors */ |
| 85 | float *invenergy/* (o) Inv energy of augmented codebook |
| 86 | vectors */ |
| 87 | ) { |
| 88 | int icount, ilow, j, tmpIndex; |
| 89 | float *pp, *ppo, *ppi, *ppe, crossDot, alfa; |
| 90 | float weighted, measure, nrjRecursive; |
| 91 | float ftmp; |
| 92 | |
| 93 | /* Compute the energy for the first (low-5) |
| 94 | noninterpolated samples */ |
| 95 | nrjRecursive = (float) 0.0; |
| 96 | pp = buffer - low + 1; |
| 97 | for (j=0; j<(low-5); j++) { |
| 98 | nrjRecursive += ( (*pp)*(*pp) ); |
| 99 | pp++; |
| 100 | } |
| 101 | ppe = buffer - low; |
| 102 | |
| 103 | |
| 104 | for (icount=low; icount<=high; icount++) { |
| 105 | |
| 106 | /* Index of the codebook vector used for retrieving |
| 107 | energy values */ |
| 108 | tmpIndex = startIndex+icount-20; |
| 109 | |
| 110 | ilow = icount-4; |
| 111 | |
| 112 | /* Update the energy recursively to save complexity */ |
| 113 | nrjRecursive = nrjRecursive + (*ppe)*(*ppe); |
| 114 | ppe--; |
| 115 | energy[tmpIndex] = nrjRecursive; |
| 116 | |
| 117 | /* Compute cross dot product for the first (low-5) |
| 118 | samples */ |
| 119 | |
| 120 | |
| 121 | |
| 122 | |
| 123 | |
| 124 | crossDot = (float) 0.0; |
| 125 | pp = buffer-icount; |
| 126 | for (j=0; j<ilow; j++) { |
| 127 | crossDot += target[j]*(*pp++); |
| 128 | } |
| 129 | |
| 130 | /* interpolation */ |
| 131 | alfa = (float) 0.2; |
| 132 | ppo = buffer-4; |
| 133 | ppi = buffer-icount-4; |
| 134 | for (j=ilow; j<icount; j++) { |
| 135 | weighted = ((float)1.0-alfa)*(*ppo)+alfa*(*ppi); |
| 136 | ppo++; |
| 137 | ppi++; |
| 138 | energy[tmpIndex] += weighted*weighted; |
| 139 | crossDot += target[j]*weighted; |
| 140 | alfa += (float)0.2; |
| 141 | } |
| 142 | |
| 143 | /* Compute energy and cross dot product for the |
| 144 | remaining samples */ |
| 145 | pp = buffer - icount; |
| 146 | for (j=icount; j<SUBL; j++) { |
| 147 | energy[tmpIndex] += (*pp)*(*pp); |
| 148 | crossDot += target[j]*(*pp++); |
| 149 | } |
| 150 | |
| 151 | if (energy[tmpIndex]>0.0) { |
| 152 | invenergy[tmpIndex]=(float)1.0/(energy[tmpIndex]+EPS); |
| 153 | } else { |
| 154 | invenergy[tmpIndex] = (float) 0.0; |
| 155 | } |
| 156 | |
| 157 | if (stage==0) { |
| 158 | measure = (float)-10000000.0; |
| 159 | |
| 160 | if (crossDot > 0.0) { |
| 161 | measure = crossDot*crossDot*invenergy[tmpIndex]; |
| 162 | } |
| 163 | } |
| 164 | else { |
| 165 | measure = crossDot*crossDot*invenergy[tmpIndex]; |
| 166 | } |
| 167 | |
| 168 | /* check if measure is better */ |
| 169 | ftmp = crossDot*invenergy[tmpIndex]; |
| 170 | |
| 171 | if ((measure>*max_measure) && (fabs(ftmp)<CB_MAXGAIN)) { |
| 172 | |
| 173 | |
| 174 | |
| 175 | |
| 176 | |
| 177 | *best_index = tmpIndex; |
| 178 | *max_measure = measure; |
| 179 | *gain = ftmp; |
| 180 | } |
| 181 | } |
| 182 | } |
| 183 | |
| 184 | |
| 185 | /*----------------------------------------------------------------* |
| 186 | * Recreate a specific codebook vector from the augmented part. |
| 187 | * |
| 188 | *----------------------------------------------------------------*/ |
| 189 | |
| 190 | void createAugmentedVec( |
| 191 | int index, /* (i) Index for the augmented vector |
| 192 | to be created */ |
| 193 | float *buffer, /* (i) Pointer to the end of the buffer for |
| 194 | augmented codebook construction */ |
| 195 | float *cbVec/* (o) The construced codebook vector */ |
| 196 | ) { |
| 197 | int ilow, j; |
| 198 | float *pp, *ppo, *ppi, alfa, alfa1, weighted; |
| 199 | |
| 200 | ilow = index-5; |
| 201 | |
| 202 | /* copy the first noninterpolated part */ |
| 203 | |
| 204 | pp = buffer-index; |
| 205 | memcpy(cbVec,pp,sizeof(float)*index); |
| 206 | |
| 207 | /* interpolation */ |
| 208 | |
| 209 | alfa1 = (float)0.2; |
| 210 | alfa = 0.0; |
| 211 | ppo = buffer-5; |
| 212 | ppi = buffer-index-5; |
| 213 | for (j=ilow; j<index; j++) { |
| 214 | weighted = ((float)1.0-alfa)*(*ppo)+alfa*(*ppi); |
| 215 | ppo++; |
| 216 | ppi++; |
| 217 | cbVec[j] = weighted; |
| 218 | alfa += alfa1; |
| 219 | } |
| 220 | |
| 221 | /* copy the second noninterpolated part */ |
| 222 | |
| 223 | pp = buffer - index; |
| 224 | memcpy(cbVec+index,pp,sizeof(float)*(SUBL-index)); |
| 225 | |
| 226 | |
| 227 | |
| 228 | |
| 229 | |
| 230 | } |
| 231 | |