blob: 212102e72c90224f52be092d9b6961d70b713258 [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 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,
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
68#if 1
69/* Alternate tuning based on exp_tuning_knobs from 2010/10/21:
70 87 5 25 14 300
71120 5 25 16 400
72125 5 25 17 500
73130 5 24 18 600
74130 5 24 19 920
75140 7 24 20 1240
76170 7 20 21 2000
77120 5 20 21 4000
78 */
79
80#define BITALLOC_SIZE 9
81/* Bit allocation table in units of 1/32 bit/sample (0.1875 dB SNR) */
82static const unsigned char band_allocation[] = {
83 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
84 99, 99, 90, 84, 78, 71, 65, 58, 51, 45, 39, 32, 26, 20, 1, 0, 0, 0, 0, 0, 0,
85124,124,109, 98, 88, 77, 71, 65, 59, 52, 46, 40, 34, 27, 21, 15, 1, 0, 0, 0, 0,
86132,132,117,107, 97, 87, 80, 74, 68, 62, 55, 49, 43, 37, 30, 23, 17, 1, 1, 0, 0,
87138,138,123,112,102, 91, 85, 79, 73, 67, 61, 55, 49, 43, 37, 31, 25, 19, 1, 0, 0,
88152,152,139,130,120,110,104, 98, 92, 86, 80, 74, 68, 62, 56, 50, 44, 38, 32, 8, 0,
89167,167,154,145,136,127,117,108,102, 96, 90, 84, 78, 72, 66, 60, 54, 48, 42, 36, 2,
90215,215,194,180,165,151,137,121,116,111,106,101, 96, 91, 86, 81, 76, 71, 66, 61, 56,
91240,240,239,233,225,218,211,203,198,193,188,183,178,173,168,163,158,153,148,143,138,
92};
93
94#else
Jean-Marc Valin78ea9fd2010-09-24 08:27:28 -040095/* Alternate tuning (partially derived from Vorbis) */
96#define BITALLOC_SIZE 11
97/* Bit allocation table in units of 1/32 bit/sample (0.1875 dB SNR) */
98static const unsigned char band_allocation[] = {
99 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
100 85, 85, 75, 70, 63, 55, 50, 45, 40, 35, 33, 28, 15, 1, 0, 0, 0, 0, 0, 0, 0,
101108,105, 96, 88, 83, 77, 72, 66, 59, 53, 49, 44, 41, 37, 30, 27, 1, 0, 0, 0, 0,
102120,117,108,100, 95, 89, 84, 78, 71, 65, 61, 56, 53, 49, 42, 34, 30, 25, 1, 0, 0,
103136,131,123,118,109, 99, 93, 87, 81, 75, 69, 66, 61, 56, 50, 45, 40, 35, 32, 1, 1,
104151,148,138,131,122,113,105,102, 96, 92, 85, 82, 76, 68, 63, 58, 51, 44, 38, 27, 8,
105171,168,158,147,139,130,123,119,111,108,103, 99, 91, 82, 78, 75, 66, 55, 48, 36, 12,
106187,184,174,163,155,146,139,135,127,124,119,115,107, 98, 94, 91, 82, 71, 64, 52, 28,
107203,200,191,181,174,166,159,156,149,147,143,139,132,124,121,119,110,100, 94, 83, 60,
108219,216,207,197,190,183,176,173,166,164,161,157,150,142,139,138,129,119,113,102, 80,
109229,229,224,222,223,224,224,225,222,221,221,220,220,219,218,200,178,154,146,130,102,
110};
Jean-Marc Valin94491652010-10-21 17:10:24 -0400111#endif
Jean-Marc Valin78ea9fd2010-09-24 08:27:28 -0400112#endif
113
Jean-Marc Valinf39e8692008-03-10 12:13:23 +1100114#ifdef STATIC_MODES
Jean-Marc Valinb18ec0b2008-04-11 04:07:52 +1000115#include "static_modes.c"
Jean-Marc Valinf39e8692008-03-10 12:13:23 +1100116#endif
117
Jean-Marc Valind748cd52008-03-01 07:27:03 +1100118#ifndef M_PI
119#define M_PI 3.141592653
120#endif
121
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +1100122
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400123int celt_mode_info(const CELTMode *mode, int request, celt_int32 *value)
Jean-Marc Valinf997ad52008-01-31 16:47:16 +1100124{
125 switch (request)
126 {
Jean-Marc Valinf997ad52008-01-31 16:47:16 +1100127 case CELT_GET_LOOKAHEAD:
128 *value = mode->overlap;
129 break;
Jean-Marc Valin59093c02008-05-15 21:53:27 +1000130 case CELT_GET_BITSTREAM_VERSION:
131 *value = CELT_BITSTREAM_VERSION;
132 break;
Gregory Maxwelld9458cd2009-05-30 17:04:02 -0400133 case CELT_GET_SAMPLE_RATE:
134 *value = mode->Fs;
135 break;
Jean-Marc Valincb7a2a32008-02-11 16:44:48 +1100136 default:
Jean-Marc Valinb6f90612008-10-05 22:39:13 -0400137 return CELT_UNIMPLEMENTED;
Jean-Marc Valinf997ad52008-01-31 16:47:16 +1100138 }
Jean-Marc Valincb7a2a32008-02-11 16:44:48 +1100139 return CELT_OK;
Jean-Marc Valinf997ad52008-01-31 16:47:16 +1100140}
141
Jean-Marc Valin5588d522008-03-10 15:07:58 +1100142#ifndef STATIC_MODES
143
Jean-Marc Valin17683eb2008-02-18 21:45:19 +1100144/* Defining 25 critical bands for the full 0-20 kHz audio bandwidth
145 Taken from http://ccrma.stanford.edu/~jos/bbt/Bark_Frequency_Scale.html */
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100146#define BARK_BANDS 25
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400147static const celt_int16 bark_freq[BARK_BANDS+1] = {
Jean-Marc Valin17683eb2008-02-18 21:45:19 +1100148 0, 100, 200, 300, 400,
149 510, 630, 770, 920, 1080,
150 1270, 1480, 1720, 2000, 2320,
151 2700, 3150, 3700, 4400, 5300,
152 6400, 7700, 9500, 12000, 15500,
153 20000};
154
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400155static celt_int16 *compute_ebands(celt_int32 Fs, int frame_size, int res, int *nbEBands)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100156{
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400157 celt_int16 *eBands;
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400158 int i, lin, low, high, nBark, offset=0;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100159
Jean-Marc Valin3b0df0d2010-07-16 15:55:30 -0400160 /* All modes that have 2.5 ms short blocks use the same definition */
161 if (Fs == 400*(celt_int32)frame_size)
Jean-Marc Valin20639c42010-05-19 16:10:12 -0400162 {
163 *nbEBands = sizeof(eband5ms)/sizeof(eband5ms[0])-1;
Jean-Marc Valin8952c452010-07-16 21:48:44 -0400164 eBands = celt_alloc(sizeof(celt_int16)*(*nbEBands+1));
165 for (i=0;i<*nbEBands+1;i++)
Jean-Marc Valin20639c42010-05-19 16:10:12 -0400166 eBands[i] = eband5ms[i];
Jean-Marc Valin20639c42010-05-19 16:10:12 -0400167 return eBands;
168 }
Gregory Maxwellcbaf67e2008-09-28 04:19:19 -0400169 /* Find the number of critical bands supported by our sampling rate */
170 for (nBark=1;nBark<BARK_BANDS;nBark++)
171 if (bark_freq[nBark+1]*2 >= Fs)
172 break;
173
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100174 /* Find where the linear part ends (i.e. where the spacing is more than min_width */
Gregory Maxwellcbaf67e2008-09-28 04:19:19 -0400175 for (lin=0;lin<nBark;lin++)
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400176 if (bark_freq[lin+1]-bark_freq[lin] >= res)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100177 break;
Jean-Marc Valin4fb95682010-04-20 23:30:22 -0400178
Jean-Marc Valin65ee67a2010-04-26 07:08:44 -0400179 low = (bark_freq[lin]+res/2)/res;
Gregory Maxwellcbaf67e2008-09-28 04:19:19 -0400180 high = nBark-lin;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100181 *nbEBands = low+high;
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400182 eBands = celt_alloc(sizeof(celt_int16)*(*nbEBands+2));
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100183
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400184 if (eBands==NULL)
185 return NULL;
186
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100187 /* Linear spacing (min_width) */
188 for (i=0;i<low;i++)
Jean-Marc Valin65ee67a2010-04-26 07:08:44 -0400189 eBands[i] = i;
Jean-Marc Valinbe8d1252010-04-21 18:09:07 -0400190 if (low>0)
191 offset = eBands[low-1]*res - bark_freq[lin-1];
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100192 /* Spacing follows critical bands */
193 for (i=0;i<high;i++)
Jean-Marc Valin39f68ac2009-10-03 23:27:52 -0400194 {
195 int target = bark_freq[lin+i];
Jean-Marc Valin65ee67a2010-04-26 07:08:44 -0400196 eBands[i+low] = (target+(offset+res)/2)/res;
Jean-Marc Valin39f68ac2009-10-03 23:27:52 -0400197 offset = eBands[i+low]*res - target;
198 }
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100199 /* Enforce the minimum spacing at the boundary */
200 for (i=0;i<*nbEBands;i++)
Jean-Marc Valin65ee67a2010-04-26 07:08:44 -0400201 if (eBands[i] < i)
202 eBands[i] = i;
203 eBands[*nbEBands] = (bark_freq[nBark]+res/2)/res;
Jean-Marc Valin8952c452010-07-16 21:48:44 -0400204 if (eBands[*nbEBands] > frame_size)
205 eBands[*nbEBands] = frame_size;
Jean-Marc Valinfbfddf72009-07-19 21:07:12 -0400206 for (i=1;i<*nbEBands-1;i++)
207 {
208 if (eBands[i+1]-eBands[i] < eBands[i]-eBands[i-1])
209 {
Jean-Marc Valin65ee67a2010-04-26 07:08:44 -0400210 eBands[i] -= (2*eBands[i]-eBands[i-1]-eBands[i+1])/2;
Jean-Marc Valinfbfddf72009-07-19 21:07:12 -0400211 }
212 }
Jean-Marc Valin65ee67a2010-04-26 07:08:44 -0400213 /*for (i=0;i<=*nbEBands+1;i++)
Jean-Marc Valinfbfddf72009-07-19 21:07:12 -0400214 printf ("%d ", eBands[i]);
Jean-Marc Valin39f68ac2009-10-03 23:27:52 -0400215 printf ("\n");
216 exit(1);*/
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100217 /* FIXME: Remove last band if too small */
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100218 return eBands;
219}
220
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400221static void compute_allocation_table(CELTMode *mode, int res)
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100222{
Jean-Marc Valin2f6c5fe2010-06-28 17:22:37 -0400223 int i, j;
Jean-Marc Valin01b54b92010-06-03 23:29:35 -0400224 unsigned char *allocVectors;
Jean-Marc Valinc51e98b2010-06-03 22:11:41 -0400225 int maxBands = sizeof(eband5ms)/sizeof(eband5ms[0])-1;
Jean-Marc Valin36e6e012008-08-02 22:25:19 -0400226
Jean-Marc Valin12e851d2010-06-03 08:12:11 -0400227 mode->nbAllocVectors = BITALLOC_SIZE;
Jean-Marc Valin01b54b92010-06-03 23:29:35 -0400228 allocVectors = celt_alloc(sizeof(unsigned char)*(BITALLOC_SIZE*mode->nbEBands));
Jean-Marc Valin12e851d2010-06-03 08:12:11 -0400229 if (allocVectors==NULL)
230 return;
231
Jean-Marc Valinc51e98b2010-06-03 22:11:41 -0400232 /* Check for standard mode */
Jean-Marc Valin12e851d2010-06-03 08:12:11 -0400233 if (mode->Fs == 400*(celt_int32)mode->shortMdctSize && mode->Fs >= 40000)
234 {
235 for (i=0;i<BITALLOC_SIZE*mode->nbEBands;i++)
Jean-Marc Valinffe50612010-06-04 00:13:19 -0400236 allocVectors[i] = band_allocation[i];
Jean-Marc Valin12e851d2010-06-03 08:12:11 -0400237 mode->allocVectors = allocVectors;
238 return;
239 }
Jean-Marc Valinc51e98b2010-06-03 22:11:41 -0400240 /* If not the standard mode, interpolate */
241
Jean-Marc Valin36e6e012008-08-02 22:25:19 -0400242 /* Compute per-codec-band allocation from per-critical-band matrix */
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100243 for (i=0;i<BITALLOC_SIZE;i++)
244 {
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400245 celt_int32 current = 0;
Gregory Maxwellec836da2009-05-04 14:55:40 -0400246 int eband = 0;
Jean-Marc Valin2f6c5fe2010-06-28 17:22:37 -0400247 /* We may be looping over too many bands, but eband will stop being
248 incremented once we reach the last band */
249 for (j=0;j<maxBands;j++)
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100250 {
Jean-Marc Valin137f3362010-04-14 17:42:22 -0400251 int edge, low, high;
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400252 celt_int32 alloc;
Jean-Marc Valinffe50612010-06-04 00:13:19 -0400253 alloc = band_allocation[i*maxBands + j]*(mode->eBands[eband+1]-mode->eBands[eband])<<4;
Jean-Marc Valinc51e98b2010-06-03 22:11:41 -0400254 low = eband5ms[j]*200;
255 high = eband5ms[j+1]*200;
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400256 edge = mode->eBands[eband+1]*res;
Jean-Marc Valin3ff5e4c2010-04-14 18:02:09 -0400257 while (edge <= high && eband < mode->nbEBands)
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100258 {
Jean-Marc Valin137f3362010-04-14 17:42:22 -0400259 celt_int32 num;
260 int den, bits;
Jean-Marc Valinbb8fa1f2010-06-03 00:33:42 -0400261 int N = (mode->eBands[eband+1]-mode->eBands[eband]);
Jean-Marc Valin137f3362010-04-14 17:42:22 -0400262 num = alloc * (edge-low);
263 den = high-low;
264 /* Divide with rounding */
265 bits = (2*num+den)/(2*den);
Jean-Marc Valinc51e98b2010-06-03 22:11:41 -0400266 allocVectors[i*mode->nbEBands+eband] = (2*(current+bits)+(N<<4))/(2*N<<4);
Jean-Marc Valin137f3362010-04-14 17:42:22 -0400267 /* Remove the part of the band we just allocated */
268 low = edge;
269 alloc -= bits;
270
271 /* Move to next eband */
272 current = 0;
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100273 eband++;
Jean-Marc Valin8952c452010-07-16 21:48:44 -0400274 if (eband < mode->nbEBands)
275 edge = mode->eBands[eband+1]*res;
Jean-Marc Valin137f3362010-04-14 17:42:22 -0400276 }
277 current += alloc;
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100278 }
Jean-Marc Valin137f3362010-04-14 17:42:22 -0400279 if (eband < mode->nbEBands)
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400280 {
Jean-Marc Valinbb8fa1f2010-06-03 00:33:42 -0400281 int N = (mode->eBands[eband+1]-mode->eBands[eband]);
Jean-Marc Valinc51e98b2010-06-03 22:11:41 -0400282 allocVectors[i*mode->nbEBands+eband] = (2*current+(N<<4))/(2*N<<4);
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400283 }
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100284 }
Jean-Marc Valinc51e98b2010-06-03 22:11:41 -0400285 /*printf ("\n");
286 for (i=0;i<BITALLOC_SIZE;i++)
Jean-Marc Valinbb8fa1f2010-06-03 00:33:42 -0400287 {
288 for (j=0;j<mode->nbEBands;j++)
289 printf ("%d ", allocVectors[i*mode->nbEBands+j]);
290 printf ("\n");
291 }
292 exit(0);*/
293
Jean-Marc Valin36e6e012008-08-02 22:25:19 -0400294 mode->allocVectors = allocVectors;
Jean-Marc Valinad637192008-05-07 13:44:39 +1000295}
296
Jean-Marc Valin36e6e012008-08-02 22:25:19 -0400297#endif /* STATIC_MODES */
298
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400299CELTMode *celt_mode_create(celt_int32 Fs, int frame_size, int *error)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100300{
Jean-Marc Valin47c248a2008-04-26 08:16:12 +1000301 int i;
Jean-Marc Valin40603b22010-08-25 23:02:49 -0400302#ifdef STATIC_MODES
303 for (i=0;i<TOTAL_MODES;i++)
304 {
305 if (Fs == static_mode_list[i]->Fs &&
306 frame_size == static_mode_list[i]->shortMdctSize*static_mode_list[i]->nbShortMdcts)
307 {
308 return (CELTMode*)static_mode_list[i];
309 }
310 }
Jean-Marc Valin40603b22010-08-25 23:02:49 -0400311 if (error)
312 *error = CELT_BAD_ARG;
313 return NULL;
314#else
315 int res;
316 CELTMode *mode=NULL;
317 celt_word16 *window;
318 celt_int16 *logN;
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400319 int LM;
Jean-Marc Valin47c248a2008-04-26 08:16:12 +1000320#ifdef STDIN_TUNING
321 scanf("%d ", &MIN_BINS);
322 scanf("%d ", &BITALLOC_SIZE);
323 band_allocation = celt_alloc(sizeof(int)*BARK_BANDS*BITALLOC_SIZE);
324 for (i=0;i<BARK_BANDS*BITALLOC_SIZE;i++)
325 {
326 scanf("%d ", band_allocation+i);
327 }
328#endif
Jean-Marc Valinf7cec832008-04-18 17:29:56 +1000329 ALLOC_STACK;
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400330#if !defined(VAR_ARRAYS) && !defined(USE_ALLOCA)
331 if (global_stack==NULL)
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400332 goto failure;
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400333#endif
Jean-Marc Valin3dbc1d02008-03-08 15:21:24 +1100334
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100335 /* The good thing here is that permutation of the arguments will automatically be invalid */
336
Jean-Marc Valin223b69d2010-07-16 11:47:50 -0400337 if (Fs < 8000 || Fs > 96000)
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100338 {
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100339 if (error)
340 *error = CELT_BAD_ARG;
341 return NULL;
342 }
Jean-Marc Valin223b69d2010-07-16 11:47:50 -0400343 if (frame_size < 40 || frame_size > 1024 || frame_size%2!=0)
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100344 {
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100345 if (error)
346 *error = CELT_BAD_ARG;
347 return NULL;
348 }
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100349
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100350 mode = celt_alloc(sizeof(CELTMode));
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400351 if (mode==NULL)
352 goto failure;
Jean-Marc Valine6b74652008-02-20 18:01:08 +1100353 mode->Fs = Fs;
Gregory Maxwell23e654f2008-09-27 16:20:03 -0400354
Jean-Marc Valin223b69d2010-07-16 11:47:50 -0400355 /* Pre/de-emphasis depends on sampling rate. The "standard" pre-emphasis
356 is defined as A(z) = 1 - 0.85*z^-1 at 48 kHz. Other rates should
357 approximate that. */
358 if(Fs < 12000) /* 8 kHz */
359 {
360 mode->preemph[0] = QCONST16(.35f, 15);
361 mode->preemph[1] = -QCONST16(.18f, 15);
362 mode->preemph[2] = QCONST16(.272f, SIG_SHIFT);
363 mode->preemph[3] = QCONST16(3.6765f, 13);
364 } else if(Fs < 24000) /* 16 kHz */
365 {
366 mode->preemph[0] = QCONST16(.6f, 15);
367 mode->preemph[1] = -QCONST16(.18f, 15);
368 mode->preemph[2] = QCONST16(.4425f, SIG_SHIFT);
369 mode->preemph[3] = QCONST16(2.259887f, 13);
370 } else if(Fs < 40000) /* 32 kHz */
371 {
372 mode->preemph[0] = QCONST16(.78f, 15);
373 mode->preemph[1] = -QCONST16(.1f, 15);
374 mode->preemph[2] = QCONST16(.75f, SIG_SHIFT);
375 mode->preemph[3] = QCONST16(1.33333333f, 13);
376 } else /* 48 kHz */
377 {
378 mode->preemph[0] = QCONST16(.85f, 15);
379 mode->preemph[1] = QCONST16(.0f, 15);
380 mode->preemph[2] = QCONST16(1.f, SIG_SHIFT);
381 mode->preemph[3] = QCONST16(1.f, 13);
382 }
383
Jean-Marc Valina2546bb2010-07-16 12:00:00 -0400384 if ((celt_int32)frame_size*75 >= Fs && (frame_size%16)==0)
Jean-Marc Valine6d832a2009-07-08 22:21:31 -0400385 {
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400386 LM = 3;
Jean-Marc Valina2546bb2010-07-16 12:00:00 -0400387 } else if ((celt_int32)frame_size*150 >= Fs && (frame_size%8)==0)
Jean-Marc Valin16ca18b2008-06-18 23:44:48 +1000388 {
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400389 LM = 2;
Jean-Marc Valina2546bb2010-07-16 12:00:00 -0400390 } else if ((celt_int32)frame_size*300 >= Fs && (frame_size%4)==0)
Gregory Maxwell23e654f2008-09-27 16:20:03 -0400391 {
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400392 LM = 1;
Gregory Maxwell23e654f2008-09-27 16:20:03 -0400393 } else
394 {
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400395 LM = 0;
Jean-Marc Valin16ca18b2008-06-18 23:44:48 +1000396 }
Gregory Maxwell23e654f2008-09-27 16:20:03 -0400397
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400398 mode->maxLM = LM;
399 mode->nbShortMdcts = 1<<LM;
Jean-Marc Valin60ff9992010-06-27 13:49:38 -0400400 mode->shortMdctSize = frame_size/mode->nbShortMdcts;
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400401 res = (mode->Fs+mode->shortMdctSize)/(2*mode->shortMdctSize);
402
403 mode->eBands = compute_ebands(Fs, mode->shortMdctSize, res, &mode->nbEBands);
Jean-Marc Valinfbfddf72009-07-19 21:07:12 -0400404 if (mode->eBands==NULL)
405 goto failure;
Jean-Marc Valinfbfddf72009-07-19 21:07:12 -0400406
Jean-Marc Valin85f41b22010-07-16 18:12:45 -0400407 mode->effEBands = mode->nbEBands;
408 while (mode->eBands[mode->effEBands] > mode->shortMdctSize)
409 mode->effEBands--;
Jean-Marc Valin4834c922009-09-28 19:17:34 -0400410
Jean-Marc Valin08192e32009-07-02 13:28:55 -0400411 /* Overlap must be divisible by 4 */
Jean-Marc Valin16ca18b2008-06-18 23:44:48 +1000412 if (mode->nbShortMdcts > 1)
Jean-Marc Valince4dd362010-05-07 07:45:18 -0400413 mode->overlap = (mode->shortMdctSize>>2)<<2;
Jean-Marc Valin16ca18b2008-06-18 23:44:48 +1000414 else
Gregory Maxwell23e654f2008-09-27 16:20:03 -0400415 mode->overlap = (frame_size>>3)<<2;
416
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400417
418 compute_allocation_table(mode, res);
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400419 if (mode->allocVectors==NULL)
420 goto failure;
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100421
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400422 window = (celt_word16*)celt_alloc(mode->overlap*sizeof(celt_word16));
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400423 if (window==NULL)
424 goto failure;
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100425
Jean-Marc Valinf28062f2008-03-03 13:24:01 +1100426#ifndef FIXED_POINT
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100427 for (i=0;i<mode->overlap;i++)
Jean-Marc Valin3dbc1d02008-03-08 15:21:24 +1100428 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 +1100429#else
430 for (i=0;i<mode->overlap;i++)
Jean-Marc Valin8974f002010-03-20 00:41:39 -0400431 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 +1100432#endif
Jean-Marc Valin3dbc1d02008-03-08 15:21:24 +1100433 mode->window = window;
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100434
Jean-Marc Valinf400a3c2010-04-05 23:58:44 -0400435 logN = (celt_int16*)celt_alloc(mode->nbEBands*sizeof(celt_int16));
436 if (logN==NULL)
437 goto failure;
438
439 for (i=0;i<mode->nbEBands;i++)
Jean-Marc Valinaead79b2010-05-11 07:34:24 -0400440 logN[i] = log2_frac(mode->eBands[i+1]-mode->eBands[i], BITRES);
Jean-Marc Valinf400a3c2010-04-05 23:58:44 -0400441 mode->logN = logN;
Jean-Marc Valin3ad8db42010-08-25 13:11:09 -0400442
443 compute_pulse_cache(mode, mode->maxLM);
Jean-Marc Valin640f7fd2009-06-21 09:47:51 -0400444
Jean-Marc Valin732ea382010-08-25 13:52:27 -0400445 clt_mdct_init(&mode->mdct, 2*mode->shortMdctSize*mode->nbShortMdcts, mode->maxLM);
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400446 if ((mode->mdct.trig==NULL)
Jean-Marc Valin9714f662009-08-12 20:29:57 -0400447#ifndef ENABLE_TI_DSPLIB55
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400448 || (mode->mdct.kfft==NULL)
Jean-Marc Valin9714f662009-08-12 20:29:57 -0400449#endif
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400450 )
451 goto failure;
452
Jean-Marc Valin073d0bc2010-05-05 21:37:53 -0400453 mode->prob = quant_prob_alloc(mode);
454 if (mode->prob==NULL)
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400455 goto failure;
Jean-Marc Valin40603b22010-08-25 23:02:49 -0400456
Jean-Marc Valin680a9ec2008-03-10 14:52:18 +1100457 if (error)
458 *error = CELT_OK;
Jean-Marc Valin40603b22010-08-25 23:02:49 -0400459
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100460 return mode;
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400461failure:
462 if (error)
463 *error = CELT_INVALID_MODE;
464 if (mode!=NULL)
465 celt_mode_destroy(mode);
466 return NULL;
Jean-Marc Valin40603b22010-08-25 23:02:49 -0400467#endif /* !STATIC_MODES */
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100468}
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100469
Peter Kirk19f9dc92008-06-06 14:38:38 +0200470void celt_mode_destroy(CELTMode *mode)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100471{
Jean-Marc Valin40603b22010-08-25 23:02:49 -0400472#ifndef STATIC_MODES
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400473 if (mode == NULL)
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400474 return;
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400475
Jean-Marc Valin31bec962010-04-07 18:30:28 -0400476 celt_free((celt_int16*)mode->eBands);
477 celt_free((celt_int16*)mode->allocVectors);
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400478
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400479 celt_free((celt_word16*)mode->window);
Jean-Marc Valin31bec962010-04-07 18:30:28 -0400480 celt_free((celt_int16*)mode->logN);
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100481
Jean-Marc Valin732ea382010-08-25 13:52:27 -0400482 celt_free((celt_int16*)mode->cache.index);
483 celt_free((unsigned char*)mode->cache.bits);
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400484 clt_mdct_clear(&mode->mdct);
Jean-Marc Valinbb528812010-08-25 22:12:18 -0400485 quant_prob_free(mode->prob);
Jean-Marc Valin073d0bc2010-05-05 21:37:53 -0400486
Jean-Marc Valin949902f2008-03-11 10:43:06 +1100487 celt_free((CELTMode *)mode);
Jean-Marc Valin40603b22010-08-25 23:02:49 -0400488#endif
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100489}