Improvements to static modes
[opus.git] / libcelt / modes.c
1 /* (C) 2007-2008 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 #ifdef HAVE_CONFIG_H
33 #include "config.h"
34 #endif
35
36 #include "celt.h"
37 #include "modes.h"
38 #include "rate.h"
39 #include "os_support.h"
40
41 #ifdef STATIC_MODES
42 #include "static_modes.h"
43 #endif
44
45 #define MODEVALID 0xa110ca7e
46 #define MODEFREED 0xb10cf8ee
47
48 #ifndef M_PI
49 #define M_PI 3.141592653
50 #endif
51
52
53 int celt_mode_info(const CELTMode *mode, int request, celt_int32_t *value)
54 {
55    switch (request)
56    {
57       case CELT_GET_FRAME_SIZE:
58          *value = mode->mdctSize;
59          break;
60       case CELT_GET_LOOKAHEAD:
61          *value = mode->overlap;
62          break;
63       case CELT_GET_NB_CHANNELS:
64          *value = mode->nbChannels;
65          break;
66       default:
67          return CELT_BAD_ARG;
68    }
69    return CELT_OK;
70 }
71
72 #define PBANDS 8
73 #define MIN_BINS 4
74 /* Defining 25 critical bands for the full 0-20 kHz audio bandwidth
75    Taken from http://ccrma.stanford.edu/~jos/bbt/Bark_Frequency_Scale.html */
76 #define BARK_BANDS 25
77 static const celt_int16_t bark_freq[BARK_BANDS+1] = {
78       0,   100,   200,   300,   400,
79     510,   630,   770,   920,  1080,
80    1270,  1480,  1720,  2000,  2320,
81    2700,  3150,  3700,  4400,  5300,
82    6400,  7700,  9500, 12000, 15500,
83   20000};
84
85 static const celt_int16_t pitch_freq[PBANDS+1] ={0, 345, 689, 1034, 1378, 2067, 3273, 5340, 6374};
86
87 /* This allocation table is per critical band. When creating a mode, the bits get added together 
88    into the codec bands, which are sometimes larger than one critical band at low frequency */
89 #define BITALLOC_SIZE 10
90 static const int band_allocation[BARK_BANDS*BITALLOC_SIZE] = 
91    {  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,
92       2,  2,  2,  1,  2,  2,  2,  2,  2,  1,  2,  2,  5,  5,  7,  7,  7,  5,  4,  0,  0,  0,  0,  0,  0,
93       2,  2,  2,  2,  3,  2,  2,  2,  2,  2,  3,  2,  6,  6,  8,  8,  8,  6,  5,  4,  0,  0,  0,  0,  0,
94       3,  2,  2,  2,  3,  3,  2,  3,  2,  2,  4,  3,  7,  7,  9,  9,  9,  7,  6,  5,  5,  5,  0,  0,  0,
95       3,  3,  2,  2,  3,  3,  3,  3,  3,  2,  4,  4,  9,  9, 10, 10, 10,  9,  6,  5,  5,  5,  5,  0,  0,
96       3,  3,  2,  2,  3,  3,  3,  3,  3,  3,  4,  4, 10, 10, 12, 12, 12, 10, 10, 10, 11, 10, 10,  5,  5,
97       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,
98       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,
99       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,
100      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,
101    };
102
103
104    static int *compute_ebands(celt_int32_t Fs, int frame_size, int *nbEBands)
105 {
106    int *eBands;
107    int i, res, min_width, lin, low, high;
108    res = (Fs+frame_size)/(2*frame_size);
109    min_width = MIN_BINS*res;
110    /*printf ("min_width = %d\n", min_width);*/
111
112    /* Find where the linear part ends (i.e. where the spacing is more than min_width */
113    for (lin=0;lin<BARK_BANDS;lin++)
114       if (bark_freq[lin+1]-bark_freq[lin] >= min_width)
115          break;
116    
117    /*printf ("lin = %d (%d Hz)\n", lin, bark_freq[lin]);*/
118    low = ((bark_freq[lin]/res)+(MIN_BINS-1))/MIN_BINS;
119    high = BARK_BANDS-lin;
120    *nbEBands = low+high;
121    eBands = celt_alloc(sizeof(int)*(*nbEBands+2));
122    
123    /* Linear spacing (min_width) */
124    for (i=0;i<low;i++)
125       eBands[i] = MIN_BINS*i;
126    /* Spacing follows critical bands */
127    for (i=0;i<high;i++)
128       eBands[i+low] = (bark_freq[lin+i]+res/2)/res;
129    /* Enforce the minimum spacing at the boundary */
130    for (i=0;i<*nbEBands;i++)
131       if (eBands[i] < MIN_BINS*i)
132          eBands[i] = MIN_BINS*i;
133    eBands[*nbEBands] = (bark_freq[BARK_BANDS]+res/2)/res;
134    eBands[*nbEBands+1] = frame_size;
135    if (eBands[*nbEBands] > eBands[*nbEBands+1])
136       eBands[*nbEBands] = eBands[*nbEBands+1];
137    
138    /* FIXME: Remove last band if too small */
139    /*for (i=0;i<*nbEBands+2;i++)
140       printf("%d ", eBands[i]);
141    printf ("\n");*/
142    return eBands;
143 }
144
145 static void compute_pbands(CELTMode *mode, int res)
146 {
147    int i;
148    int *pBands;
149    pBands=celt_alloc(sizeof(int)*(PBANDS+2));
150    mode->nbPBands = PBANDS;
151    for (i=0;i<PBANDS+1;i++)
152    {
153       pBands[i] = (pitch_freq[i]+res/2)/res;
154       if (pBands[i] < mode->eBands[i])
155          pBands[i] = mode->eBands[i];
156    }
157    pBands[PBANDS+1] = mode->eBands[mode->nbEBands+1];
158    for (i=1;i<mode->nbPBands+1;i++)
159    {
160       int j;
161       for (j=0;j<mode->nbEBands;j++)
162          if (mode->eBands[j] <= pBands[i] && mode->eBands[j+1] > pBands[i])
163             break;
164       /*printf ("%d %d\n", i, j);*/
165       if (mode->eBands[j] != pBands[i])
166       {
167          if (pBands[i]-mode->eBands[j] < mode->eBands[j+1]-pBands[i] && 
168              mode->eBands[j] != pBands[i-1])
169             pBands[i] = mode->eBands[j];
170          else
171             pBands[i] = mode->eBands[j+1];
172       }
173    }
174    /*for (i=0;i<mode->nbPBands+2;i++)
175       printf("%d ", pBands[i]);
176    printf ("\n");*/
177    mode->pBands = pBands;
178    mode->pitchEnd = pBands[PBANDS];
179 }
180
181 static void compute_allocation_table(CELTMode *mode, int res)
182 {
183    int i, j, eband;
184    int *allocVectors;
185    
186    mode->nbAllocVectors = BITALLOC_SIZE;
187    allocVectors = celt_alloc(sizeof(int)*(BITALLOC_SIZE*mode->nbEBands));
188    for (i=0;i<BITALLOC_SIZE;i++)
189    {
190       eband = 0;
191       for (j=0;j<BARK_BANDS;j++)
192       {
193          int edge, low;
194          edge = mode->eBands[eband+1]*res;
195          if (edge < bark_freq[j+1])
196          {
197             int num, den;
198             num = band_allocation[i*BARK_BANDS+j] * (edge-bark_freq[j]);
199             den = bark_freq[j+1]-bark_freq[j];
200             low = (num+den/2)/den;
201             allocVectors[i*mode->nbEBands+eband] += low;
202             eband++;
203             allocVectors[i*mode->nbEBands+eband] += band_allocation[i*BARK_BANDS+j]-low;
204          } else {
205             allocVectors[i*mode->nbEBands+eband] += band_allocation[i*BARK_BANDS+j];
206          }
207       }
208    }
209    /*for (i=0;i<BITALLOC_SIZE;i++)
210    {
211       for (j=0;j<mode->nbEBands;j++)
212          printf ("%2d ", allocVectors[i*mode->nbEBands+j]);
213       printf ("\n");
214    }*/
215    mode->allocVectors = allocVectors;
216 }
217
218
219
220 CELTMode *celt_mode_create(celt_int32_t Fs, int channels, int frame_size, int lookahead, int *error)
221 {
222 #ifdef STATIC_MODES
223    CELTMode *mode = NULL;
224    int i;
225    for (i=0;i<TOTAL_MODES;i++)
226    {
227       if (Fs == static_mode_list[i]->Fs &&
228           channels == static_mode_list[i]->nbChannels &&
229           frame_size == static_mode_list[i]->mdctSize &&
230           lookahead == static_mode_list[i]->overlap)
231       {
232          mode = static_mode_list[i];
233          break;
234       }
235    }
236    if (mode == NULL)
237    {
238       celt_warning("Mode not included as part of the static modes");
239       if (error)
240          *error = CELT_BAD_ARG;
241       return NULL;
242    }
243 #else
244    int res;
245    int i;
246    CELTMode *mode;
247    celt_word16_t *window;
248
249    /* The good thing here is that permutation of the arguments will automatically be invalid */
250    
251    if (Fs < 32000 || Fs > 64000)
252    {
253       celt_warning("Sampling rate must be between 32 kHz and 64 kHz");
254       if (error)
255          *error = CELT_BAD_ARG;
256       return NULL;
257    }
258    if (channels < 0 || channels > 2)
259    {
260       celt_warning("Only mono and stereo supported");
261       if (error)
262          *error = CELT_BAD_ARG;
263       return NULL;
264    }
265    if (frame_size < 64 || frame_size > 256 || frame_size%2!=0)
266    {
267       celt_warning("Only even frame sizes between 64 and 256 are supported");
268       if (error)
269          *error = CELT_BAD_ARG;
270       return NULL;
271    }
272    if (lookahead < 32 || lookahead > frame_size)
273    {
274       celt_warning("The overlap must be between 32 and the frame size");
275       if (error)
276          *error = CELT_BAD_ARG;
277       return NULL;
278    }
279    res = (Fs+frame_size)/(2*frame_size);
280    
281    mode = celt_alloc(sizeof(CELTMode));
282    mode->Fs = Fs;
283    mode->overlap = lookahead;
284    mode->mdctSize = frame_size;
285    mode->nbMdctBlocks = 1;
286    mode->nbChannels = channels;
287    mode->eBands = compute_ebands(Fs, frame_size, &mode->nbEBands);
288    compute_pbands(mode, res);
289    mode->ePredCoef = QCONST16(.8f,15);
290    
291    compute_allocation_table(mode, res);
292    /*printf ("%d bands\n", mode->nbEBands);*/
293    
294    window = (celt_word16_t*)celt_alloc(mode->overlap*sizeof(celt_word16_t));
295
296 #ifndef FIXED_POINT
297    for (i=0;i<mode->overlap;i++)
298       window[i] = Q15ONE*sin(.5*M_PI* sin(.5*M_PI*(i+.5)/mode->overlap) * sin(.5*M_PI*(i+.5)/mode->overlap));
299 #else
300    for (i=0;i<mode->overlap;i++)
301       window[i] = MIN32(32767,32768.*sin(.5*M_PI* sin(.5*M_PI*(i+.5)/mode->overlap) * sin(.5*M_PI*(i+.5)/mode->overlap)));
302 #endif
303    mode->window = window;
304
305    mode->marker_start = MODEVALID;
306    mode->marker_end = MODEVALID;
307 #endif
308    mdct_init(&mode->mdct, 2*mode->mdctSize);
309    compute_alloc_cache(mode);
310    psydecay_init(&mode->psy, MAX_PERIOD/2, mode->Fs);
311    if (error)
312       *error = CELT_OK;
313    return mode;
314 }
315
316 void celt_mode_destroy(CELTMode *mode)
317 {
318    int i;
319    const int *prevPtr = NULL;
320    for (i=0;i<mode->nbEBands;i++)
321    {
322       if (mode->bits[i] != prevPtr)
323       {
324          prevPtr = mode->bits[i];
325          celt_free((int*)mode->bits[i]);
326       }
327    }
328    celt_free((int**)mode->bits);
329    mdct_clear(&mode->mdct);
330    psydecay_clear(&mode->psy);
331 #ifndef STATIC_MODES
332    if (check_mode(mode) != CELT_OK)
333       return;
334    celt_free((int*)mode->eBands);
335    celt_free((int*)mode->pBands);
336    celt_free((int*)mode->allocVectors);
337    
338    celt_free((celt_word16_t*)mode->window);
339
340    mode->marker_start = MODEFREED;
341    mode->marker_end = MODEFREED;
342    celt_free((CELTMode *)mode);
343 #endif
344 }
345
346 int check_mode(const CELTMode *mode)
347 {
348    if (mode->marker_start == MODEVALID && mode->marker_end == MODEVALID)
349       return CELT_OK;
350    if (mode->marker_start == MODEFREED || mode->marker_end == MODEFREED)
351       celt_warning("Using a mode that has already been freed");
352    else
353       celt_warning("This is not a valid CELT mode");
354    return CELT_INVALID_MODE;
355 }