annotate src/opus-1.3/celt/modes.c @ 83:ae30d91d2ffe

Replace these with versions built using an older toolset (so as to avoid ABI compatibilities when linking on Ubuntu 14.04 for packaging purposes)
author Chris Cannam
date Fri, 07 Feb 2020 11:51:13 +0000
parents 7aeed7906520
children
rev   line source
Chris@69 1 /* Copyright (c) 2007-2008 CSIRO
Chris@69 2 Copyright (c) 2007-2009 Xiph.Org Foundation
Chris@69 3 Copyright (c) 2008 Gregory Maxwell
Chris@69 4 Written by Jean-Marc Valin and Gregory Maxwell */
Chris@69 5 /*
Chris@69 6 Redistribution and use in source and binary forms, with or without
Chris@69 7 modification, are permitted provided that the following conditions
Chris@69 8 are met:
Chris@69 9
Chris@69 10 - Redistributions of source code must retain the above copyright
Chris@69 11 notice, this list of conditions and the following disclaimer.
Chris@69 12
Chris@69 13 - Redistributions in binary form must reproduce the above copyright
Chris@69 14 notice, this list of conditions and the following disclaimer in the
Chris@69 15 documentation and/or other materials provided with the distribution.
Chris@69 16
Chris@69 17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
Chris@69 18 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
Chris@69 19 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
Chris@69 20 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
Chris@69 21 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
Chris@69 22 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
Chris@69 23 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
Chris@69 24 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
Chris@69 25 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
Chris@69 26 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
Chris@69 27 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Chris@69 28 */
Chris@69 29
Chris@69 30 #ifdef HAVE_CONFIG_H
Chris@69 31 #include "config.h"
Chris@69 32 #endif
Chris@69 33
Chris@69 34 #include "celt.h"
Chris@69 35 #include "modes.h"
Chris@69 36 #include "rate.h"
Chris@69 37 #include "os_support.h"
Chris@69 38 #include "stack_alloc.h"
Chris@69 39 #include "quant_bands.h"
Chris@69 40 #include "cpu_support.h"
Chris@69 41
Chris@69 42 static const opus_int16 eband5ms[] = {
Chris@69 43 /*0 200 400 600 800 1k 1.2 1.4 1.6 2k 2.4 2.8 3.2 4k 4.8 5.6 6.8 8k 9.6 12k 15.6 */
Chris@69 44 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 34, 40, 48, 60, 78, 100
Chris@69 45 };
Chris@69 46
Chris@69 47 /* Alternate tuning (partially derived from Vorbis) */
Chris@69 48 #define BITALLOC_SIZE 11
Chris@69 49 /* Bit allocation table in units of 1/32 bit/sample (0.1875 dB SNR) */
Chris@69 50 static const unsigned char band_allocation[] = {
Chris@69 51 /*0 200 400 600 800 1k 1.2 1.4 1.6 2k 2.4 2.8 3.2 4k 4.8 5.6 6.8 8k 9.6 12k 15.6 */
Chris@69 52 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
Chris@69 53 90, 80, 75, 69, 63, 56, 49, 40, 34, 29, 20, 18, 10, 0, 0, 0, 0, 0, 0, 0, 0,
Chris@69 54 110,100, 90, 84, 78, 71, 65, 58, 51, 45, 39, 32, 26, 20, 12, 0, 0, 0, 0, 0, 0,
Chris@69 55 118,110,103, 93, 86, 80, 75, 70, 65, 59, 53, 47, 40, 31, 23, 15, 4, 0, 0, 0, 0,
Chris@69 56 126,119,112,104, 95, 89, 83, 78, 72, 66, 60, 54, 47, 39, 32, 25, 17, 12, 1, 0, 0,
Chris@69 57 134,127,120,114,103, 97, 91, 85, 78, 72, 66, 60, 54, 47, 41, 35, 29, 23, 16, 10, 1,
Chris@69 58 144,137,130,124,113,107,101, 95, 88, 82, 76, 70, 64, 57, 51, 45, 39, 33, 26, 15, 1,
Chris@69 59 152,145,138,132,123,117,111,105, 98, 92, 86, 80, 74, 67, 61, 55, 49, 43, 36, 20, 1,
Chris@69 60 162,155,148,142,133,127,121,115,108,102, 96, 90, 84, 77, 71, 65, 59, 53, 46, 30, 1,
Chris@69 61 172,165,158,152,143,137,131,125,118,112,106,100, 94, 87, 81, 75, 69, 63, 56, 45, 20,
Chris@69 62 200,200,200,200,200,200,200,200,198,193,188,183,178,173,168,163,158,153,148,129,104,
Chris@69 63 };
Chris@69 64
Chris@69 65 #ifndef CUSTOM_MODES_ONLY
Chris@69 66 #ifdef FIXED_POINT
Chris@69 67 #include "static_modes_fixed.h"
Chris@69 68 #else
Chris@69 69 #include "static_modes_float.h"
Chris@69 70 #endif
Chris@69 71 #endif /* CUSTOM_MODES_ONLY */
Chris@69 72
Chris@69 73 #ifndef M_PI
Chris@69 74 #define M_PI 3.141592653
Chris@69 75 #endif
Chris@69 76
Chris@69 77 #ifdef CUSTOM_MODES
Chris@69 78
Chris@69 79 /* Defining 25 critical bands for the full 0-20 kHz audio bandwidth
Chris@69 80 Taken from http://ccrma.stanford.edu/~jos/bbt/Bark_Frequency_Scale.html */
Chris@69 81 #define BARK_BANDS 25
Chris@69 82 static const opus_int16 bark_freq[BARK_BANDS+1] = {
Chris@69 83 0, 100, 200, 300, 400,
Chris@69 84 510, 630, 770, 920, 1080,
Chris@69 85 1270, 1480, 1720, 2000, 2320,
Chris@69 86 2700, 3150, 3700, 4400, 5300,
Chris@69 87 6400, 7700, 9500, 12000, 15500,
Chris@69 88 20000};
Chris@69 89
Chris@69 90 static opus_int16 *compute_ebands(opus_int32 Fs, int frame_size, int res, int *nbEBands)
Chris@69 91 {
Chris@69 92 opus_int16 *eBands;
Chris@69 93 int i, j, lin, low, high, nBark, offset=0;
Chris@69 94
Chris@69 95 /* All modes that have 2.5 ms short blocks use the same definition */
Chris@69 96 if (Fs == 400*(opus_int32)frame_size)
Chris@69 97 {
Chris@69 98 *nbEBands = sizeof(eband5ms)/sizeof(eband5ms[0])-1;
Chris@69 99 eBands = opus_alloc(sizeof(opus_int16)*(*nbEBands+1));
Chris@69 100 for (i=0;i<*nbEBands+1;i++)
Chris@69 101 eBands[i] = eband5ms[i];
Chris@69 102 return eBands;
Chris@69 103 }
Chris@69 104 /* Find the number of critical bands supported by our sampling rate */
Chris@69 105 for (nBark=1;nBark<BARK_BANDS;nBark++)
Chris@69 106 if (bark_freq[nBark+1]*2 >= Fs)
Chris@69 107 break;
Chris@69 108
Chris@69 109 /* Find where the linear part ends (i.e. where the spacing is more than min_width */
Chris@69 110 for (lin=0;lin<nBark;lin++)
Chris@69 111 if (bark_freq[lin+1]-bark_freq[lin] >= res)
Chris@69 112 break;
Chris@69 113
Chris@69 114 low = (bark_freq[lin]+res/2)/res;
Chris@69 115 high = nBark-lin;
Chris@69 116 *nbEBands = low+high;
Chris@69 117 eBands = opus_alloc(sizeof(opus_int16)*(*nbEBands+2));
Chris@69 118
Chris@69 119 if (eBands==NULL)
Chris@69 120 return NULL;
Chris@69 121
Chris@69 122 /* Linear spacing (min_width) */
Chris@69 123 for (i=0;i<low;i++)
Chris@69 124 eBands[i] = i;
Chris@69 125 if (low>0)
Chris@69 126 offset = eBands[low-1]*res - bark_freq[lin-1];
Chris@69 127 /* Spacing follows critical bands */
Chris@69 128 for (i=0;i<high;i++)
Chris@69 129 {
Chris@69 130 int target = bark_freq[lin+i];
Chris@69 131 /* Round to an even value */
Chris@69 132 eBands[i+low] = (target+offset/2+res)/(2*res)*2;
Chris@69 133 offset = eBands[i+low]*res - target;
Chris@69 134 }
Chris@69 135 /* Enforce the minimum spacing at the boundary */
Chris@69 136 for (i=0;i<*nbEBands;i++)
Chris@69 137 if (eBands[i] < i)
Chris@69 138 eBands[i] = i;
Chris@69 139 /* Round to an even value */
Chris@69 140 eBands[*nbEBands] = (bark_freq[nBark]+res)/(2*res)*2;
Chris@69 141 if (eBands[*nbEBands] > frame_size)
Chris@69 142 eBands[*nbEBands] = frame_size;
Chris@69 143 for (i=1;i<*nbEBands-1;i++)
Chris@69 144 {
Chris@69 145 if (eBands[i+1]-eBands[i] < eBands[i]-eBands[i-1])
Chris@69 146 {
Chris@69 147 eBands[i] -= (2*eBands[i]-eBands[i-1]-eBands[i+1])/2;
Chris@69 148 }
Chris@69 149 }
Chris@69 150 /* Remove any empty bands. */
Chris@69 151 for (i=j=0;i<*nbEBands;i++)
Chris@69 152 if(eBands[i+1]>eBands[j])
Chris@69 153 eBands[++j]=eBands[i+1];
Chris@69 154 *nbEBands=j;
Chris@69 155
Chris@69 156 for (i=1;i<*nbEBands;i++)
Chris@69 157 {
Chris@69 158 /* Every band must be smaller than the last band. */
Chris@69 159 celt_assert(eBands[i]-eBands[i-1]<=eBands[*nbEBands]-eBands[*nbEBands-1]);
Chris@69 160 /* Each band must be no larger than twice the size of the previous one. */
Chris@69 161 celt_assert(eBands[i+1]-eBands[i]<=2*(eBands[i]-eBands[i-1]));
Chris@69 162 }
Chris@69 163
Chris@69 164 return eBands;
Chris@69 165 }
Chris@69 166
Chris@69 167 static void compute_allocation_table(CELTMode *mode)
Chris@69 168 {
Chris@69 169 int i, j;
Chris@69 170 unsigned char *allocVectors;
Chris@69 171 int maxBands = sizeof(eband5ms)/sizeof(eband5ms[0])-1;
Chris@69 172
Chris@69 173 mode->nbAllocVectors = BITALLOC_SIZE;
Chris@69 174 allocVectors = opus_alloc(sizeof(unsigned char)*(BITALLOC_SIZE*mode->nbEBands));
Chris@69 175 if (allocVectors==NULL)
Chris@69 176 return;
Chris@69 177
Chris@69 178 /* Check for standard mode */
Chris@69 179 if (mode->Fs == 400*(opus_int32)mode->shortMdctSize)
Chris@69 180 {
Chris@69 181 for (i=0;i<BITALLOC_SIZE*mode->nbEBands;i++)
Chris@69 182 allocVectors[i] = band_allocation[i];
Chris@69 183 mode->allocVectors = allocVectors;
Chris@69 184 return;
Chris@69 185 }
Chris@69 186 /* If not the standard mode, interpolate */
Chris@69 187 /* Compute per-codec-band allocation from per-critical-band matrix */
Chris@69 188 for (i=0;i<BITALLOC_SIZE;i++)
Chris@69 189 {
Chris@69 190 for (j=0;j<mode->nbEBands;j++)
Chris@69 191 {
Chris@69 192 int k;
Chris@69 193 for (k=0;k<maxBands;k++)
Chris@69 194 {
Chris@69 195 if (400*(opus_int32)eband5ms[k] > mode->eBands[j]*(opus_int32)mode->Fs/mode->shortMdctSize)
Chris@69 196 break;
Chris@69 197 }
Chris@69 198 if (k>maxBands-1)
Chris@69 199 allocVectors[i*mode->nbEBands+j] = band_allocation[i*maxBands + maxBands-1];
Chris@69 200 else {
Chris@69 201 opus_int32 a0, a1;
Chris@69 202 a1 = mode->eBands[j]*(opus_int32)mode->Fs/mode->shortMdctSize - 400*(opus_int32)eband5ms[k-1];
Chris@69 203 a0 = 400*(opus_int32)eband5ms[k] - mode->eBands[j]*(opus_int32)mode->Fs/mode->shortMdctSize;
Chris@69 204 allocVectors[i*mode->nbEBands+j] = (a0*band_allocation[i*maxBands+k-1]
Chris@69 205 + a1*band_allocation[i*maxBands+k])/(a0+a1);
Chris@69 206 }
Chris@69 207 }
Chris@69 208 }
Chris@69 209
Chris@69 210 /*printf ("\n");
Chris@69 211 for (i=0;i<BITALLOC_SIZE;i++)
Chris@69 212 {
Chris@69 213 for (j=0;j<mode->nbEBands;j++)
Chris@69 214 printf ("%d ", allocVectors[i*mode->nbEBands+j]);
Chris@69 215 printf ("\n");
Chris@69 216 }
Chris@69 217 exit(0);*/
Chris@69 218
Chris@69 219 mode->allocVectors = allocVectors;
Chris@69 220 }
Chris@69 221
Chris@69 222 #endif /* CUSTOM_MODES */
Chris@69 223
Chris@69 224 CELTMode *opus_custom_mode_create(opus_int32 Fs, int frame_size, int *error)
Chris@69 225 {
Chris@69 226 int i;
Chris@69 227 #ifdef CUSTOM_MODES
Chris@69 228 CELTMode *mode=NULL;
Chris@69 229 int res;
Chris@69 230 opus_val16 *window;
Chris@69 231 opus_int16 *logN;
Chris@69 232 int LM;
Chris@69 233 int arch = opus_select_arch();
Chris@69 234 ALLOC_STACK;
Chris@69 235 #if !defined(VAR_ARRAYS) && !defined(USE_ALLOCA)
Chris@69 236 if (global_stack==NULL)
Chris@69 237 goto failure;
Chris@69 238 #endif
Chris@69 239 #endif
Chris@69 240
Chris@69 241 #ifndef CUSTOM_MODES_ONLY
Chris@69 242 for (i=0;i<TOTAL_MODES;i++)
Chris@69 243 {
Chris@69 244 int j;
Chris@69 245 for (j=0;j<4;j++)
Chris@69 246 {
Chris@69 247 if (Fs == static_mode_list[i]->Fs &&
Chris@69 248 (frame_size<<j) == static_mode_list[i]->shortMdctSize*static_mode_list[i]->nbShortMdcts)
Chris@69 249 {
Chris@69 250 if (error)
Chris@69 251 *error = OPUS_OK;
Chris@69 252 return (CELTMode*)static_mode_list[i];
Chris@69 253 }
Chris@69 254 }
Chris@69 255 }
Chris@69 256 #endif /* CUSTOM_MODES_ONLY */
Chris@69 257
Chris@69 258 #ifndef CUSTOM_MODES
Chris@69 259 if (error)
Chris@69 260 *error = OPUS_BAD_ARG;
Chris@69 261 return NULL;
Chris@69 262 #else
Chris@69 263
Chris@69 264 /* The good thing here is that permutation of the arguments will automatically be invalid */
Chris@69 265
Chris@69 266 if (Fs < 8000 || Fs > 96000)
Chris@69 267 {
Chris@69 268 if (error)
Chris@69 269 *error = OPUS_BAD_ARG;
Chris@69 270 return NULL;
Chris@69 271 }
Chris@69 272 if (frame_size < 40 || frame_size > 1024 || frame_size%2!=0)
Chris@69 273 {
Chris@69 274 if (error)
Chris@69 275 *error = OPUS_BAD_ARG;
Chris@69 276 return NULL;
Chris@69 277 }
Chris@69 278 /* Frames of less than 1ms are not supported. */
Chris@69 279 if ((opus_int32)frame_size*1000 < Fs)
Chris@69 280 {
Chris@69 281 if (error)
Chris@69 282 *error = OPUS_BAD_ARG;
Chris@69 283 return NULL;
Chris@69 284 }
Chris@69 285
Chris@69 286 if ((opus_int32)frame_size*75 >= Fs && (frame_size%16)==0)
Chris@69 287 {
Chris@69 288 LM = 3;
Chris@69 289 } else if ((opus_int32)frame_size*150 >= Fs && (frame_size%8)==0)
Chris@69 290 {
Chris@69 291 LM = 2;
Chris@69 292 } else if ((opus_int32)frame_size*300 >= Fs && (frame_size%4)==0)
Chris@69 293 {
Chris@69 294 LM = 1;
Chris@69 295 } else
Chris@69 296 {
Chris@69 297 LM = 0;
Chris@69 298 }
Chris@69 299
Chris@69 300 /* Shorts longer than 3.3ms are not supported. */
Chris@69 301 if ((opus_int32)(frame_size>>LM)*300 > Fs)
Chris@69 302 {
Chris@69 303 if (error)
Chris@69 304 *error = OPUS_BAD_ARG;
Chris@69 305 return NULL;
Chris@69 306 }
Chris@69 307
Chris@69 308 mode = opus_alloc(sizeof(CELTMode));
Chris@69 309 if (mode==NULL)
Chris@69 310 goto failure;
Chris@69 311 mode->Fs = Fs;
Chris@69 312
Chris@69 313 /* Pre/de-emphasis depends on sampling rate. The "standard" pre-emphasis
Chris@69 314 is defined as A(z) = 1 - 0.85*z^-1 at 48 kHz. Other rates should
Chris@69 315 approximate that. */
Chris@69 316 if(Fs < 12000) /* 8 kHz */
Chris@69 317 {
Chris@69 318 mode->preemph[0] = QCONST16(0.3500061035f, 15);
Chris@69 319 mode->preemph[1] = -QCONST16(0.1799926758f, 15);
Chris@69 320 mode->preemph[2] = QCONST16(0.2719968125f, SIG_SHIFT); /* exact 1/preemph[3] */
Chris@69 321 mode->preemph[3] = QCONST16(3.6765136719f, 13);
Chris@69 322 } else if(Fs < 24000) /* 16 kHz */
Chris@69 323 {
Chris@69 324 mode->preemph[0] = QCONST16(0.6000061035f, 15);
Chris@69 325 mode->preemph[1] = -QCONST16(0.1799926758f, 15);
Chris@69 326 mode->preemph[2] = QCONST16(0.4424998650f, SIG_SHIFT); /* exact 1/preemph[3] */
Chris@69 327 mode->preemph[3] = QCONST16(2.2598876953f, 13);
Chris@69 328 } else if(Fs < 40000) /* 32 kHz */
Chris@69 329 {
Chris@69 330 mode->preemph[0] = QCONST16(0.7799987793f, 15);
Chris@69 331 mode->preemph[1] = -QCONST16(0.1000061035f, 15);
Chris@69 332 mode->preemph[2] = QCONST16(0.7499771125f, SIG_SHIFT); /* exact 1/preemph[3] */
Chris@69 333 mode->preemph[3] = QCONST16(1.3333740234f, 13);
Chris@69 334 } else /* 48 kHz */
Chris@69 335 {
Chris@69 336 mode->preemph[0] = QCONST16(0.8500061035f, 15);
Chris@69 337 mode->preemph[1] = QCONST16(0.0f, 15);
Chris@69 338 mode->preemph[2] = QCONST16(1.f, SIG_SHIFT);
Chris@69 339 mode->preemph[3] = QCONST16(1.f, 13);
Chris@69 340 }
Chris@69 341
Chris@69 342 mode->maxLM = LM;
Chris@69 343 mode->nbShortMdcts = 1<<LM;
Chris@69 344 mode->shortMdctSize = frame_size/mode->nbShortMdcts;
Chris@69 345 res = (mode->Fs+mode->shortMdctSize)/(2*mode->shortMdctSize);
Chris@69 346
Chris@69 347 mode->eBands = compute_ebands(Fs, mode->shortMdctSize, res, &mode->nbEBands);
Chris@69 348 if (mode->eBands==NULL)
Chris@69 349 goto failure;
Chris@69 350 #if !defined(SMALL_FOOTPRINT)
Chris@69 351 /* Make sure we don't allocate a band larger than our PVQ table.
Chris@69 352 208 should be enough, but let's be paranoid. */
Chris@69 353 if ((mode->eBands[mode->nbEBands] - mode->eBands[mode->nbEBands-1])<<LM >
Chris@69 354 208) {
Chris@69 355 goto failure;
Chris@69 356 }
Chris@69 357 #endif
Chris@69 358
Chris@69 359 mode->effEBands = mode->nbEBands;
Chris@69 360 while (mode->eBands[mode->effEBands] > mode->shortMdctSize)
Chris@69 361 mode->effEBands--;
Chris@69 362
Chris@69 363 /* Overlap must be divisible by 4 */
Chris@69 364 mode->overlap = ((mode->shortMdctSize>>2)<<2);
Chris@69 365
Chris@69 366 compute_allocation_table(mode);
Chris@69 367 if (mode->allocVectors==NULL)
Chris@69 368 goto failure;
Chris@69 369
Chris@69 370 window = (opus_val16*)opus_alloc(mode->overlap*sizeof(opus_val16));
Chris@69 371 if (window==NULL)
Chris@69 372 goto failure;
Chris@69 373
Chris@69 374 #ifndef FIXED_POINT
Chris@69 375 for (i=0;i<mode->overlap;i++)
Chris@69 376 window[i] = Q15ONE*sin(.5*M_PI* sin(.5*M_PI*(i+.5)/mode->overlap) * sin(.5*M_PI*(i+.5)/mode->overlap));
Chris@69 377 #else
Chris@69 378 for (i=0;i<mode->overlap;i++)
Chris@69 379 window[i] = MIN32(32767,floor(.5+32768.*sin(.5*M_PI* sin(.5*M_PI*(i+.5)/mode->overlap) * sin(.5*M_PI*(i+.5)/mode->overlap))));
Chris@69 380 #endif
Chris@69 381 mode->window = window;
Chris@69 382
Chris@69 383 logN = (opus_int16*)opus_alloc(mode->nbEBands*sizeof(opus_int16));
Chris@69 384 if (logN==NULL)
Chris@69 385 goto failure;
Chris@69 386
Chris@69 387 for (i=0;i<mode->nbEBands;i++)
Chris@69 388 logN[i] = log2_frac(mode->eBands[i+1]-mode->eBands[i], BITRES);
Chris@69 389 mode->logN = logN;
Chris@69 390
Chris@69 391 compute_pulse_cache(mode, mode->maxLM);
Chris@69 392
Chris@69 393 if (clt_mdct_init(&mode->mdct, 2*mode->shortMdctSize*mode->nbShortMdcts,
Chris@69 394 mode->maxLM, arch) == 0)
Chris@69 395 goto failure;
Chris@69 396
Chris@69 397 if (error)
Chris@69 398 *error = OPUS_OK;
Chris@69 399
Chris@69 400 return mode;
Chris@69 401 failure:
Chris@69 402 if (error)
Chris@69 403 *error = OPUS_ALLOC_FAIL;
Chris@69 404 if (mode!=NULL)
Chris@69 405 opus_custom_mode_destroy(mode);
Chris@69 406 return NULL;
Chris@69 407 #endif /* !CUSTOM_MODES */
Chris@69 408 }
Chris@69 409
Chris@69 410 #ifdef CUSTOM_MODES
Chris@69 411 void opus_custom_mode_destroy(CELTMode *mode)
Chris@69 412 {
Chris@69 413 int arch = opus_select_arch();
Chris@69 414
Chris@69 415 if (mode == NULL)
Chris@69 416 return;
Chris@69 417 #ifndef CUSTOM_MODES_ONLY
Chris@69 418 {
Chris@69 419 int i;
Chris@69 420 for (i=0;i<TOTAL_MODES;i++)
Chris@69 421 {
Chris@69 422 if (mode == static_mode_list[i])
Chris@69 423 {
Chris@69 424 return;
Chris@69 425 }
Chris@69 426 }
Chris@69 427 }
Chris@69 428 #endif /* CUSTOM_MODES_ONLY */
Chris@69 429 opus_free((opus_int16*)mode->eBands);
Chris@69 430 opus_free((unsigned char*)mode->allocVectors);
Chris@69 431
Chris@69 432 opus_free((opus_val16*)mode->window);
Chris@69 433 opus_free((opus_int16*)mode->logN);
Chris@69 434
Chris@69 435 opus_free((opus_int16*)mode->cache.index);
Chris@69 436 opus_free((unsigned char*)mode->cache.bits);
Chris@69 437 opus_free((unsigned char*)mode->cache.caps);
Chris@69 438 clt_mdct_clear(&mode->mdct, arch);
Chris@69 439
Chris@69 440 opus_free((CELTMode *)mode);
Chris@69 441 }
Chris@69 442 #endif