blob: e38df9a97477d6d088ed325626b49d8ec3a2b914 [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 Valin44ffd5a2008-02-22 00:39:25 +110041#define MODEVALID 0xa110ca7e
42#define MODEFREED 0xb10cf8ee
43
Jean-Marc Valind748cd52008-03-01 07:27:03 +110044#ifndef M_PI
45#define M_PI 3.141592653
46#endif
47
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +110048
Jean-Marc Valinf997ad52008-01-31 16:47:16 +110049int celt_mode_info(const CELTMode *mode, int request, celt_int32_t *value)
50{
51 switch (request)
52 {
53 case CELT_GET_FRAME_SIZE:
54 *value = mode->mdctSize;
55 break;
56 case CELT_GET_LOOKAHEAD:
57 *value = mode->overlap;
58 break;
Jean-Marc Valin4c6bc882008-01-31 17:34:27 +110059 case CELT_GET_NB_CHANNELS:
60 *value = mode->nbChannels;
61 break;
Jean-Marc Valincb7a2a32008-02-11 16:44:48 +110062 default:
63 return CELT_BAD_ARG;
Jean-Marc Valinf997ad52008-01-31 16:47:16 +110064 }
Jean-Marc Valincb7a2a32008-02-11 16:44:48 +110065 return CELT_OK;
Jean-Marc Valinf997ad52008-01-31 16:47:16 +110066}
67
Jean-Marc Valin134492a2008-02-18 16:46:22 +110068#define PBANDS 8
Jean-Marc Valin81a82952008-02-17 22:41:29 +110069#define MIN_BINS 4
Jean-Marc Valin17683eb2008-02-18 21:45:19 +110070/* Defining 25 critical bands for the full 0-20 kHz audio bandwidth
71 Taken from http://ccrma.stanford.edu/~jos/bbt/Bark_Frequency_Scale.html */
Jean-Marc Valin81a82952008-02-17 22:41:29 +110072#define BARK_BANDS 25
Jean-Marc Valin25358cd2008-02-19 12:21:32 +110073static const celt_int16_t bark_freq[BARK_BANDS+1] = {
Jean-Marc Valin17683eb2008-02-18 21:45:19 +110074 0, 100, 200, 300, 400,
75 510, 630, 770, 920, 1080,
76 1270, 1480, 1720, 2000, 2320,
77 2700, 3150, 3700, 4400, 5300,
78 6400, 7700, 9500, 12000, 15500,
79 20000};
80
Jean-Marc Valin25358cd2008-02-19 12:21:32 +110081static 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 +110082
Jean-Marc Valin75e9c862008-02-18 17:04:15 +110083/* This allocation table is per critical band. When creating a mode, the bits get added together
84 into the codec bands, which are sometimes larger than one critical band at low frequency */
Jean-Marc Valin9838fec2008-02-18 14:45:11 +110085#define BITALLOC_SIZE 10
Jean-Marc Valin25358cd2008-02-19 12:21:32 +110086static const int band_allocation[BARK_BANDS*BITALLOC_SIZE] =
Jean-Marc Valin9838fec2008-02-18 14:45:11 +110087 { 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 +110088 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,
89 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,
90 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,
91 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,
92 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 +110093 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,
94 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,
95 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,
96 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,
97 };
98
Jean-Marc Valin81a82952008-02-17 22:41:29 +110099
100static int *compute_ebands(int Fs, int frame_size, int *nbEBands)
101{
102 int *eBands;
103 int i, res, min_width, lin, low, high;
104 res = (Fs+frame_size)/(2*frame_size);
105 min_width = MIN_BINS*res;
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100106 /*printf ("min_width = %d\n", min_width);*/
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100107
108 /* Find where the linear part ends (i.e. where the spacing is more than min_width */
109 for (lin=0;lin<BARK_BANDS;lin++)
110 if (bark_freq[lin+1]-bark_freq[lin] >= min_width)
111 break;
112
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100113 /*printf ("lin = %d (%d Hz)\n", lin, bark_freq[lin]);*/
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100114 low = ((bark_freq[lin]/res)+(MIN_BINS-1))/MIN_BINS;
115 high = BARK_BANDS-lin;
116 *nbEBands = low+high;
117 eBands = celt_alloc(sizeof(int)*(*nbEBands+2));
118
119 /* Linear spacing (min_width) */
120 for (i=0;i<low;i++)
121 eBands[i] = MIN_BINS*i;
122 /* Spacing follows critical bands */
123 for (i=0;i<high;i++)
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100124 eBands[i+low] = (bark_freq[lin+i]+res/2)/res;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100125 /* Enforce the minimum spacing at the boundary */
126 for (i=0;i<*nbEBands;i++)
127 if (eBands[i] < MIN_BINS*i)
128 eBands[i] = MIN_BINS*i;
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100129 eBands[*nbEBands] = (bark_freq[BARK_BANDS]+res/2)/res;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100130 eBands[*nbEBands+1] = frame_size;
131 if (eBands[*nbEBands] > eBands[*nbEBands+1])
132 eBands[*nbEBands] = eBands[*nbEBands+1];
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100133
134 /* FIXME: Remove last band if too small */
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100135 /*for (i=0;i<*nbEBands+2;i++)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100136 printf("%d ", eBands[i]);
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100137 printf ("\n");*/
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100138 return eBands;
139}
140
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100141static void compute_pbands(CELTMode *mode, int res)
142{
143 int i;
144 int *pBands;
145 pBands=celt_alloc(sizeof(int)*(PBANDS+2));
146 mode->nbPBands = PBANDS;
147 for (i=0;i<PBANDS+1;i++)
148 {
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100149 pBands[i] = (pitch_freq[i]+res/2)/res;
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100150 if (pBands[i] < mode->eBands[i])
151 pBands[i] = mode->eBands[i];
152 }
153 pBands[PBANDS+1] = mode->eBands[mode->nbEBands+1];
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100154 for (i=1;i<mode->nbPBands+1;i++)
155 {
156 int j;
157 for (j=0;j<mode->nbEBands;j++)
158 if (mode->eBands[j] <= pBands[i] && mode->eBands[j+1] > pBands[i])
159 break;
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100160 /*printf ("%d %d\n", i, j);*/
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100161 if (mode->eBands[j] != pBands[i])
162 {
163 if (pBands[i]-mode->eBands[j] < mode->eBands[j+1]-pBands[i] &&
164 mode->eBands[j] != pBands[i-1])
165 pBands[i] = mode->eBands[j];
166 else
167 pBands[i] = mode->eBands[j+1];
168 }
169 }
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100170 /*for (i=0;i<mode->nbPBands+2;i++)
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100171 printf("%d ", pBands[i]);
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100172 printf ("\n");*/
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100173 mode->pBands = pBands;
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100174 mode->pitchEnd = pBands[PBANDS];
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100175}
176
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100177static void compute_allocation_table(CELTMode *mode, int res)
178{
179 int i, j, eband;
180 int *allocVectors;
181
182 mode->nbAllocVectors = BITALLOC_SIZE;
183 allocVectors = celt_alloc(sizeof(int)*(BITALLOC_SIZE*mode->nbEBands));
184 for (i=0;i<BITALLOC_SIZE;i++)
185 {
186 eband = 0;
187 for (j=0;j<BARK_BANDS;j++)
188 {
189 int edge, low;
190 edge = mode->eBands[eband+1]*res;
191 if (edge < bark_freq[j+1])
192 {
193 int num, den;
194 num = band_allocation[i*BARK_BANDS+j] * (edge-bark_freq[j]);
195 den = bark_freq[j+1]-bark_freq[j];
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100196 low = (num+den/2)/den;
197 allocVectors[i*mode->nbEBands+eband] += low;
198 eband++;
199 allocVectors[i*mode->nbEBands+eband] += band_allocation[i*BARK_BANDS+j]-low;
200 } else {
201 allocVectors[i*mode->nbEBands+eband] += band_allocation[i*BARK_BANDS+j];
202 }
203 }
204 }
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100205 /*for (i=0;i<BITALLOC_SIZE;i++)
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100206 {
207 for (j=0;j<mode->nbEBands;j++)
208 printf ("%2d ", allocVectors[i*mode->nbEBands+j]);
209 printf ("\n");
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100210 }*/
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100211 mode->allocVectors = allocVectors;
212}
213
Jean-Marc Valin25358cd2008-02-19 12:21:32 +1100214
215
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100216CELTMode *celt_mode_create(int Fs, int channels, int frame_size, int lookahead, int *error)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100217{
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100218 int res;
Jean-Marc Valind9de5932008-03-05 08:11:57 +1100219 int N, i;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100220 CELTMode *mode;
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100221
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100222 /* The good thing here is that permutation of the arguments will automatically be invalid */
223
224 if (Fs < 32000 || Fs > 64000)
225 {
226 celt_warning("Sampling rate must be between 32 kHz and 64 kHz");
227 if (error)
228 *error = CELT_BAD_ARG;
229 return NULL;
230 }
231 if (channels < 0 || channels > 2)
232 {
233 celt_warning("Only mono and stereo supported");
234 if (error)
235 *error = CELT_BAD_ARG;
236 return NULL;
237 }
238 if (frame_size < 64 || frame_size > 256 || frame_size%2!=0)
239 {
240 celt_warning("Only even frame sizes between 64 and 256 are supported");
241 if (error)
242 *error = CELT_BAD_ARG;
243 return NULL;
244 }
245 if (lookahead < 32 || lookahead > frame_size)
246 {
247 celt_warning("The overlap must be between 32 and the frame size");
248 if (error)
249 *error = CELT_BAD_ARG;
250 return NULL;
251 }
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100252 res = (Fs+frame_size)/(2*frame_size);
253
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100254 mode = celt_alloc(sizeof(CELTMode));
Jean-Marc Valine6b74652008-02-20 18:01:08 +1100255 mode->Fs = Fs;
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100256 mode->overlap = lookahead;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100257 mode->mdctSize = frame_size;
258 mode->nbMdctBlocks = 1;
259 mode->nbChannels = channels;
260 mode->eBands = compute_ebands(Fs, frame_size, &mode->nbEBands);
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100261 compute_pbands(mode, res);
Jean-Marc Valin8b2a5922008-02-29 00:32:51 +1100262 mode->ePredCoef = QCONST16(.8f,15);
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100263
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100264 compute_allocation_table(mode, res);
Jean-Marc Valin25358cd2008-02-19 12:21:32 +1100265 compute_alloc_cache(mode);
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100266 /*printf ("%d bands\n", mode->nbEBands);*/
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100267
268 N = mode->mdctSize;
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100269 mdct_init(&mode->mdct, 2*N);
270
Jean-Marc Valin3e08a882008-03-03 13:49:20 +1100271 mode->window = (celt_word16_t*)celt_alloc(mode->overlap*sizeof(celt_word16_t));
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100272
Jean-Marc Valinf28062f2008-03-03 13:24:01 +1100273#ifndef FIXED_POINT
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100274 for (i=0;i<mode->overlap;i++)
Jean-Marc Valin3e08a882008-03-03 13:49:20 +1100275 mode->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 +1100276#else
277 for (i=0;i<mode->overlap;i++)
Jean-Marc Valin3e08a882008-03-03 13:49:20 +1100278 mode->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 +1100279#endif
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100280
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +1100281 mode->marker_start = MODEVALID;
282 mode->marker_end = MODEVALID;
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100283 return mode;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100284}
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100285
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100286void celt_mode_destroy(CELTMode *mode)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100287{
Jean-Marc Valin25358cd2008-02-19 12:21:32 +1100288 int i;
289 const int *prevPtr = NULL;
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +1100290 if (check_mode(mode) != CELT_OK)
291 return;
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100292 celt_free((int*)mode->eBands);
293 celt_free((int*)mode->pBands);
294 celt_free((int*)mode->allocVectors);
Jean-Marc Valin25358cd2008-02-19 12:21:32 +1100295
296 for (i=0;i<mode->nbEBands;i++)
297 {
298 if (mode->bits[i] != prevPtr)
299 {
300 prevPtr = mode->bits[i];
301 celt_free((int*)mode->bits[i]);
302 }
303 }
304 celt_free((int**)mode->bits);
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100305 mdct_clear(&mode->mdct);
306 celt_free(mode->window);
307
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +1100308 mode->marker_start = MODEFREED;
309 mode->marker_end = MODEFREED;
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100310 celt_free((CELTMode *)mode);
Jean-Marc Valin25358cd2008-02-19 12:21:32 +1100311
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100312}
Jean-Marc Valin44ffd5a2008-02-22 00:39:25 +1100313
314int check_mode(const CELTMode *mode)
315{
316 if (mode->marker_start == MODEVALID && mode->marker_end == MODEVALID)
317 return CELT_OK;
318 if (mode->marker_start == MODEFREED || mode->marker_end == MODEFREED)
319 celt_warning("Using a mode that has already been freed");
320 else
321 celt_warning("This is not a valid CELT mode");
322 return CELT_INVALID_MODE;
323}