blob: 292990fc102580c5bd99eae1223152c5607664d2 [file] [log] [blame]
Jean-Marc Valin8b2a5922008-02-29 00:32:51 +11001/* (C) 2007-2008 Jean-Marc Valin, CSIRO
Jean-Marc Valinecb36a32007-12-05 01:31:49 +11002*/
3/*
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 - Neither the name of the Xiph.org Foundation nor the names of its
16 contributors may be used to endorse or promote products derived from
17 this software without specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
23 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30*/
31
Jean-Marc Valin02fa9132008-02-20 12:09:29 +110032#ifdef HAVE_CONFIG_H
33#include "config.h"
34#endif
35
Jean-Marc Valin65d57e62008-02-18 15:49:37 +110036#include "celt.h"
Jean-Marc Valinecb36a32007-12-05 01:31:49 +110037#include "modes.h"
Jean-Marc Valin472a5f02008-02-19 13:12:32 +110038#include "rate.h"
Jean-Marc Valin81a82952008-02-17 22:41:29 +110039#include "os_support.h"
Jean-Marc Valinf7cec832008-04-18 17:29:56 +100040#include "stack_alloc.h"
Jean-Marc Valin4ce92052008-04-23 13:42:10 +100041#include "quant_bands.h"
Jean-Marc Valinecb36a32007-12-05 01:31:49 +110042
Jean-Marc Valinf39e8692008-03-10 12:13:23 +110043#ifdef STATIC_MODES
Jean-Marc Valinb18ec0b2008-04-11 04:07:52 +100044#include "static_modes.c"
Jean-Marc Valinf39e8692008-03-10 12:13:23 +110045#endif
46
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +110047#define MODEVALID 0xa110ca7e
48#define MODEFREED 0xb10cf8ee
49
Jean-Marc Valind748cd52008-03-01 07:27:03 +110050#ifndef M_PI
51#define M_PI 3.141592653
52#endif
53
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +110054
Peter Kirk19f9dc92008-06-06 14:38:38 +020055int celt_mode_info(const CELTMode *mode, int request, celt_int32_t *value)
Jean-Marc Valinf997ad52008-01-31 16:47:16 +110056{
57 switch (request)
58 {
59 case CELT_GET_FRAME_SIZE:
60 *value = mode->mdctSize;
61 break;
62 case CELT_GET_LOOKAHEAD:
63 *value = mode->overlap;
64 break;
Jean-Marc Valin4c6bc882008-01-31 17:34:27 +110065 case CELT_GET_NB_CHANNELS:
66 *value = mode->nbChannels;
67 break;
Jean-Marc Valin59093c02008-05-15 21:53:27 +100068 case CELT_GET_BITSTREAM_VERSION:
69 *value = CELT_BITSTREAM_VERSION;
70 break;
Jean-Marc Valincb7a2a32008-02-11 16:44:48 +110071 default:
Jean-Marc Valinb6f90612008-10-05 22:39:13 -040072 return CELT_UNIMPLEMENTED;
Jean-Marc Valinf997ad52008-01-31 16:47:16 +110073 }
Jean-Marc Valincb7a2a32008-02-11 16:44:48 +110074 return CELT_OK;
Jean-Marc Valinf997ad52008-01-31 16:47:16 +110075}
76
Jean-Marc Valin5588d522008-03-10 15:07:58 +110077#ifndef STATIC_MODES
78
Jean-Marc Valin134492a2008-02-18 16:46:22 +110079#define PBANDS 8
Jean-Marc Valin47c248a2008-04-26 08:16:12 +100080
81#ifdef STDIN_TUNING
82int MIN_BINS;
83#else
Jean-Marc Valin52824c72008-05-06 18:01:17 +100084#define MIN_BINS 3
Jean-Marc Valin47c248a2008-04-26 08:16:12 +100085#endif
86
Jean-Marc Valin17683eb2008-02-18 21:45:19 +110087/* Defining 25 critical bands for the full 0-20 kHz audio bandwidth
88 Taken from http://ccrma.stanford.edu/~jos/bbt/Bark_Frequency_Scale.html */
Jean-Marc Valin81a82952008-02-17 22:41:29 +110089#define BARK_BANDS 25
Jean-Marc Valin25358cd2008-02-19 12:21:32 +110090static const celt_int16_t bark_freq[BARK_BANDS+1] = {
Jean-Marc Valin17683eb2008-02-18 21:45:19 +110091 0, 100, 200, 300, 400,
92 510, 630, 770, 920, 1080,
93 1270, 1480, 1720, 2000, 2320,
94 2700, 3150, 3700, 4400, 5300,
95 6400, 7700, 9500, 12000, 15500,
96 20000};
97
Jean-Marc Valin25358cd2008-02-19 12:21:32 +110098static const celt_int16_t pitch_freq[PBANDS+1] ={0, 345, 689, 1034, 1378, 2067, 3273, 5340, 6374};
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +110099
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100100/* This allocation table is per critical band. When creating a mode, the bits get added together
101 into the codec bands, which are sometimes larger than one critical band at low frequency */
Jean-Marc Valin47c248a2008-04-26 08:16:12 +1000102
103#ifdef STDIN_TUNING
104int BITALLOC_SIZE;
105int *band_allocation;
106#else
Jean-Marc Valin9c709062008-08-03 22:07:06 -0400107#define BITALLOC_SIZE 12
Jean-Marc Valin25358cd2008-02-19 12:21:32 +1100108static const int band_allocation[BARK_BANDS*BITALLOC_SIZE] =
Jean-Marc Valin9c709062008-08-03 22:07:06 -0400109 { 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,
110 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,
Jean-Marc Valin52824c72008-05-06 18:01:17 +1000111 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 4, 5, 7, 7, 7, 5, 4, 0, 0, 0, 0, 0, 0,
112 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 3, 3, 5, 6, 8, 8, 8, 6, 5, 4, 0, 0, 0, 0, 0,
113 3, 2, 2, 2, 3, 3, 2, 3, 2, 3, 4, 4, 6, 7, 9, 9, 9, 7, 6, 5, 5, 5, 0, 0, 0,
114 3, 3, 2, 2, 3, 3, 3, 3, 3, 4, 4, 5, 7, 9, 10, 10, 10, 9, 6, 5, 5, 5, 5, 1, 0,
Jean-Marc Valin6855bf62008-05-07 16:44:29 +1000115 4, 3, 3, 3, 3, 3, 3, 3, 4, 4, 6, 7, 7, 9, 11, 10, 10, 9, 9, 8, 11, 10, 10, 1, 1,
Jean-Marc Valinf61be662008-09-22 10:46:55 -0400116 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 8, 8, 10, 12, 12, 11, 11, 17, 12, 15, 15, 20, 18, 10, 1,
117 8, 7, 7, 7, 7, 7, 8, 8, 9, 10, 11, 12, 14, 17, 18, 21, 22, 27, 29, 39, 37, 38, 40, 35, 1,
Jean-Marc Valin6855bf62008-05-07 16:44:29 +1000118 7, 7, 7, 7, 7, 7, 10, 10, 10, 13, 14, 18, 20, 24, 28, 32, 32, 35, 38, 38, 42, 50, 59, 54, 31,
119 8, 8, 8, 8, 8, 9, 10, 12, 14, 20, 22, 25, 28, 30, 35, 42, 46, 50, 55, 60, 62, 62, 62, 62, 62,
Jean-Marc Valin9eba8232008-08-02 20:51:44 -0400120 12, 12, 12, 12, 12, 13, 15, 18, 22, 30, 32, 35, 40, 45, 55, 62, 66, 70, 85, 90, 92, 92, 92, 92, 92,
121 };
Jean-Marc Valin47c248a2008-04-26 08:16:12 +1000122#endif
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100123
Jean-Marc Valindb0141e2008-03-10 16:37:37 +1100124static celt_int16_t *compute_ebands(celt_int32_t Fs, int frame_size, int *nbEBands)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100125{
Jean-Marc Valindb0141e2008-03-10 16:37:37 +1100126 celt_int16_t *eBands;
Gregory Maxwellcbaf67e2008-09-28 04:19:19 -0400127 int i, res, min_width, lin, low, high, nBark;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100128 res = (Fs+frame_size)/(2*frame_size);
129 min_width = MIN_BINS*res;
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100130 /*printf ("min_width = %d\n", min_width);*/
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100131
Gregory Maxwellcbaf67e2008-09-28 04:19:19 -0400132 /* Find the number of critical bands supported by our sampling rate */
133 for (nBark=1;nBark<BARK_BANDS;nBark++)
134 if (bark_freq[nBark+1]*2 >= Fs)
135 break;
136
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100137 /* Find where the linear part ends (i.e. where the spacing is more than min_width */
Gregory Maxwellcbaf67e2008-09-28 04:19:19 -0400138 for (lin=0;lin<nBark;lin++)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100139 if (bark_freq[lin+1]-bark_freq[lin] >= min_width)
140 break;
141
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100142 /*printf ("lin = %d (%d Hz)\n", lin, bark_freq[lin]);*/
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100143 low = ((bark_freq[lin]/res)+(MIN_BINS-1))/MIN_BINS;
Gregory Maxwellcbaf67e2008-09-28 04:19:19 -0400144 high = nBark-lin;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100145 *nbEBands = low+high;
Jean-Marc Valindb0141e2008-03-10 16:37:37 +1100146 eBands = celt_alloc(sizeof(celt_int16_t)*(*nbEBands+2));
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100147
148 /* Linear spacing (min_width) */
149 for (i=0;i<low;i++)
150 eBands[i] = MIN_BINS*i;
151 /* Spacing follows critical bands */
152 for (i=0;i<high;i++)
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100153 eBands[i+low] = (bark_freq[lin+i]+res/2)/res;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100154 /* Enforce the minimum spacing at the boundary */
155 for (i=0;i<*nbEBands;i++)
156 if (eBands[i] < MIN_BINS*i)
157 eBands[i] = MIN_BINS*i;
Gregory Maxwellcbaf67e2008-09-28 04:19:19 -0400158 eBands[*nbEBands] = (bark_freq[nBark]+res/2)/res;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100159 eBands[*nbEBands+1] = frame_size;
160 if (eBands[*nbEBands] > eBands[*nbEBands+1])
161 eBands[*nbEBands] = eBands[*nbEBands+1];
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100162
163 /* FIXME: Remove last band if too small */
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100164 /*for (i=0;i<*nbEBands+2;i++)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100165 printf("%d ", eBands[i]);
Jean-Marc Valinf61be662008-09-22 10:46:55 -0400166 printf ("\n");
167 exit(1);*/
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100168 return eBands;
169}
170
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100171static void compute_pbands(CELTMode *mode, int res)
172{
173 int i;
Jean-Marc Valindb0141e2008-03-10 16:37:37 +1100174 celt_int16_t *pBands;
175 pBands=celt_alloc(sizeof(celt_int16_t)*(PBANDS+2));
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100176 mode->nbPBands = PBANDS;
177 for (i=0;i<PBANDS+1;i++)
178 {
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100179 pBands[i] = (pitch_freq[i]+res/2)/res;
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100180 if (pBands[i] < mode->eBands[i])
181 pBands[i] = mode->eBands[i];
182 }
183 pBands[PBANDS+1] = mode->eBands[mode->nbEBands+1];
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100184 for (i=1;i<mode->nbPBands+1;i++)
185 {
186 int j;
187 for (j=0;j<mode->nbEBands;j++)
188 if (mode->eBands[j] <= pBands[i] && mode->eBands[j+1] > pBands[i])
189 break;
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100190 /*printf ("%d %d\n", i, j);*/
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100191 if (mode->eBands[j] != pBands[i])
192 {
193 if (pBands[i]-mode->eBands[j] < mode->eBands[j+1]-pBands[i] &&
194 mode->eBands[j] != pBands[i-1])
195 pBands[i] = mode->eBands[j];
196 else
197 pBands[i] = mode->eBands[j+1];
198 }
199 }
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100200 /*for (i=0;i<mode->nbPBands+2;i++)
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100201 printf("%d ", pBands[i]);
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100202 printf ("\n");*/
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100203 mode->pBands = pBands;
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100204 mode->pitchEnd = pBands[PBANDS];
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100205}
206
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100207static void compute_allocation_table(CELTMode *mode, int res)
208{
Gregory Maxwellcbaf67e2008-09-28 04:19:19 -0400209 int i, j, eband, nBark;
Jean-Marc Valin36e6e012008-08-02 22:25:19 -0400210 celt_int16_t *allocVectors, *allocEnergy;
211 const int C = CHANNELS(mode);
212
Gregory Maxwellcbaf67e2008-09-28 04:19:19 -0400213 /* Find the number of critical bands supported by our sampling rate */
214 for (nBark=1;nBark<BARK_BANDS;nBark++)
215 if (bark_freq[nBark+1]*2 >= mode->Fs)
216 break;
217
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100218 mode->nbAllocVectors = BITALLOC_SIZE;
Jean-Marc Valindb0141e2008-03-10 16:37:37 +1100219 allocVectors = celt_alloc(sizeof(celt_int16_t)*(BITALLOC_SIZE*mode->nbEBands));
Jean-Marc Valin36e6e012008-08-02 22:25:19 -0400220 allocEnergy = celt_alloc(sizeof(celt_int16_t)*(mode->nbAllocVectors*(mode->nbEBands+1)));
221 /* Compute per-codec-band allocation from per-critical-band matrix */
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100222 for (i=0;i<BITALLOC_SIZE;i++)
223 {
224 eband = 0;
Gregory Maxwellcbaf67e2008-09-28 04:19:19 -0400225 for (j=0;j<nBark;j++)
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100226 {
Jean-Marc Valin5c0d4862008-07-24 08:49:34 -0400227 int edge, low;
228 celt_int32_t alloc;
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100229 edge = mode->eBands[eband+1]*res;
Jean-Marc Valin13294b52008-05-30 16:07:06 +1000230 alloc = band_allocation[i*BARK_BANDS+j];
Jean-Marc Valin36e6e012008-08-02 22:25:19 -0400231 alloc = alloc*C*mode->mdctSize/256;
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100232 if (edge < bark_freq[j+1])
233 {
234 int num, den;
Jean-Marc Valin13294b52008-05-30 16:07:06 +1000235 num = alloc * (edge-bark_freq[j]);
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100236 den = bark_freq[j+1]-bark_freq[j];
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100237 low = (num+den/2)/den;
238 allocVectors[i*mode->nbEBands+eband] += low;
239 eband++;
Jean-Marc Valin13294b52008-05-30 16:07:06 +1000240 allocVectors[i*mode->nbEBands+eband] += alloc-low;
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100241 } else {
Jean-Marc Valin13294b52008-05-30 16:07:06 +1000242 allocVectors[i*mode->nbEBands+eband] += alloc;
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100243 }
244 }
245 }
Jean-Marc Valin36e6e012008-08-02 22:25:19 -0400246 /* Compute fine energy resolution and update the pulse allocation table to subtract that */
Jean-Marc Valinad637192008-05-07 13:44:39 +1000247 for (i=0;i<mode->nbAllocVectors;i++)
248 {
249 int sum = 0;
Jean-Marc Valinad637192008-05-07 13:44:39 +1000250 for (j=0;j<mode->nbEBands;j++)
251 {
Jean-Marc Valin9c709062008-08-03 22:07:06 -0400252 int ebits;
253 int min_bits=0;
Jean-Marc Valin504f8c22008-08-05 20:39:53 -0400254 if (allocVectors[i*mode->nbEBands+j] > 0)
Jean-Marc Valin9c709062008-08-03 22:07:06 -0400255 min_bits = 1;
Jean-Marc Valinc24b5182008-09-19 16:49:26 -0400256 ebits = IMAX(min_bits , allocVectors[i*mode->nbEBands+j] / (C*(mode->eBands[j+1]-mode->eBands[j])));
Jean-Marc Valin504f8c22008-08-05 20:39:53 -0400257 if (ebits>7)
258 ebits=7;
Jean-Marc Valin36e6e012008-08-02 22:25:19 -0400259 /* The bits used for fine allocation can't be used for pulses */
Jean-Marc Valin9c709062008-08-03 22:07:06 -0400260 /* However, we give two "free" bits to all modes to compensate for the fact that some energy
261 resolution is needed regardless of the frame size. */
262 if (ebits>1)
263 allocVectors[i*mode->nbEBands+j] -= C*(ebits-2);
Jean-Marc Valin504f8c22008-08-05 20:39:53 -0400264 if (allocVectors[i*mode->nbEBands+j] < 0)
265 allocVectors[i*mode->nbEBands+j] = 0;
Jean-Marc Valin9c709062008-08-03 22:07:06 -0400266 sum += ebits;
267 allocEnergy[i*(mode->nbEBands+1)+j] = ebits;
Jean-Marc Valinad637192008-05-07 13:44:39 +1000268 }
Jean-Marc Valin36e6e012008-08-02 22:25:19 -0400269 allocEnergy[i*(mode->nbEBands+1)+mode->nbEBands] = sum;
Jean-Marc Valinad637192008-05-07 13:44:39 +1000270 }
Jean-Marc Valin36e6e012008-08-02 22:25:19 -0400271 mode->energy_alloc = allocEnergy;
272 mode->allocVectors = allocVectors;
Jean-Marc Valinad637192008-05-07 13:44:39 +1000273}
274
Jean-Marc Valin36e6e012008-08-02 22:25:19 -0400275#endif /* STATIC_MODES */
276
Jean-Marc Valin16ca18b2008-06-18 23:44:48 +1000277CELTMode *celt_mode_create(celt_int32_t Fs, int channels, int frame_size, int *error)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100278{
Jean-Marc Valin47c248a2008-04-26 08:16:12 +1000279 int i;
280#ifdef STDIN_TUNING
281 scanf("%d ", &MIN_BINS);
282 scanf("%d ", &BITALLOC_SIZE);
283 band_allocation = celt_alloc(sizeof(int)*BARK_BANDS*BITALLOC_SIZE);
284 for (i=0;i<BARK_BANDS*BITALLOC_SIZE;i++)
285 {
286 scanf("%d ", band_allocation+i);
287 }
288#endif
Jean-Marc Valinf39e8692008-03-10 12:13:23 +1100289#ifdef STATIC_MODES
Jean-Marc Valin949902f2008-03-11 10:43:06 +1100290 const CELTMode *m = NULL;
291 CELTMode *mode=NULL;
Jean-Marc Valinf7cec832008-04-18 17:29:56 +1000292 ALLOC_STACK;
Jean-Marc Valin680a9ec2008-03-10 14:52:18 +1100293 for (i=0;i<TOTAL_MODES;i++)
294 {
295 if (Fs == static_mode_list[i]->Fs &&
296 channels == static_mode_list[i]->nbChannels &&
Jean-Marc Valin60d08372008-10-03 07:30:08 -0400297 frame_size == static_mode_list[i]->mdctSize)
Jean-Marc Valin680a9ec2008-03-10 14:52:18 +1100298 {
Jean-Marc Valin949902f2008-03-11 10:43:06 +1100299 m = static_mode_list[i];
Jean-Marc Valin680a9ec2008-03-10 14:52:18 +1100300 break;
301 }
302 }
Jean-Marc Valin949902f2008-03-11 10:43:06 +1100303 if (m == NULL)
Jean-Marc Valin680a9ec2008-03-10 14:52:18 +1100304 {
305 celt_warning("Mode not included as part of the static modes");
306 if (error)
307 *error = CELT_BAD_ARG;
308 return NULL;
309 }
Jean-Marc Valin949902f2008-03-11 10:43:06 +1100310 mode = (CELTMode*)celt_alloc(sizeof(CELTMode));
311 CELT_COPY(mode, m, 1);
Jean-Marc Valinf39e8692008-03-10 12:13:23 +1100312#else
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100313 int res;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100314 CELTMode *mode;
Jean-Marc Valin3dbc1d02008-03-08 15:21:24 +1100315 celt_word16_t *window;
Jean-Marc Valinf7cec832008-04-18 17:29:56 +1000316 ALLOC_STACK;
Jean-Marc Valin3dbc1d02008-03-08 15:21:24 +1100317
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100318 /* The good thing here is that permutation of the arguments will automatically be invalid */
319
320 if (Fs < 32000 || Fs > 64000)
321 {
322 celt_warning("Sampling rate must be between 32 kHz and 64 kHz");
323 if (error)
324 *error = CELT_BAD_ARG;
325 return NULL;
326 }
327 if (channels < 0 || channels > 2)
328 {
329 celt_warning("Only mono and stereo supported");
330 if (error)
331 *error = CELT_BAD_ARG;
332 return NULL;
333 }
Jean-Marc Valin96748cf2008-06-06 17:04:07 +1000334 if (frame_size < 64 || frame_size > 512 || frame_size%2!=0)
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100335 {
Gregory Maxwellcbaf67e2008-09-28 04:19:19 -0400336 celt_warning("Only even frame sizes from 64 to 512 are supported");
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100337 if (error)
338 *error = CELT_BAD_ARG;
339 return NULL;
340 }
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100341 res = (Fs+frame_size)/(2*frame_size);
342
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100343 mode = celt_alloc(sizeof(CELTMode));
Jean-Marc Valine6b74652008-02-20 18:01:08 +1100344 mode->Fs = Fs;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100345 mode->mdctSize = frame_size;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100346 mode->nbChannels = channels;
347 mode->eBands = compute_ebands(Fs, frame_size, &mode->nbEBands);
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100348 compute_pbands(mode, res);
Jean-Marc Valin8b2a5922008-02-29 00:32:51 +1100349 mode->ePredCoef = QCONST16(.8f,15);
Gregory Maxwell23e654f2008-09-27 16:20:03 -0400350
351 if (frame_size > 384 && (frame_size%8)==0)
Jean-Marc Valin16ca18b2008-06-18 23:44:48 +1000352 {
Gregory Maxwell23e654f2008-09-27 16:20:03 -0400353 mode->nbShortMdcts = 4;
354 } else if (frame_size > 384 && (frame_size%10)==0)
Jean-Marc Valin16ca18b2008-06-18 23:44:48 +1000355 {
Gregory Maxwell23e654f2008-09-27 16:20:03 -0400356 mode->nbShortMdcts = 5;
357 } else if (frame_size > 256 && (frame_size%6)==0)
Jean-Marc Valin16ca18b2008-06-18 23:44:48 +1000358 {
Gregory Maxwell23e654f2008-09-27 16:20:03 -0400359 mode->nbShortMdcts = 3;
360 } else if (frame_size > 256 && (frame_size%8)==0)
361 {
362 mode->nbShortMdcts = 4;
363 } else if (frame_size > 64 && (frame_size%4)==0)
364 {
365 mode->nbShortMdcts = 2;
366 } else if (frame_size > 128 && (frame_size%6)==0)
367 {
368 mode->nbShortMdcts = 3;
369 } else
370 {
371 mode->nbShortMdcts = 1;
Jean-Marc Valin16ca18b2008-06-18 23:44:48 +1000372 }
Gregory Maxwell23e654f2008-09-27 16:20:03 -0400373
Jean-Marc Valin16ca18b2008-06-18 23:44:48 +1000374 if (mode->nbShortMdcts > 1)
Gregory Maxwell23e654f2008-09-27 16:20:03 -0400375 mode->overlap = ((frame_size/mode->nbShortMdcts)>>2)<<2; /* Overlap must be divisible by 4 */
Jean-Marc Valin16ca18b2008-06-18 23:44:48 +1000376 else
Gregory Maxwell23e654f2008-09-27 16:20:03 -0400377 mode->overlap = (frame_size>>3)<<2;
378
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100379 compute_allocation_table(mode, res);
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100380 /*printf ("%d bands\n", mode->nbEBands);*/
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100381
Jean-Marc Valin3dbc1d02008-03-08 15:21:24 +1100382 window = (celt_word16_t*)celt_alloc(mode->overlap*sizeof(celt_word16_t));
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100383
Jean-Marc Valinf28062f2008-03-03 13:24:01 +1100384#ifndef FIXED_POINT
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100385 for (i=0;i<mode->overlap;i++)
Jean-Marc Valin3dbc1d02008-03-08 15:21:24 +1100386 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 +1100387#else
388 for (i=0;i<mode->overlap;i++)
Jean-Marc Valin3dbc1d02008-03-08 15:21:24 +1100389 window[i] = MIN32(32767,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 +1100390#endif
Jean-Marc Valin3dbc1d02008-03-08 15:21:24 +1100391 mode->window = window;
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100392
Jean-Marc Valinbf2d6482008-05-23 16:57:34 +1000393 mode->bits = (const celt_int16_t **)compute_alloc_cache(mode, 1);
Jean-Marc Valinb0bef852008-10-02 23:52:46 -0400394 if (mode->nbChannels>=2)
395 mode->bits_stereo = (const celt_int16_t **)compute_alloc_cache(mode, mode->nbChannels);
Jean-Marc Valinb76ee702008-03-10 15:42:35 +1100396
Jean-Marc Valin70720a32008-04-19 21:39:26 +1000397#ifndef SHORTCUTS
Jean-Marc Valin5588d522008-03-10 15:07:58 +1100398 psydecay_init(&mode->psy, MAX_PERIOD/2, mode->Fs);
Jean-Marc Valin70720a32008-04-19 21:39:26 +1000399#endif
400
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +1100401 mode->marker_start = MODEVALID;
402 mode->marker_end = MODEVALID;
Jean-Marc Valinb76ee702008-03-10 15:42:35 +1100403#endif /* !STATIC_MODES */
Jean-Marc Valinf39e8692008-03-10 12:13:23 +1100404 mdct_init(&mode->mdct, 2*mode->mdctSize);
Jean-Marc Valin24c9cda2008-05-02 10:34:07 +1000405 mode->fft = pitch_state_alloc(MAX_PERIOD);
406
Jean-Marc Valin9d1decd2008-06-17 13:28:13 +1000407 mode->shortMdctSize = mode->mdctSize/mode->nbShortMdcts;
408 mdct_init(&mode->shortMdct, 2*mode->shortMdctSize);
409 mode->shortWindow = mode->window;
410
Jean-Marc Valin4ce92052008-04-23 13:42:10 +1000411 mode->prob = quant_prob_alloc(mode);
Jean-Marc Valinbf2d6482008-05-23 16:57:34 +1000412
Jean-Marc Valin680a9ec2008-03-10 14:52:18 +1100413 if (error)
414 *error = CELT_OK;
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100415 return mode;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100416}
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100417
Peter Kirk19f9dc92008-06-06 14:38:38 +0200418void celt_mode_destroy(CELTMode *mode)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100419{
Jean-Marc Valin5588d522008-03-10 15:07:58 +1100420#ifndef STATIC_MODES
Jean-Marc Valin25358cd2008-02-19 12:21:32 +1100421 int i;
Jean-Marc Valindb0141e2008-03-10 16:37:37 +1100422 const celt_int16_t *prevPtr = NULL;
Jean-Marc Valin25358cd2008-02-19 12:21:32 +1100423 for (i=0;i<mode->nbEBands;i++)
424 {
425 if (mode->bits[i] != prevPtr)
426 {
427 prevPtr = mode->bits[i];
428 celt_free((int*)mode->bits[i]);
429 }
430 }
431 celt_free((int**)mode->bits);
Gregory Maxwellb6a3b0c2008-10-03 17:12:44 -0400432 if (mode->bits_stereo != NULL)
433 {
434 for (i=0;i<mode->nbEBands;i++)
435 {
436 if (mode->bits_stereo[i] != prevPtr)
437 {
438 prevPtr = mode->bits_stereo[i];
439 celt_free((int*)mode->bits_stereo[i]);
440 }
441 }
442 celt_free((int**)mode->bits_stereo);
443 }
Jean-Marc Valinf39e8692008-03-10 12:13:23 +1100444 if (check_mode(mode) != CELT_OK)
445 return;
446 celt_free((int*)mode->eBands);
447 celt_free((int*)mode->pBands);
448 celt_free((int*)mode->allocVectors);
Jean-Marc Valin25ec9ac2008-10-04 22:37:11 -0400449 celt_free((celt_int16_t *)mode->energy_alloc);
450
Jean-Marc Valin3dbc1d02008-03-08 15:21:24 +1100451 celt_free((celt_word16_t*)mode->window);
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100452
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +1100453 mode->marker_start = MODEFREED;
454 mode->marker_end = MODEFREED;
Jean-Marc Valin70720a32008-04-19 21:39:26 +1000455#ifndef SHORTCUTS
Jean-Marc Valin5588d522008-03-10 15:07:58 +1100456 psydecay_clear(&mode->psy);
Jean-Marc Valinf39e8692008-03-10 12:13:23 +1100457#endif
Jean-Marc Valin70720a32008-04-19 21:39:26 +1000458#endif
Jean-Marc Valin9656ca02008-04-11 17:23:01 +1000459 mdct_clear(&mode->mdct);
Jean-Marc Valinc9943942008-08-30 00:55:07 -0400460 mdct_clear(&mode->shortMdct);
Jean-Marc Valin24c9cda2008-05-02 10:34:07 +1000461 pitch_state_free(mode->fft);
Jean-Marc Valin4ce92052008-04-23 13:42:10 +1000462 quant_prob_free(mode->prob);
Jean-Marc Valin949902f2008-03-11 10:43:06 +1100463 celt_free((CELTMode *)mode);
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100464}
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +1100465
466int check_mode(const CELTMode *mode)
467{
468 if (mode->marker_start == MODEVALID && mode->marker_end == MODEVALID)
469 return CELT_OK;
470 if (mode->marker_start == MODEFREED || mode->marker_end == MODEFREED)
471 celt_warning("Using a mode that has already been freed");
472 else
473 celt_warning("This is not a valid CELT mode");
474 return CELT_INVALID_MODE;
475}