blob: 259a49bc998eb962f001f9a1e742a3b5551e3505 [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 Valin8ccda882010-10-04 18:01:45 -040046 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 -040047};
48
Jean-Marc Valinc992a0d2010-11-19 14:06:10 -050049#if 0
Jean-Marc Valin78ea9fd2010-09-24 08:27:28 -040050
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,
Jean-Marc Valin35095c62010-11-04 13:24:44 -040056 95, 90, 80, 75, 65, 60, 55, 50, 44, 40, 35, 30, 15, 1, 0, 0, 0, 0, 0, 0, 0,
57100, 95, 90, 88, 85, 82, 78, 74, 70, 65, 60, 54, 45, 35, 25, 15, 1, 0, 0, 0, 0,
Jean-Marc Valine0c25452010-09-03 11:52:38 -040058120,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,
Jean-Marc Valin8ccda882010-10-04 18:01:45 -040060170,165,157,155,149,145,143,138,138,138,129,124,108, 96, 88, 83, 72, 56, 44, 28, 2,
61192,192,160,160,160,160,160,160,160,160,150,140,120,110,100, 90, 80, 70, 60, 50, 20,
62224,224,192,192,192,192,192,192,192,160,160,160,160,160,160,160,160,120, 80, 64, 40,
63255,255,224,224,224,224,224,224,224,192,192,192,192,192,192,192,192,192,192,192,120,
Jean-Marc Valine0c25452010-09-03 11:52:38 -040064};
65
Jean-Marc Valin78ea9fd2010-09-24 08:27:28 -040066#else
Jean-Marc Valin94491652010-10-21 17:10:24 -040067
Jean-Marc Valin54d84c02010-11-19 11:45:37 -050068/* Alternate tuning (partially derived from Vorbis) */
Jean-Marc Valin59858632010-12-21 11:28:23 -050069#define BITALLOC_SIZE 12
Jean-Marc Valin94491652010-10-21 17:10:24 -040070/* Bit allocation table in units of 1/32 bit/sample (0.1875 dB SNR) */
71static const unsigned char band_allocation[] = {
Jean-Marc Valin54d84c02010-11-19 11:45:37 -050072/*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 -040073 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 -050074 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 -050075110,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 -050076118,110,103, 93, 86, 80, 75, 70, 65, 59, 53, 47, 40, 31, 23, 15, 4, 0, 0, 0, 0,
77126,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 -050078134,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 -050079144,137,130,124,113,107,101, 95, 88, 82, 76, 70, 64, 57, 51, 45, 39, 33, 26, 15, 1,
80152,145,138,132,123,117,111,105, 98, 92, 86, 80, 74, 67, 61, 55, 49, 43, 36, 20, 1,
81162,155,148,142,133,127,121,115,108,102, 96, 90, 84, 77, 71, 65, 59, 53, 46, 30, 1,
82172,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 -080083200,200,200,200,200,200,200,200,198,193,188,183,178,173,168,163,158,153,148,129,104,
84255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,251,251,239,204,129,104,
Jean-Marc Valin94491652010-10-21 17:10:24 -040085};
Jean-Marc Valin78ea9fd2010-09-24 08:27:28 -040086#endif
87
Jean-Marc Valin665da0b2011-01-30 12:15:12 -050088#ifndef CUSTOM_MODES_ONLY
89 #ifdef FIXED_POINT
90 #include "static_modes_fixed.c"
91 #else
92 #include "static_modes_float.c"
93 #endif
94#endif /* CUSTOM_MODES_ONLY */
Jean-Marc Valinf39e8692008-03-10 12:13:23 +110095
Jean-Marc Valind748cd52008-03-01 07:27:03 +110096#ifndef M_PI
97#define M_PI 3.141592653
98#endif
99
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +1100100
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400101int celt_mode_info(const CELTMode *mode, int request, celt_int32 *value)
Jean-Marc Valinf997ad52008-01-31 16:47:16 +1100102{
103 switch (request)
104 {
Jean-Marc Valinf997ad52008-01-31 16:47:16 +1100105 case CELT_GET_LOOKAHEAD:
106 *value = mode->overlap;
107 break;
Jean-Marc Valin59093c02008-05-15 21:53:27 +1000108 case CELT_GET_BITSTREAM_VERSION:
109 *value = CELT_BITSTREAM_VERSION;
110 break;
Gregory Maxwelld9458cd2009-05-30 17:04:02 -0400111 case CELT_GET_SAMPLE_RATE:
112 *value = mode->Fs;
113 break;
Jean-Marc Valincb7a2a32008-02-11 16:44:48 +1100114 default:
Jean-Marc Valinb6f90612008-10-05 22:39:13 -0400115 return CELT_UNIMPLEMENTED;
Jean-Marc Valinf997ad52008-01-31 16:47:16 +1100116 }
Jean-Marc Valincb7a2a32008-02-11 16:44:48 +1100117 return CELT_OK;
Jean-Marc Valinf997ad52008-01-31 16:47:16 +1100118}
119
Jean-Marc Valin5ad35bf2011-01-28 22:42:09 -0500120#ifdef CUSTOM_MODES
Jean-Marc Valin5588d522008-03-10 15:07:58 +1100121
Jean-Marc Valin17683eb2008-02-18 21:45:19 +1100122/* Defining 25 critical bands for the full 0-20 kHz audio bandwidth
123 Taken from http://ccrma.stanford.edu/~jos/bbt/Bark_Frequency_Scale.html */
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100124#define BARK_BANDS 25
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400125static const celt_int16 bark_freq[BARK_BANDS+1] = {
Jean-Marc Valin17683eb2008-02-18 21:45:19 +1100126 0, 100, 200, 300, 400,
127 510, 630, 770, 920, 1080,
128 1270, 1480, 1720, 2000, 2320,
129 2700, 3150, 3700, 4400, 5300,
130 6400, 7700, 9500, 12000, 15500,
131 20000};
132
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400133static celt_int16 *compute_ebands(celt_int32 Fs, int frame_size, int res, int *nbEBands)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100134{
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400135 celt_int16 *eBands;
Timothy B. Terriberrycb8f3662011-02-01 12:32:34 -0800136 int i, j, lin, low, high, nBark, offset=0;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100137
Jean-Marc Valin3b0df0d2010-07-16 15:55:30 -0400138 /* All modes that have 2.5 ms short blocks use the same definition */
139 if (Fs == 400*(celt_int32)frame_size)
Jean-Marc Valin20639c42010-05-19 16:10:12 -0400140 {
141 *nbEBands = sizeof(eband5ms)/sizeof(eband5ms[0])-1;
Jean-Marc Valin8952c452010-07-16 21:48:44 -0400142 eBands = celt_alloc(sizeof(celt_int16)*(*nbEBands+1));
143 for (i=0;i<*nbEBands+1;i++)
Jean-Marc Valin20639c42010-05-19 16:10:12 -0400144 eBands[i] = eband5ms[i];
Jean-Marc Valin20639c42010-05-19 16:10:12 -0400145 return eBands;
146 }
Gregory Maxwellcbaf67e2008-09-28 04:19:19 -0400147 /* Find the number of critical bands supported by our sampling rate */
148 for (nBark=1;nBark<BARK_BANDS;nBark++)
149 if (bark_freq[nBark+1]*2 >= Fs)
150 break;
151
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100152 /* Find where the linear part ends (i.e. where the spacing is more than min_width */
Gregory Maxwellcbaf67e2008-09-28 04:19:19 -0400153 for (lin=0;lin<nBark;lin++)
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400154 if (bark_freq[lin+1]-bark_freq[lin] >= res)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100155 break;
Jean-Marc Valin4fb95682010-04-20 23:30:22 -0400156
Jean-Marc Valin65ee67a2010-04-26 07:08:44 -0400157 low = (bark_freq[lin]+res/2)/res;
Gregory Maxwellcbaf67e2008-09-28 04:19:19 -0400158 high = nBark-lin;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100159 *nbEBands = low+high;
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400160 eBands = celt_alloc(sizeof(celt_int16)*(*nbEBands+2));
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100161
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400162 if (eBands==NULL)
163 return NULL;
164
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100165 /* Linear spacing (min_width) */
166 for (i=0;i<low;i++)
Jean-Marc Valin65ee67a2010-04-26 07:08:44 -0400167 eBands[i] = i;
Jean-Marc Valinbe8d1252010-04-21 18:09:07 -0400168 if (low>0)
169 offset = eBands[low-1]*res - bark_freq[lin-1];
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100170 /* Spacing follows critical bands */
171 for (i=0;i<high;i++)
Jean-Marc Valin39f68ac2009-10-03 23:27:52 -0400172 {
173 int target = bark_freq[lin+i];
Jean-Marc Valin44203902011-01-12 09:22:29 -0500174 /* Round to an even value */
175 eBands[i+low] = (target+offset/2+res)/(2*res)*2;
Jean-Marc Valin39f68ac2009-10-03 23:27:52 -0400176 offset = eBands[i+low]*res - target;
177 }
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100178 /* Enforce the minimum spacing at the boundary */
179 for (i=0;i<*nbEBands;i++)
Jean-Marc Valin65ee67a2010-04-26 07:08:44 -0400180 if (eBands[i] < i)
181 eBands[i] = i;
Jean-Marc Valin44203902011-01-12 09:22:29 -0500182 /* Round to an even value */
183 eBands[*nbEBands] = (bark_freq[nBark]+res)/(2*res)*2;
Jean-Marc Valin8952c452010-07-16 21:48:44 -0400184 if (eBands[*nbEBands] > frame_size)
185 eBands[*nbEBands] = frame_size;
Jean-Marc Valinfbfddf72009-07-19 21:07:12 -0400186 for (i=1;i<*nbEBands-1;i++)
187 {
188 if (eBands[i+1]-eBands[i] < eBands[i]-eBands[i-1])
189 {
Jean-Marc Valin65ee67a2010-04-26 07:08:44 -0400190 eBands[i] -= (2*eBands[i]-eBands[i-1]-eBands[i+1])/2;
Jean-Marc Valinfbfddf72009-07-19 21:07:12 -0400191 }
192 }
Timothy B. Terriberrycb8f3662011-02-01 12:32:34 -0800193 /* Remove any empty bands. */
194 for (i=j=0;i<*nbEBands;i++)
195 if(eBands[i+1]>eBands[j])
196 eBands[++j]=eBands[i+1];
197 *nbEBands=j;
198
Timothy B. Terriberry2799c292011-02-01 12:53:05 -0800199 for (i=1;i<*nbEBands;i++)
200 {
201 /* Every band must be smaller than the last band. */
202 celt_assert(eBands[i]-eBands[i-1]<=eBands[*nbEBands]-eBands[*nbEBands-1]);
203 /* Each band must be no larger than twice the size of the previous one. */
204 celt_assert(eBands[i+1]-eBands[i]<=2*(eBands[i]-eBands[i-1]));
205 }
206
Jean-Marc Valin65ee67a2010-04-26 07:08:44 -0400207 /*for (i=0;i<=*nbEBands+1;i++)
Jean-Marc Valinfbfddf72009-07-19 21:07:12 -0400208 printf ("%d ", eBands[i]);
Jean-Marc Valin39f68ac2009-10-03 23:27:52 -0400209 printf ("\n");
210 exit(1);*/
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100211 /* FIXME: Remove last band if too small */
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100212 return eBands;
213}
214
Jean-Marc Valine3e2c262011-01-26 13:09:53 -0500215static void compute_allocation_table(CELTMode *mode)
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100216{
Jean-Marc Valin2f6c5fe2010-06-28 17:22:37 -0400217 int i, j;
Jean-Marc Valin01b54b92010-06-03 23:29:35 -0400218 unsigned char *allocVectors;
Jean-Marc Valinc51e98b2010-06-03 22:11:41 -0400219 int maxBands = sizeof(eband5ms)/sizeof(eband5ms[0])-1;
Jean-Marc Valin36e6e012008-08-02 22:25:19 -0400220
Jean-Marc Valin12e851d2010-06-03 08:12:11 -0400221 mode->nbAllocVectors = BITALLOC_SIZE;
Jean-Marc Valin01b54b92010-06-03 23:29:35 -0400222 allocVectors = celt_alloc(sizeof(unsigned char)*(BITALLOC_SIZE*mode->nbEBands));
Jean-Marc Valin12e851d2010-06-03 08:12:11 -0400223 if (allocVectors==NULL)
224 return;
225
Jean-Marc Valinc51e98b2010-06-03 22:11:41 -0400226 /* Check for standard mode */
Jean-Marc Valin8e31ab32010-12-16 16:45:35 -0500227 if (mode->Fs == 400*(celt_int32)mode->shortMdctSize)
Jean-Marc Valin12e851d2010-06-03 08:12:11 -0400228 {
229 for (i=0;i<BITALLOC_SIZE*mode->nbEBands;i++)
Jean-Marc Valinffe50612010-06-04 00:13:19 -0400230 allocVectors[i] = band_allocation[i];
Jean-Marc Valin12e851d2010-06-03 08:12:11 -0400231 mode->allocVectors = allocVectors;
232 return;
233 }
Jean-Marc Valinc51e98b2010-06-03 22:11:41 -0400234 /* If not the standard mode, interpolate */
Jean-Marc Valin36e6e012008-08-02 22:25:19 -0400235 /* Compute per-codec-band allocation from per-critical-band matrix */
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100236 for (i=0;i<BITALLOC_SIZE;i++)
237 {
Jean-Marc Valin1bfa18c2010-12-01 16:11:38 -0500238 for (j=0;j<mode->nbEBands;j++)
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100239 {
Jean-Marc Valin1bfa18c2010-12-01 16:11:38 -0500240 int k;
241 for (k=0;k<maxBands;k++)
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100242 {
Jean-Marc Valin1bfa18c2010-12-01 16:11:38 -0500243 if (400*(celt_int32)eband5ms[k] > mode->eBands[j]*(celt_int32)mode->Fs/mode->shortMdctSize)
244 break;
Jean-Marc Valin137f3362010-04-14 17:42:22 -0400245 }
Jean-Marc Valin1bfa18c2010-12-01 16:11:38 -0500246 if (k>mode->nbEBands-1)
247 allocVectors[i*mode->nbEBands+j] = band_allocation[i*maxBands + maxBands-1];
248 else {
249 celt_int32 a0, a1;
250 a1 = mode->eBands[j]*(celt_int32)mode->Fs/mode->shortMdctSize - 400*(celt_int32)eband5ms[k-1];
251 a0 = 400*(celt_int32)eband5ms[k] - mode->eBands[j]*(celt_int32)mode->Fs/mode->shortMdctSize;
252 allocVectors[i*mode->nbEBands+j] = (a0*band_allocation[i*maxBands+k-1]
253 + a1*band_allocation[i*maxBands+k])/(a0+a1);
254 }
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400255 }
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100256 }
Jean-Marc Valin1bfa18c2010-12-01 16:11:38 -0500257
Jean-Marc Valinc51e98b2010-06-03 22:11:41 -0400258 /*printf ("\n");
259 for (i=0;i<BITALLOC_SIZE;i++)
Jean-Marc Valinbb8fa1f2010-06-03 00:33:42 -0400260 {
261 for (j=0;j<mode->nbEBands;j++)
262 printf ("%d ", allocVectors[i*mode->nbEBands+j]);
263 printf ("\n");
264 }
265 exit(0);*/
266
Jean-Marc Valin36e6e012008-08-02 22:25:19 -0400267 mode->allocVectors = allocVectors;
Jean-Marc Valinad637192008-05-07 13:44:39 +1000268}
269
Jean-Marc Valin5ad35bf2011-01-28 22:42:09 -0500270#endif /* CUSTOM_MODES */
Jean-Marc Valin36e6e012008-08-02 22:25:19 -0400271
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400272CELTMode *celt_mode_create(celt_int32 Fs, int frame_size, int *error)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100273{
Jean-Marc Valin47c248a2008-04-26 08:16:12 +1000274 int i;
Jean-Marc Valin40603b22010-08-25 23:02:49 -0400275 int res;
276 CELTMode *mode=NULL;
277 celt_word16 *window;
278 celt_int16 *logN;
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400279 int LM;
Jean-Marc Valin47c248a2008-04-26 08:16:12 +1000280#ifdef STDIN_TUNING
281 scanf("%d ", &MIN_BINS);
282 scanf("%d ", &BITALLOC_SIZE);
283 band_allocation = celt_alloc(sizeof(int)*BARK_BANDS*BITALLOC_SIZE);
284 for (i=0;i<BARK_BANDS*BITALLOC_SIZE;i++)
285 {
286 scanf("%d ", band_allocation+i);
287 }
288#endif
Jean-Marc Valin7e983192011-02-01 18:00:29 -0500289#ifdef CUSTOM_MODES
Jean-Marc Valinf7cec832008-04-18 17:29:56 +1000290 ALLOC_STACK;
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400291#if !defined(VAR_ARRAYS) && !defined(USE_ALLOCA)
292 if (global_stack==NULL)
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400293 goto failure;
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400294#endif
Jean-Marc Valin7e983192011-02-01 18:00:29 -0500295#endif
Jean-Marc Valin3dbc1d02008-03-08 15:21:24 +1100296
Jean-Marc Valin665da0b2011-01-30 12:15:12 -0500297#ifndef CUSTOM_MODES_ONLY
Jean-Marc Valin5ad35bf2011-01-28 22:42:09 -0500298 for (i=0;i<TOTAL_MODES;i++)
299 {
Jean-Marc Valinc97b2582011-01-28 23:07:32 -0500300 int j;
301 for (j=0;j<4;j++)
Jean-Marc Valin5ad35bf2011-01-28 22:42:09 -0500302 {
Jean-Marc Valinc97b2582011-01-28 23:07:32 -0500303 if (Fs == static_mode_list[i]->Fs &&
304 (frame_size<<j) == static_mode_list[i]->shortMdctSize*static_mode_list[i]->nbShortMdcts)
305 {
306 if (error)
307 *error = CELT_OK;
308 return (CELTMode*)static_mode_list[i];
309 }
Jean-Marc Valin5ad35bf2011-01-28 22:42:09 -0500310 }
311 }
Jean-Marc Valin665da0b2011-01-30 12:15:12 -0500312#endif /* CUSTOM_MODES_ONLY */
313
Jean-Marc Valin5ad35bf2011-01-28 22:42:09 -0500314#ifndef CUSTOM_MODES
315 if (error)
316 *error = CELT_BAD_ARG;
317 return NULL;
318#else
319
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100320 /* The good thing here is that permutation of the arguments will automatically be invalid */
321
Jean-Marc Valin223b69d2010-07-16 11:47:50 -0400322 if (Fs < 8000 || Fs > 96000)
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100323 {
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100324 if (error)
325 *error = CELT_BAD_ARG;
326 return NULL;
327 }
Jean-Marc Valin223b69d2010-07-16 11:47:50 -0400328 if (frame_size < 40 || frame_size > 1024 || frame_size%2!=0)
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100329 {
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100330 if (error)
331 *error = CELT_BAD_ARG;
332 return NULL;
333 }
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100334
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100335 mode = celt_alloc(sizeof(CELTMode));
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400336 if (mode==NULL)
337 goto failure;
Jean-Marc Valine6b74652008-02-20 18:01:08 +1100338 mode->Fs = Fs;
Gregory Maxwell23e654f2008-09-27 16:20:03 -0400339
Jean-Marc Valin223b69d2010-07-16 11:47:50 -0400340 /* Pre/de-emphasis depends on sampling rate. The "standard" pre-emphasis
341 is defined as A(z) = 1 - 0.85*z^-1 at 48 kHz. Other rates should
342 approximate that. */
343 if(Fs < 12000) /* 8 kHz */
344 {
Jean-Marc Valin49f76802011-01-27 17:01:59 -0500345 mode->preemph[0] = QCONST16(0.3500061035f, 15);
346 mode->preemph[1] = -QCONST16(0.1799926758f, 15);
Jean-Marc Valin09213de2011-01-27 21:43:24 -0500347 mode->preemph[2] = QCONST16(0.2719968125f, SIG_SHIFT); /* exact 1/preemph[3] */
Jean-Marc Valin49f76802011-01-27 17:01:59 -0500348 mode->preemph[3] = QCONST16(3.6765136719f, 13);
Jean-Marc Valin223b69d2010-07-16 11:47:50 -0400349 } else if(Fs < 24000) /* 16 kHz */
350 {
Jean-Marc Valin49f76802011-01-27 17:01:59 -0500351 mode->preemph[0] = QCONST16(0.6000061035f, 15);
352 mode->preemph[1] = -QCONST16(0.1799926758f, 15);
Jean-Marc Valin09213de2011-01-27 21:43:24 -0500353 mode->preemph[2] = QCONST16(0.4424998650f, SIG_SHIFT); /* exact 1/preemph[3] */
354 mode->preemph[3] = QCONST16(2.2598876953f, 13);
Jean-Marc Valin223b69d2010-07-16 11:47:50 -0400355 } else if(Fs < 40000) /* 32 kHz */
356 {
Jean-Marc Valin49f76802011-01-27 17:01:59 -0500357 mode->preemph[0] = QCONST16(0.7799987793f, 15);
358 mode->preemph[1] = -QCONST16(0.1000061035f, 15);
Jean-Marc Valin09213de2011-01-27 21:43:24 -0500359 mode->preemph[2] = QCONST16(0.7499771125f, SIG_SHIFT); /* exact 1/preemph[3] */
Jean-Marc Valin49f76802011-01-27 17:01:59 -0500360 mode->preemph[3] = QCONST16(1.3333740234f, 13);
Jean-Marc Valin223b69d2010-07-16 11:47:50 -0400361 } else /* 48 kHz */
362 {
Jean-Marc Valin49f76802011-01-27 17:01:59 -0500363 mode->preemph[0] = QCONST16(0.8500061035f, 15);
364 mode->preemph[1] = QCONST16(0.0f, 15);
Jean-Marc Valin223b69d2010-07-16 11:47:50 -0400365 mode->preemph[2] = QCONST16(1.f, SIG_SHIFT);
366 mode->preemph[3] = QCONST16(1.f, 13);
367 }
368
Jean-Marc Valina2546bb2010-07-16 12:00:00 -0400369 if ((celt_int32)frame_size*75 >= Fs && (frame_size%16)==0)
Jean-Marc Valine6d832a2009-07-08 22:21:31 -0400370 {
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400371 LM = 3;
Jean-Marc Valina2546bb2010-07-16 12:00:00 -0400372 } else if ((celt_int32)frame_size*150 >= Fs && (frame_size%8)==0)
Jean-Marc Valin16ca18b2008-06-18 23:44:48 +1000373 {
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400374 LM = 2;
Jean-Marc Valina2546bb2010-07-16 12:00:00 -0400375 } else if ((celt_int32)frame_size*300 >= Fs && (frame_size%4)==0)
Gregory Maxwell23e654f2008-09-27 16:20:03 -0400376 {
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400377 LM = 1;
Gregory Maxwell23e654f2008-09-27 16:20:03 -0400378 } else
379 {
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400380 LM = 0;
Jean-Marc Valin16ca18b2008-06-18 23:44:48 +1000381 }
Gregory Maxwell23e654f2008-09-27 16:20:03 -0400382
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400383 mode->maxLM = LM;
384 mode->nbShortMdcts = 1<<LM;
Jean-Marc Valin60ff9992010-06-27 13:49:38 -0400385 mode->shortMdctSize = frame_size/mode->nbShortMdcts;
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400386 res = (mode->Fs+mode->shortMdctSize)/(2*mode->shortMdctSize);
387
388 mode->eBands = compute_ebands(Fs, mode->shortMdctSize, res, &mode->nbEBands);
Jean-Marc Valinfbfddf72009-07-19 21:07:12 -0400389 if (mode->eBands==NULL)
390 goto failure;
Jean-Marc Valinfbfddf72009-07-19 21:07:12 -0400391
Jean-Marc Valin85f41b22010-07-16 18:12:45 -0400392 mode->effEBands = mode->nbEBands;
393 while (mode->eBands[mode->effEBands] > mode->shortMdctSize)
394 mode->effEBands--;
Jean-Marc Valin4834c922009-09-28 19:17:34 -0400395
Jean-Marc Valin08192e32009-07-02 13:28:55 -0400396 /* Overlap must be divisible by 4 */
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -0500397 mode->overlap = ((mode->shortMdctSize>>2)<<2);
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400398
Jean-Marc Valine3e2c262011-01-26 13:09:53 -0500399 compute_allocation_table(mode);
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400400 if (mode->allocVectors==NULL)
401 goto failure;
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100402
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400403 window = (celt_word16*)celt_alloc(mode->overlap*sizeof(celt_word16));
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400404 if (window==NULL)
405 goto failure;
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100406
Jean-Marc Valinf28062f2008-03-03 13:24:01 +1100407#ifndef FIXED_POINT
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100408 for (i=0;i<mode->overlap;i++)
Jean-Marc Valin3dbc1d02008-03-08 15:21:24 +1100409 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 +1100410#else
411 for (i=0;i<mode->overlap;i++)
Jean-Marc Valin8974f002010-03-20 00:41:39 -0400412 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 +1100413#endif
Jean-Marc Valin3dbc1d02008-03-08 15:21:24 +1100414 mode->window = window;
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100415
Jean-Marc Valinf400a3c2010-04-05 23:58:44 -0400416 logN = (celt_int16*)celt_alloc(mode->nbEBands*sizeof(celt_int16));
417 if (logN==NULL)
418 goto failure;
419
420 for (i=0;i<mode->nbEBands;i++)
Jean-Marc Valinaead79b2010-05-11 07:34:24 -0400421 logN[i] = log2_frac(mode->eBands[i+1]-mode->eBands[i], BITRES);
Jean-Marc Valinf400a3c2010-04-05 23:58:44 -0400422 mode->logN = logN;
Jean-Marc Valin3ad8db42010-08-25 13:11:09 -0400423
424 compute_pulse_cache(mode, mode->maxLM);
Jean-Marc Valin640f7fd2009-06-21 09:47:51 -0400425
Jean-Marc Valin732ea382010-08-25 13:52:27 -0400426 clt_mdct_init(&mode->mdct, 2*mode->shortMdctSize*mode->nbShortMdcts, mode->maxLM);
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400427 if ((mode->mdct.trig==NULL)
Jean-Marc Valin9714f662009-08-12 20:29:57 -0400428#ifndef ENABLE_TI_DSPLIB55
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400429 || (mode->mdct.kfft==NULL)
Jean-Marc Valin9714f662009-08-12 20:29:57 -0400430#endif
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400431 )
432 goto failure;
433
Jean-Marc Valin680a9ec2008-03-10 14:52:18 +1100434 if (error)
435 *error = CELT_OK;
Jean-Marc Valin40603b22010-08-25 23:02:49 -0400436
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100437 return mode;
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400438failure:
439 if (error)
440 *error = CELT_INVALID_MODE;
441 if (mode!=NULL)
442 celt_mode_destroy(mode);
443 return NULL;
Jean-Marc Valin5ad35bf2011-01-28 22:42:09 -0500444#endif /* !CUSTOM_MODES */
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100445}
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100446
Peter Kirk19f9dc92008-06-06 14:38:38 +0200447void celt_mode_destroy(CELTMode *mode)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100448{
Jean-Marc Valin5ad35bf2011-01-28 22:42:09 -0500449#ifdef CUSTOM_MODES
450 int i;
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400451 if (mode == NULL)
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400452 return;
Jean-Marc Valin665da0b2011-01-30 12:15:12 -0500453#ifndef CUSTOM_MODES_ONLY
Jean-Marc Valin5ad35bf2011-01-28 22:42:09 -0500454 for (i=0;i<TOTAL_MODES;i++)
455 {
456 if (mode == static_mode_list[i])
457 {
458 return;
459 }
460 }
Jean-Marc Valin665da0b2011-01-30 12:15:12 -0500461#endif /* CUSTOM_MODES_ONLY */
Jean-Marc Valin31bec962010-04-07 18:30:28 -0400462 celt_free((celt_int16*)mode->eBands);
463 celt_free((celt_int16*)mode->allocVectors);
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400464
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400465 celt_free((celt_word16*)mode->window);
Jean-Marc Valin31bec962010-04-07 18:30:28 -0400466 celt_free((celt_int16*)mode->logN);
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100467
Jean-Marc Valin732ea382010-08-25 13:52:27 -0400468 celt_free((celt_int16*)mode->cache.index);
469 celt_free((unsigned char*)mode->cache.bits);
Timothy B. Terriberryc5643072011-01-29 12:57:18 -0800470 celt_free((unsigned char*)mode->cache.caps);
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400471 clt_mdct_clear(&mode->mdct);
Jean-Marc Valin073d0bc2010-05-05 21:37:53 -0400472
Jean-Marc Valin949902f2008-03-11 10:43:06 +1100473 celt_free((CELTMode *)mode);
Jean-Marc Valin40603b22010-08-25 23:02:49 -0400474#endif
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100475}