blob: e641ea283ac8bb7704a04bb6ba1b86e879607610 [file] [log] [blame]
Jean-Marc Valinecb36a32007-12-05 01:31:49 +11001/* (C) 2007 Jean-Marc Valin, CSIRO
2*/
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 Valinf997ad52008-01-31 16:47:16 +110041int celt_mode_info(const CELTMode *mode, int request, celt_int32_t *value)
42{
43 switch (request)
44 {
45 case CELT_GET_FRAME_SIZE:
46 *value = mode->mdctSize;
47 break;
48 case CELT_GET_LOOKAHEAD:
49 *value = mode->overlap;
50 break;
Jean-Marc Valin4c6bc882008-01-31 17:34:27 +110051 case CELT_GET_NB_CHANNELS:
52 *value = mode->nbChannels;
53 break;
Jean-Marc Valincb7a2a32008-02-11 16:44:48 +110054 default:
55 return CELT_BAD_ARG;
Jean-Marc Valinf997ad52008-01-31 16:47:16 +110056 }
Jean-Marc Valincb7a2a32008-02-11 16:44:48 +110057 return CELT_OK;
Jean-Marc Valinf997ad52008-01-31 16:47:16 +110058}
59
Jean-Marc Valin134492a2008-02-18 16:46:22 +110060#define PBANDS 8
Jean-Marc Valin81a82952008-02-17 22:41:29 +110061#define MIN_BINS 4
Jean-Marc Valin17683eb2008-02-18 21:45:19 +110062/* Defining 25 critical bands for the full 0-20 kHz audio bandwidth
63 Taken from http://ccrma.stanford.edu/~jos/bbt/Bark_Frequency_Scale.html */
Jean-Marc Valin81a82952008-02-17 22:41:29 +110064#define BARK_BANDS 25
Jean-Marc Valin25358cd2008-02-19 12:21:32 +110065static const celt_int16_t bark_freq[BARK_BANDS+1] = {
Jean-Marc Valin17683eb2008-02-18 21:45:19 +110066 0, 100, 200, 300, 400,
67 510, 630, 770, 920, 1080,
68 1270, 1480, 1720, 2000, 2320,
69 2700, 3150, 3700, 4400, 5300,
70 6400, 7700, 9500, 12000, 15500,
71 20000};
72
Jean-Marc Valin25358cd2008-02-19 12:21:32 +110073static 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 +110074
Jean-Marc Valin75e9c862008-02-18 17:04:15 +110075/* This allocation table is per critical band. When creating a mode, the bits get added together
76 into the codec bands, which are sometimes larger than one critical band at low frequency */
Jean-Marc Valin9838fec2008-02-18 14:45:11 +110077#define BITALLOC_SIZE 10
Jean-Marc Valin25358cd2008-02-19 12:21:32 +110078static const int band_allocation[BARK_BANDS*BITALLOC_SIZE] =
Jean-Marc Valin9838fec2008-02-18 14:45:11 +110079 { 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 +110080 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,
81 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,
82 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,
83 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,
84 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 +110085 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,
86 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,
87 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,
88 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,
89 };
90
Jean-Marc Valin81a82952008-02-17 22:41:29 +110091
92static int *compute_ebands(int Fs, int frame_size, int *nbEBands)
93{
94 int *eBands;
95 int i, res, min_width, lin, low, high;
96 res = (Fs+frame_size)/(2*frame_size);
97 min_width = MIN_BINS*res;
Jean-Marc Valina85657b2008-02-20 11:59:30 +110098 /*printf ("min_width = %d\n", min_width);*/
Jean-Marc Valin81a82952008-02-17 22:41:29 +110099
100 /* Find where the linear part ends (i.e. where the spacing is more than min_width */
101 for (lin=0;lin<BARK_BANDS;lin++)
102 if (bark_freq[lin+1]-bark_freq[lin] >= min_width)
103 break;
104
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100105 /*printf ("lin = %d (%d Hz)\n", lin, bark_freq[lin]);*/
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100106 low = ((bark_freq[lin]/res)+(MIN_BINS-1))/MIN_BINS;
107 high = BARK_BANDS-lin;
108 *nbEBands = low+high;
109 eBands = celt_alloc(sizeof(int)*(*nbEBands+2));
110
111 /* Linear spacing (min_width) */
112 for (i=0;i<low;i++)
113 eBands[i] = MIN_BINS*i;
114 /* Spacing follows critical bands */
115 for (i=0;i<high;i++)
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100116 eBands[i+low] = (bark_freq[lin+i]+res/2)/res;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100117 /* Enforce the minimum spacing at the boundary */
118 for (i=0;i<*nbEBands;i++)
119 if (eBands[i] < MIN_BINS*i)
120 eBands[i] = MIN_BINS*i;
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100121 eBands[*nbEBands] = (bark_freq[BARK_BANDS]+res/2)/res;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100122 eBands[*nbEBands+1] = frame_size;
123 if (eBands[*nbEBands] > eBands[*nbEBands+1])
124 eBands[*nbEBands] = eBands[*nbEBands+1];
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100125
126 /* FIXME: Remove last band if too small */
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100127 /*for (i=0;i<*nbEBands+2;i++)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100128 printf("%d ", eBands[i]);
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100129 printf ("\n");*/
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100130 return eBands;
131}
132
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100133static void compute_pbands(CELTMode *mode, int res)
134{
135 int i;
136 int *pBands;
137 pBands=celt_alloc(sizeof(int)*(PBANDS+2));
138 mode->nbPBands = PBANDS;
139 for (i=0;i<PBANDS+1;i++)
140 {
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100141 pBands[i] = (pitch_freq[i]+res/2)/res;
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100142 if (pBands[i] < mode->eBands[i])
143 pBands[i] = mode->eBands[i];
144 }
145 pBands[PBANDS+1] = mode->eBands[mode->nbEBands+1];
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100146 for (i=1;i<mode->nbPBands+1;i++)
147 {
148 int j;
149 for (j=0;j<mode->nbEBands;j++)
150 if (mode->eBands[j] <= pBands[i] && mode->eBands[j+1] > pBands[i])
151 break;
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100152 /*printf ("%d %d\n", i, j);*/
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100153 if (mode->eBands[j] != pBands[i])
154 {
155 if (pBands[i]-mode->eBands[j] < mode->eBands[j+1]-pBands[i] &&
156 mode->eBands[j] != pBands[i-1])
157 pBands[i] = mode->eBands[j];
158 else
159 pBands[i] = mode->eBands[j+1];
160 }
161 }
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100162 /*for (i=0;i<mode->nbPBands+2;i++)
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100163 printf("%d ", pBands[i]);
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100164 printf ("\n");*/
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100165 mode->pBands = pBands;
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100166 mode->pitchEnd = pBands[PBANDS];
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100167}
168
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100169static void compute_allocation_table(CELTMode *mode, int res)
170{
171 int i, j, eband;
172 int *allocVectors;
173
174 mode->nbAllocVectors = BITALLOC_SIZE;
175 allocVectors = celt_alloc(sizeof(int)*(BITALLOC_SIZE*mode->nbEBands));
176 for (i=0;i<BITALLOC_SIZE;i++)
177 {
178 eband = 0;
179 for (j=0;j<BARK_BANDS;j++)
180 {
181 int edge, low;
182 edge = mode->eBands[eband+1]*res;
183 if (edge < bark_freq[j+1])
184 {
185 int num, den;
186 num = band_allocation[i*BARK_BANDS+j] * (edge-bark_freq[j]);
187 den = bark_freq[j+1]-bark_freq[j];
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100188 low = (num+den/2)/den;
189 allocVectors[i*mode->nbEBands+eband] += low;
190 eband++;
191 allocVectors[i*mode->nbEBands+eband] += band_allocation[i*BARK_BANDS+j]-low;
192 } else {
193 allocVectors[i*mode->nbEBands+eband] += band_allocation[i*BARK_BANDS+j];
194 }
195 }
196 }
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100197 /*for (i=0;i<BITALLOC_SIZE;i++)
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100198 {
199 for (j=0;j<mode->nbEBands;j++)
200 printf ("%2d ", allocVectors[i*mode->nbEBands+j]);
201 printf ("\n");
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100202 }*/
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100203 mode->allocVectors = allocVectors;
204}
205
Jean-Marc Valin25358cd2008-02-19 12:21:32 +1100206
207
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100208CELTMode *celt_mode_create(int Fs, int channels, int frame_size, int lookahead, int *error)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100209{
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100210 int res;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100211 CELTMode *mode;
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100212
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100213 /* The good thing here is that permutation of the arguments will automatically be invalid */
214
215 if (Fs < 32000 || Fs > 64000)
216 {
217 celt_warning("Sampling rate must be between 32 kHz and 64 kHz");
218 if (error)
219 *error = CELT_BAD_ARG;
220 return NULL;
221 }
222 if (channels < 0 || channels > 2)
223 {
224 celt_warning("Only mono and stereo supported");
225 if (error)
226 *error = CELT_BAD_ARG;
227 return NULL;
228 }
229 if (frame_size < 64 || frame_size > 256 || frame_size%2!=0)
230 {
231 celt_warning("Only even frame sizes between 64 and 256 are supported");
232 if (error)
233 *error = CELT_BAD_ARG;
234 return NULL;
235 }
236 if (lookahead < 32 || lookahead > frame_size)
237 {
238 celt_warning("The overlap must be between 32 and the frame size");
239 if (error)
240 *error = CELT_BAD_ARG;
241 return NULL;
242 }
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100243 res = (Fs+frame_size)/(2*frame_size);
244
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100245 mode = celt_alloc(sizeof(CELTMode));
Jean-Marc Valine6b74652008-02-20 18:01:08 +1100246 mode->Fs = Fs;
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100247 mode->overlap = lookahead;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100248 mode->mdctSize = frame_size;
249 mode->nbMdctBlocks = 1;
250 mode->nbChannels = channels;
251 mode->eBands = compute_ebands(Fs, frame_size, &mode->nbEBands);
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100252 compute_pbands(mode, res);
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100253 mode->ePredCoef = .8;
254
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100255 compute_allocation_table(mode, res);
Jean-Marc Valin25358cd2008-02-19 12:21:32 +1100256 compute_alloc_cache(mode);
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100257 /*printf ("%d bands\n", mode->nbEBands);*/
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100258 return mode;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100259}
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100260
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100261void celt_mode_destroy(CELTMode *mode)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100262{
Jean-Marc Valin25358cd2008-02-19 12:21:32 +1100263 int i;
264 const int *prevPtr = NULL;
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100265 celt_free((int*)mode->eBands);
266 celt_free((int*)mode->pBands);
267 celt_free((int*)mode->allocVectors);
Jean-Marc Valin25358cd2008-02-19 12:21:32 +1100268
269 for (i=0;i<mode->nbEBands;i++)
270 {
271 if (mode->bits[i] != prevPtr)
272 {
273 prevPtr = mode->bits[i];
274 celt_free((int*)mode->bits[i]);
275 }
276 }
277 celt_free((int**)mode->bits);
278
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100279 celt_free((CELTMode *)mode);
Jean-Marc Valin25358cd2008-02-19 12:21:32 +1100280
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100281}