Can now generate the entire mode struct
[opus.git] / libcelt / modes.c
1 /* (C) 2007 Jean-Marc Valin, CSIRO
2 */
3 /*
4    Redistribution and use in source and binary forms, with or without
5    modification, are permitted provided that the following conditions
6    are met:
7    
8    - Redistributions of source code must retain the above copyright
9    notice, this list of conditions and the following disclaimer.
10    
11    - Redistributions in binary form must reproduce the above copyright
12    notice, this list of conditions and the following disclaimer in the
13    documentation and/or other materials provided with the distribution.
14    
15    - Neither the name of the Xiph.org Foundation nor the names of its
16    contributors may be used to endorse or promote products derived from
17    this software without specific prior written permission.
18    
19    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22    A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
23    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include "modes.h"
33 #include "os_support.h"
34
35 #define NBANDS 18
36 #define PBANDS 8
37 #define PITCH_END 74
38
39 #define NBANDS128 15
40 #define PBANDS128 8
41 #define PITCH_END128 45
42
43 const int qbank0[NBANDS   +2] = {0,  4,  8, 12, 16, 20, 24, 28, 32, 38, 44, 52, 62, 74, 90,112,142,182, 232,256};
44 const int pbank0[PBANDS   +2] = {0,  4,  8, 12, 16,     24,         38,         62, PITCH_END, 256};
45
46 #define NALLOCS 7
47 int bitalloc0[NBANDS*NALLOCS] = 
48    { 5,  4,  4,  4,  3,  3,  2,  2,  2,  2,  1,  1,  1,  1,  0,  0,  0,  0,
49      8,  7,  7,  6,  6,  6,  5,  4,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,
50     10,  9,  9,  8,  8,  8,  8,  8,  8,  8,  9, 10, 11, 12, 17, 15,  6,  7,
51     16, 15, 14, 14, 14, 13, 13, 13, 13, 13, 15, 16, 17, 18, 20, 18, 11, 12,
52     26, 25, 24, 22, 20, 18, 19, 19, 25, 22, 25, 30, 30, 35, 35, 35, 35, 25,
53     32, 30, 28, 27, 25, 24, 23, 21, 29, 27, 35, 40, 42, 50, 59, 54, 51, 36,
54     42, 40, 38, 37, 35, 34, 33, 31, 39, 37, 45, 50, 52, 60, 60, 60, 60, 46,
55 };
56
57
58 #define NBANDS256 15
59 #define PBANDS256 8
60 #define PITCH_END256 88
61 const int qbank3[NBANDS256+2] = {0, 4, 8, 12, 16, 24, 32, 40, 48, 56, 72, 88, 104, 136, 168, 232, 256};
62 //const int pbank3[PBANDS256+2] = {0, 8, 16, 24, 40, PITCH_END256, 256};
63 const int pbank3[PBANDS256+2] = {0, 4, 8, 12, 16, 24, 40, 56, PITCH_END256, 256};
64
65 static const CELTMode mono_mode = {
66    128,         /**< overlap */
67    256,         /**< mdctSize */
68    1,           /**< nbMdctBlocks */
69    1,           /**< channels */
70    
71    NBANDS,      /**< nbEBands */
72    PBANDS,      /**< nbPBands */
73    PITCH_END,   /**< pitchEnd */
74    
75    qbank0,      /**< eBands */
76    pbank0,      /**< pBands*/
77    
78    0.8,         /**< ePredCoef */
79    
80    NALLOCS,     /**< nbAllocVectors */
81    bitalloc0,   /**< allocVectors */
82 };
83
84
85 /* Stereo mode around 120 kbps */
86 static const CELTMode stereo_mode = {
87    128,         /**< overlap */
88    256,         /**< mdctSize */
89    1,           /**< nbMdctBlocks */
90    2,           /**< channels */
91    
92    NBANDS,      /**< nbEBands */
93    PBANDS,      /**< nbPBands */
94    PITCH_END,   /**< pitchEnd */
95    
96    qbank0,      /**< eBands */
97    pbank0,      /**< pBands*/
98    
99    0.8,         /**< ePredCoef */
100    
101    NALLOCS,     /**< nbAllocVectors */
102    bitalloc0,   /**< allocVectors */
103 };
104
105 const CELTMode const *celt_mono = &mono_mode;
106 const CELTMode const *celt_stereo = &stereo_mode;
107
108
109 #define NBANDS51 17
110 #define PBANDS51 8
111 #define PITCH_END51 64
112 const int qbank51[NBANDS51 +2] = {0,  4,  8, 12, 16, 20, 24, 28, 32, 38, 44, 52, 64, 78, 96,122,156,204, 256};
113 const int qbank51b[NBANDS +2] = {0,  3,  6, 9, 12, 16, 20, 24, 28, 32, 38, 44, 52, 64, 78, 96,122,156,204, 256};
114
115 const int pbank51[PBANDS51 +2] = {0,  4,  8, 12, 16,     24,     32,     44,     PITCH_END51, 256};
116 const int pbank51b[PBANDS +2] = {0,  3,  6, 9, 12,     20,     38,     52,     PITCH_END51, 256};
117 #define NALLOCS51 10
118 int bitalloc51[NBANDS51*NALLOCS51] = 
119    { 6,   5,  3,  2,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
120      7,   6,  5,  4,  3,  3,  3,  3,  3,  3,  3,  0,  0,  0,  0,  0,  0,
121      8,   7,  6,  5,  4,  4,  4,  4,  4,  4,  4,  4,  0,  0,  0,  0,  0,
122      9,   8,  7,  7,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  0,  0,  0,
123      10,  9,  8,  8,  7,  7,  5,  5,  5,  5,  5,  5,  5,  5,  5,  0,  0,
124      10,  9,  9,  8,  8,  8,  8,  8,  8,  8,  9, 10, 11, 10, 10,  5,  5,
125      16, 15, 14, 14, 14, 13, 13, 13, 13, 13, 15, 16, 17, 18, 20, 18, 11,
126      26, 25, 24, 22, 20, 18, 19, 19, 25, 22, 25, 30, 30, 35, 35, 35, 35,
127      32, 30, 28, 27, 25, 24, 23, 21, 29, 27, 35, 40, 42, 50, 59, 54, 51,
128      42, 40, 38, 37, 35, 34, 33, 31, 39, 37, 45, 50, 52, 60, 60, 60, 60,
129    };
130
131 static const CELTMode ld51 = {
132    128,         /**< overlap */
133    256,         /**< mdctSize */
134    1,           /**< nbMdctBlocks */
135    1,           /**< channels */
136    
137    NBANDS51,    /**< nbEBands */
138    PBANDS51,    /**< nbPBands */
139    PITCH_END51, /**< pitchEnd */
140    
141    qbank51,     /**< eBands */
142    pbank51,     /**< pBands*/
143    
144    0.8,         /**< ePredCoef */
145    
146    NALLOCS51,   /**< nbAllocVectors */
147    bitalloc51,  /**< allocVectors */
148 };
149 const CELTMode const *celt_ld51 = &ld51;
150
151 int celt_mode_info(const CELTMode *mode, int request, celt_int32_t *value)
152 {
153    switch (request)
154    {
155       case CELT_GET_FRAME_SIZE:
156          *value = mode->mdctSize;
157          break;
158       case CELT_GET_LOOKAHEAD:
159          *value = mode->overlap;
160          break;
161       case CELT_GET_NB_CHANNELS:
162          *value = mode->nbChannels;
163          break;
164       default:
165          return CELT_BAD_ARG;
166    }
167    return CELT_OK;
168 }
169
170 #define MIN_BINS 4
171 #define BARK_BANDS 25
172 const celt_int16_t bark_freq[BARK_BANDS+1] = {
173       0,   101,   200,   301,   405,
174     516,   635,   766,   912,  1077,
175    1263,  1476,  1720,  2003,  2333,
176    2721,  3184,  3742,  4428,  5285,
177    6376,  7791,  9662, 12181, 15624,
178    20397};
179    
180 const celt_int16_t pitch_freq[PBANDS+1] ={0, 345, 689, 1034, 1378, 2067, 3273, 5340, 6374};
181
182 #define BITALLOC_SIZE 10
183 int band_allocation[BARK_BANDS*BITALLOC_SIZE] = 
184    {  2,  2,  1,  1,  2,  2,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
185       2,  2,  2,  1,  2,  2,  2,  2,  2,  1,  2,  2,  3,  3,  3,  3,  3,  3,  3,  0,  0,  0,  0,  0,  0,
186       2,  2,  2,  2,  3,  2,  2,  2,  2,  2,  3,  2,  4,  4,  4,  4,  4,  4,  4,  4,  0,  0,  0,  0,  0,
187       3,  2,  2,  2,  3,  3,  2,  3,  2,  2,  4,  3,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  0,  0,  0,
188       3,  3,  2,  2,  3,  3,  3,  3,  3,  2,  4,  4,  7,  7,  5,  5,  5,  5,  5,  5,  5,  5,  5,  0,  0,
189       3,  3,  2,  2,  3,  3,  3,  3,  3,  3,  4,  4,  8,  8,  8,  8,  8,  8,  9, 10, 11, 10, 10,  5,  5,
190       4,  4,  4,  4,  5,  5,  5,  5,  5,  4,  7,  7, 14, 13, 13, 13, 13, 13, 15, 16, 17, 18, 20, 18, 11,
191       7,  7,  6,  6,  9,  8,  8,  8,  8,  8, 11, 11, 20, 18, 19, 19, 25, 22, 25, 30, 30, 35, 35, 35, 35,
192       8,  8,  8,  8, 10, 10, 10, 10,  9,  9, 19, 18, 25, 24, 23, 21, 29, 27, 35, 40, 42, 50, 59, 54, 51,
193      11, 11, 10, 10, 14, 13, 13, 13, 13, 12, 19, 18, 35, 34, 33, 31, 39, 37, 45, 50, 52, 60, 60, 60, 60,
194    };
195
196
197 static int *compute_ebands(int Fs, int frame_size, int *nbEBands)
198 {
199    int *eBands;
200    int i, res, min_width, lin, low, high;
201    res = (Fs+frame_size)/(2*frame_size);
202    min_width = MIN_BINS*res;
203    //printf ("min_width = %d\n", min_width);
204
205    /* Find where the linear part ends (i.e. where the spacing is more than min_width */
206    for (lin=0;lin<BARK_BANDS;lin++)
207       if (bark_freq[lin+1]-bark_freq[lin] >= min_width)
208          break;
209    
210    //printf ("lin = %d (%d Hz)\n", lin, bark_freq[lin]);
211    low = ((bark_freq[lin]/res)+(MIN_BINS-1))/MIN_BINS;
212    high = BARK_BANDS-lin;
213    *nbEBands = low+high;
214    eBands = celt_alloc(sizeof(int)*(*nbEBands+2));
215    
216    /* Linear spacing (min_width) */
217    for (i=0;i<low;i++)
218       eBands[i] = MIN_BINS*i;
219    /* Spacing follows critical bands */
220    for (i=0;i<high;i++)
221       eBands[i+low] = (bark_freq[lin+i]+res/2)/res;
222    /* Enforce the minimum spacing at the boundary */
223    for (i=0;i<*nbEBands;i++)
224       if (eBands[i] < MIN_BINS*i)
225          eBands[i] = MIN_BINS*i;
226    eBands[*nbEBands] = (bark_freq[BARK_BANDS]+res/2)/res;
227    eBands[*nbEBands+1] = frame_size;
228    if (eBands[*nbEBands] > eBands[*nbEBands+1])
229       eBands[*nbEBands] = eBands[*nbEBands+1];
230    
231    /* FIXME: Remove last band if too small */
232    for (i=0;i<*nbEBands+2;i++)
233       printf("%d ", eBands[i]);
234    printf ("\n");
235    return eBands;
236 }
237
238 static void compute_pbands(CELTMode *mode, int res)
239 {
240    int i;
241    int *pBands;
242    pBands=celt_alloc(sizeof(int)*(PBANDS+2));
243    mode->nbPBands = PBANDS;
244    for (i=0;i<PBANDS+1;i++)
245    {
246       pBands[i] = (pitch_freq[i]+res/2)/res;
247       if (pBands[i] < mode->eBands[i])
248          pBands[i] = mode->eBands[i];
249    }
250    pBands[PBANDS+1] = mode->eBands[mode->nbEBands+1];
251    for (i=1;i<mode->nbPBands+1;i++)
252    {
253       int j;
254       for (j=0;j<mode->nbEBands;j++)
255          if (mode->eBands[j] <= pBands[i] && mode->eBands[j+1] > pBands[i])
256             break;
257       //printf ("%d %d\n", i, j);
258       if (mode->eBands[j] != pBands[i])
259       {
260          if (pBands[i]-mode->eBands[j] < mode->eBands[j+1]-pBands[i] && 
261              mode->eBands[j] != pBands[i-1])
262             pBands[i] = mode->eBands[j];
263          else
264             pBands[i] = mode->eBands[j+1];
265       }
266    }
267    for (i=0;i<mode->nbPBands+2;i++)
268       printf("%d ", pBands[i]);
269    printf ("\n");
270    mode->pBands = pBands;
271    mode->pitchEnd = pBands[PBANDS];
272 }
273
274 static void compute_allocation_table(CELTMode *mode, int res)
275 {
276    int i, j, eband;
277    int *allocVectors;
278    
279    mode->nbAllocVectors = BITALLOC_SIZE;
280    allocVectors = celt_alloc(sizeof(int)*(BITALLOC_SIZE*mode->nbEBands));
281    for (i=0;i<BITALLOC_SIZE;i++)
282    {
283       eband = 0;
284       for (j=0;j<BARK_BANDS;j++)
285       {
286          int edge, low;
287          edge = mode->eBands[eband+1]*res;
288          if (edge < bark_freq[j+1])
289          {
290             int num, den;
291             num = band_allocation[i*BARK_BANDS+j] * (edge-bark_freq[j]);
292             den = bark_freq[j+1]-bark_freq[j];
293             //low = band_allocation[i*BARK_BANDS+j] * (edge-bark_freq[j])/(bark_freq[j+1]-bark_freq[j]);
294             low = (num+den/2)/den;
295             allocVectors[i*mode->nbEBands+eband] += low;
296             eband++;
297             allocVectors[i*mode->nbEBands+eband] += band_allocation[i*BARK_BANDS+j]-low;
298          } else {
299             allocVectors[i*mode->nbEBands+eband] += band_allocation[i*BARK_BANDS+j];
300          }
301       }
302    }
303    for (i=0;i<BITALLOC_SIZE;i++)
304    {
305       for (j=0;j<mode->nbEBands;j++)
306          printf ("%2d ", allocVectors[i*mode->nbEBands+j]);
307       printf ("\n");
308    }
309    mode->allocVectors = allocVectors;
310 }
311
312 CELTMode *celt_mode_create(int Fs, int channels, int frame_size, int overlap)
313 {
314    int res;
315    CELTMode *mode;
316
317    res = (Fs+frame_size)/(2*frame_size);
318    
319    mode = celt_alloc(sizeof(CELTMode));
320    mode->overlap = overlap;
321    mode->mdctSize = frame_size;
322    mode->nbMdctBlocks = 1;
323    mode->nbChannels = channels;
324    mode->eBands = compute_ebands(Fs, frame_size, &mode->nbEBands);
325    compute_pbands(mode, res);
326    mode->ePredCoef = .8;
327    
328    compute_allocation_table(mode, res);
329    
330    printf ("%d bands\n", mode->nbEBands);
331    return mode;
332 }
333
334 /*int main()
335 {
336    celt_mode_create(44100, 1, 256, 128);
337    return 0;
338 }*/
339