blob: 07ad8cf88bdf29f49fd889ad0f686f4a42a80edc [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 Valinecb36a32007-12-05 01:31:49 +110040
Jean-Marc Valinf39e8692008-03-10 12:13:23 +110041#ifdef STATIC_MODES
42#include "static_modes.h"
43#endif
44
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +110045#define MODEVALID 0xa110ca7e
46#define MODEFREED 0xb10cf8ee
47
Jean-Marc Valind748cd52008-03-01 07:27:03 +110048#ifndef M_PI
49#define M_PI 3.141592653
50#endif
51
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +110052
Jean-Marc Valinf997ad52008-01-31 16:47:16 +110053int celt_mode_info(const CELTMode *mode, int request, celt_int32_t *value)
54{
55 switch (request)
56 {
57 case CELT_GET_FRAME_SIZE:
58 *value = mode->mdctSize;
59 break;
60 case CELT_GET_LOOKAHEAD:
61 *value = mode->overlap;
62 break;
Jean-Marc Valin4c6bc882008-01-31 17:34:27 +110063 case CELT_GET_NB_CHANNELS:
64 *value = mode->nbChannels;
65 break;
Jean-Marc Valincb7a2a32008-02-11 16:44:48 +110066 default:
67 return CELT_BAD_ARG;
Jean-Marc Valinf997ad52008-01-31 16:47:16 +110068 }
Jean-Marc Valincb7a2a32008-02-11 16:44:48 +110069 return CELT_OK;
Jean-Marc Valinf997ad52008-01-31 16:47:16 +110070}
71
Jean-Marc Valin5588d522008-03-10 15:07:58 +110072#ifndef STATIC_MODES
73
Jean-Marc Valin134492a2008-02-18 16:46:22 +110074#define PBANDS 8
Jean-Marc Valin81a82952008-02-17 22:41:29 +110075#define MIN_BINS 4
Jean-Marc Valin17683eb2008-02-18 21:45:19 +110076/* Defining 25 critical bands for the full 0-20 kHz audio bandwidth
77 Taken from http://ccrma.stanford.edu/~jos/bbt/Bark_Frequency_Scale.html */
Jean-Marc Valin81a82952008-02-17 22:41:29 +110078#define BARK_BANDS 25
Jean-Marc Valin25358cd2008-02-19 12:21:32 +110079static const celt_int16_t bark_freq[BARK_BANDS+1] = {
Jean-Marc Valin17683eb2008-02-18 21:45:19 +110080 0, 100, 200, 300, 400,
81 510, 630, 770, 920, 1080,
82 1270, 1480, 1720, 2000, 2320,
83 2700, 3150, 3700, 4400, 5300,
84 6400, 7700, 9500, 12000, 15500,
85 20000};
86
Jean-Marc Valin25358cd2008-02-19 12:21:32 +110087static 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 +110088
Jean-Marc Valin75e9c862008-02-18 17:04:15 +110089/* This allocation table is per critical band. When creating a mode, the bits get added together
90 into the codec bands, which are sometimes larger than one critical band at low frequency */
Jean-Marc Valin9838fec2008-02-18 14:45:11 +110091#define BITALLOC_SIZE 10
Jean-Marc Valin25358cd2008-02-19 12:21:32 +110092static const int band_allocation[BARK_BANDS*BITALLOC_SIZE] =
Jean-Marc Valin9838fec2008-02-18 14:45:11 +110093 { 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 Valin5a4bbde2008-02-19 14:32:08 +110094 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 5, 5, 7, 7, 7, 5, 4, 0, 0, 0, 0, 0, 0,
95 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 3, 2, 6, 6, 8, 8, 8, 6, 5, 4, 0, 0, 0, 0, 0,
96 3, 2, 2, 2, 3, 3, 2, 3, 2, 2, 4, 3, 7, 7, 9, 9, 9, 7, 6, 5, 5, 5, 0, 0, 0,
97 3, 3, 2, 2, 3, 3, 3, 3, 3, 2, 4, 4, 9, 9, 10, 10, 10, 9, 6, 5, 5, 5, 5, 0, 0,
98 3, 3, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 10, 10, 12, 12, 12, 10, 10, 10, 11, 10, 10, 5, 5,
Jean-Marc Valin9838fec2008-02-18 14:45:11 +110099 4, 4, 4, 4, 5, 5, 5, 5, 5, 4, 7, 7, 14, 13, 13, 13, 13, 13, 15, 16, 17, 18, 20, 18, 11,
100 7, 7, 6, 6, 9, 8, 8, 8, 8, 8, 11, 11, 20, 18, 19, 19, 25, 22, 25, 30, 30, 35, 35, 35, 35,
101 8, 8, 8, 8, 10, 10, 10, 10, 9, 9, 19, 18, 25, 24, 23, 21, 29, 27, 35, 40, 42, 50, 59, 54, 51,
102 11, 11, 10, 10, 14, 13, 13, 13, 13, 12, 19, 18, 35, 34, 33, 31, 39, 37, 45, 50, 52, 60, 60, 60, 60,
103 };
104
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100105
Jean-Marc Valin5588d522008-03-10 15:07:58 +1100106static int *compute_ebands(celt_int32_t Fs, int frame_size, int *nbEBands)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100107{
108 int *eBands;
109 int i, res, min_width, lin, low, high;
110 res = (Fs+frame_size)/(2*frame_size);
111 min_width = MIN_BINS*res;
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100112 /*printf ("min_width = %d\n", min_width);*/
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100113
114 /* Find where the linear part ends (i.e. where the spacing is more than min_width */
115 for (lin=0;lin<BARK_BANDS;lin++)
116 if (bark_freq[lin+1]-bark_freq[lin] >= min_width)
117 break;
118
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100119 /*printf ("lin = %d (%d Hz)\n", lin, bark_freq[lin]);*/
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100120 low = ((bark_freq[lin]/res)+(MIN_BINS-1))/MIN_BINS;
121 high = BARK_BANDS-lin;
122 *nbEBands = low+high;
123 eBands = celt_alloc(sizeof(int)*(*nbEBands+2));
124
125 /* Linear spacing (min_width) */
126 for (i=0;i<low;i++)
127 eBands[i] = MIN_BINS*i;
128 /* Spacing follows critical bands */
129 for (i=0;i<high;i++)
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100130 eBands[i+low] = (bark_freq[lin+i]+res/2)/res;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100131 /* Enforce the minimum spacing at the boundary */
132 for (i=0;i<*nbEBands;i++)
133 if (eBands[i] < MIN_BINS*i)
134 eBands[i] = MIN_BINS*i;
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100135 eBands[*nbEBands] = (bark_freq[BARK_BANDS]+res/2)/res;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100136 eBands[*nbEBands+1] = frame_size;
137 if (eBands[*nbEBands] > eBands[*nbEBands+1])
138 eBands[*nbEBands] = eBands[*nbEBands+1];
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100139
140 /* FIXME: Remove last band if too small */
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100141 /*for (i=0;i<*nbEBands+2;i++)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100142 printf("%d ", eBands[i]);
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100143 printf ("\n");*/
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100144 return eBands;
145}
146
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100147static void compute_pbands(CELTMode *mode, int res)
148{
149 int i;
150 int *pBands;
151 pBands=celt_alloc(sizeof(int)*(PBANDS+2));
152 mode->nbPBands = PBANDS;
153 for (i=0;i<PBANDS+1;i++)
154 {
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100155 pBands[i] = (pitch_freq[i]+res/2)/res;
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100156 if (pBands[i] < mode->eBands[i])
157 pBands[i] = mode->eBands[i];
158 }
159 pBands[PBANDS+1] = mode->eBands[mode->nbEBands+1];
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100160 for (i=1;i<mode->nbPBands+1;i++)
161 {
162 int j;
163 for (j=0;j<mode->nbEBands;j++)
164 if (mode->eBands[j] <= pBands[i] && mode->eBands[j+1] > pBands[i])
165 break;
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100166 /*printf ("%d %d\n", i, j);*/
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100167 if (mode->eBands[j] != pBands[i])
168 {
169 if (pBands[i]-mode->eBands[j] < mode->eBands[j+1]-pBands[i] &&
170 mode->eBands[j] != pBands[i-1])
171 pBands[i] = mode->eBands[j];
172 else
173 pBands[i] = mode->eBands[j+1];
174 }
175 }
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100176 /*for (i=0;i<mode->nbPBands+2;i++)
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100177 printf("%d ", pBands[i]);
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100178 printf ("\n");*/
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100179 mode->pBands = pBands;
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100180 mode->pitchEnd = pBands[PBANDS];
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100181}
182
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100183static void compute_allocation_table(CELTMode *mode, int res)
184{
185 int i, j, eband;
186 int *allocVectors;
187
188 mode->nbAllocVectors = BITALLOC_SIZE;
189 allocVectors = celt_alloc(sizeof(int)*(BITALLOC_SIZE*mode->nbEBands));
190 for (i=0;i<BITALLOC_SIZE;i++)
191 {
192 eband = 0;
193 for (j=0;j<BARK_BANDS;j++)
194 {
195 int edge, low;
196 edge = mode->eBands[eband+1]*res;
197 if (edge < bark_freq[j+1])
198 {
199 int num, den;
200 num = band_allocation[i*BARK_BANDS+j] * (edge-bark_freq[j]);
201 den = bark_freq[j+1]-bark_freq[j];
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100202 low = (num+den/2)/den;
203 allocVectors[i*mode->nbEBands+eband] += low;
204 eband++;
205 allocVectors[i*mode->nbEBands+eband] += band_allocation[i*BARK_BANDS+j]-low;
206 } else {
207 allocVectors[i*mode->nbEBands+eband] += band_allocation[i*BARK_BANDS+j];
208 }
209 }
210 }
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100211 /*for (i=0;i<BITALLOC_SIZE;i++)
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100212 {
213 for (j=0;j<mode->nbEBands;j++)
214 printf ("%2d ", allocVectors[i*mode->nbEBands+j]);
215 printf ("\n");
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100216 }*/
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100217 mode->allocVectors = allocVectors;
218}
219
Jean-Marc Valin5588d522008-03-10 15:07:58 +1100220#endif /* STATIC_MODES */
Jean-Marc Valin25358cd2008-02-19 12:21:32 +1100221
Jean-Marc Valind0f57872008-03-08 07:39:47 +1100222CELTMode *celt_mode_create(celt_int32_t Fs, int channels, int frame_size, int lookahead, int *error)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100223{
Jean-Marc Valinf39e8692008-03-10 12:13:23 +1100224#ifdef STATIC_MODES
Jean-Marc Valin680a9ec2008-03-10 14:52:18 +1100225 CELTMode *mode = NULL;
226 int i;
227 for (i=0;i<TOTAL_MODES;i++)
228 {
229 if (Fs == static_mode_list[i]->Fs &&
230 channels == static_mode_list[i]->nbChannels &&
231 frame_size == static_mode_list[i]->mdctSize &&
232 lookahead == static_mode_list[i]->overlap)
233 {
234 mode = static_mode_list[i];
235 break;
236 }
237 }
238 if (mode == NULL)
239 {
240 celt_warning("Mode not included as part of the static modes");
241 if (error)
242 *error = CELT_BAD_ARG;
243 return NULL;
244 }
Jean-Marc Valinf39e8692008-03-10 12:13:23 +1100245#else
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100246 int res;
Jean-Marc Valinf39e8692008-03-10 12:13:23 +1100247 int i;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100248 CELTMode *mode;
Jean-Marc Valin3dbc1d02008-03-08 15:21:24 +1100249 celt_word16_t *window;
250
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100251 /* The good thing here is that permutation of the arguments will automatically be invalid */
252
253 if (Fs < 32000 || Fs > 64000)
254 {
255 celt_warning("Sampling rate must be between 32 kHz and 64 kHz");
256 if (error)
257 *error = CELT_BAD_ARG;
258 return NULL;
259 }
260 if (channels < 0 || channels > 2)
261 {
262 celt_warning("Only mono and stereo supported");
263 if (error)
264 *error = CELT_BAD_ARG;
265 return NULL;
266 }
267 if (frame_size < 64 || frame_size > 256 || frame_size%2!=0)
268 {
269 celt_warning("Only even frame sizes between 64 and 256 are supported");
270 if (error)
271 *error = CELT_BAD_ARG;
272 return NULL;
273 }
274 if (lookahead < 32 || lookahead > frame_size)
275 {
276 celt_warning("The overlap must be between 32 and the frame size");
277 if (error)
278 *error = CELT_BAD_ARG;
279 return NULL;
280 }
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100281 res = (Fs+frame_size)/(2*frame_size);
282
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100283 mode = celt_alloc(sizeof(CELTMode));
Jean-Marc Valine6b74652008-02-20 18:01:08 +1100284 mode->Fs = Fs;
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100285 mode->overlap = lookahead;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100286 mode->mdctSize = frame_size;
287 mode->nbMdctBlocks = 1;
288 mode->nbChannels = channels;
289 mode->eBands = compute_ebands(Fs, frame_size, &mode->nbEBands);
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100290 compute_pbands(mode, res);
Jean-Marc Valin8b2a5922008-02-29 00:32:51 +1100291 mode->ePredCoef = QCONST16(.8f,15);
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100292
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100293 compute_allocation_table(mode, res);
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100294 /*printf ("%d bands\n", mode->nbEBands);*/
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100295
Jean-Marc Valin3dbc1d02008-03-08 15:21:24 +1100296 window = (celt_word16_t*)celt_alloc(mode->overlap*sizeof(celt_word16_t));
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100297
Jean-Marc Valinf28062f2008-03-03 13:24:01 +1100298#ifndef FIXED_POINT
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100299 for (i=0;i<mode->overlap;i++)
Jean-Marc Valin3dbc1d02008-03-08 15:21:24 +1100300 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 +1100301#else
302 for (i=0;i<mode->overlap;i++)
Jean-Marc Valin3dbc1d02008-03-08 15:21:24 +1100303 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 +1100304#endif
Jean-Marc Valin3dbc1d02008-03-08 15:21:24 +1100305 mode->window = window;
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100306
Jean-Marc Valin5588d522008-03-10 15:07:58 +1100307 psydecay_init(&mode->psy, MAX_PERIOD/2, mode->Fs);
308
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +1100309 mode->marker_start = MODEVALID;
310 mode->marker_end = MODEVALID;
Jean-Marc Valinf39e8692008-03-10 12:13:23 +1100311#endif
312 mdct_init(&mode->mdct, 2*mode->mdctSize);
313 compute_alloc_cache(mode);
Jean-Marc Valin680a9ec2008-03-10 14:52:18 +1100314 if (error)
315 *error = CELT_OK;
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100316 return mode;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100317}
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100318
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100319void celt_mode_destroy(CELTMode *mode)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100320{
Jean-Marc Valin5588d522008-03-10 15:07:58 +1100321#ifndef STATIC_MODES
Jean-Marc Valin25358cd2008-02-19 12:21:32 +1100322 int i;
323 const int *prevPtr = NULL;
Jean-Marc Valin25358cd2008-02-19 12:21:32 +1100324 for (i=0;i<mode->nbEBands;i++)
325 {
326 if (mode->bits[i] != prevPtr)
327 {
328 prevPtr = mode->bits[i];
329 celt_free((int*)mode->bits[i]);
330 }
331 }
332 celt_free((int**)mode->bits);
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100333 mdct_clear(&mode->mdct);
Jean-Marc Valinf39e8692008-03-10 12:13:23 +1100334 if (check_mode(mode) != CELT_OK)
335 return;
336 celt_free((int*)mode->eBands);
337 celt_free((int*)mode->pBands);
338 celt_free((int*)mode->allocVectors);
339
Jean-Marc Valin3dbc1d02008-03-08 15:21:24 +1100340 celt_free((celt_word16_t*)mode->window);
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100341
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +1100342 mode->marker_start = MODEFREED;
343 mode->marker_end = MODEFREED;
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100344 celt_free((CELTMode *)mode);
Jean-Marc Valin5588d522008-03-10 15:07:58 +1100345 psydecay_clear(&mode->psy);
Jean-Marc Valinf39e8692008-03-10 12:13:23 +1100346#endif
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100347}
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +1100348
349int check_mode(const CELTMode *mode)
350{
351 if (mode->marker_start == MODEVALID && mode->marker_end == MODEVALID)
352 return CELT_OK;
353 if (mode->marker_start == MODEFREED || mode->marker_end == MODEFREED)
354 celt_warning("Using a mode that has already been freed");
355 else
356 celt_warning("This is not a valid CELT mode");
357 return CELT_INVALID_MODE;
358}