blob: f33cfab3ff24a243c2b2213033412b87098d7208 [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[] = {
Jean-Marc Valin9cc56bf2011-02-01 22:03:26 -050046/*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 */
Jean-Marc Valin8ccda882010-10-04 18:01:45 -040047 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 34, 40, 48, 60, 78, 100
Jean-Marc Valine0c25452010-09-03 11:52:38 -040048};
49
Jean-Marc Valin54d84c02010-11-19 11:45:37 -050050/* Alternate tuning (partially derived from Vorbis) */
Timothy B. Terriberryce6d0902011-02-01 17:41:12 -080051#define BITALLOC_SIZE 11
Jean-Marc Valin94491652010-10-21 17:10:24 -040052/* Bit allocation table in units of 1/32 bit/sample (0.1875 dB SNR) */
53static const unsigned char band_allocation[] = {
Jean-Marc Valin54d84c02010-11-19 11:45:37 -050054/*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 */
Jean-Marc Valin94491652010-10-21 17:10:24 -040055 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
Jean-Marc Valinc992a0d2010-11-19 14:06:10 -050056 90, 80, 75, 69, 63, 56, 49, 40, 34, 29, 20, 18, 10, 0, 0, 0, 0, 0, 0, 0, 0,
Jean-Marc Valin54d84c02010-11-19 11:45:37 -050057110,100, 90, 84, 78, 71, 65, 58, 51, 45, 39, 32, 26, 20, 12, 0, 0, 0, 0, 0, 0,
Jean-Marc Valinc992a0d2010-11-19 14:06:10 -050058118,110,103, 93, 86, 80, 75, 70, 65, 59, 53, 47, 40, 31, 23, 15, 4, 0, 0, 0, 0,
59126,119,112,104, 95, 89, 83, 78, 72, 66, 60, 54, 47, 39, 32, 25, 17, 12, 1, 0, 0,
Jean-Marc Valin54d84c02010-11-19 11:45:37 -050060134,127,120,114,103, 97, 91, 85, 78, 72, 66, 60, 54, 47, 41, 35, 29, 23, 16, 10, 1,
Jean-Marc Valindd4bf632010-11-30 15:31:45 -050061144,137,130,124,113,107,101, 95, 88, 82, 76, 70, 64, 57, 51, 45, 39, 33, 26, 15, 1,
62152,145,138,132,123,117,111,105, 98, 92, 86, 80, 74, 67, 61, 55, 49, 43, 36, 20, 1,
63162,155,148,142,133,127,121,115,108,102, 96, 90, 84, 77, 71, 65, 59, 53, 46, 30, 1,
64172,165,158,152,143,137,131,125,118,112,106,100, 94, 87, 81, 75, 69, 63, 56, 45, 20,
Timothy B. Terriberry89039a32011-01-30 22:27:13 -080065200,200,200,200,200,200,200,200,198,193,188,183,178,173,168,163,158,153,148,129,104,
Jean-Marc Valin94491652010-10-21 17:10:24 -040066};
Jean-Marc Valin78ea9fd2010-09-24 08:27:28 -040067
Jean-Marc Valin665da0b2011-01-30 12:15:12 -050068#ifndef CUSTOM_MODES_ONLY
69 #ifdef FIXED_POINT
70 #include "static_modes_fixed.c"
71 #else
72 #include "static_modes_float.c"
73 #endif
74#endif /* CUSTOM_MODES_ONLY */
Jean-Marc Valinf39e8692008-03-10 12:13:23 +110075
Jean-Marc Valind748cd52008-03-01 07:27:03 +110076#ifndef M_PI
77#define M_PI 3.141592653
78#endif
79
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +110080
Jean-Marc Valin30f7f812009-10-17 14:35:13 -040081int celt_mode_info(const CELTMode *mode, int request, celt_int32 *value)
Jean-Marc Valinf997ad52008-01-31 16:47:16 +110082{
83 switch (request)
84 {
Jean-Marc Valinf997ad52008-01-31 16:47:16 +110085 case CELT_GET_LOOKAHEAD:
86 *value = mode->overlap;
87 break;
Jean-Marc Valin59093c02008-05-15 21:53:27 +100088 case CELT_GET_BITSTREAM_VERSION:
89 *value = CELT_BITSTREAM_VERSION;
90 break;
Gregory Maxwelld9458cd2009-05-30 17:04:02 -040091 case CELT_GET_SAMPLE_RATE:
92 *value = mode->Fs;
93 break;
Jean-Marc Valincb7a2a32008-02-11 16:44:48 +110094 default:
Jean-Marc Valinb6f90612008-10-05 22:39:13 -040095 return CELT_UNIMPLEMENTED;
Jean-Marc Valinf997ad52008-01-31 16:47:16 +110096 }
Jean-Marc Valincb7a2a32008-02-11 16:44:48 +110097 return CELT_OK;
Jean-Marc Valinf997ad52008-01-31 16:47:16 +110098}
99
Jean-Marc Valin5ad35bf2011-01-28 22:42:09 -0500100#ifdef CUSTOM_MODES
Jean-Marc Valin5588d522008-03-10 15:07:58 +1100101
Jean-Marc Valin17683eb2008-02-18 21:45:19 +1100102/* Defining 25 critical bands for the full 0-20 kHz audio bandwidth
103 Taken from http://ccrma.stanford.edu/~jos/bbt/Bark_Frequency_Scale.html */
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100104#define BARK_BANDS 25
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400105static const celt_int16 bark_freq[BARK_BANDS+1] = {
Jean-Marc Valin17683eb2008-02-18 21:45:19 +1100106 0, 100, 200, 300, 400,
107 510, 630, 770, 920, 1080,
108 1270, 1480, 1720, 2000, 2320,
109 2700, 3150, 3700, 4400, 5300,
110 6400, 7700, 9500, 12000, 15500,
111 20000};
112
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400113static celt_int16 *compute_ebands(celt_int32 Fs, int frame_size, int res, int *nbEBands)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100114{
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400115 celt_int16 *eBands;
Timothy B. Terriberrycb8f3662011-02-01 12:32:34 -0800116 int i, j, lin, low, high, nBark, offset=0;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100117
Jean-Marc Valin3b0df0d2010-07-16 15:55:30 -0400118 /* All modes that have 2.5 ms short blocks use the same definition */
119 if (Fs == 400*(celt_int32)frame_size)
Jean-Marc Valin20639c42010-05-19 16:10:12 -0400120 {
121 *nbEBands = sizeof(eband5ms)/sizeof(eband5ms[0])-1;
Jean-Marc Valin8952c452010-07-16 21:48:44 -0400122 eBands = celt_alloc(sizeof(celt_int16)*(*nbEBands+1));
123 for (i=0;i<*nbEBands+1;i++)
Jean-Marc Valin20639c42010-05-19 16:10:12 -0400124 eBands[i] = eband5ms[i];
Jean-Marc Valin20639c42010-05-19 16:10:12 -0400125 return eBands;
126 }
Gregory Maxwellcbaf67e2008-09-28 04:19:19 -0400127 /* Find the number of critical bands supported by our sampling rate */
128 for (nBark=1;nBark<BARK_BANDS;nBark++)
129 if (bark_freq[nBark+1]*2 >= Fs)
130 break;
131
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100132 /* Find where the linear part ends (i.e. where the spacing is more than min_width */
Gregory Maxwellcbaf67e2008-09-28 04:19:19 -0400133 for (lin=0;lin<nBark;lin++)
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400134 if (bark_freq[lin+1]-bark_freq[lin] >= res)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100135 break;
Jean-Marc Valin4fb95682010-04-20 23:30:22 -0400136
Jean-Marc Valin65ee67a2010-04-26 07:08:44 -0400137 low = (bark_freq[lin]+res/2)/res;
Gregory Maxwellcbaf67e2008-09-28 04:19:19 -0400138 high = nBark-lin;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100139 *nbEBands = low+high;
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400140 eBands = celt_alloc(sizeof(celt_int16)*(*nbEBands+2));
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100141
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400142 if (eBands==NULL)
143 return NULL;
144
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100145 /* Linear spacing (min_width) */
146 for (i=0;i<low;i++)
Jean-Marc Valin65ee67a2010-04-26 07:08:44 -0400147 eBands[i] = i;
Jean-Marc Valinbe8d1252010-04-21 18:09:07 -0400148 if (low>0)
149 offset = eBands[low-1]*res - bark_freq[lin-1];
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100150 /* Spacing follows critical bands */
151 for (i=0;i<high;i++)
Jean-Marc Valin39f68ac2009-10-03 23:27:52 -0400152 {
153 int target = bark_freq[lin+i];
Jean-Marc Valin44203902011-01-12 09:22:29 -0500154 /* Round to an even value */
155 eBands[i+low] = (target+offset/2+res)/(2*res)*2;
Jean-Marc Valin39f68ac2009-10-03 23:27:52 -0400156 offset = eBands[i+low]*res - target;
157 }
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100158 /* Enforce the minimum spacing at the boundary */
159 for (i=0;i<*nbEBands;i++)
Jean-Marc Valin65ee67a2010-04-26 07:08:44 -0400160 if (eBands[i] < i)
161 eBands[i] = i;
Jean-Marc Valin44203902011-01-12 09:22:29 -0500162 /* Round to an even value */
163 eBands[*nbEBands] = (bark_freq[nBark]+res)/(2*res)*2;
Jean-Marc Valin8952c452010-07-16 21:48:44 -0400164 if (eBands[*nbEBands] > frame_size)
165 eBands[*nbEBands] = frame_size;
Jean-Marc Valinfbfddf72009-07-19 21:07:12 -0400166 for (i=1;i<*nbEBands-1;i++)
167 {
168 if (eBands[i+1]-eBands[i] < eBands[i]-eBands[i-1])
169 {
Jean-Marc Valin65ee67a2010-04-26 07:08:44 -0400170 eBands[i] -= (2*eBands[i]-eBands[i-1]-eBands[i+1])/2;
Jean-Marc Valinfbfddf72009-07-19 21:07:12 -0400171 }
172 }
Timothy B. Terriberrycb8f3662011-02-01 12:32:34 -0800173 /* Remove any empty bands. */
174 for (i=j=0;i<*nbEBands;i++)
175 if(eBands[i+1]>eBands[j])
176 eBands[++j]=eBands[i+1];
177 *nbEBands=j;
178
Timothy B. Terriberry2799c292011-02-01 12:53:05 -0800179 for (i=1;i<*nbEBands;i++)
180 {
181 /* Every band must be smaller than the last band. */
182 celt_assert(eBands[i]-eBands[i-1]<=eBands[*nbEBands]-eBands[*nbEBands-1]);
183 /* Each band must be no larger than twice the size of the previous one. */
184 celt_assert(eBands[i+1]-eBands[i]<=2*(eBands[i]-eBands[i-1]));
185 }
186
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100187 return eBands;
188}
189
Jean-Marc Valine3e2c262011-01-26 13:09:53 -0500190static void compute_allocation_table(CELTMode *mode)
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100191{
Jean-Marc Valin2f6c5fe2010-06-28 17:22:37 -0400192 int i, j;
Jean-Marc Valin01b54b92010-06-03 23:29:35 -0400193 unsigned char *allocVectors;
Jean-Marc Valinc51e98b2010-06-03 22:11:41 -0400194 int maxBands = sizeof(eband5ms)/sizeof(eband5ms[0])-1;
Jean-Marc Valin36e6e012008-08-02 22:25:19 -0400195
Jean-Marc Valin12e851d2010-06-03 08:12:11 -0400196 mode->nbAllocVectors = BITALLOC_SIZE;
Jean-Marc Valin01b54b92010-06-03 23:29:35 -0400197 allocVectors = celt_alloc(sizeof(unsigned char)*(BITALLOC_SIZE*mode->nbEBands));
Jean-Marc Valin12e851d2010-06-03 08:12:11 -0400198 if (allocVectors==NULL)
199 return;
200
Jean-Marc Valinc51e98b2010-06-03 22:11:41 -0400201 /* Check for standard mode */
Jean-Marc Valin8e31ab32010-12-16 16:45:35 -0500202 if (mode->Fs == 400*(celt_int32)mode->shortMdctSize)
Jean-Marc Valin12e851d2010-06-03 08:12:11 -0400203 {
204 for (i=0;i<BITALLOC_SIZE*mode->nbEBands;i++)
Jean-Marc Valinffe50612010-06-04 00:13:19 -0400205 allocVectors[i] = band_allocation[i];
Jean-Marc Valin12e851d2010-06-03 08:12:11 -0400206 mode->allocVectors = allocVectors;
207 return;
208 }
Jean-Marc Valinc51e98b2010-06-03 22:11:41 -0400209 /* If not the standard mode, interpolate */
Jean-Marc Valin36e6e012008-08-02 22:25:19 -0400210 /* Compute per-codec-band allocation from per-critical-band matrix */
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100211 for (i=0;i<BITALLOC_SIZE;i++)
212 {
Jean-Marc Valin1bfa18c2010-12-01 16:11:38 -0500213 for (j=0;j<mode->nbEBands;j++)
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100214 {
Jean-Marc Valin1bfa18c2010-12-01 16:11:38 -0500215 int k;
216 for (k=0;k<maxBands;k++)
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100217 {
Jean-Marc Valin1bfa18c2010-12-01 16:11:38 -0500218 if (400*(celt_int32)eband5ms[k] > mode->eBands[j]*(celt_int32)mode->Fs/mode->shortMdctSize)
219 break;
Jean-Marc Valin137f3362010-04-14 17:42:22 -0400220 }
Jean-Marc Valin1bfa18c2010-12-01 16:11:38 -0500221 if (k>mode->nbEBands-1)
222 allocVectors[i*mode->nbEBands+j] = band_allocation[i*maxBands + maxBands-1];
223 else {
224 celt_int32 a0, a1;
225 a1 = mode->eBands[j]*(celt_int32)mode->Fs/mode->shortMdctSize - 400*(celt_int32)eband5ms[k-1];
226 a0 = 400*(celt_int32)eband5ms[k] - mode->eBands[j]*(celt_int32)mode->Fs/mode->shortMdctSize;
227 allocVectors[i*mode->nbEBands+j] = (a0*band_allocation[i*maxBands+k-1]
228 + a1*band_allocation[i*maxBands+k])/(a0+a1);
229 }
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400230 }
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100231 }
Jean-Marc Valin1bfa18c2010-12-01 16:11:38 -0500232
Jean-Marc Valinc51e98b2010-06-03 22:11:41 -0400233 /*printf ("\n");
234 for (i=0;i<BITALLOC_SIZE;i++)
Jean-Marc Valinbb8fa1f2010-06-03 00:33:42 -0400235 {
236 for (j=0;j<mode->nbEBands;j++)
237 printf ("%d ", allocVectors[i*mode->nbEBands+j]);
238 printf ("\n");
239 }
240 exit(0);*/
241
Jean-Marc Valin36e6e012008-08-02 22:25:19 -0400242 mode->allocVectors = allocVectors;
Jean-Marc Valinad637192008-05-07 13:44:39 +1000243}
244
Jean-Marc Valin5ad35bf2011-01-28 22:42:09 -0500245#endif /* CUSTOM_MODES */
Jean-Marc Valin36e6e012008-08-02 22:25:19 -0400246
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400247CELTMode *celt_mode_create(celt_int32 Fs, int frame_size, int *error)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100248{
Jean-Marc Valin47c248a2008-04-26 08:16:12 +1000249 int i;
Jean-Marc Valin40603b22010-08-25 23:02:49 -0400250 CELTMode *mode=NULL;
Gregory Maxwell95becbe2011-02-03 21:06:43 -0500251#ifdef CUSTOM_MODES
252 int res;
Jean-Marc Valin40603b22010-08-25 23:02:49 -0400253 celt_word16 *window;
254 celt_int16 *logN;
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400255 int LM;
Gregory Maxwell95becbe2011-02-03 21:06:43 -0500256#endif
Jean-Marc Valin47c248a2008-04-26 08:16:12 +1000257#ifdef STDIN_TUNING
258 scanf("%d ", &MIN_BINS);
259 scanf("%d ", &BITALLOC_SIZE);
260 band_allocation = celt_alloc(sizeof(int)*BARK_BANDS*BITALLOC_SIZE);
261 for (i=0;i<BARK_BANDS*BITALLOC_SIZE;i++)
262 {
263 scanf("%d ", band_allocation+i);
264 }
265#endif
Jean-Marc Valin7e983192011-02-01 18:00:29 -0500266#ifdef CUSTOM_MODES
Jean-Marc Valinf7cec832008-04-18 17:29:56 +1000267 ALLOC_STACK;
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400268#if !defined(VAR_ARRAYS) && !defined(USE_ALLOCA)
269 if (global_stack==NULL)
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400270 goto failure;
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400271#endif
Jean-Marc Valin7e983192011-02-01 18:00:29 -0500272#endif
Jean-Marc Valin3dbc1d02008-03-08 15:21:24 +1100273
Jean-Marc Valin665da0b2011-01-30 12:15:12 -0500274#ifndef CUSTOM_MODES_ONLY
Jean-Marc Valin5ad35bf2011-01-28 22:42:09 -0500275 for (i=0;i<TOTAL_MODES;i++)
276 {
Jean-Marc Valinc97b2582011-01-28 23:07:32 -0500277 int j;
278 for (j=0;j<4;j++)
Jean-Marc Valin5ad35bf2011-01-28 22:42:09 -0500279 {
Jean-Marc Valinc97b2582011-01-28 23:07:32 -0500280 if (Fs == static_mode_list[i]->Fs &&
281 (frame_size<<j) == static_mode_list[i]->shortMdctSize*static_mode_list[i]->nbShortMdcts)
282 {
283 if (error)
284 *error = CELT_OK;
285 return (CELTMode*)static_mode_list[i];
286 }
Jean-Marc Valin5ad35bf2011-01-28 22:42:09 -0500287 }
288 }
Jean-Marc Valin665da0b2011-01-30 12:15:12 -0500289#endif /* CUSTOM_MODES_ONLY */
290
Jean-Marc Valin5ad35bf2011-01-28 22:42:09 -0500291#ifndef CUSTOM_MODES
292 if (error)
293 *error = CELT_BAD_ARG;
294 return NULL;
295#else
296
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100297 /* The good thing here is that permutation of the arguments will automatically be invalid */
298
Jean-Marc Valin223b69d2010-07-16 11:47:50 -0400299 if (Fs < 8000 || Fs > 96000)
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100300 {
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100301 if (error)
302 *error = CELT_BAD_ARG;
303 return NULL;
304 }
Jean-Marc Valin223b69d2010-07-16 11:47:50 -0400305 if (frame_size < 40 || frame_size > 1024 || frame_size%2!=0)
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100306 {
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100307 if (error)
308 *error = CELT_BAD_ARG;
309 return NULL;
310 }
Timothy B. Terriberryaa6fec62011-02-01 15:36:59 -0800311 /* Frames of less than 1ms are not supported. */
312 if ((celt_int32)frame_size*1000 < Fs)
313 {
314 if (error)
315 *error = CELT_INVALID_MODE;
316 return NULL;
317 }
318
319 if ((celt_int32)frame_size*75 >= Fs && (frame_size%16)==0)
320 {
321 LM = 3;
322 } else if ((celt_int32)frame_size*150 >= Fs && (frame_size%8)==0)
323 {
324 LM = 2;
325 } else if ((celt_int32)frame_size*300 >= Fs && (frame_size%4)==0)
326 {
327 LM = 1;
Timothy B. Terriberrycf5d3a82011-02-02 11:42:33 -0800328 } else
Timothy B. Terriberryaa6fec62011-02-01 15:36:59 -0800329 {
330 LM = 0;
331 }
Timothy B. Terriberrycf5d3a82011-02-02 11:42:33 -0800332
Timothy B. Terriberryaa6fec62011-02-01 15:36:59 -0800333 /* Shorts longer than 3.3ms are not supported. */
Timothy B. Terriberrycf5d3a82011-02-02 11:42:33 -0800334 if ((celt_int32)(frame_size>>LM)*300 > Fs)
Timothy B. Terriberryaa6fec62011-02-01 15:36:59 -0800335 {
336 if (error)
337 *error = CELT_INVALID_MODE;
338 return NULL;
339 }
340
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100341 mode = celt_alloc(sizeof(CELTMode));
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400342 if (mode==NULL)
343 goto failure;
Jean-Marc Valine6b74652008-02-20 18:01:08 +1100344 mode->Fs = Fs;
Gregory Maxwell23e654f2008-09-27 16:20:03 -0400345
Jean-Marc Valin223b69d2010-07-16 11:47:50 -0400346 /* Pre/de-emphasis depends on sampling rate. The "standard" pre-emphasis
347 is defined as A(z) = 1 - 0.85*z^-1 at 48 kHz. Other rates should
348 approximate that. */
349 if(Fs < 12000) /* 8 kHz */
350 {
Jean-Marc Valin49f76802011-01-27 17:01:59 -0500351 mode->preemph[0] = QCONST16(0.3500061035f, 15);
352 mode->preemph[1] = -QCONST16(0.1799926758f, 15);
Jean-Marc Valin09213de2011-01-27 21:43:24 -0500353 mode->preemph[2] = QCONST16(0.2719968125f, SIG_SHIFT); /* exact 1/preemph[3] */
Jean-Marc Valin49f76802011-01-27 17:01:59 -0500354 mode->preemph[3] = QCONST16(3.6765136719f, 13);
Jean-Marc Valin223b69d2010-07-16 11:47:50 -0400355 } else if(Fs < 24000) /* 16 kHz */
356 {
Jean-Marc Valin49f76802011-01-27 17:01:59 -0500357 mode->preemph[0] = QCONST16(0.6000061035f, 15);
358 mode->preemph[1] = -QCONST16(0.1799926758f, 15);
Jean-Marc Valin09213de2011-01-27 21:43:24 -0500359 mode->preemph[2] = QCONST16(0.4424998650f, SIG_SHIFT); /* exact 1/preemph[3] */
360 mode->preemph[3] = QCONST16(2.2598876953f, 13);
Jean-Marc Valin223b69d2010-07-16 11:47:50 -0400361 } else if(Fs < 40000) /* 32 kHz */
362 {
Jean-Marc Valin49f76802011-01-27 17:01:59 -0500363 mode->preemph[0] = QCONST16(0.7799987793f, 15);
364 mode->preemph[1] = -QCONST16(0.1000061035f, 15);
Jean-Marc Valin09213de2011-01-27 21:43:24 -0500365 mode->preemph[2] = QCONST16(0.7499771125f, SIG_SHIFT); /* exact 1/preemph[3] */
Jean-Marc Valin49f76802011-01-27 17:01:59 -0500366 mode->preemph[3] = QCONST16(1.3333740234f, 13);
Jean-Marc Valin223b69d2010-07-16 11:47:50 -0400367 } else /* 48 kHz */
368 {
Jean-Marc Valin49f76802011-01-27 17:01:59 -0500369 mode->preemph[0] = QCONST16(0.8500061035f, 15);
370 mode->preemph[1] = QCONST16(0.0f, 15);
Jean-Marc Valin223b69d2010-07-16 11:47:50 -0400371 mode->preemph[2] = QCONST16(1.f, SIG_SHIFT);
372 mode->preemph[3] = QCONST16(1.f, 13);
373 }
374
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400375 mode->maxLM = LM;
376 mode->nbShortMdcts = 1<<LM;
Jean-Marc Valin60ff9992010-06-27 13:49:38 -0400377 mode->shortMdctSize = frame_size/mode->nbShortMdcts;
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400378 res = (mode->Fs+mode->shortMdctSize)/(2*mode->shortMdctSize);
379
380 mode->eBands = compute_ebands(Fs, mode->shortMdctSize, res, &mode->nbEBands);
Jean-Marc Valinfbfddf72009-07-19 21:07:12 -0400381 if (mode->eBands==NULL)
382 goto failure;
Jean-Marc Valinfbfddf72009-07-19 21:07:12 -0400383
Jean-Marc Valin85f41b22010-07-16 18:12:45 -0400384 mode->effEBands = mode->nbEBands;
385 while (mode->eBands[mode->effEBands] > mode->shortMdctSize)
386 mode->effEBands--;
Jean-Marc Valin4834c922009-09-28 19:17:34 -0400387
Jean-Marc Valin08192e32009-07-02 13:28:55 -0400388 /* Overlap must be divisible by 4 */
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -0500389 mode->overlap = ((mode->shortMdctSize>>2)<<2);
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400390
Jean-Marc Valine3e2c262011-01-26 13:09:53 -0500391 compute_allocation_table(mode);
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400392 if (mode->allocVectors==NULL)
393 goto failure;
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100394
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400395 window = (celt_word16*)celt_alloc(mode->overlap*sizeof(celt_word16));
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400396 if (window==NULL)
397 goto failure;
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100398
Jean-Marc Valinf28062f2008-03-03 13:24:01 +1100399#ifndef FIXED_POINT
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100400 for (i=0;i<mode->overlap;i++)
Jean-Marc Valin3dbc1d02008-03-08 15:21:24 +1100401 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 +1100402#else
403 for (i=0;i<mode->overlap;i++)
Jean-Marc Valin8974f002010-03-20 00:41:39 -0400404 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 +1100405#endif
Jean-Marc Valin3dbc1d02008-03-08 15:21:24 +1100406 mode->window = window;
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100407
Jean-Marc Valinf400a3c2010-04-05 23:58:44 -0400408 logN = (celt_int16*)celt_alloc(mode->nbEBands*sizeof(celt_int16));
409 if (logN==NULL)
410 goto failure;
411
412 for (i=0;i<mode->nbEBands;i++)
Jean-Marc Valinaead79b2010-05-11 07:34:24 -0400413 logN[i] = log2_frac(mode->eBands[i+1]-mode->eBands[i], BITRES);
Jean-Marc Valinf400a3c2010-04-05 23:58:44 -0400414 mode->logN = logN;
Jean-Marc Valin3ad8db42010-08-25 13:11:09 -0400415
416 compute_pulse_cache(mode, mode->maxLM);
Jean-Marc Valin640f7fd2009-06-21 09:47:51 -0400417
Jean-Marc Valin732ea382010-08-25 13:52:27 -0400418 clt_mdct_init(&mode->mdct, 2*mode->shortMdctSize*mode->nbShortMdcts, mode->maxLM);
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400419 if ((mode->mdct.trig==NULL)
Jean-Marc Valin9714f662009-08-12 20:29:57 -0400420#ifndef ENABLE_TI_DSPLIB55
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400421 || (mode->mdct.kfft==NULL)
Jean-Marc Valin9714f662009-08-12 20:29:57 -0400422#endif
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400423 )
424 goto failure;
425
Jean-Marc Valin680a9ec2008-03-10 14:52:18 +1100426 if (error)
427 *error = CELT_OK;
Jean-Marc Valin40603b22010-08-25 23:02:49 -0400428
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100429 return mode;
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400430failure:
431 if (error)
432 *error = CELT_INVALID_MODE;
433 if (mode!=NULL)
434 celt_mode_destroy(mode);
435 return NULL;
Jean-Marc Valin5ad35bf2011-01-28 22:42:09 -0500436#endif /* !CUSTOM_MODES */
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100437}
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100438
Peter Kirk19f9dc92008-06-06 14:38:38 +0200439void celt_mode_destroy(CELTMode *mode)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100440{
Jean-Marc Valin5ad35bf2011-01-28 22:42:09 -0500441#ifdef CUSTOM_MODES
442 int i;
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400443 if (mode == NULL)
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400444 return;
Jean-Marc Valin665da0b2011-01-30 12:15:12 -0500445#ifndef CUSTOM_MODES_ONLY
Jean-Marc Valin5ad35bf2011-01-28 22:42:09 -0500446 for (i=0;i<TOTAL_MODES;i++)
447 {
448 if (mode == static_mode_list[i])
449 {
450 return;
451 }
452 }
Jean-Marc Valin665da0b2011-01-30 12:15:12 -0500453#endif /* CUSTOM_MODES_ONLY */
Jean-Marc Valin31bec962010-04-07 18:30:28 -0400454 celt_free((celt_int16*)mode->eBands);
455 celt_free((celt_int16*)mode->allocVectors);
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400456
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400457 celt_free((celt_word16*)mode->window);
Jean-Marc Valin31bec962010-04-07 18:30:28 -0400458 celt_free((celt_int16*)mode->logN);
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100459
Jean-Marc Valin732ea382010-08-25 13:52:27 -0400460 celt_free((celt_int16*)mode->cache.index);
461 celt_free((unsigned char*)mode->cache.bits);
Timothy B. Terriberryc5643072011-01-29 12:57:18 -0800462 celt_free((unsigned char*)mode->cache.caps);
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400463 clt_mdct_clear(&mode->mdct);
Jean-Marc Valin073d0bc2010-05-05 21:37:53 -0400464
Jean-Marc Valin949902f2008-03-11 10:43:06 +1100465 celt_free((CELTMode *)mode);
Jean-Marc Valin40603b22010-08-25 23:02:49 -0400466#endif
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100467}