blob: 7b38c1e825b105481958a6958a5a582c011129b5 [file] [log] [blame]
Jean-Marc Valin8b2ff0d2009-10-17 21:40:10 -04001/* Copyright (c) 2007-2008 CSIRO
2 Copyright (c) 2007-2009 Xiph.Org Foundation
3 Copyright (c) 2008 Gregory Maxwell
4 Written by Jean-Marc Valin and Gregory Maxwell */
Jean-Marc Valinecb36a32007-12-05 01:31:49 +11005/*
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
8 are met:
9
10 - Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12
13 - Redistributions in binary form must reproduce the above copyright
14 notice, this list of conditions and the following disclaimer in the
15 documentation and/or other materials provided with the distribution.
16
17 - Neither the name of the Xiph.org Foundation nor the names of its
18 contributors may be used to endorse or promote products derived from
19 this software without specific prior written permission.
20
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
25 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32*/
33
Jean-Marc Valin02fa9132008-02-20 12:09:29 +110034#ifdef HAVE_CONFIG_H
35#include "config.h"
36#endif
37
Jean-Marc Valin65d57e62008-02-18 15:49:37 +110038#include "celt.h"
Jean-Marc Valinecb36a32007-12-05 01:31:49 +110039#include "modes.h"
Jean-Marc Valin472a5f02008-02-19 13:12:32 +110040#include "rate.h"
Jean-Marc Valin81a82952008-02-17 22:41:29 +110041#include "os_support.h"
Jean-Marc Valinf7cec832008-04-18 17:29:56 +100042#include "stack_alloc.h"
Jean-Marc Valin4ce92052008-04-23 13:42:10 +100043#include "quant_bands.h"
Jean-Marc Valinecb36a32007-12-05 01:31:49 +110044
Jean-Marc Valine0c25452010-09-03 11:52:38 -040045static const celt_int16 eband5ms[] = {
46 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 34, 40, 48, 60, 78, 100
47};
48
Jean-Marc Valin78ea9fd2010-09-24 08:27:28 -040049#if 1
50
Jean-Marc Valine0c25452010-09-03 11:52:38 -040051#define BITALLOC_SIZE 9
52/* Bit allocation table in units of 1/32 bit/sample (0.1875 dB SNR) */
53static const unsigned char band_allocation[] = {
54/*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 */
55 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
56 80, 80, 75, 70, 65, 60, 55, 50, 44, 40, 35, 30, 15, 1, 0, 0, 0, 0, 0, 0, 0,
57 90, 85, 85, 85, 85, 82, 78, 74, 70, 65, 60, 54, 45, 35, 25, 15, 1, 0, 0, 0, 0,
58120,110,110,110,100, 96, 90, 88, 84, 76, 70, 65, 60, 45, 35, 25, 20, 1, 1, 0, 0,
59135,125,125,125,115,112,104,104,100, 96, 83, 78, 70, 55, 46, 36, 32, 28, 20, 8, 0,
60175,170,167,155,149,145,143,138,138,138,129,124,108, 96, 88, 83, 72, 56, 44, 28, 2,
61224,192,192,192,192,192,192,192,192,192,192,192,156,128,108, 96, 88, 76, 68, 44, 20,
62255,224,224,224,224,224,224,224,224,224,224,224,224,188,164,148,124, 96, 80, 64, 40,
63255,255,255,255,255,255,255,255,255,255,255,255,255,255,252,220,188,144,104, 84, 60,
64};
65
Jean-Marc Valin78ea9fd2010-09-24 08:27:28 -040066#else
67/* Alternate tuning (partially derived from Vorbis) */
68#define BITALLOC_SIZE 11
69/* Bit allocation table in units of 1/32 bit/sample (0.1875 dB SNR) */
70static const unsigned char band_allocation[] = {
71 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
72 85, 85, 75, 70, 63, 55, 50, 45, 40, 35, 33, 28, 15, 1, 0, 0, 0, 0, 0, 0, 0,
73108,105, 96, 88, 83, 77, 72, 66, 59, 53, 49, 44, 41, 37, 30, 27, 1, 0, 0, 0, 0,
74120,117,108,100, 95, 89, 84, 78, 71, 65, 61, 56, 53, 49, 42, 34, 30, 25, 1, 0, 0,
75136,131,123,118,109, 99, 93, 87, 81, 75, 69, 66, 61, 56, 50, 45, 40, 35, 32, 1, 1,
76151,148,138,131,122,113,105,102, 96, 92, 85, 82, 76, 68, 63, 58, 51, 44, 38, 27, 8,
77171,168,158,147,139,130,123,119,111,108,103, 99, 91, 82, 78, 75, 66, 55, 48, 36, 12,
78187,184,174,163,155,146,139,135,127,124,119,115,107, 98, 94, 91, 82, 71, 64, 52, 28,
79203,200,191,181,174,166,159,156,149,147,143,139,132,124,121,119,110,100, 94, 83, 60,
80219,216,207,197,190,183,176,173,166,164,161,157,150,142,139,138,129,119,113,102, 80,
81229,229,224,222,223,224,224,225,222,221,221,220,220,219,218,200,178,154,146,130,102,
82};
83
84#endif
85
Jean-Marc Valinf39e8692008-03-10 12:13:23 +110086#ifdef STATIC_MODES
Jean-Marc Valinb18ec0b2008-04-11 04:07:52 +100087#include "static_modes.c"
Jean-Marc Valinf39e8692008-03-10 12:13:23 +110088#endif
89
Jean-Marc Valind748cd52008-03-01 07:27:03 +110090#ifndef M_PI
91#define M_PI 3.141592653
92#endif
93
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +110094
Jean-Marc Valin30f7f812009-10-17 14:35:13 -040095int celt_mode_info(const CELTMode *mode, int request, celt_int32 *value)
Jean-Marc Valinf997ad52008-01-31 16:47:16 +110096{
97 switch (request)
98 {
Jean-Marc Valinf997ad52008-01-31 16:47:16 +110099 case CELT_GET_LOOKAHEAD:
100 *value = mode->overlap;
101 break;
Jean-Marc Valin59093c02008-05-15 21:53:27 +1000102 case CELT_GET_BITSTREAM_VERSION:
103 *value = CELT_BITSTREAM_VERSION;
104 break;
Gregory Maxwelld9458cd2009-05-30 17:04:02 -0400105 case CELT_GET_SAMPLE_RATE:
106 *value = mode->Fs;
107 break;
Jean-Marc Valincb7a2a32008-02-11 16:44:48 +1100108 default:
Jean-Marc Valinb6f90612008-10-05 22:39:13 -0400109 return CELT_UNIMPLEMENTED;
Jean-Marc Valinf997ad52008-01-31 16:47:16 +1100110 }
Jean-Marc Valincb7a2a32008-02-11 16:44:48 +1100111 return CELT_OK;
Jean-Marc Valinf997ad52008-01-31 16:47:16 +1100112}
113
Jean-Marc Valin5588d522008-03-10 15:07:58 +1100114#ifndef STATIC_MODES
115
Jean-Marc Valin17683eb2008-02-18 21:45:19 +1100116/* Defining 25 critical bands for the full 0-20 kHz audio bandwidth
117 Taken from http://ccrma.stanford.edu/~jos/bbt/Bark_Frequency_Scale.html */
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100118#define BARK_BANDS 25
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400119static const celt_int16 bark_freq[BARK_BANDS+1] = {
Jean-Marc Valin17683eb2008-02-18 21:45:19 +1100120 0, 100, 200, 300, 400,
121 510, 630, 770, 920, 1080,
122 1270, 1480, 1720, 2000, 2320,
123 2700, 3150, 3700, 4400, 5300,
124 6400, 7700, 9500, 12000, 15500,
125 20000};
126
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400127static celt_int16 *compute_ebands(celt_int32 Fs, int frame_size, int res, int *nbEBands)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100128{
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400129 celt_int16 *eBands;
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400130 int i, lin, low, high, nBark, offset=0;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100131
Jean-Marc Valin3b0df0d2010-07-16 15:55:30 -0400132 /* All modes that have 2.5 ms short blocks use the same definition */
133 if (Fs == 400*(celt_int32)frame_size)
Jean-Marc Valin20639c42010-05-19 16:10:12 -0400134 {
135 *nbEBands = sizeof(eband5ms)/sizeof(eband5ms[0])-1;
Jean-Marc Valin8952c452010-07-16 21:48:44 -0400136 eBands = celt_alloc(sizeof(celt_int16)*(*nbEBands+1));
137 for (i=0;i<*nbEBands+1;i++)
Jean-Marc Valin20639c42010-05-19 16:10:12 -0400138 eBands[i] = eband5ms[i];
Jean-Marc Valin20639c42010-05-19 16:10:12 -0400139 return eBands;
140 }
Gregory Maxwellcbaf67e2008-09-28 04:19:19 -0400141 /* Find the number of critical bands supported by our sampling rate */
142 for (nBark=1;nBark<BARK_BANDS;nBark++)
143 if (bark_freq[nBark+1]*2 >= Fs)
144 break;
145
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100146 /* Find where the linear part ends (i.e. where the spacing is more than min_width */
Gregory Maxwellcbaf67e2008-09-28 04:19:19 -0400147 for (lin=0;lin<nBark;lin++)
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400148 if (bark_freq[lin+1]-bark_freq[lin] >= res)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100149 break;
Jean-Marc Valin4fb95682010-04-20 23:30:22 -0400150
Jean-Marc Valin65ee67a2010-04-26 07:08:44 -0400151 low = (bark_freq[lin]+res/2)/res;
Gregory Maxwellcbaf67e2008-09-28 04:19:19 -0400152 high = nBark-lin;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100153 *nbEBands = low+high;
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400154 eBands = celt_alloc(sizeof(celt_int16)*(*nbEBands+2));
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100155
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400156 if (eBands==NULL)
157 return NULL;
158
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100159 /* Linear spacing (min_width) */
160 for (i=0;i<low;i++)
Jean-Marc Valin65ee67a2010-04-26 07:08:44 -0400161 eBands[i] = i;
Jean-Marc Valinbe8d1252010-04-21 18:09:07 -0400162 if (low>0)
163 offset = eBands[low-1]*res - bark_freq[lin-1];
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100164 /* Spacing follows critical bands */
165 for (i=0;i<high;i++)
Jean-Marc Valin39f68ac2009-10-03 23:27:52 -0400166 {
167 int target = bark_freq[lin+i];
Jean-Marc Valin65ee67a2010-04-26 07:08:44 -0400168 eBands[i+low] = (target+(offset+res)/2)/res;
Jean-Marc Valin39f68ac2009-10-03 23:27:52 -0400169 offset = eBands[i+low]*res - target;
170 }
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100171 /* Enforce the minimum spacing at the boundary */
172 for (i=0;i<*nbEBands;i++)
Jean-Marc Valin65ee67a2010-04-26 07:08:44 -0400173 if (eBands[i] < i)
174 eBands[i] = i;
175 eBands[*nbEBands] = (bark_freq[nBark]+res/2)/res;
Jean-Marc Valin8952c452010-07-16 21:48:44 -0400176 if (eBands[*nbEBands] > frame_size)
177 eBands[*nbEBands] = frame_size;
Jean-Marc Valinfbfddf72009-07-19 21:07:12 -0400178 for (i=1;i<*nbEBands-1;i++)
179 {
180 if (eBands[i+1]-eBands[i] < eBands[i]-eBands[i-1])
181 {
Jean-Marc Valin65ee67a2010-04-26 07:08:44 -0400182 eBands[i] -= (2*eBands[i]-eBands[i-1]-eBands[i+1])/2;
Jean-Marc Valinfbfddf72009-07-19 21:07:12 -0400183 }
184 }
Jean-Marc Valin65ee67a2010-04-26 07:08:44 -0400185 /*for (i=0;i<=*nbEBands+1;i++)
Jean-Marc Valinfbfddf72009-07-19 21:07:12 -0400186 printf ("%d ", eBands[i]);
Jean-Marc Valin39f68ac2009-10-03 23:27:52 -0400187 printf ("\n");
188 exit(1);*/
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100189 /* FIXME: Remove last band if too small */
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100190 return eBands;
191}
192
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400193static void compute_allocation_table(CELTMode *mode, int res)
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100194{
Jean-Marc Valin2f6c5fe2010-06-28 17:22:37 -0400195 int i, j;
Jean-Marc Valin01b54b92010-06-03 23:29:35 -0400196 unsigned char *allocVectors;
Jean-Marc Valinc51e98b2010-06-03 22:11:41 -0400197 int maxBands = sizeof(eband5ms)/sizeof(eband5ms[0])-1;
Jean-Marc Valin36e6e012008-08-02 22:25:19 -0400198
Jean-Marc Valin12e851d2010-06-03 08:12:11 -0400199 mode->nbAllocVectors = BITALLOC_SIZE;
Jean-Marc Valin01b54b92010-06-03 23:29:35 -0400200 allocVectors = celt_alloc(sizeof(unsigned char)*(BITALLOC_SIZE*mode->nbEBands));
Jean-Marc Valin12e851d2010-06-03 08:12:11 -0400201 if (allocVectors==NULL)
202 return;
203
Jean-Marc Valinc51e98b2010-06-03 22:11:41 -0400204 /* Check for standard mode */
Jean-Marc Valin12e851d2010-06-03 08:12:11 -0400205 if (mode->Fs == 400*(celt_int32)mode->shortMdctSize && mode->Fs >= 40000)
206 {
207 for (i=0;i<BITALLOC_SIZE*mode->nbEBands;i++)
Jean-Marc Valinffe50612010-06-04 00:13:19 -0400208 allocVectors[i] = band_allocation[i];
Jean-Marc Valin12e851d2010-06-03 08:12:11 -0400209 mode->allocVectors = allocVectors;
210 return;
211 }
Jean-Marc Valinc51e98b2010-06-03 22:11:41 -0400212 /* If not the standard mode, interpolate */
213
Jean-Marc Valin36e6e012008-08-02 22:25:19 -0400214 /* Compute per-codec-band allocation from per-critical-band matrix */
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100215 for (i=0;i<BITALLOC_SIZE;i++)
216 {
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400217 celt_int32 current = 0;
Gregory Maxwellec836da2009-05-04 14:55:40 -0400218 int eband = 0;
Jean-Marc Valin2f6c5fe2010-06-28 17:22:37 -0400219 /* We may be looping over too many bands, but eband will stop being
220 incremented once we reach the last band */
221 for (j=0;j<maxBands;j++)
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100222 {
Jean-Marc Valin137f3362010-04-14 17:42:22 -0400223 int edge, low, high;
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400224 celt_int32 alloc;
Jean-Marc Valinffe50612010-06-04 00:13:19 -0400225 alloc = band_allocation[i*maxBands + j]*(mode->eBands[eband+1]-mode->eBands[eband])<<4;
Jean-Marc Valinc51e98b2010-06-03 22:11:41 -0400226 low = eband5ms[j]*200;
227 high = eband5ms[j+1]*200;
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400228 edge = mode->eBands[eband+1]*res;
Jean-Marc Valin3ff5e4c2010-04-14 18:02:09 -0400229 while (edge <= high && eband < mode->nbEBands)
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100230 {
Jean-Marc Valin137f3362010-04-14 17:42:22 -0400231 celt_int32 num;
232 int den, bits;
Jean-Marc Valinbb8fa1f2010-06-03 00:33:42 -0400233 int N = (mode->eBands[eband+1]-mode->eBands[eband]);
Jean-Marc Valin137f3362010-04-14 17:42:22 -0400234 num = alloc * (edge-low);
235 den = high-low;
236 /* Divide with rounding */
237 bits = (2*num+den)/(2*den);
Jean-Marc Valinc51e98b2010-06-03 22:11:41 -0400238 allocVectors[i*mode->nbEBands+eband] = (2*(current+bits)+(N<<4))/(2*N<<4);
Jean-Marc Valin137f3362010-04-14 17:42:22 -0400239 /* Remove the part of the band we just allocated */
240 low = edge;
241 alloc -= bits;
242
243 /* Move to next eband */
244 current = 0;
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100245 eband++;
Jean-Marc Valin8952c452010-07-16 21:48:44 -0400246 if (eband < mode->nbEBands)
247 edge = mode->eBands[eband+1]*res;
Jean-Marc Valin137f3362010-04-14 17:42:22 -0400248 }
249 current += alloc;
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100250 }
Jean-Marc Valin137f3362010-04-14 17:42:22 -0400251 if (eband < mode->nbEBands)
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400252 {
Jean-Marc Valinbb8fa1f2010-06-03 00:33:42 -0400253 int N = (mode->eBands[eband+1]-mode->eBands[eband]);
Jean-Marc Valinc51e98b2010-06-03 22:11:41 -0400254 allocVectors[i*mode->nbEBands+eband] = (2*current+(N<<4))/(2*N<<4);
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400255 }
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100256 }
Jean-Marc Valinc51e98b2010-06-03 22:11:41 -0400257 /*printf ("\n");
258 for (i=0;i<BITALLOC_SIZE;i++)
Jean-Marc Valinbb8fa1f2010-06-03 00:33:42 -0400259 {
260 for (j=0;j<mode->nbEBands;j++)
261 printf ("%d ", allocVectors[i*mode->nbEBands+j]);
262 printf ("\n");
263 }
264 exit(0);*/
265
Jean-Marc Valin36e6e012008-08-02 22:25:19 -0400266 mode->allocVectors = allocVectors;
Jean-Marc Valinad637192008-05-07 13:44:39 +1000267}
268
Jean-Marc Valin36e6e012008-08-02 22:25:19 -0400269#endif /* STATIC_MODES */
270
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400271CELTMode *celt_mode_create(celt_int32 Fs, int frame_size, int *error)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100272{
Jean-Marc Valin47c248a2008-04-26 08:16:12 +1000273 int i;
Jean-Marc Valin40603b22010-08-25 23:02:49 -0400274#ifdef STATIC_MODES
275 for (i=0;i<TOTAL_MODES;i++)
276 {
277 if (Fs == static_mode_list[i]->Fs &&
278 frame_size == static_mode_list[i]->shortMdctSize*static_mode_list[i]->nbShortMdcts)
279 {
280 return (CELTMode*)static_mode_list[i];
281 }
282 }
Jean-Marc Valin40603b22010-08-25 23:02:49 -0400283 if (error)
284 *error = CELT_BAD_ARG;
285 return NULL;
286#else
287 int res;
288 CELTMode *mode=NULL;
289 celt_word16 *window;
290 celt_int16 *logN;
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400291 int LM;
Jean-Marc Valin47c248a2008-04-26 08:16:12 +1000292#ifdef STDIN_TUNING
293 scanf("%d ", &MIN_BINS);
294 scanf("%d ", &BITALLOC_SIZE);
295 band_allocation = celt_alloc(sizeof(int)*BARK_BANDS*BITALLOC_SIZE);
296 for (i=0;i<BARK_BANDS*BITALLOC_SIZE;i++)
297 {
298 scanf("%d ", band_allocation+i);
299 }
300#endif
Jean-Marc Valinf7cec832008-04-18 17:29:56 +1000301 ALLOC_STACK;
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400302#if !defined(VAR_ARRAYS) && !defined(USE_ALLOCA)
303 if (global_stack==NULL)
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400304 goto failure;
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400305#endif
Jean-Marc Valin3dbc1d02008-03-08 15:21:24 +1100306
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100307 /* The good thing here is that permutation of the arguments will automatically be invalid */
308
Jean-Marc Valin223b69d2010-07-16 11:47:50 -0400309 if (Fs < 8000 || Fs > 96000)
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100310 {
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100311 if (error)
312 *error = CELT_BAD_ARG;
313 return NULL;
314 }
Jean-Marc Valin223b69d2010-07-16 11:47:50 -0400315 if (frame_size < 40 || frame_size > 1024 || frame_size%2!=0)
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100316 {
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100317 if (error)
318 *error = CELT_BAD_ARG;
319 return NULL;
320 }
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100321
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100322 mode = celt_alloc(sizeof(CELTMode));
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400323 if (mode==NULL)
324 goto failure;
Jean-Marc Valine6b74652008-02-20 18:01:08 +1100325 mode->Fs = Fs;
Gregory Maxwell23e654f2008-09-27 16:20:03 -0400326
Jean-Marc Valin223b69d2010-07-16 11:47:50 -0400327 /* Pre/de-emphasis depends on sampling rate. The "standard" pre-emphasis
328 is defined as A(z) = 1 - 0.85*z^-1 at 48 kHz. Other rates should
329 approximate that. */
330 if(Fs < 12000) /* 8 kHz */
331 {
332 mode->preemph[0] = QCONST16(.35f, 15);
333 mode->preemph[1] = -QCONST16(.18f, 15);
334 mode->preemph[2] = QCONST16(.272f, SIG_SHIFT);
335 mode->preemph[3] = QCONST16(3.6765f, 13);
336 } else if(Fs < 24000) /* 16 kHz */
337 {
338 mode->preemph[0] = QCONST16(.6f, 15);
339 mode->preemph[1] = -QCONST16(.18f, 15);
340 mode->preemph[2] = QCONST16(.4425f, SIG_SHIFT);
341 mode->preemph[3] = QCONST16(2.259887f, 13);
342 } else if(Fs < 40000) /* 32 kHz */
343 {
344 mode->preemph[0] = QCONST16(.78f, 15);
345 mode->preemph[1] = -QCONST16(.1f, 15);
346 mode->preemph[2] = QCONST16(.75f, SIG_SHIFT);
347 mode->preemph[3] = QCONST16(1.33333333f, 13);
348 } else /* 48 kHz */
349 {
350 mode->preemph[0] = QCONST16(.85f, 15);
351 mode->preemph[1] = QCONST16(.0f, 15);
352 mode->preemph[2] = QCONST16(1.f, SIG_SHIFT);
353 mode->preemph[3] = QCONST16(1.f, 13);
354 }
355
Jean-Marc Valina2546bb2010-07-16 12:00:00 -0400356 if ((celt_int32)frame_size*75 >= Fs && (frame_size%16)==0)
Jean-Marc Valine6d832a2009-07-08 22:21:31 -0400357 {
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400358 LM = 3;
Jean-Marc Valina2546bb2010-07-16 12:00:00 -0400359 } else if ((celt_int32)frame_size*150 >= Fs && (frame_size%8)==0)
Jean-Marc Valin16ca18b2008-06-18 23:44:48 +1000360 {
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400361 LM = 2;
Jean-Marc Valina2546bb2010-07-16 12:00:00 -0400362 } else if ((celt_int32)frame_size*300 >= Fs && (frame_size%4)==0)
Gregory Maxwell23e654f2008-09-27 16:20:03 -0400363 {
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400364 LM = 1;
Gregory Maxwell23e654f2008-09-27 16:20:03 -0400365 } else
366 {
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400367 LM = 0;
Jean-Marc Valin16ca18b2008-06-18 23:44:48 +1000368 }
Gregory Maxwell23e654f2008-09-27 16:20:03 -0400369
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400370 mode->maxLM = LM;
371 mode->nbShortMdcts = 1<<LM;
Jean-Marc Valin60ff9992010-06-27 13:49:38 -0400372 mode->shortMdctSize = frame_size/mode->nbShortMdcts;
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400373 res = (mode->Fs+mode->shortMdctSize)/(2*mode->shortMdctSize);
374
375 mode->eBands = compute_ebands(Fs, mode->shortMdctSize, res, &mode->nbEBands);
Jean-Marc Valinfbfddf72009-07-19 21:07:12 -0400376 if (mode->eBands==NULL)
377 goto failure;
Jean-Marc Valinfbfddf72009-07-19 21:07:12 -0400378
Jean-Marc Valin85f41b22010-07-16 18:12:45 -0400379 mode->effEBands = mode->nbEBands;
380 while (mode->eBands[mode->effEBands] > mode->shortMdctSize)
381 mode->effEBands--;
Jean-Marc Valin4834c922009-09-28 19:17:34 -0400382
Jean-Marc Valin08192e32009-07-02 13:28:55 -0400383 /* Overlap must be divisible by 4 */
Jean-Marc Valin16ca18b2008-06-18 23:44:48 +1000384 if (mode->nbShortMdcts > 1)
Jean-Marc Valince4dd362010-05-07 07:45:18 -0400385 mode->overlap = (mode->shortMdctSize>>2)<<2;
Jean-Marc Valin16ca18b2008-06-18 23:44:48 +1000386 else
Gregory Maxwell23e654f2008-09-27 16:20:03 -0400387 mode->overlap = (frame_size>>3)<<2;
388
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400389
390 compute_allocation_table(mode, res);
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400391 if (mode->allocVectors==NULL)
392 goto failure;
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100393
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400394 window = (celt_word16*)celt_alloc(mode->overlap*sizeof(celt_word16));
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400395 if (window==NULL)
396 goto failure;
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100397
Jean-Marc Valinf28062f2008-03-03 13:24:01 +1100398#ifndef FIXED_POINT
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100399 for (i=0;i<mode->overlap;i++)
Jean-Marc Valin3dbc1d02008-03-08 15:21:24 +1100400 window[i] = Q15ONE*sin(.5*M_PI* sin(.5*M_PI*(i+.5)/mode->overlap) * sin(.5*M_PI*(i+.5)/mode->overlap));
Jean-Marc Valinf28062f2008-03-03 13:24:01 +1100401#else
402 for (i=0;i<mode->overlap;i++)
Jean-Marc Valin8974f002010-03-20 00:41:39 -0400403 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))));
Jean-Marc Valinf28062f2008-03-03 13:24:01 +1100404#endif
Jean-Marc Valin3dbc1d02008-03-08 15:21:24 +1100405 mode->window = window;
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100406
Jean-Marc Valinf400a3c2010-04-05 23:58:44 -0400407 logN = (celt_int16*)celt_alloc(mode->nbEBands*sizeof(celt_int16));
408 if (logN==NULL)
409 goto failure;
410
411 for (i=0;i<mode->nbEBands;i++)
Jean-Marc Valinaead79b2010-05-11 07:34:24 -0400412 logN[i] = log2_frac(mode->eBands[i+1]-mode->eBands[i], BITRES);
Jean-Marc Valinf400a3c2010-04-05 23:58:44 -0400413 mode->logN = logN;
Jean-Marc Valin3ad8db42010-08-25 13:11:09 -0400414
415 compute_pulse_cache(mode, mode->maxLM);
Jean-Marc Valin640f7fd2009-06-21 09:47:51 -0400416
Jean-Marc Valin732ea382010-08-25 13:52:27 -0400417 clt_mdct_init(&mode->mdct, 2*mode->shortMdctSize*mode->nbShortMdcts, mode->maxLM);
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400418 if ((mode->mdct.trig==NULL)
Jean-Marc Valin9714f662009-08-12 20:29:57 -0400419#ifndef ENABLE_TI_DSPLIB55
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400420 || (mode->mdct.kfft==NULL)
Jean-Marc Valin9714f662009-08-12 20:29:57 -0400421#endif
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400422 )
423 goto failure;
424
Jean-Marc Valin073d0bc2010-05-05 21:37:53 -0400425 mode->prob = quant_prob_alloc(mode);
426 if (mode->prob==NULL)
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400427 goto failure;
Jean-Marc Valin40603b22010-08-25 23:02:49 -0400428
Jean-Marc Valin680a9ec2008-03-10 14:52:18 +1100429 if (error)
430 *error = CELT_OK;
Jean-Marc Valin40603b22010-08-25 23:02:49 -0400431
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100432 return mode;
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400433failure:
434 if (error)
435 *error = CELT_INVALID_MODE;
436 if (mode!=NULL)
437 celt_mode_destroy(mode);
438 return NULL;
Jean-Marc Valin40603b22010-08-25 23:02:49 -0400439#endif /* !STATIC_MODES */
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100440}
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100441
Peter Kirk19f9dc92008-06-06 14:38:38 +0200442void celt_mode_destroy(CELTMode *mode)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100443{
Jean-Marc Valin40603b22010-08-25 23:02:49 -0400444#ifndef STATIC_MODES
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400445 if (mode == NULL)
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400446 return;
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400447
Jean-Marc Valin31bec962010-04-07 18:30:28 -0400448 celt_free((celt_int16*)mode->eBands);
449 celt_free((celt_int16*)mode->allocVectors);
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400450
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400451 celt_free((celt_word16*)mode->window);
Jean-Marc Valin31bec962010-04-07 18:30:28 -0400452 celt_free((celt_int16*)mode->logN);
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100453
Jean-Marc Valin732ea382010-08-25 13:52:27 -0400454 celt_free((celt_int16*)mode->cache.index);
455 celt_free((unsigned char*)mode->cache.bits);
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400456 clt_mdct_clear(&mode->mdct);
Jean-Marc Valinbb528812010-08-25 22:12:18 -0400457 quant_prob_free(mode->prob);
Jean-Marc Valin073d0bc2010-05-05 21:37:53 -0400458
Jean-Marc Valin949902f2008-03-11 10:43:06 +1100459 celt_free((CELTMode *)mode);
Jean-Marc Valin40603b22010-08-25 23:02:49 -0400460#endif
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100461}