blob: d1512d03d92038f5541e93e12831412174c8b07b [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 Valin9c709062008-08-03 22:07:06 -040095#define BITALLOC_SIZE 12
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 Valin12e851d2010-06-03 08:12:11 -0400103 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
104 10, 3, 8, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
105 10, 6, 8, 6, 5, 4, 3, 2, 7, 10, 11, 9, 7, 3, 1, 0, 0, 0, 0, 0, 0,
106 10, 10, 14, 11, 10, 8, 6, 5, 10, 12, 13, 11, 8, 4, 2, 1, 0, 0, 0, 0, 0,
107 13, 10, 17, 16, 14, 12, 10, 8, 12, 14, 14, 12, 9, 5, 3, 2, 2, 1, 0, 0, 0,
108 17, 21, 23, 26, 24, 20, 17, 16, 17, 18, 16, 14, 11, 6, 3, 2, 2, 1, 1, 0, 0,
109 21, 21, 36, 32, 28, 24, 23, 23, 22, 18, 18, 14, 11, 7, 5, 5, 5, 3, 3, 0, 0,
110 31, 35, 40, 32, 30, 28, 26, 26, 25, 24, 19, 15, 15, 13, 9, 9, 8, 7, 5, 2, 0,
111 42, 46, 46, 37, 35, 34, 33, 32, 34, 35, 32, 31, 27, 24, 23, 23, 18, 14, 11, 7, 0,
112 46, 49, 46, 46, 42, 43, 44, 47, 50, 52, 51, 48, 39, 32, 27, 24, 22, 19, 17, 11, 5,
113 53, 53, 49, 48, 55, 66, 71, 71, 71, 65, 64, 64, 56, 47, 41, 37, 31, 24, 20, 16, 10,
114 60, 64, 74, 74, 87,103,106,102,101,100,101, 95, 80, 69, 63, 55, 47, 36, 26, 21, 15,
115};
Jean-Marc Valin20639c42010-05-19 16:10:12 -0400116
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400117static celt_int16 *compute_ebands(celt_int32 Fs, int frame_size, int res, int *nbEBands)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100118{
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400119 celt_int16 *eBands;
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400120 int i, lin, low, high, nBark, offset=0;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100121
Jean-Marc Valin3b0df0d2010-07-16 15:55:30 -0400122 /* All modes that have 2.5 ms short blocks use the same definition */
123 if (Fs == 400*(celt_int32)frame_size)
Jean-Marc Valin20639c42010-05-19 16:10:12 -0400124 {
125 *nbEBands = sizeof(eband5ms)/sizeof(eband5ms[0])-1;
Jean-Marc Valin8952c452010-07-16 21:48:44 -0400126 eBands = celt_alloc(sizeof(celt_int16)*(*nbEBands+1));
127 for (i=0;i<*nbEBands+1;i++)
Jean-Marc Valin20639c42010-05-19 16:10:12 -0400128 eBands[i] = eband5ms[i];
Jean-Marc Valin20639c42010-05-19 16:10:12 -0400129 return eBands;
130 }
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 Valin7f1c9422010-04-29 11:24:11 -0400138 if (bark_freq[lin+1]-bark_freq[lin] >= res)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100139 break;
Jean-Marc Valin4fb95682010-04-20 23:30:22 -0400140
Jean-Marc Valin65ee67a2010-04-26 07:08:44 -0400141 low = (bark_freq[lin]+res/2)/res;
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 Valin65ee67a2010-04-26 07:08:44 -0400151 eBands[i] = i;
Jean-Marc Valinbe8d1252010-04-21 18:09:07 -0400152 if (low>0)
153 offset = eBands[low-1]*res - bark_freq[lin-1];
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100154 /* Spacing follows critical bands */
155 for (i=0;i<high;i++)
Jean-Marc Valin39f68ac2009-10-03 23:27:52 -0400156 {
157 int target = bark_freq[lin+i];
Jean-Marc Valin65ee67a2010-04-26 07:08:44 -0400158 eBands[i+low] = (target+(offset+res)/2)/res;
Jean-Marc Valin39f68ac2009-10-03 23:27:52 -0400159 offset = eBands[i+low]*res - target;
160 }
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100161 /* Enforce the minimum spacing at the boundary */
162 for (i=0;i<*nbEBands;i++)
Jean-Marc Valin65ee67a2010-04-26 07:08:44 -0400163 if (eBands[i] < i)
164 eBands[i] = i;
165 eBands[*nbEBands] = (bark_freq[nBark]+res/2)/res;
Jean-Marc Valin8952c452010-07-16 21:48:44 -0400166 if (eBands[*nbEBands] > frame_size)
167 eBands[*nbEBands] = frame_size;
Jean-Marc Valinfbfddf72009-07-19 21:07:12 -0400168 for (i=1;i<*nbEBands-1;i++)
169 {
170 if (eBands[i+1]-eBands[i] < eBands[i]-eBands[i-1])
171 {
Jean-Marc Valin65ee67a2010-04-26 07:08:44 -0400172 eBands[i] -= (2*eBands[i]-eBands[i-1]-eBands[i+1])/2;
Jean-Marc Valinfbfddf72009-07-19 21:07:12 -0400173 }
174 }
Jean-Marc Valin65ee67a2010-04-26 07:08:44 -0400175 /*for (i=0;i<=*nbEBands+1;i++)
Jean-Marc Valinfbfddf72009-07-19 21:07:12 -0400176 printf ("%d ", eBands[i]);
Jean-Marc Valin39f68ac2009-10-03 23:27:52 -0400177 printf ("\n");
178 exit(1);*/
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100179 /* FIXME: Remove last band if too small */
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100180 return eBands;
181}
182
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400183static void compute_allocation_table(CELTMode *mode, int res)
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100184{
Jean-Marc Valin2f6c5fe2010-06-28 17:22:37 -0400185 int i, j;
Jean-Marc Valin01b54b92010-06-03 23:29:35 -0400186 unsigned char *allocVectors;
Jean-Marc Valinc51e98b2010-06-03 22:11:41 -0400187 int maxBands = sizeof(eband5ms)/sizeof(eband5ms[0])-1;
Jean-Marc Valin36e6e012008-08-02 22:25:19 -0400188
Jean-Marc Valin12e851d2010-06-03 08:12:11 -0400189 mode->nbAllocVectors = BITALLOC_SIZE;
Jean-Marc Valin01b54b92010-06-03 23:29:35 -0400190 allocVectors = celt_alloc(sizeof(unsigned char)*(BITALLOC_SIZE*mode->nbEBands));
Jean-Marc Valin12e851d2010-06-03 08:12:11 -0400191 if (allocVectors==NULL)
192 return;
193
Jean-Marc Valinc51e98b2010-06-03 22:11:41 -0400194 /* Check for standard mode */
Jean-Marc Valin12e851d2010-06-03 08:12:11 -0400195 if (mode->Fs == 400*(celt_int32)mode->shortMdctSize && mode->Fs >= 40000)
196 {
197 for (i=0;i<BITALLOC_SIZE*mode->nbEBands;i++)
Jean-Marc Valinffe50612010-06-04 00:13:19 -0400198 allocVectors[i] = band_allocation[i];
Jean-Marc Valin12e851d2010-06-03 08:12:11 -0400199 mode->allocVectors = allocVectors;
200 return;
201 }
Jean-Marc Valinc51e98b2010-06-03 22:11:41 -0400202 /* If not the standard mode, interpolate */
203
Jean-Marc Valin36e6e012008-08-02 22:25:19 -0400204 /* Compute per-codec-band allocation from per-critical-band matrix */
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100205 for (i=0;i<BITALLOC_SIZE;i++)
206 {
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400207 celt_int32 current = 0;
Gregory Maxwellec836da2009-05-04 14:55:40 -0400208 int eband = 0;
Jean-Marc Valin2f6c5fe2010-06-28 17:22:37 -0400209 /* We may be looping over too many bands, but eband will stop being
210 incremented once we reach the last band */
211 for (j=0;j<maxBands;j++)
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100212 {
Jean-Marc Valin137f3362010-04-14 17:42:22 -0400213 int edge, low, high;
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400214 celt_int32 alloc;
Jean-Marc Valinffe50612010-06-04 00:13:19 -0400215 alloc = band_allocation[i*maxBands + j]*(mode->eBands[eband+1]-mode->eBands[eband])<<4;
Jean-Marc Valinc51e98b2010-06-03 22:11:41 -0400216 low = eband5ms[j]*200;
217 high = eband5ms[j+1]*200;
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400218 edge = mode->eBands[eband+1]*res;
Jean-Marc Valin3ff5e4c2010-04-14 18:02:09 -0400219 while (edge <= high && eband < mode->nbEBands)
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100220 {
Jean-Marc Valin137f3362010-04-14 17:42:22 -0400221 celt_int32 num;
222 int den, bits;
Jean-Marc Valinbb8fa1f2010-06-03 00:33:42 -0400223 int N = (mode->eBands[eband+1]-mode->eBands[eband]);
Jean-Marc Valin137f3362010-04-14 17:42:22 -0400224 num = alloc * (edge-low);
225 den = high-low;
226 /* Divide with rounding */
227 bits = (2*num+den)/(2*den);
Jean-Marc Valinc51e98b2010-06-03 22:11:41 -0400228 allocVectors[i*mode->nbEBands+eband] = (2*(current+bits)+(N<<4))/(2*N<<4);
Jean-Marc Valin137f3362010-04-14 17:42:22 -0400229 /* Remove the part of the band we just allocated */
230 low = edge;
231 alloc -= bits;
232
233 /* Move to next eband */
234 current = 0;
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100235 eband++;
Jean-Marc Valin8952c452010-07-16 21:48:44 -0400236 if (eband < mode->nbEBands)
237 edge = mode->eBands[eband+1]*res;
Jean-Marc Valin137f3362010-04-14 17:42:22 -0400238 }
239 current += alloc;
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100240 }
Jean-Marc Valin137f3362010-04-14 17:42:22 -0400241 if (eband < mode->nbEBands)
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400242 {
Jean-Marc Valinbb8fa1f2010-06-03 00:33:42 -0400243 int N = (mode->eBands[eband+1]-mode->eBands[eband]);
Jean-Marc Valinc51e98b2010-06-03 22:11:41 -0400244 allocVectors[i*mode->nbEBands+eband] = (2*current+(N<<4))/(2*N<<4);
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400245 }
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100246 }
Jean-Marc Valinc51e98b2010-06-03 22:11:41 -0400247 /*printf ("\n");
248 for (i=0;i<BITALLOC_SIZE;i++)
Jean-Marc Valinbb8fa1f2010-06-03 00:33:42 -0400249 {
250 for (j=0;j<mode->nbEBands;j++)
251 printf ("%d ", allocVectors[i*mode->nbEBands+j]);
252 printf ("\n");
253 }
254 exit(0);*/
255
Jean-Marc Valin36e6e012008-08-02 22:25:19 -0400256 mode->allocVectors = allocVectors;
Jean-Marc Valinad637192008-05-07 13:44:39 +1000257}
258
Jean-Marc Valin36e6e012008-08-02 22:25:19 -0400259#endif /* STATIC_MODES */
260
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400261CELTMode *celt_mode_create(celt_int32 Fs, int frame_size, int *error)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100262{
Jean-Marc Valin47c248a2008-04-26 08:16:12 +1000263 int i;
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400264 int LM;
Jean-Marc Valin47c248a2008-04-26 08:16:12 +1000265#ifdef STDIN_TUNING
266 scanf("%d ", &MIN_BINS);
267 scanf("%d ", &BITALLOC_SIZE);
268 band_allocation = celt_alloc(sizeof(int)*BARK_BANDS*BITALLOC_SIZE);
269 for (i=0;i<BARK_BANDS*BITALLOC_SIZE;i++)
270 {
271 scanf("%d ", band_allocation+i);
272 }
273#endif
Jean-Marc Valinf39e8692008-03-10 12:13:23 +1100274#ifdef STATIC_MODES
Jean-Marc Valin949902f2008-03-11 10:43:06 +1100275 const CELTMode *m = NULL;
276 CELTMode *mode=NULL;
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)
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400280 goto failure;
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400281#endif
Jean-Marc Valin680a9ec2008-03-10 14:52:18 +1100282 for (i=0;i<TOTAL_MODES;i++)
283 {
284 if (Fs == static_mode_list[i]->Fs &&
Jean-Marc Valin60ff9992010-06-27 13:49:38 -0400285 frame_size == static_mode_list[i]->shortMdctSize*static_mode_list[i]->nbShortMdcts)
Jean-Marc Valin680a9ec2008-03-10 14:52:18 +1100286 {
Jean-Marc Valin949902f2008-03-11 10:43:06 +1100287 m = static_mode_list[i];
Jean-Marc Valin680a9ec2008-03-10 14:52:18 +1100288 break;
289 }
290 }
Jean-Marc Valin949902f2008-03-11 10:43:06 +1100291 if (m == NULL)
Jean-Marc Valin680a9ec2008-03-10 14:52:18 +1100292 {
293 celt_warning("Mode not included as part of the static modes");
294 if (error)
295 *error = CELT_BAD_ARG;
296 return NULL;
297 }
Jean-Marc Valin949902f2008-03-11 10:43:06 +1100298 mode = (CELTMode*)celt_alloc(sizeof(CELTMode));
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400299 if (mode==NULL)
300 goto failure;
Jean-Marc Valin949902f2008-03-11 10:43:06 +1100301 CELT_COPY(mode, m, 1);
Jean-Marc Valinf477d582010-06-27 09:56:26 -0400302 mode->bits = mode->_bits+1;
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400303 mode->marker_start = MODEPARTIAL;
Jean-Marc Valinf39e8692008-03-10 12:13:23 +1100304#else
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100305 int res;
Gregory Maxwell84966952009-06-30 01:06:04 -0400306 CELTMode *mode=NULL;
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400307 celt_word16 *window;
Jean-Marc Valinf400a3c2010-04-05 23:58:44 -0400308 celt_int16 *logN;
Jean-Marc Valinf7cec832008-04-18 17:29:56 +1000309 ALLOC_STACK;
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400310#if !defined(VAR_ARRAYS) && !defined(USE_ALLOCA)
311 if (global_stack==NULL)
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400312 goto failure;
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400313#endif
Jean-Marc Valin3dbc1d02008-03-08 15:21:24 +1100314
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100315 /* The good thing here is that permutation of the arguments will automatically be invalid */
316
Jean-Marc Valin223b69d2010-07-16 11:47:50 -0400317 if (Fs < 8000 || Fs > 96000)
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100318 {
Jean-Marc Valin223b69d2010-07-16 11:47:50 -0400319 celt_warning("Sampling rate must be between 8 kHz and 96 kHz");
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100320 if (error)
321 *error = CELT_BAD_ARG;
322 return NULL;
323 }
Jean-Marc Valin223b69d2010-07-16 11:47:50 -0400324 if (frame_size < 40 || frame_size > 1024 || frame_size%2!=0)
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100325 {
Jean-Marc Valin223b69d2010-07-16 11:47:50 -0400326 celt_warning("Only even frame sizes from 40 to 1024 are supported");
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100327 if (error)
328 *error = CELT_BAD_ARG;
329 return NULL;
330 }
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100331
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100332 mode = celt_alloc(sizeof(CELTMode));
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400333 if (mode==NULL)
334 goto failure;
335 mode->marker_start = MODEPARTIAL;
Jean-Marc Valine6b74652008-02-20 18:01:08 +1100336 mode->Fs = Fs;
Jean-Marc Valin8b2a5922008-02-29 00:32:51 +1100337 mode->ePredCoef = QCONST16(.8f,15);
Gregory Maxwell23e654f2008-09-27 16:20:03 -0400338
Jean-Marc Valin223b69d2010-07-16 11:47:50 -0400339 /* Pre/de-emphasis depends on sampling rate. The "standard" pre-emphasis
340 is defined as A(z) = 1 - 0.85*z^-1 at 48 kHz. Other rates should
341 approximate that. */
342 if(Fs < 12000) /* 8 kHz */
343 {
344 mode->preemph[0] = QCONST16(.35f, 15);
345 mode->preemph[1] = -QCONST16(.18f, 15);
346 mode->preemph[2] = QCONST16(.272f, SIG_SHIFT);
347 mode->preemph[3] = QCONST16(3.6765f, 13);
348 } else if(Fs < 24000) /* 16 kHz */
349 {
350 mode->preemph[0] = QCONST16(.6f, 15);
351 mode->preemph[1] = -QCONST16(.18f, 15);
352 mode->preemph[2] = QCONST16(.4425f, SIG_SHIFT);
353 mode->preemph[3] = QCONST16(2.259887f, 13);
354 } else if(Fs < 40000) /* 32 kHz */
355 {
356 mode->preemph[0] = QCONST16(.78f, 15);
357 mode->preemph[1] = -QCONST16(.1f, 15);
358 mode->preemph[2] = QCONST16(.75f, SIG_SHIFT);
359 mode->preemph[3] = QCONST16(1.33333333f, 13);
360 } else /* 48 kHz */
361 {
362 mode->preemph[0] = QCONST16(.85f, 15);
363 mode->preemph[1] = QCONST16(.0f, 15);
364 mode->preemph[2] = QCONST16(1.f, SIG_SHIFT);
365 mode->preemph[3] = QCONST16(1.f, 13);
366 }
367
Jean-Marc Valina2546bb2010-07-16 12:00:00 -0400368 if ((celt_int32)frame_size*75 >= Fs && (frame_size%16)==0)
Jean-Marc Valine6d832a2009-07-08 22:21:31 -0400369 {
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400370 LM = 3;
Jean-Marc Valina2546bb2010-07-16 12:00:00 -0400371 } else if ((celt_int32)frame_size*150 >= Fs && (frame_size%8)==0)
Jean-Marc Valin16ca18b2008-06-18 23:44:48 +1000372 {
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400373 LM = 2;
Jean-Marc Valina2546bb2010-07-16 12:00:00 -0400374 } else if ((celt_int32)frame_size*300 >= Fs && (frame_size%4)==0)
Gregory Maxwell23e654f2008-09-27 16:20:03 -0400375 {
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400376 LM = 1;
Gregory Maxwell23e654f2008-09-27 16:20:03 -0400377 } else
378 {
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400379 LM = 0;
Jean-Marc Valin16ca18b2008-06-18 23:44:48 +1000380 }
Gregory Maxwell23e654f2008-09-27 16:20:03 -0400381
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400382 mode->maxLM = LM;
383 mode->nbShortMdcts = 1<<LM;
Jean-Marc Valin60ff9992010-06-27 13:49:38 -0400384 mode->shortMdctSize = frame_size/mode->nbShortMdcts;
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400385 res = (mode->Fs+mode->shortMdctSize)/(2*mode->shortMdctSize);
386
387 mode->eBands = compute_ebands(Fs, mode->shortMdctSize, res, &mode->nbEBands);
Jean-Marc Valinfbfddf72009-07-19 21:07:12 -0400388 if (mode->eBands==NULL)
389 goto failure;
Jean-Marc Valinfbfddf72009-07-19 21:07:12 -0400390
Jean-Marc Valin85f41b22010-07-16 18:12:45 -0400391 mode->effEBands = mode->nbEBands;
392 while (mode->eBands[mode->effEBands] > mode->shortMdctSize)
393 mode->effEBands--;
Jean-Marc Valine949b722010-05-07 07:48:07 -0400394 mode->pitchEnd = 4000*(celt_int32)mode->shortMdctSize/Fs;
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 Valin16ca18b2008-06-18 23:44:48 +1000397 if (mode->nbShortMdcts > 1)
Jean-Marc Valince4dd362010-05-07 07:45:18 -0400398 mode->overlap = (mode->shortMdctSize>>2)<<2;
Jean-Marc Valin16ca18b2008-06-18 23:44:48 +1000399 else
Gregory Maxwell23e654f2008-09-27 16:20:03 -0400400 mode->overlap = (frame_size>>3)<<2;
401
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400402
403 compute_allocation_table(mode, res);
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400404 if (mode->allocVectors==NULL)
405 goto failure;
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100406
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400407 window = (celt_word16*)celt_alloc(mode->overlap*sizeof(celt_word16));
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400408 if (window==NULL)
409 goto failure;
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100410
Jean-Marc Valinf28062f2008-03-03 13:24:01 +1100411#ifndef FIXED_POINT
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100412 for (i=0;i<mode->overlap;i++)
Jean-Marc Valin3dbc1d02008-03-08 15:21:24 +1100413 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 +1100414#else
415 for (i=0;i<mode->overlap;i++)
Jean-Marc Valin8974f002010-03-20 00:41:39 -0400416 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 +1100417#endif
Jean-Marc Valin3dbc1d02008-03-08 15:21:24 +1100418 mode->window = window;
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100419
Jean-Marc Valincae30df2010-05-21 00:26:03 -0400420 mode->bits = mode->_bits+1;
Jean-Marc Valin073d0bc2010-05-05 21:37:53 -0400421 for (i=0;(1<<i)<=mode->nbShortMdcts;i++)
Jean-Marc Valincae30df2010-05-21 00:26:03 -0400422 {
423 mode->bits[i] = (const celt_int16 **)compute_alloc_cache(mode, 1<<i);
424 if (mode->bits[i]==NULL)
425 goto failure;
426 }
427 mode->bits[-1] = (const celt_int16 **)compute_alloc_cache(mode, 0);
428 if (mode->bits[-1]==NULL)
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400429 goto failure;
Jean-Marc Valinb76ee702008-03-10 15:42:35 +1100430
Jean-Marc Valinf400a3c2010-04-05 23:58:44 -0400431 logN = (celt_int16*)celt_alloc(mode->nbEBands*sizeof(celt_int16));
432 if (logN==NULL)
433 goto failure;
434
435 for (i=0;i<mode->nbEBands;i++)
Jean-Marc Valinaead79b2010-05-11 07:34:24 -0400436 logN[i] = log2_frac(mode->eBands[i+1]-mode->eBands[i], BITRES);
Jean-Marc Valinf400a3c2010-04-05 23:58:44 -0400437 mode->logN = logN;
Jean-Marc Valinb76ee702008-03-10 15:42:35 +1100438#endif /* !STATIC_MODES */
Jean-Marc Valin640f7fd2009-06-21 09:47:51 -0400439
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400440 clt_mdct_init(&mode->mdct, 2*mode->shortMdctSize*mode->nbShortMdcts, LM);
441 if ((mode->mdct.trig==NULL)
Jean-Marc Valin9714f662009-08-12 20:29:57 -0400442#ifndef ENABLE_TI_DSPLIB55
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400443 || (mode->mdct.kfft==NULL)
Jean-Marc Valin9714f662009-08-12 20:29:57 -0400444#endif
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400445 )
446 goto failure;
447
Jean-Marc Valin073d0bc2010-05-05 21:37:53 -0400448 mode->prob = quant_prob_alloc(mode);
449 if (mode->prob==NULL)
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400450 goto failure;
Jean-Marc Valinbf2d6482008-05-23 16:57:34 +1000451
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400452 mode->marker_start = MODEVALID;
453 mode->marker_end = MODEVALID;
Jean-Marc Valin680a9ec2008-03-10 14:52:18 +1100454 if (error)
455 *error = CELT_OK;
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100456 return mode;
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400457failure:
458 if (error)
459 *error = CELT_INVALID_MODE;
460 if (mode!=NULL)
461 celt_mode_destroy(mode);
462 return NULL;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100463}
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100464
Peter Kirk19f9dc92008-06-06 14:38:38 +0200465void celt_mode_destroy(CELTMode *mode)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100466{
Jean-Marc Valin073d0bc2010-05-05 21:37:53 -0400467 int i, m;
Jean-Marc Valin30f7f812009-10-17 14:35:13 -0400468 const celt_int16 *prevPtr = NULL;
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400469 if (mode == NULL)
470 {
471 celt_warning("NULL passed to celt_mode_destroy");
472 return;
473 }
474
475 if (mode->marker_start == MODEFREED || mode->marker_end == MODEFREED)
476 {
477 celt_warning("Freeing a mode which has already been freed");
478 return;
479 }
480
481 if (mode->marker_start != MODEVALID && mode->marker_start != MODEPARTIAL)
482 {
483 celt_warning("This is not a valid CELT mode structure");
484 return;
485 }
486 mode->marker_start = MODEFREED;
Jean-Marc Valin5588d522008-03-10 15:07:58 +1100487#ifndef STATIC_MODES
Jean-Marc Valin073d0bc2010-05-05 21:37:53 -0400488 for (m=0;(1<<m)<=mode->nbShortMdcts;m++)
Jean-Marc Valin25358cd2008-02-19 12:21:32 +1100489 {
Jean-Marc Valin073d0bc2010-05-05 21:37:53 -0400490 if (mode->bits[m]!=NULL)
Jean-Marc Valin25358cd2008-02-19 12:21:32 +1100491 {
Jean-Marc Valin073d0bc2010-05-05 21:37:53 -0400492 for (i=0;i<mode->nbEBands;i++)
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400493 {
Jean-Marc Valin073d0bc2010-05-05 21:37:53 -0400494 if (mode->bits[m][i] != prevPtr)
495 {
496 prevPtr = mode->bits[m][i];
497 celt_free((int*)mode->bits[m][i]);
498 }
499 }
Jean-Marc Valin25358cd2008-02-19 12:21:32 +1100500 }
Jean-Marc Valin073d0bc2010-05-05 21:37:53 -0400501 celt_free((celt_int16**)mode->bits[m]);
502 }
Jean-Marc Valincae30df2010-05-21 00:26:03 -0400503 if (mode->bits[-1]!=NULL)
504 {
505 for (i=0;i<mode->nbEBands;i++)
506 {
507 if (mode->bits[-1][i] != prevPtr)
508 {
509 prevPtr = mode->bits[-1][i];
510 celt_free((int*)mode->bits[-1][i]);
511 }
512 }
513 }
514 celt_free((celt_int16**)mode->bits[-1]);
515
Jean-Marc Valin31bec962010-04-07 18:30:28 -0400516 celt_free((celt_int16*)mode->eBands);
517 celt_free((celt_int16*)mode->allocVectors);
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400518
Jean-Marc Valin234969c2009-10-17 22:12:42 -0400519 celt_free((celt_word16*)mode->window);
Jean-Marc Valin31bec962010-04-07 18:30:28 -0400520 celt_free((celt_int16*)mode->logN);
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100521
Jean-Marc Valin70720a32008-04-19 21:39:26 +1000522#endif
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400523 clt_mdct_clear(&mode->mdct);
Jean-Marc Valin073d0bc2010-05-05 21:37:53 -0400524
Jean-Marc Valin4ce92052008-04-23 13:42:10 +1000525 quant_prob_free(mode->prob);
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400526 mode->marker_end = MODEFREED;
Jean-Marc Valin949902f2008-03-11 10:43:06 +1100527 celt_free((CELTMode *)mode);
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100528}
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +1100529
530int check_mode(const CELTMode *mode)
531{
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400532 if (mode==NULL)
533 return CELT_INVALID_MODE;
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +1100534 if (mode->marker_start == MODEVALID && mode->marker_end == MODEVALID)
535 return CELT_OK;
536 if (mode->marker_start == MODEFREED || mode->marker_end == MODEFREED)
537 celt_warning("Using a mode that has already been freed");
538 else
539 celt_warning("This is not a valid CELT mode");
540 return CELT_INVALID_MODE;
541}