blob: b002183310271ac987a83f3aef36f2555e7e0858 [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 Valinf39e8692008-03-10 12:13:23 +110045#ifdef STATIC_MODES
Jean-Marc Valinb18ec0b2008-04-11 04:07:52 +100046#include "static_modes.c"
Jean-Marc Valinf39e8692008-03-10 12:13:23 +110047#endif
48
Gregory Maxwelldc67fa92009-06-04 17:17:35 -040049#define MODEVALID 0xa110ca7e
50#define MODEPARTIAL 0x7eca10a1
51#define MODEFREED 0xb10cf8ee
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +110052
Jean-Marc Valind748cd52008-03-01 07:27:03 +110053#ifndef M_PI
54#define M_PI 3.141592653
55#endif
56
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +110057
Jean-Marc Valin30f7f812009-10-17 14:35:13 -040058int celt_mode_info(const CELTMode *mode, int request, celt_int32 *value)
Jean-Marc Valinf997ad52008-01-31 16:47:16 +110059{
Gregory Maxwelldc67fa92009-06-04 17:17:35 -040060 if (check_mode(mode) != CELT_OK)
61 return CELT_INVALID_MODE;
Jean-Marc Valinf997ad52008-01-31 16:47:16 +110062 switch (request)
63 {
Jean-Marc Valinf997ad52008-01-31 16:47:16 +110064 case CELT_GET_LOOKAHEAD:
65 *value = mode->overlap;
66 break;
Jean-Marc Valin59093c02008-05-15 21:53:27 +100067 case CELT_GET_BITSTREAM_VERSION:
68 *value = CELT_BITSTREAM_VERSION;
69 break;
Gregory Maxwelld9458cd2009-05-30 17:04:02 -040070 case CELT_GET_SAMPLE_RATE:
71 *value = mode->Fs;
72 break;
Jean-Marc Valincb7a2a32008-02-11 16:44:48 +110073 default:
Jean-Marc Valinb6f90612008-10-05 22:39:13 -040074 return CELT_UNIMPLEMENTED;
Jean-Marc Valinf997ad52008-01-31 16:47:16 +110075 }
Jean-Marc Valincb7a2a32008-02-11 16:44:48 +110076 return CELT_OK;
Jean-Marc Valinf997ad52008-01-31 16:47:16 +110077}
78
Jean-Marc Valin5588d522008-03-10 15:07:58 +110079#ifndef STATIC_MODES
80
Jean-Marc Valin17683eb2008-02-18 21:45:19 +110081/* Defining 25 critical bands for the full 0-20 kHz audio bandwidth
82 Taken from http://ccrma.stanford.edu/~jos/bbt/Bark_Frequency_Scale.html */
Jean-Marc Valin81a82952008-02-17 22:41:29 +110083#define BARK_BANDS 25
Jean-Marc Valin30f7f812009-10-17 14:35:13 -040084static const celt_int16 bark_freq[BARK_BANDS+1] = {
Jean-Marc Valin17683eb2008-02-18 21:45:19 +110085 0, 100, 200, 300, 400,
86 510, 630, 770, 920, 1080,
87 1270, 1480, 1720, 2000, 2320,
88 2700, 3150, 3700, 4400, 5300,
89 6400, 7700, 9500, 12000, 15500,
90 20000};
91
Jean-Marc Valin75e9c862008-02-18 17:04:15 +110092/* This allocation table is per critical band. When creating a mode, the bits get added together
93 into the codec bands, which are sometimes larger than one critical band at low frequency */
Jean-Marc Valin47c248a2008-04-26 08:16:12 +100094
Jean-Marc Valinea17d422010-07-28 10:39:04 +020095#define BITALLOC_SIZE 10
Jean-Marc Valin81a82952008-02-17 22:41:29 +110096
Jean-Marc Valin12e851d2010-06-03 08:12:11 -040097static const celt_int16 eband5ms[] = {
98 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 34, 40, 48, 60, 78, 100
99};
100
Jean-Marc Valinffe50612010-06-04 00:13:19 -0400101static const unsigned char band_allocation[] = {
102 /* 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 Valinea17d422010-07-28 10:39:04 +0200103 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
Jean-Marc Valin12e851d2010-06-03 08:12:11 -0400104 10, 10, 14, 11, 10, 8, 6, 5, 10, 12, 13, 11, 8, 4, 2, 1, 0, 0, 0, 0, 0,
105 13, 10, 17, 16, 14, 12, 10, 8, 12, 14, 14, 12, 9, 5, 3, 2, 2, 1, 0, 0, 0,
106 17, 21, 23, 26, 24, 20, 17, 16, 17, 18, 16, 14, 11, 6, 3, 2, 2, 1, 1, 0, 0,
107 21, 21, 36, 32, 28, 24, 23, 23, 22, 18, 18, 14, 11, 7, 5, 5, 5, 3, 3, 0, 0,
108 31, 35, 40, 32, 30, 28, 26, 26, 25, 24, 19, 15, 15, 13, 9, 9, 8, 7, 5, 2, 0,
109 42, 46, 46, 37, 35, 34, 33, 32, 34, 35, 32, 31, 27, 24, 23, 23, 18, 14, 11, 7, 0,
110 46, 49, 46, 46, 42, 43, 44, 47, 50, 52, 51, 48, 39, 32, 27, 24, 22, 19, 17, 11, 5,
111 53, 53, 49, 48, 55, 66, 71, 71, 71, 65, 64, 64, 56, 47, 41, 37, 31, 24, 20, 16, 10,
112 60, 64, 74, 74, 87,103,106,102,101,100,101, 95, 80, 69, 63, 55, 47, 36, 26, 21, 15,
113};
Jean-Marc Valin20639c42010-05-19 16:10:12 -0400114
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400115static celt_int16 *compute_ebands(celt_int32 Fs, int frame_size, int res, int *nbEBands)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100116{
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400117 celt_int16 *eBands;
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400118 int i, lin, low, high, nBark, offset=0;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100119
Jean-Marc Valin3b0df0d2010-07-16 15:55:30 -0400120 /* All modes that have 2.5 ms short blocks use the same definition */
121 if (Fs == 400*(celt_int32)frame_size)
Jean-Marc Valin20639c42010-05-19 16:10:12 -0400122 {
123 *nbEBands = sizeof(eband5ms)/sizeof(eband5ms[0])-1;
Jean-Marc Valin8952c452010-07-16 21:48:44 -0400124 eBands = celt_alloc(sizeof(celt_int16)*(*nbEBands+1));
125 for (i=0;i<*nbEBands+1;i++)
Jean-Marc Valin20639c42010-05-19 16:10:12 -0400126 eBands[i] = eband5ms[i];
Jean-Marc Valin20639c42010-05-19 16:10:12 -0400127 return eBands;
128 }
Gregory Maxwellcbaf67e2008-09-28 04:19:19 -0400129 /* Find the number of critical bands supported by our sampling rate */
130 for (nBark=1;nBark<BARK_BANDS;nBark++)
131 if (bark_freq[nBark+1]*2 >= Fs)
132 break;
133
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100134 /* Find where the linear part ends (i.e. where the spacing is more than min_width */
Gregory Maxwellcbaf67e2008-09-28 04:19:19 -0400135 for (lin=0;lin<nBark;lin++)
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400136 if (bark_freq[lin+1]-bark_freq[lin] >= res)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100137 break;
Jean-Marc Valin4fb95682010-04-20 23:30:22 -0400138
Jean-Marc Valin65ee67a2010-04-26 07:08:44 -0400139 low = (bark_freq[lin]+res/2)/res;
Gregory Maxwellcbaf67e2008-09-28 04:19:19 -0400140 high = nBark-lin;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100141 *nbEBands = low+high;
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400142 eBands = celt_alloc(sizeof(celt_int16)*(*nbEBands+2));
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100143
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400144 if (eBands==NULL)
145 return NULL;
146
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100147 /* Linear spacing (min_width) */
148 for (i=0;i<low;i++)
Jean-Marc Valin65ee67a2010-04-26 07:08:44 -0400149 eBands[i] = i;
Jean-Marc Valinbe8d1252010-04-21 18:09:07 -0400150 if (low>0)
151 offset = eBands[low-1]*res - bark_freq[lin-1];
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100152 /* Spacing follows critical bands */
153 for (i=0;i<high;i++)
Jean-Marc Valin39f68ac2009-10-03 23:27:52 -0400154 {
155 int target = bark_freq[lin+i];
Jean-Marc Valin65ee67a2010-04-26 07:08:44 -0400156 eBands[i+low] = (target+(offset+res)/2)/res;
Jean-Marc Valin39f68ac2009-10-03 23:27:52 -0400157 offset = eBands[i+low]*res - target;
158 }
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100159 /* Enforce the minimum spacing at the boundary */
160 for (i=0;i<*nbEBands;i++)
Jean-Marc Valin65ee67a2010-04-26 07:08:44 -0400161 if (eBands[i] < i)
162 eBands[i] = i;
163 eBands[*nbEBands] = (bark_freq[nBark]+res/2)/res;
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 }
Jean-Marc Valin65ee67a2010-04-26 07:08:44 -0400173 /*for (i=0;i<=*nbEBands+1;i++)
Jean-Marc Valinfbfddf72009-07-19 21:07:12 -0400174 printf ("%d ", eBands[i]);
Jean-Marc Valin39f68ac2009-10-03 23:27:52 -0400175 printf ("\n");
176 exit(1);*/
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100177 /* FIXME: Remove last band if too small */
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100178 return eBands;
179}
180
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400181static void compute_allocation_table(CELTMode *mode, int res)
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100182{
Jean-Marc Valin2f6c5fe2010-06-28 17:22:37 -0400183 int i, j;
Jean-Marc Valin01b54b92010-06-03 23:29:35 -0400184 unsigned char *allocVectors;
Jean-Marc Valinc51e98b2010-06-03 22:11:41 -0400185 int maxBands = sizeof(eband5ms)/sizeof(eband5ms[0])-1;
Jean-Marc Valin36e6e012008-08-02 22:25:19 -0400186
Jean-Marc Valin12e851d2010-06-03 08:12:11 -0400187 mode->nbAllocVectors = BITALLOC_SIZE;
Jean-Marc Valin01b54b92010-06-03 23:29:35 -0400188 allocVectors = celt_alloc(sizeof(unsigned char)*(BITALLOC_SIZE*mode->nbEBands));
Jean-Marc Valin12e851d2010-06-03 08:12:11 -0400189 if (allocVectors==NULL)
190 return;
191
Jean-Marc Valinc51e98b2010-06-03 22:11:41 -0400192 /* Check for standard mode */
Jean-Marc Valin12e851d2010-06-03 08:12:11 -0400193 if (mode->Fs == 400*(celt_int32)mode->shortMdctSize && mode->Fs >= 40000)
194 {
195 for (i=0;i<BITALLOC_SIZE*mode->nbEBands;i++)
Jean-Marc Valinffe50612010-06-04 00:13:19 -0400196 allocVectors[i] = band_allocation[i];
Jean-Marc Valin12e851d2010-06-03 08:12:11 -0400197 mode->allocVectors = allocVectors;
198 return;
199 }
Jean-Marc Valinc51e98b2010-06-03 22:11:41 -0400200 /* If not the standard mode, interpolate */
201
Jean-Marc Valin36e6e012008-08-02 22:25:19 -0400202 /* Compute per-codec-band allocation from per-critical-band matrix */
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100203 for (i=0;i<BITALLOC_SIZE;i++)
204 {
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400205 celt_int32 current = 0;
Gregory Maxwellec836da2009-05-04 14:55:40 -0400206 int eband = 0;
Jean-Marc Valin2f6c5fe2010-06-28 17:22:37 -0400207 /* We may be looping over too many bands, but eband will stop being
208 incremented once we reach the last band */
209 for (j=0;j<maxBands;j++)
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100210 {
Jean-Marc Valin137f3362010-04-14 17:42:22 -0400211 int edge, low, high;
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400212 celt_int32 alloc;
Jean-Marc Valinffe50612010-06-04 00:13:19 -0400213 alloc = band_allocation[i*maxBands + j]*(mode->eBands[eband+1]-mode->eBands[eband])<<4;
Jean-Marc Valinc51e98b2010-06-03 22:11:41 -0400214 low = eband5ms[j]*200;
215 high = eband5ms[j+1]*200;
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400216 edge = mode->eBands[eband+1]*res;
Jean-Marc Valin3ff5e4c2010-04-14 18:02:09 -0400217 while (edge <= high && eband < mode->nbEBands)
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100218 {
Jean-Marc Valin137f3362010-04-14 17:42:22 -0400219 celt_int32 num;
220 int den, bits;
Jean-Marc Valinbb8fa1f2010-06-03 00:33:42 -0400221 int N = (mode->eBands[eband+1]-mode->eBands[eband]);
Jean-Marc Valin137f3362010-04-14 17:42:22 -0400222 num = alloc * (edge-low);
223 den = high-low;
224 /* Divide with rounding */
225 bits = (2*num+den)/(2*den);
Jean-Marc Valinc51e98b2010-06-03 22:11:41 -0400226 allocVectors[i*mode->nbEBands+eband] = (2*(current+bits)+(N<<4))/(2*N<<4);
Jean-Marc Valin137f3362010-04-14 17:42:22 -0400227 /* Remove the part of the band we just allocated */
228 low = edge;
229 alloc -= bits;
230
231 /* Move to next eband */
232 current = 0;
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100233 eband++;
Jean-Marc Valin8952c452010-07-16 21:48:44 -0400234 if (eband < mode->nbEBands)
235 edge = mode->eBands[eband+1]*res;
Jean-Marc Valin137f3362010-04-14 17:42:22 -0400236 }
237 current += alloc;
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100238 }
Jean-Marc Valin137f3362010-04-14 17:42:22 -0400239 if (eband < mode->nbEBands)
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400240 {
Jean-Marc Valinbb8fa1f2010-06-03 00:33:42 -0400241 int N = (mode->eBands[eband+1]-mode->eBands[eband]);
Jean-Marc Valinc51e98b2010-06-03 22:11:41 -0400242 allocVectors[i*mode->nbEBands+eband] = (2*current+(N<<4))/(2*N<<4);
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400243 }
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100244 }
Jean-Marc Valinc51e98b2010-06-03 22:11:41 -0400245 /*printf ("\n");
246 for (i=0;i<BITALLOC_SIZE;i++)
Jean-Marc Valinbb8fa1f2010-06-03 00:33:42 -0400247 {
248 for (j=0;j<mode->nbEBands;j++)
249 printf ("%d ", allocVectors[i*mode->nbEBands+j]);
250 printf ("\n");
251 }
252 exit(0);*/
253
Jean-Marc Valin36e6e012008-08-02 22:25:19 -0400254 mode->allocVectors = allocVectors;
Jean-Marc Valinad637192008-05-07 13:44:39 +1000255}
256
Jean-Marc Valin36e6e012008-08-02 22:25:19 -0400257#endif /* STATIC_MODES */
258
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400259CELTMode *celt_mode_create(celt_int32 Fs, int frame_size, int *error)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100260{
Jean-Marc Valin47c248a2008-04-26 08:16:12 +1000261 int i;
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400262 int LM;
Jean-Marc Valin47c248a2008-04-26 08:16:12 +1000263#ifdef STDIN_TUNING
264 scanf("%d ", &MIN_BINS);
265 scanf("%d ", &BITALLOC_SIZE);
266 band_allocation = celt_alloc(sizeof(int)*BARK_BANDS*BITALLOC_SIZE);
267 for (i=0;i<BARK_BANDS*BITALLOC_SIZE;i++)
268 {
269 scanf("%d ", band_allocation+i);
270 }
271#endif
Jean-Marc Valinf39e8692008-03-10 12:13:23 +1100272#ifdef STATIC_MODES
Jean-Marc Valin949902f2008-03-11 10:43:06 +1100273 const CELTMode *m = NULL;
274 CELTMode *mode=NULL;
Jean-Marc Valinf7cec832008-04-18 17:29:56 +1000275 ALLOC_STACK;
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400276#if !defined(VAR_ARRAYS) && !defined(USE_ALLOCA)
277 if (global_stack==NULL)
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400278 goto failure;
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400279#endif
Jean-Marc Valin680a9ec2008-03-10 14:52:18 +1100280 for (i=0;i<TOTAL_MODES;i++)
281 {
282 if (Fs == static_mode_list[i]->Fs &&
Jean-Marc Valin60ff9992010-06-27 13:49:38 -0400283 frame_size == static_mode_list[i]->shortMdctSize*static_mode_list[i]->nbShortMdcts)
Jean-Marc Valin680a9ec2008-03-10 14:52:18 +1100284 {
Jean-Marc Valin949902f2008-03-11 10:43:06 +1100285 m = static_mode_list[i];
Jean-Marc Valin680a9ec2008-03-10 14:52:18 +1100286 break;
287 }
288 }
Jean-Marc Valin949902f2008-03-11 10:43:06 +1100289 if (m == NULL)
Jean-Marc Valin680a9ec2008-03-10 14:52:18 +1100290 {
291 celt_warning("Mode not included as part of the static modes");
292 if (error)
293 *error = CELT_BAD_ARG;
294 return NULL;
295 }
Jean-Marc Valin949902f2008-03-11 10:43:06 +1100296 mode = (CELTMode*)celt_alloc(sizeof(CELTMode));
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400297 if (mode==NULL)
298 goto failure;
Jean-Marc Valin949902f2008-03-11 10:43:06 +1100299 CELT_COPY(mode, m, 1);
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400300 mode->marker_start = MODEPARTIAL;
Jean-Marc Valinf39e8692008-03-10 12:13:23 +1100301#else
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100302 int res;
Gregory Maxwell84966952009-06-30 01:06:04 -0400303 CELTMode *mode=NULL;
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400304 celt_word16 *window;
Jean-Marc Valinf400a3c2010-04-05 23:58:44 -0400305 celt_int16 *logN;
Jean-Marc Valinf7cec832008-04-18 17:29:56 +1000306 ALLOC_STACK;
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400307#if !defined(VAR_ARRAYS) && !defined(USE_ALLOCA)
308 if (global_stack==NULL)
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400309 goto failure;
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400310#endif
Jean-Marc Valin3dbc1d02008-03-08 15:21:24 +1100311
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100312 /* The good thing here is that permutation of the arguments will automatically be invalid */
313
Jean-Marc Valin223b69d2010-07-16 11:47:50 -0400314 if (Fs < 8000 || Fs > 96000)
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100315 {
Jean-Marc Valin223b69d2010-07-16 11:47:50 -0400316 celt_warning("Sampling rate must be between 8 kHz and 96 kHz");
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100317 if (error)
318 *error = CELT_BAD_ARG;
319 return NULL;
320 }
Jean-Marc Valin223b69d2010-07-16 11:47:50 -0400321 if (frame_size < 40 || frame_size > 1024 || frame_size%2!=0)
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100322 {
Jean-Marc Valin223b69d2010-07-16 11:47:50 -0400323 celt_warning("Only even frame sizes from 40 to 1024 are supported");
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100324 if (error)
325 *error = CELT_BAD_ARG;
326 return NULL;
327 }
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100328
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100329 mode = celt_alloc(sizeof(CELTMode));
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400330 if (mode==NULL)
331 goto failure;
332 mode->marker_start = MODEPARTIAL;
Jean-Marc Valine6b74652008-02-20 18:01:08 +1100333 mode->Fs = Fs;
Gregory Maxwell23e654f2008-09-27 16:20:03 -0400334
Jean-Marc Valin223b69d2010-07-16 11:47:50 -0400335 /* Pre/de-emphasis depends on sampling rate. The "standard" pre-emphasis
336 is defined as A(z) = 1 - 0.85*z^-1 at 48 kHz. Other rates should
337 approximate that. */
338 if(Fs < 12000) /* 8 kHz */
339 {
340 mode->preemph[0] = QCONST16(.35f, 15);
341 mode->preemph[1] = -QCONST16(.18f, 15);
342 mode->preemph[2] = QCONST16(.272f, SIG_SHIFT);
343 mode->preemph[3] = QCONST16(3.6765f, 13);
344 } else if(Fs < 24000) /* 16 kHz */
345 {
346 mode->preemph[0] = QCONST16(.6f, 15);
347 mode->preemph[1] = -QCONST16(.18f, 15);
348 mode->preemph[2] = QCONST16(.4425f, SIG_SHIFT);
349 mode->preemph[3] = QCONST16(2.259887f, 13);
350 } else if(Fs < 40000) /* 32 kHz */
351 {
352 mode->preemph[0] = QCONST16(.78f, 15);
353 mode->preemph[1] = -QCONST16(.1f, 15);
354 mode->preemph[2] = QCONST16(.75f, SIG_SHIFT);
355 mode->preemph[3] = QCONST16(1.33333333f, 13);
356 } else /* 48 kHz */
357 {
358 mode->preemph[0] = QCONST16(.85f, 15);
359 mode->preemph[1] = QCONST16(.0f, 15);
360 mode->preemph[2] = QCONST16(1.f, SIG_SHIFT);
361 mode->preemph[3] = QCONST16(1.f, 13);
362 }
363
Jean-Marc Valina2546bb2010-07-16 12:00:00 -0400364 if ((celt_int32)frame_size*75 >= Fs && (frame_size%16)==0)
Jean-Marc Valine6d832a2009-07-08 22:21:31 -0400365 {
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400366 LM = 3;
Jean-Marc Valina2546bb2010-07-16 12:00:00 -0400367 } else if ((celt_int32)frame_size*150 >= Fs && (frame_size%8)==0)
Jean-Marc Valin16ca18b2008-06-18 23:44:48 +1000368 {
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400369 LM = 2;
Jean-Marc Valina2546bb2010-07-16 12:00:00 -0400370 } else if ((celt_int32)frame_size*300 >= Fs && (frame_size%4)==0)
Gregory Maxwell23e654f2008-09-27 16:20:03 -0400371 {
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400372 LM = 1;
Gregory Maxwell23e654f2008-09-27 16:20:03 -0400373 } else
374 {
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400375 LM = 0;
Jean-Marc Valin16ca18b2008-06-18 23:44:48 +1000376 }
Gregory Maxwell23e654f2008-09-27 16:20:03 -0400377
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400378 mode->maxLM = LM;
379 mode->nbShortMdcts = 1<<LM;
Jean-Marc Valin60ff9992010-06-27 13:49:38 -0400380 mode->shortMdctSize = frame_size/mode->nbShortMdcts;
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400381 res = (mode->Fs+mode->shortMdctSize)/(2*mode->shortMdctSize);
382
383 mode->eBands = compute_ebands(Fs, mode->shortMdctSize, res, &mode->nbEBands);
Jean-Marc Valinfbfddf72009-07-19 21:07:12 -0400384 if (mode->eBands==NULL)
385 goto failure;
Jean-Marc Valinfbfddf72009-07-19 21:07:12 -0400386
Jean-Marc Valin85f41b22010-07-16 18:12:45 -0400387 mode->effEBands = mode->nbEBands;
388 while (mode->eBands[mode->effEBands] > mode->shortMdctSize)
389 mode->effEBands--;
Jean-Marc Valin4834c922009-09-28 19:17:34 -0400390
Jean-Marc Valin08192e32009-07-02 13:28:55 -0400391 /* Overlap must be divisible by 4 */
Jean-Marc Valin16ca18b2008-06-18 23:44:48 +1000392 if (mode->nbShortMdcts > 1)
Jean-Marc Valince4dd362010-05-07 07:45:18 -0400393 mode->overlap = (mode->shortMdctSize>>2)<<2;
Jean-Marc Valin16ca18b2008-06-18 23:44:48 +1000394 else
Gregory Maxwell23e654f2008-09-27 16:20:03 -0400395 mode->overlap = (frame_size>>3)<<2;
396
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400397
398 compute_allocation_table(mode, res);
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400399 if (mode->allocVectors==NULL)
400 goto failure;
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100401
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400402 window = (celt_word16*)celt_alloc(mode->overlap*sizeof(celt_word16));
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400403 if (window==NULL)
404 goto failure;
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100405
Jean-Marc Valinf28062f2008-03-03 13:24:01 +1100406#ifndef FIXED_POINT
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100407 for (i=0;i<mode->overlap;i++)
Jean-Marc Valin3dbc1d02008-03-08 15:21:24 +1100408 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 +1100409#else
410 for (i=0;i<mode->overlap;i++)
Jean-Marc Valin8974f002010-03-20 00:41:39 -0400411 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 +1100412#endif
Jean-Marc Valin3dbc1d02008-03-08 15:21:24 +1100413 mode->window = window;
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100414
Jean-Marc Valinf400a3c2010-04-05 23:58:44 -0400415 logN = (celt_int16*)celt_alloc(mode->nbEBands*sizeof(celt_int16));
416 if (logN==NULL)
417 goto failure;
418
419 for (i=0;i<mode->nbEBands;i++)
Jean-Marc Valinaead79b2010-05-11 07:34:24 -0400420 logN[i] = log2_frac(mode->eBands[i+1]-mode->eBands[i], BITRES);
Jean-Marc Valinf400a3c2010-04-05 23:58:44 -0400421 mode->logN = logN;
Jean-Marc Valin3ad8db42010-08-25 13:11:09 -0400422
423 compute_pulse_cache(mode, mode->maxLM);
Jean-Marc Valin640f7fd2009-06-21 09:47:51 -0400424
Jean-Marc Valin732ea382010-08-25 13:52:27 -0400425 clt_mdct_init(&mode->mdct, 2*mode->shortMdctSize*mode->nbShortMdcts, mode->maxLM);
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400426 if ((mode->mdct.trig==NULL)
Jean-Marc Valin9714f662009-08-12 20:29:57 -0400427#ifndef ENABLE_TI_DSPLIB55
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400428 || (mode->mdct.kfft==NULL)
Jean-Marc Valin9714f662009-08-12 20:29:57 -0400429#endif
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400430 )
431 goto failure;
432
Jean-Marc Valin073d0bc2010-05-05 21:37:53 -0400433 mode->prob = quant_prob_alloc(mode);
434 if (mode->prob==NULL)
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400435 goto failure;
Jean-Marc Valinbf2d6482008-05-23 16:57:34 +1000436
Jean-Marc Valinbb528812010-08-25 22:12:18 -0400437#endif /* !STATIC_MODES */
438
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400439 mode->marker_start = MODEVALID;
440 mode->marker_end = MODEVALID;
Jean-Marc Valin680a9ec2008-03-10 14:52:18 +1100441 if (error)
442 *error = CELT_OK;
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100443 return mode;
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400444failure:
445 if (error)
446 *error = CELT_INVALID_MODE;
447 if (mode!=NULL)
448 celt_mode_destroy(mode);
449 return NULL;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100450}
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100451
Peter Kirk19f9dc92008-06-06 14:38:38 +0200452void celt_mode_destroy(CELTMode *mode)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100453{
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400454 if (mode == NULL)
455 {
456 celt_warning("NULL passed to celt_mode_destroy");
457 return;
458 }
459
460 if (mode->marker_start == MODEFREED || mode->marker_end == MODEFREED)
461 {
462 celt_warning("Freeing a mode which has already been freed");
463 return;
464 }
465
466 if (mode->marker_start != MODEVALID && mode->marker_start != MODEPARTIAL)
467 {
468 celt_warning("This is not a valid CELT mode structure");
469 return;
470 }
471 mode->marker_start = MODEFREED;
Jean-Marc Valin5588d522008-03-10 15:07:58 +1100472#ifndef STATIC_MODES
Jean-Marc Valin31bec962010-04-07 18:30:28 -0400473 celt_free((celt_int16*)mode->eBands);
474 celt_free((celt_int16*)mode->allocVectors);
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400475
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400476 celt_free((celt_word16*)mode->window);
Jean-Marc Valin31bec962010-04-07 18:30:28 -0400477 celt_free((celt_int16*)mode->logN);
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100478
Jean-Marc Valin732ea382010-08-25 13:52:27 -0400479 celt_free((celt_int16*)mode->cache.index);
480 celt_free((unsigned char*)mode->cache.bits);
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400481 clt_mdct_clear(&mode->mdct);
Jean-Marc Valinbb528812010-08-25 22:12:18 -0400482 quant_prob_free(mode->prob);
Jean-Marc Valin31b189b2010-08-25 21:21:43 -0400483#endif
Jean-Marc Valin073d0bc2010-05-05 21:37:53 -0400484
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400485 mode->marker_end = MODEFREED;
Jean-Marc Valin949902f2008-03-11 10:43:06 +1100486 celt_free((CELTMode *)mode);
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100487}
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +1100488
489int check_mode(const CELTMode *mode)
490{
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400491 if (mode==NULL)
492 return CELT_INVALID_MODE;
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +1100493 if (mode->marker_start == MODEVALID && mode->marker_end == MODEVALID)
494 return CELT_OK;
495 if (mode->marker_start == MODEFREED || mode->marker_end == MODEFREED)
496 celt_warning("Using a mode that has already been freed");
497 else
498 celt_warning("This is not a valid CELT mode");
499 return CELT_INVALID_MODE;
500}