blob: 3358b65fa15e582dbc6a92757883f9e03e7b48f3 [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 {
64 case CELT_GET_FRAME_SIZE:
65 *value = mode->mdctSize;
66 break;
67 case CELT_GET_LOOKAHEAD:
68 *value = mode->overlap;
69 break;
Jean-Marc Valin59093c02008-05-15 21:53:27 +100070 case CELT_GET_BITSTREAM_VERSION:
71 *value = CELT_BITSTREAM_VERSION;
72 break;
Gregory Maxwelld9458cd2009-05-30 17:04:02 -040073 case CELT_GET_SAMPLE_RATE:
74 *value = mode->Fs;
75 break;
Jean-Marc Valincb7a2a32008-02-11 16:44:48 +110076 default:
Jean-Marc Valinb6f90612008-10-05 22:39:13 -040077 return CELT_UNIMPLEMENTED;
Jean-Marc Valinf997ad52008-01-31 16:47:16 +110078 }
Jean-Marc Valincb7a2a32008-02-11 16:44:48 +110079 return CELT_OK;
Jean-Marc Valinf997ad52008-01-31 16:47:16 +110080}
81
Jean-Marc Valin5588d522008-03-10 15:07:58 +110082#ifndef STATIC_MODES
83
Jean-Marc Valin17683eb2008-02-18 21:45:19 +110084/* Defining 25 critical bands for the full 0-20 kHz audio bandwidth
85 Taken from http://ccrma.stanford.edu/~jos/bbt/Bark_Frequency_Scale.html */
Jean-Marc Valin81a82952008-02-17 22:41:29 +110086#define BARK_BANDS 25
Jean-Marc Valin30f7f812009-10-17 14:35:13 -040087static const celt_int16 bark_freq[BARK_BANDS+1] = {
Jean-Marc Valin17683eb2008-02-18 21:45:19 +110088 0, 100, 200, 300, 400,
89 510, 630, 770, 920, 1080,
90 1270, 1480, 1720, 2000, 2320,
91 2700, 3150, 3700, 4400, 5300,
92 6400, 7700, 9500, 12000, 15500,
93 20000};
94
Jean-Marc Valin75e9c862008-02-18 17:04:15 +110095/* This allocation table is per critical band. When creating a mode, the bits get added together
96 into the codec bands, which are sometimes larger than one critical band at low frequency */
Jean-Marc Valin47c248a2008-04-26 08:16:12 +100097
98#ifdef STDIN_TUNING
99int BITALLOC_SIZE;
100int *band_allocation;
101#else
Jean-Marc Valin9c709062008-08-03 22:07:06 -0400102#define BITALLOC_SIZE 12
Jean-Marc Valin25358cd2008-02-19 12:21:32 +1100103static const int band_allocation[BARK_BANDS*BITALLOC_SIZE] =
Christopher Montgomery8e511a82009-07-03 02:10:17 -0400104 /* 0 100 200 300 400 510 630 770 920 1k 1.2 1.5 1.7 2k 2.3 2.7 3.1 3.7 4.4 5.3 6.4 7.7 9.5 12k 15k */
105 { 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*0*/
106 2, 2, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*1*/
107 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 4, 5, 7, 7, 7, 5, 4, 0, 0, 0, 0, 0, 0, /*2*/
108 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 5, 6, 8, 8, 8, 6, 5, 4, 0, 0, 0, 0, 0, /*3*/
109 3, 2, 2, 2, 3, 4, 4, 4, 4, 4, 4, 4, 6, 7, 9, 9, 9, 7, 6, 5, 5, 5, 0, 0, 0, /*4*/
110 3, 3, 3, 4, 4, 5, 6, 6, 6, 6, 6, 7, 7, 9, 10, 10, 10, 9, 6, 5, 5, 5, 5, 1, 0, /*5*/
111 4, 3, 3, 4, 6, 7, 7, 7, 7, 7, 8, 9, 9, 9, 11, 10, 10, 9, 9, 8, 11, 10, 10, 1, 0, /*6*/
112 5, 5, 5, 6, 7, 7, 7, 7, 8, 8, 9, 10, 10, 12, 12, 11, 11, 17, 12, 15, 15, 20, 18, 10, 1, /*7*/
113 6, 7, 7, 7, 8, 8, 8, 8, 9, 10, 11, 12, 14, 17, 18, 21, 22, 27, 29, 39, 37, 38, 40, 35, 1, /*8*/
114 7, 7, 7, 8, 8, 8, 10, 10, 10, 13, 14, 18, 20, 24, 28, 32, 32, 35, 38, 38, 42, 50, 59, 54, 31, /*9*/
115 8, 8, 8, 8, 8, 9, 10, 12, 14, 20, 22, 25, 28, 30, 35, 42, 46, 50, 55, 60, 62, 62, 72, 82, 62, /*10*/
116 9, 9, 9, 10, 12, 13, 15, 18, 22, 30, 32, 35, 40, 45, 55, 62, 66, 70, 85, 90, 92, 92, 92,102, 92, /*11*/
Jean-Marc Valin9eba8232008-08-02 20:51:44 -0400117 };
Jean-Marc Valin47c248a2008-04-26 08:16:12 +1000118#endif
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100119
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400120static celt_int16 *compute_ebands(celt_int32 Fs, int frame_size, int nbShortMdcts, int *nbEBands)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100121{
Jean-Marc Valin6db9e6e2009-09-29 23:16:26 -0400122 int min_bins = 3;
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400123 celt_int16 *eBands;
Jean-Marc Valin39f68ac2009-10-03 23:27:52 -0400124 int i, res, min_width, lin, low, high, nBark, offset=0;
Jean-Marc Valinfbfddf72009-07-19 21:07:12 -0400125
Jean-Marc Valind5e54362009-09-30 20:50:41 -0400126 /*if (min_bins < nbShortMdcts)
127 min_bins = nbShortMdcts;*/
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100128 res = (Fs+frame_size)/(2*frame_size);
Jean-Marc Valinfbfddf72009-07-19 21:07:12 -0400129 min_width = min_bins*res;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100130
Gregory Maxwellcbaf67e2008-09-28 04:19:19 -0400131 /* Find the number of critical bands supported by our sampling rate */
132 for (nBark=1;nBark<BARK_BANDS;nBark++)
133 if (bark_freq[nBark+1]*2 >= Fs)
134 break;
135
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100136 /* Find where the linear part ends (i.e. where the spacing is more than min_width */
Gregory Maxwellcbaf67e2008-09-28 04:19:19 -0400137 for (lin=0;lin<nBark;lin++)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100138 if (bark_freq[lin+1]-bark_freq[lin] >= min_width)
139 break;
140
Jean-Marc Valinfbfddf72009-07-19 21:07:12 -0400141 low = ((bark_freq[lin]/res)+(min_bins-1))/min_bins;
Gregory Maxwellcbaf67e2008-09-28 04:19:19 -0400142 high = nBark-lin;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100143 *nbEBands = low+high;
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400144 eBands = celt_alloc(sizeof(celt_int16)*(*nbEBands+2));
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100145
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400146 if (eBands==NULL)
147 return NULL;
148
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100149 /* Linear spacing (min_width) */
150 for (i=0;i<low;i++)
Jean-Marc Valinfbfddf72009-07-19 21:07:12 -0400151 eBands[i] = min_bins*i;
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];
156 eBands[i+low] = (2*target+offset+res)/(2*res);
157 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 Valinfbfddf72009-07-19 21:07:12 -0400161 if (eBands[i] < min_bins*i)
162 eBands[i] = min_bins*i;
Jean-Marc Valin6db9e6e2009-09-29 23:16:26 -0400163 eBands[*nbEBands] = (bark_freq[nBark]+res/2)/res;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100164 eBands[*nbEBands+1] = frame_size;
165 if (eBands[*nbEBands] > eBands[*nbEBands+1])
166 eBands[*nbEBands] = eBands[*nbEBands+1];
Jean-Marc Valinfbfddf72009-07-19 21:07:12 -0400167 for (i=1;i<*nbEBands-1;i++)
168 {
169 if (eBands[i+1]-eBands[i] < eBands[i]-eBands[i-1])
170 {
Jean-Marc Valin39f68ac2009-10-03 23:27:52 -0400171 eBands[i] -= (2*eBands[i]-eBands[i-1]-eBands[i+1]+1)/2;
Jean-Marc Valinfbfddf72009-07-19 21:07:12 -0400172 }
173 }
174 /*for (i=0;i<*nbEBands+1;i++)
175 printf ("%d ", eBands[i]);
Jean-Marc Valin39f68ac2009-10-03 23:27:52 -0400176 printf ("\n");
177 exit(1);*/
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100178 /* FIXME: Remove last band if too small */
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100179 return eBands;
180}
181
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100182static void compute_allocation_table(CELTMode *mode, int res)
183{
Gregory Maxwellec836da2009-05-04 14:55:40 -0400184 int i, j, nBark;
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400185 celt_int16 *allocVectors;
Jean-Marc Valin36e6e012008-08-02 22:25:19 -0400186
Gregory Maxwellcbaf67e2008-09-28 04:19:19 -0400187 /* Find the number of critical bands supported by our sampling rate */
188 for (nBark=1;nBark<BARK_BANDS;nBark++)
189 if (bark_freq[nBark+1]*2 >= mode->Fs)
190 break;
191
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100192 mode->nbAllocVectors = BITALLOC_SIZE;
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400193 allocVectors = celt_alloc(sizeof(celt_int16)*(BITALLOC_SIZE*mode->nbEBands));
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400194 if (allocVectors==NULL)
195 return;
Jean-Marc Valin36e6e012008-08-02 22:25:19 -0400196 /* Compute per-codec-band allocation from per-critical-band matrix */
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100197 for (i=0;i<BITALLOC_SIZE;i++)
198 {
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400199 celt_int32 current = 0;
Gregory Maxwellec836da2009-05-04 14:55:40 -0400200 int eband = 0;
Gregory Maxwellcbaf67e2008-09-28 04:19:19 -0400201 for (j=0;j<nBark;j++)
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100202 {
Jean-Marc Valin5c0d4862008-07-24 08:49:34 -0400203 int edge, low;
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400204 celt_int32 alloc;
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100205 edge = mode->eBands[eband+1]*res;
Jean-Marc Valin6a978022009-10-13 20:35:21 -0400206 alloc = mode->mdctSize*band_allocation[i*BARK_BANDS+j];
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100207 if (edge < bark_freq[j+1])
208 {
209 int num, den;
Jean-Marc Valin13294b52008-05-30 16:07:06 +1000210 num = alloc * (edge-bark_freq[j]);
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100211 den = bark_freq[j+1]-bark_freq[j];
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100212 low = (num+den/2)/den;
Gregory Maxwellec836da2009-05-04 14:55:40 -0400213 allocVectors[i*mode->nbEBands+eband] = (current+low+128)/256;
214 current=0;
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100215 eband++;
Gregory Maxwellec836da2009-05-04 14:55:40 -0400216 current += alloc-low;
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100217 } else {
Gregory Maxwellec836da2009-05-04 14:55:40 -0400218 current += alloc;
219 }
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100220 }
Gregory Maxwellec836da2009-05-04 14:55:40 -0400221 allocVectors[i*mode->nbEBands+eband] = (current+128)/256;
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100222 }
Jean-Marc Valin36e6e012008-08-02 22:25:19 -0400223 mode->allocVectors = allocVectors;
Jean-Marc Valinad637192008-05-07 13:44:39 +1000224}
225
Jean-Marc Valin36e6e012008-08-02 22:25:19 -0400226#endif /* STATIC_MODES */
227
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400228CELTMode *celt_mode_create(celt_int32 Fs, int frame_size, int *error)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100229{
Jean-Marc Valin47c248a2008-04-26 08:16:12 +1000230 int i;
231#ifdef STDIN_TUNING
232 scanf("%d ", &MIN_BINS);
233 scanf("%d ", &BITALLOC_SIZE);
234 band_allocation = celt_alloc(sizeof(int)*BARK_BANDS*BITALLOC_SIZE);
235 for (i=0;i<BARK_BANDS*BITALLOC_SIZE;i++)
236 {
237 scanf("%d ", band_allocation+i);
238 }
239#endif
Jean-Marc Valinf39e8692008-03-10 12:13:23 +1100240#ifdef STATIC_MODES
Jean-Marc Valin949902f2008-03-11 10:43:06 +1100241 const CELTMode *m = NULL;
242 CELTMode *mode=NULL;
Jean-Marc Valinf7cec832008-04-18 17:29:56 +1000243 ALLOC_STACK;
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400244#if !defined(VAR_ARRAYS) && !defined(USE_ALLOCA)
245 if (global_stack==NULL)
246 {
247 celt_free(global_stack);
248 goto failure;
249 }
250#endif
Jean-Marc Valin680a9ec2008-03-10 14:52:18 +1100251 for (i=0;i<TOTAL_MODES;i++)
252 {
253 if (Fs == static_mode_list[i]->Fs &&
Jean-Marc Valin60d08372008-10-03 07:30:08 -0400254 frame_size == static_mode_list[i]->mdctSize)
Jean-Marc Valin680a9ec2008-03-10 14:52:18 +1100255 {
Jean-Marc Valin949902f2008-03-11 10:43:06 +1100256 m = static_mode_list[i];
Jean-Marc Valin680a9ec2008-03-10 14:52:18 +1100257 break;
258 }
259 }
Jean-Marc Valin949902f2008-03-11 10:43:06 +1100260 if (m == NULL)
Jean-Marc Valin680a9ec2008-03-10 14:52:18 +1100261 {
262 celt_warning("Mode not included as part of the static modes");
263 if (error)
264 *error = CELT_BAD_ARG;
265 return NULL;
266 }
Jean-Marc Valin949902f2008-03-11 10:43:06 +1100267 mode = (CELTMode*)celt_alloc(sizeof(CELTMode));
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400268 if (mode==NULL)
269 goto failure;
Jean-Marc Valin949902f2008-03-11 10:43:06 +1100270 CELT_COPY(mode, m, 1);
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400271 mode->marker_start = MODEPARTIAL;
Jean-Marc Valinf39e8692008-03-10 12:13:23 +1100272#else
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100273 int res;
Gregory Maxwell84966952009-06-30 01:06:04 -0400274 CELTMode *mode=NULL;
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400275 celt_word16 *window;
Jean-Marc Valinf400a3c2010-04-05 23:58:44 -0400276 celt_int16 *logN;
Jean-Marc Valinf7cec832008-04-18 17:29:56 +1000277 ALLOC_STACK;
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400278#if !defined(VAR_ARRAYS) && !defined(USE_ALLOCA)
279 if (global_stack==NULL)
280 {
281 celt_free(global_stack);
282 goto failure;
283 }
284#endif
Jean-Marc Valin3dbc1d02008-03-08 15:21:24 +1100285
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100286 /* The good thing here is that permutation of the arguments will automatically be invalid */
287
Gregory Maxwell8ed86582008-12-02 12:06:14 -0500288 if (Fs < 32000 || Fs > 96000)
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100289 {
Gregory Maxwell8ed86582008-12-02 12:06:14 -0500290 celt_warning("Sampling rate must be between 32 kHz and 96 kHz");
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100291 if (error)
292 *error = CELT_BAD_ARG;
293 return NULL;
294 }
Jean-Marc Valine6d832a2009-07-08 22:21:31 -0400295 if (frame_size < 64 || frame_size > 1024 || frame_size%2!=0)
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100296 {
Jean-Marc Valine6d832a2009-07-08 22:21:31 -0400297 celt_warning("Only even frame sizes from 64 to 1024 are supported");
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100298 if (error)
299 *error = CELT_BAD_ARG;
300 return NULL;
301 }
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100302 res = (Fs+frame_size)/(2*frame_size);
303
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100304 mode = celt_alloc(sizeof(CELTMode));
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400305 if (mode==NULL)
306 goto failure;
307 mode->marker_start = MODEPARTIAL;
Jean-Marc Valine6b74652008-02-20 18:01:08 +1100308 mode->Fs = Fs;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100309 mode->mdctSize = frame_size;
Jean-Marc Valin8b2a5922008-02-29 00:32:51 +1100310 mode->ePredCoef = QCONST16(.8f,15);
Gregory Maxwell23e654f2008-09-27 16:20:03 -0400311
Jean-Marc Valine6d832a2009-07-08 22:21:31 -0400312 if (frame_size > 640 && (frame_size%16)==0)
313 {
314 mode->nbShortMdcts = 8;
315 } else if (frame_size > 384 && (frame_size%8)==0)
Jean-Marc Valin16ca18b2008-06-18 23:44:48 +1000316 {
Gregory Maxwell23e654f2008-09-27 16:20:03 -0400317 mode->nbShortMdcts = 4;
318 } else if (frame_size > 384 && (frame_size%10)==0)
Jean-Marc Valin16ca18b2008-06-18 23:44:48 +1000319 {
Gregory Maxwell23e654f2008-09-27 16:20:03 -0400320 mode->nbShortMdcts = 5;
321 } else if (frame_size > 256 && (frame_size%6)==0)
Jean-Marc Valin16ca18b2008-06-18 23:44:48 +1000322 {
Gregory Maxwell23e654f2008-09-27 16:20:03 -0400323 mode->nbShortMdcts = 3;
324 } else if (frame_size > 256 && (frame_size%8)==0)
325 {
326 mode->nbShortMdcts = 4;
327 } else if (frame_size > 64 && (frame_size%4)==0)
328 {
329 mode->nbShortMdcts = 2;
330 } else if (frame_size > 128 && (frame_size%6)==0)
331 {
332 mode->nbShortMdcts = 3;
333 } else
334 {
335 mode->nbShortMdcts = 1;
Jean-Marc Valin16ca18b2008-06-18 23:44:48 +1000336 }
Gregory Maxwell23e654f2008-09-27 16:20:03 -0400337
Jean-Marc Valinfbfddf72009-07-19 21:07:12 -0400338 mode->eBands = compute_ebands(Fs, frame_size, mode->nbShortMdcts, &mode->nbEBands);
339 if (mode->eBands==NULL)
340 goto failure;
Jean-Marc Valinfbfddf72009-07-19 21:07:12 -0400341
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400342 mode->pitchEnd = 4000*(celt_int32)frame_size/Fs;
Jean-Marc Valin4834c922009-09-28 19:17:34 -0400343
Jean-Marc Valin08192e32009-07-02 13:28:55 -0400344 /* Overlap must be divisible by 4 */
Jean-Marc Valin16ca18b2008-06-18 23:44:48 +1000345 if (mode->nbShortMdcts > 1)
Jean-Marc Valin08192e32009-07-02 13:28:55 -0400346 mode->overlap = ((frame_size/mode->nbShortMdcts)>>2)<<2;
Jean-Marc Valin16ca18b2008-06-18 23:44:48 +1000347 else
Gregory Maxwell23e654f2008-09-27 16:20:03 -0400348 mode->overlap = (frame_size>>3)<<2;
349
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100350 compute_allocation_table(mode, res);
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400351 if (mode->allocVectors==NULL)
352 goto failure;
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100353
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400354 window = (celt_word16*)celt_alloc(mode->overlap*sizeof(celt_word16));
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400355 if (window==NULL)
356 goto failure;
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100357
Jean-Marc Valinf28062f2008-03-03 13:24:01 +1100358#ifndef FIXED_POINT
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100359 for (i=0;i<mode->overlap;i++)
Jean-Marc Valin3dbc1d02008-03-08 15:21:24 +1100360 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 +1100361#else
362 for (i=0;i<mode->overlap;i++)
Jean-Marc Valin8974f002010-03-20 00:41:39 -0400363 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 +1100364#endif
Jean-Marc Valin3dbc1d02008-03-08 15:21:24 +1100365 mode->window = window;
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100366
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400367 mode->bits = (const celt_int16 **)compute_alloc_cache(mode, 1);
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400368 if (mode->bits==NULL)
369 goto failure;
Jean-Marc Valinb76ee702008-03-10 15:42:35 +1100370
Jean-Marc Valinf400a3c2010-04-05 23:58:44 -0400371 logN = (celt_int16*)celt_alloc(mode->nbEBands*sizeof(celt_int16));
372 if (logN==NULL)
373 goto failure;
374
375 for (i=0;i<mode->nbEBands;i++)
376 logN[i] = log2_frac(mode->eBands[i+1]-mode->eBands[i], BITRES);
377 mode->logN = logN;
Jean-Marc Valinb76ee702008-03-10 15:42:35 +1100378#endif /* !STATIC_MODES */
Jean-Marc Valin640f7fd2009-06-21 09:47:51 -0400379
Jean-Marc Valin6d584ac2009-11-21 21:57:44 -0500380 clt_mdct_init(&mode->mdct, 2*mode->mdctSize);
Jean-Marc Valin24c9cda2008-05-02 10:34:07 +1000381
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000382 mode->shortMdctSize = mode->mdctSize/mode->nbShortMdcts;
Jean-Marc Valin6d584ac2009-11-21 21:57:44 -0500383 clt_mdct_init(&mode->shortMdct, 2*mode->shortMdctSize);
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000384 mode->shortWindow = mode->window;
Jean-Marc Valin4ce92052008-04-23 13:42:10 +1000385 mode->prob = quant_prob_alloc(mode);
Jean-Marc Valin9714f662009-08-12 20:29:57 -0400386 if ((mode->mdct.trig==NULL) || (mode->shortMdct.trig==NULL)
387#ifndef ENABLE_TI_DSPLIB55
Jean-Marc Valin9319e3e2009-11-09 13:51:54 +0900388 || (mode->mdct.kfft==NULL) || (mode->shortMdct.kfft==NULL)
Jean-Marc Valin9714f662009-08-12 20:29:57 -0400389#endif
390 || (mode->prob==NULL))
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400391 goto failure;
Jean-Marc Valinbf2d6482008-05-23 16:57:34 +1000392
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400393 mode->marker_start = MODEVALID;
394 mode->marker_end = MODEVALID;
Jean-Marc Valin680a9ec2008-03-10 14:52:18 +1100395 if (error)
396 *error = CELT_OK;
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100397 return mode;
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400398failure:
399 if (error)
400 *error = CELT_INVALID_MODE;
401 if (mode!=NULL)
402 celt_mode_destroy(mode);
403 return NULL;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100404}
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100405
Peter Kirk19f9dc92008-06-06 14:38:38 +0200406void celt_mode_destroy(CELTMode *mode)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100407{
Jean-Marc Valinf43488c2009-06-05 11:07:31 -0400408 int i;
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400409 const celt_int16 *prevPtr = NULL;
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400410 if (mode == NULL)
411 {
412 celt_warning("NULL passed to celt_mode_destroy");
413 return;
414 }
415
416 if (mode->marker_start == MODEFREED || mode->marker_end == MODEFREED)
417 {
418 celt_warning("Freeing a mode which has already been freed");
419 return;
420 }
421
422 if (mode->marker_start != MODEVALID && mode->marker_start != MODEPARTIAL)
423 {
424 celt_warning("This is not a valid CELT mode structure");
425 return;
426 }
427 mode->marker_start = MODEFREED;
Jean-Marc Valin5588d522008-03-10 15:07:58 +1100428#ifndef STATIC_MODES
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400429 if (mode->bits!=NULL)
Jean-Marc Valin25358cd2008-02-19 12:21:32 +1100430 {
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400431 for (i=0;i<mode->nbEBands;i++)
Jean-Marc Valin25358cd2008-02-19 12:21:32 +1100432 {
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400433 if (mode->bits[i] != prevPtr)
434 {
435 prevPtr = mode->bits[i];
436 celt_free((int*)mode->bits[i]);
437 }
Jean-Marc Valin25358cd2008-02-19 12:21:32 +1100438 }
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400439 }
Jean-Marc Valin25358cd2008-02-19 12:21:32 +1100440 celt_free((int**)mode->bits);
Jean-Marc Valinf39e8692008-03-10 12:13:23 +1100441 celt_free((int*)mode->eBands);
Jean-Marc Valinf39e8692008-03-10 12:13:23 +1100442 celt_free((int*)mode->allocVectors);
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400443
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400444 celt_free((celt_word16*)mode->window);
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100445
Jean-Marc Valin70720a32008-04-19 21:39:26 +1000446#endif
Jean-Marc Valin6d584ac2009-11-21 21:57:44 -0500447 clt_mdct_clear(&mode->mdct);
448 clt_mdct_clear(&mode->shortMdct);
Jean-Marc Valin4ce92052008-04-23 13:42:10 +1000449 quant_prob_free(mode->prob);
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400450 mode->marker_end = MODEFREED;
Jean-Marc Valin949902f2008-03-11 10:43:06 +1100451 celt_free((CELTMode *)mode);
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100452}
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +1100453
454int check_mode(const CELTMode *mode)
455{
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400456 if (mode==NULL)
457 return CELT_INVALID_MODE;
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +1100458 if (mode->marker_start == MODEVALID && mode->marker_end == MODEVALID)
459 return CELT_OK;
460 if (mode->marker_start == MODEFREED || mode->marker_end == MODEFREED)
461 celt_warning("Using a mode that has already been freed");
462 else
463 celt_warning("This is not a valid CELT mode");
464 return CELT_INVALID_MODE;
465}