1885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* Copyright (c) 2007-2008 CSIRO
2885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   Copyright (c) 2007-2009 Xiph.Org Foundation
3885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   Copyright (c) 2008 Gregory Maxwell
4885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   Written by Jean-Marc Valin and Gregory Maxwell */
5885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/*
6885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   Redistribution and use in source and binary forms, with or without
7885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   modification, are permitted provided that the following conditions
8885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   are met:
9885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
10885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   - Redistributions of source code must retain the above copyright
11885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   notice, this list of conditions and the following disclaimer.
12885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
13885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   - Redistributions in binary form must reproduce the above copyright
14885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   notice, this list of conditions and the following disclaimer in the
15885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   documentation and/or other materials provided with the distribution.
16885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
17885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org*/
29885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
30885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef HAVE_CONFIG_H
31885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "config.h"
32885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif
33885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
34885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "celt.h"
35885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "modes.h"
36885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "rate.h"
37885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "os_support.h"
38885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "stack_alloc.h"
39885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "quant_bands.h"
40885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
41885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic const opus_int16 eband5ms[] = {
42885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/*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 */
43885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  0,  1,  2,  3,  4,  5,  6,  7,  8, 10, 12, 14, 16, 20, 24, 28, 34, 40, 48, 60, 78, 100
44885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org};
45885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
46885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* Alternate tuning (partially derived from Vorbis) */
47885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#define BITALLOC_SIZE 11
48885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* Bit allocation table in units of 1/32 bit/sample (0.1875 dB SNR) */
49885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic const unsigned char band_allocation[] = {
50885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/*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 */
51885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
52885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 90, 80, 75, 69, 63, 56, 49, 40, 34, 29, 20, 18, 10,  0,  0,  0,  0,  0,  0,  0,  0,
53885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org110,100, 90, 84, 78, 71, 65, 58, 51, 45, 39, 32, 26, 20, 12,  0,  0,  0,  0,  0,  0,
54885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org118,110,103, 93, 86, 80, 75, 70, 65, 59, 53, 47, 40, 31, 23, 15,  4,  0,  0,  0,  0,
55885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org126,119,112,104, 95, 89, 83, 78, 72, 66, 60, 54, 47, 39, 32, 25, 17, 12,  1,  0,  0,
56885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org134,127,120,114,103, 97, 91, 85, 78, 72, 66, 60, 54, 47, 41, 35, 29, 23, 16, 10,  1,
57885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org144,137,130,124,113,107,101, 95, 88, 82, 76, 70, 64, 57, 51, 45, 39, 33, 26, 15,  1,
58885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org152,145,138,132,123,117,111,105, 98, 92, 86, 80, 74, 67, 61, 55, 49, 43, 36, 20,  1,
59885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org162,155,148,142,133,127,121,115,108,102, 96, 90, 84, 77, 71, 65, 59, 53, 46, 30,  1,
60885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org172,165,158,152,143,137,131,125,118,112,106,100, 94, 87, 81, 75, 69, 63, 56, 45, 20,
61885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org200,200,200,200,200,200,200,200,198,193,188,183,178,173,168,163,158,153,148,129,104,
62885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org};
63885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
64885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifndef CUSTOM_MODES_ONLY
65885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org #ifdef FIXED_POINT
66885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  #include "static_modes_fixed.h"
67885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org #else
68885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  #include "static_modes_float.h"
69885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org #endif
70885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif /* CUSTOM_MODES_ONLY */
71885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
72885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifndef M_PI
73885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#define M_PI 3.141592653
74885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif
75885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
76885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef CUSTOM_MODES
77885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
78885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* Defining 25 critical bands for the full 0-20 kHz audio bandwidth
79885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   Taken from http://ccrma.stanford.edu/~jos/bbt/Bark_Frequency_Scale.html */
80885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#define BARK_BANDS 25
81885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic const opus_int16 bark_freq[BARK_BANDS+1] = {
82885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      0,   100,   200,   300,   400,
83885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    510,   630,   770,   920,  1080,
84885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   1270,  1480,  1720,  2000,  2320,
85885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   2700,  3150,  3700,  4400,  5300,
86885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   6400,  7700,  9500, 12000, 15500,
87885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  20000};
88885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
89885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic opus_int16 *compute_ebands(opus_int32 Fs, int frame_size, int res, int *nbEBands)
90885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
91885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   opus_int16 *eBands;
92885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int i, j, lin, low, high, nBark, offset=0;
93885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
94885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   /* All modes that have 2.5 ms short blocks use the same definition */
95885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   if (Fs == 400*(opus_int32)frame_size)
96885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
97885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      *nbEBands = sizeof(eband5ms)/sizeof(eband5ms[0])-1;
98885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      eBands = opus_alloc(sizeof(opus_int16)*(*nbEBands+1));
99885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      for (i=0;i<*nbEBands+1;i++)
100885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         eBands[i] = eband5ms[i];
101885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      return eBands;
102885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
103885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   /* Find the number of critical bands supported by our sampling rate */
104885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   for (nBark=1;nBark<BARK_BANDS;nBark++)
105885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org    if (bark_freq[nBark+1]*2 >= Fs)
106885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       break;
107885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
108885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   /* Find where the linear part ends (i.e. where the spacing is more than min_width */
109885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   for (lin=0;lin<nBark;lin++)
110885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if (bark_freq[lin+1]-bark_freq[lin] >= res)
111885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         break;
112885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
113885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   low = (bark_freq[lin]+res/2)/res;
114885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   high = nBark-lin;
115885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   *nbEBands = low+high;
116885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   eBands = opus_alloc(sizeof(opus_int16)*(*nbEBands+2));
117885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
118885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   if (eBands==NULL)
119885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      return NULL;
120885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
121885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   /* Linear spacing (min_width) */
122885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   for (i=0;i<low;i++)
123885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      eBands[i] = i;
124885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   if (low>0)
125885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      offset = eBands[low-1]*res - bark_freq[lin-1];
126885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   /* Spacing follows critical bands */
127885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   for (i=0;i<high;i++)
128885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
129885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      int target = bark_freq[lin+i];
130885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      /* Round to an even value */
131885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      eBands[i+low] = (target+offset/2+res)/(2*res)*2;
132885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      offset = eBands[i+low]*res - target;
133885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
134885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   /* Enforce the minimum spacing at the boundary */
135885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   for (i=0;i<*nbEBands;i++)
136885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if (eBands[i] < i)
137885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         eBands[i] = i;
138885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   /* Round to an even value */
139885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   eBands[*nbEBands] = (bark_freq[nBark]+res)/(2*res)*2;
140885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   if (eBands[*nbEBands] > frame_size)
141885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      eBands[*nbEBands] = frame_size;
142885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   for (i=1;i<*nbEBands-1;i++)
143885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
144885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if (eBands[i+1]-eBands[i] < eBands[i]-eBands[i-1])
145885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {
146885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         eBands[i] -= (2*eBands[i]-eBands[i-1]-eBands[i+1])/2;
147885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
148885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
149885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   /* Remove any empty bands. */
150885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   for (i=j=0;i<*nbEBands;i++)
151885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if(eBands[i+1]>eBands[j])
152885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         eBands[++j]=eBands[i+1];
153885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   *nbEBands=j;
154885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
155885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   for (i=1;i<*nbEBands;i++)
156885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
157885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      /* Every band must be smaller than the last band. */
158885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      celt_assert(eBands[i]-eBands[i-1]<=eBands[*nbEBands]-eBands[*nbEBands-1]);
159885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      /* Each band must be no larger than twice the size of the previous one. */
160885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      celt_assert(eBands[i+1]-eBands[i]<=2*(eBands[i]-eBands[i-1]));
161885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
162885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
163885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   return eBands;
164885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
165885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
166885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic void compute_allocation_table(CELTMode *mode)
167885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
168885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int i, j;
169885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   unsigned char *allocVectors;
170885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int maxBands = sizeof(eband5ms)/sizeof(eband5ms[0])-1;
171885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
172885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   mode->nbAllocVectors = BITALLOC_SIZE;
173885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   allocVectors = opus_alloc(sizeof(unsigned char)*(BITALLOC_SIZE*mode->nbEBands));
174885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   if (allocVectors==NULL)
175885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      return;
176885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
177885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   /* Check for standard mode */
178885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   if (mode->Fs == 400*(opus_int32)mode->shortMdctSize)
179885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
180885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      for (i=0;i<BITALLOC_SIZE*mode->nbEBands;i++)
181885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         allocVectors[i] = band_allocation[i];
182885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      mode->allocVectors = allocVectors;
183885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      return;
184885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
185885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   /* If not the standard mode, interpolate */
186885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   /* Compute per-codec-band allocation from per-critical-band matrix */
187885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   for (i=0;i<BITALLOC_SIZE;i++)
188885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
189885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      for (j=0;j<mode->nbEBands;j++)
190885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {
191885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         int k;
192885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         for (k=0;k<maxBands;k++)
193885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         {
194885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            if (400*(opus_int32)eband5ms[k] > mode->eBands[j]*(opus_int32)mode->Fs/mode->shortMdctSize)
195885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               break;
196885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         }
197885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         if (k>maxBands-1)
198885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            allocVectors[i*mode->nbEBands+j] = band_allocation[i*maxBands + maxBands-1];
199885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         else {
200885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            opus_int32 a0, a1;
201885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            a1 = mode->eBands[j]*(opus_int32)mode->Fs/mode->shortMdctSize - 400*(opus_int32)eband5ms[k-1];
202885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            a0 = 400*(opus_int32)eband5ms[k] - mode->eBands[j]*(opus_int32)mode->Fs/mode->shortMdctSize;
203885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            allocVectors[i*mode->nbEBands+j] = (a0*band_allocation[i*maxBands+k-1]
204885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                                             + a1*band_allocation[i*maxBands+k])/(a0+a1);
205885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         }
206885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
207885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
208885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
209885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   /*printf ("\n");
210885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   for (i=0;i<BITALLOC_SIZE;i++)
211885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
212885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      for (j=0;j<mode->nbEBands;j++)
213885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         printf ("%d ", allocVectors[i*mode->nbEBands+j]);
214885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      printf ("\n");
215885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
216885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   exit(0);*/
217885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
218885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   mode->allocVectors = allocVectors;
219885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
220885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
221885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif /* CUSTOM_MODES */
222885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
223885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgCELTMode *opus_custom_mode_create(opus_int32 Fs, int frame_size, int *error)
224885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
225885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int i;
226885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef CUSTOM_MODES
227885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   CELTMode *mode=NULL;
228885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int res;
229885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   opus_val16 *window;
230885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   opus_int16 *logN;
231885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int LM;
232885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   ALLOC_STACK;
233885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#if !defined(VAR_ARRAYS) && !defined(USE_ALLOCA)
234885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   if (global_stack==NULL)
235885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      goto failure;
236885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif
237885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif
238885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
239885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifndef CUSTOM_MODES_ONLY
240885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   for (i=0;i<TOTAL_MODES;i++)
241885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
242885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      int j;
243885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      for (j=0;j<4;j++)
244885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {
245885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         if (Fs == static_mode_list[i]->Fs &&
246885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               (frame_size<<j) == static_mode_list[i]->shortMdctSize*static_mode_list[i]->nbShortMdcts)
247885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         {
248885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            if (error)
249885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               *error = OPUS_OK;
250885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            return (CELTMode*)static_mode_list[i];
251885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         }
252885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
253885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
254885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif /* CUSTOM_MODES_ONLY */
255885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
256885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifndef CUSTOM_MODES
257885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   if (error)
258885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      *error = OPUS_BAD_ARG;
259885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   return NULL;
260885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#else
261885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
262885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   /* The good thing here is that permutation of the arguments will automatically be invalid */
263885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
264885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   if (Fs < 8000 || Fs > 96000)
265885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
266885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if (error)
267885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         *error = OPUS_BAD_ARG;
268885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      return NULL;
269885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
270885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   if (frame_size < 40 || frame_size > 1024 || frame_size%2!=0)
271885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
272885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if (error)
273885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         *error = OPUS_BAD_ARG;
274885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      return NULL;
275885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
276885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   /* Frames of less than 1ms are not supported. */
277885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   if ((opus_int32)frame_size*1000 < Fs)
278885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
279885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if (error)
280885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         *error = OPUS_BAD_ARG;
281885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      return NULL;
282885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
283885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
284885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   if ((opus_int32)frame_size*75 >= Fs && (frame_size%16)==0)
285885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
286885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org     LM = 3;
287885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   } else if ((opus_int32)frame_size*150 >= Fs && (frame_size%8)==0)
288885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
289885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org     LM = 2;
290885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   } else if ((opus_int32)frame_size*300 >= Fs && (frame_size%4)==0)
291885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
292885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org     LM = 1;
293885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   } else
294885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
295885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org     LM = 0;
296885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
297885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
298885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   /* Shorts longer than 3.3ms are not supported. */
299885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   if ((opus_int32)(frame_size>>LM)*300 > Fs)
300885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
301885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if (error)
302885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         *error = OPUS_BAD_ARG;
303885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      return NULL;
304885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
305885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
306885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   mode = opus_alloc(sizeof(CELTMode));
307885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   if (mode==NULL)
308885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      goto failure;
309885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   mode->Fs = Fs;
310885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
311885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   /* Pre/de-emphasis depends on sampling rate. The "standard" pre-emphasis
312885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      is defined as A(z) = 1 - 0.85*z^-1 at 48 kHz. Other rates should
313885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      approximate that. */
314885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   if(Fs < 12000) /* 8 kHz */
315885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
316885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      mode->preemph[0] =  QCONST16(0.3500061035f, 15);
317885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      mode->preemph[1] = -QCONST16(0.1799926758f, 15);
318885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      mode->preemph[2] =  QCONST16(0.2719968125f, SIG_SHIFT); /* exact 1/preemph[3] */
319885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      mode->preemph[3] =  QCONST16(3.6765136719f, 13);
320885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   } else if(Fs < 24000) /* 16 kHz */
321885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
322885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      mode->preemph[0] =  QCONST16(0.6000061035f, 15);
323885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      mode->preemph[1] = -QCONST16(0.1799926758f, 15);
324885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      mode->preemph[2] =  QCONST16(0.4424998650f, SIG_SHIFT); /* exact 1/preemph[3] */
325885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      mode->preemph[3] =  QCONST16(2.2598876953f, 13);
326885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   } else if(Fs < 40000) /* 32 kHz */
327885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
328885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      mode->preemph[0] =  QCONST16(0.7799987793f, 15);
329885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      mode->preemph[1] = -QCONST16(0.1000061035f, 15);
330885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      mode->preemph[2] =  QCONST16(0.7499771125f, SIG_SHIFT); /* exact 1/preemph[3] */
331885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      mode->preemph[3] =  QCONST16(1.3333740234f, 13);
332885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   } else /* 48 kHz */
333885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
334885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      mode->preemph[0] =  QCONST16(0.8500061035f, 15);
335885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      mode->preemph[1] =  QCONST16(0.0f, 15);
336885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      mode->preemph[2] =  QCONST16(1.f, SIG_SHIFT);
337885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      mode->preemph[3] =  QCONST16(1.f, 13);
338885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
339885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
340885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   mode->maxLM = LM;
341885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   mode->nbShortMdcts = 1<<LM;
342885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   mode->shortMdctSize = frame_size/mode->nbShortMdcts;
343885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   res = (mode->Fs+mode->shortMdctSize)/(2*mode->shortMdctSize);
344885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
345885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   mode->eBands = compute_ebands(Fs, mode->shortMdctSize, res, &mode->nbEBands);
346885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   if (mode->eBands==NULL)
347885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      goto failure;
348885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
349885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   mode->effEBands = mode->nbEBands;
350885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   while (mode->eBands[mode->effEBands] > mode->shortMdctSize)
351885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      mode->effEBands--;
352885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
353885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   /* Overlap must be divisible by 4 */
354885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   mode->overlap = ((mode->shortMdctSize>>2)<<2);
355885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
356885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   compute_allocation_table(mode);
357885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   if (mode->allocVectors==NULL)
358885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      goto failure;
359885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
360885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   window = (opus_val16*)opus_alloc(mode->overlap*sizeof(opus_val16));
361885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   if (window==NULL)
362885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      goto failure;
363885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
364885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifndef FIXED_POINT
365885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   for (i=0;i<mode->overlap;i++)
366885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      window[i] = Q15ONE*sin(.5*M_PI* sin(.5*M_PI*(i+.5)/mode->overlap) * sin(.5*M_PI*(i+.5)/mode->overlap));
367885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#else
368885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   for (i=0;i<mode->overlap;i++)
369885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      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))));
370885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif
371885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   mode->window = window;
372885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
373885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   logN = (opus_int16*)opus_alloc(mode->nbEBands*sizeof(opus_int16));
374885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   if (logN==NULL)
375885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      goto failure;
376885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
377885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   for (i=0;i<mode->nbEBands;i++)
378885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      logN[i] = log2_frac(mode->eBands[i+1]-mode->eBands[i], BITRES);
379885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   mode->logN = logN;
380885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
381885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   compute_pulse_cache(mode, mode->maxLM);
382885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
383885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   if (clt_mdct_init(&mode->mdct, 2*mode->shortMdctSize*mode->nbShortMdcts,
384885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org           mode->maxLM) == 0)
385885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      goto failure;
386885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
387885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   if (error)
388885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      *error = OPUS_OK;
389885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
390885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   return mode;
391885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgfailure:
392885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   if (error)
393885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      *error = OPUS_ALLOC_FAIL;
394885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   if (mode!=NULL)
395885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      opus_custom_mode_destroy(mode);
396885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   return NULL;
397885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif /* !CUSTOM_MODES */
398885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
399885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
400885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef CUSTOM_MODES
401885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgvoid opus_custom_mode_destroy(CELTMode *mode)
402885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
403885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   if (mode == NULL)
404885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      return;
405885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifndef CUSTOM_MODES_ONLY
406885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
407885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org     int i;
408885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org     for (i=0;i<TOTAL_MODES;i++)
409885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org     {
410885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        if (mode == static_mode_list[i])
411885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        {
412885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org           return;
413885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        }
414885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org     }
415885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
416885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif /* CUSTOM_MODES_ONLY */
417885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   opus_free((opus_int16*)mode->eBands);
418885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   opus_free((opus_int16*)mode->allocVectors);
419885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
420885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   opus_free((opus_val16*)mode->window);
421885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   opus_free((opus_int16*)mode->logN);
422885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
423885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   opus_free((opus_int16*)mode->cache.index);
424885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   opus_free((unsigned char*)mode->cache.bits);
425885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   opus_free((unsigned char*)mode->cache.caps);
426885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   clt_mdct_clear(&mode->mdct);
427885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
428885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   opus_free((CELTMode *)mode);
429885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
430885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif
431