blob: 7eb2e02881e4156e43f4a00e299e481bade3fe95 [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 Valin65d57e62008-02-18 15:49:37 +110032#include "celt.h"
Jean-Marc Valinecb36a32007-12-05 01:31:49 +110033#include "modes.h"
Jean-Marc Valin81a82952008-02-17 22:41:29 +110034#include "os_support.h"
Jean-Marc Valinecb36a32007-12-05 01:31:49 +110035
Jean-Marc Valin36d78e62007-12-13 14:59:30 +110036#define NBANDS 18
Jean-Marc Valin2875f6b2008-01-05 13:32:32 +110037#define PBANDS 8
Jean-Marc Valin95c59ea2008-01-08 16:22:37 +110038#define PITCH_END 74
Jean-Marc Valin36d78e62007-12-13 14:59:30 +110039
Jean-Marc Valinecb36a32007-12-05 01:31:49 +110040#define NBANDS128 15
Jean-Marc Valin2875f6b2008-01-05 13:32:32 +110041#define PBANDS128 8
42#define PITCH_END128 45
Jean-Marc Valinecb36a32007-12-05 01:31:49 +110043
Jean-Marc Valin95c59ea2008-01-08 16:22:37 +110044const int qbank0[NBANDS +2] = {0, 4, 8, 12, 16, 20, 24, 28, 32, 38, 44, 52, 62, 74, 90,112,142,182, 232,256};
45const int pbank0[PBANDS +2] = {0, 4, 8, 12, 16, 24, 38, 62, PITCH_END, 256};
Jean-Marc Valin36d78e62007-12-13 14:59:30 +110046
Jean-Marc Valin4fbd18d2008-01-17 14:07:55 +110047#define NALLOCS 7
48int bitalloc0[NBANDS*NALLOCS] =
49 { 5, 4, 4, 4, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0,
50 8, 7, 7, 6, 6, 6, 5, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
51 10, 9, 9, 8, 8, 8, 8, 8, 8, 8, 9, 10, 11, 12, 17, 15, 6, 7,
52 16, 15, 14, 14, 14, 13, 13, 13, 13, 13, 15, 16, 17, 18, 20, 18, 11, 12,
53 26, 25, 24, 22, 20, 18, 19, 19, 25, 22, 25, 30, 30, 35, 35, 35, 35, 25,
54 32, 30, 28, 27, 25, 24, 23, 21, 29, 27, 35, 40, 42, 50, 59, 54, 51, 36,
55 42, 40, 38, 37, 35, 34, 33, 31, 39, 37, 45, 50, 52, 60, 60, 60, 60, 46,
Jean-Marc Valinf51ca492008-01-17 10:58:38 +110056};
Jean-Marc Valina5431bf2008-01-03 20:53:01 +110057
Jean-Marc Valin4fbd18d2008-01-17 14:07:55 +110058
Jean-Marc Valina5431bf2008-01-03 20:53:01 +110059#define NBANDS256 15
Jean-Marc Valin2875f6b2008-01-05 13:32:32 +110060#define PBANDS256 8
61#define PITCH_END256 88
Jean-Marc Valina4833ff2008-01-10 15:34:00 +110062const int qbank3[NBANDS256+2] = {0, 4, 8, 12, 16, 24, 32, 40, 48, 56, 72, 88, 104, 136, 168, 232, 256};
Jean-Marc Valin2875f6b2008-01-05 13:32:32 +110063//const int pbank3[PBANDS256+2] = {0, 8, 16, 24, 40, PITCH_END256, 256};
Jean-Marc Valina4833ff2008-01-10 15:34:00 +110064const int pbank3[PBANDS256+2] = {0, 4, 8, 12, 16, 24, 40, 56, PITCH_END256, 256};
Jean-Marc Valin36d78e62007-12-13 14:59:30 +110065
Jean-Marc Valin3cfcd052008-01-18 13:56:08 +110066static const CELTMode mono_mode = {
Jean-Marc Valina5431bf2008-01-03 20:53:01 +110067 128, /**< overlap */
Jean-Marc Valin95c59ea2008-01-08 16:22:37 +110068 256, /**< mdctSize */
69 1, /**< nbMdctBlocks */
Jean-Marc Valin36d78e62007-12-13 14:59:30 +110070 1, /**< channels */
71
72 NBANDS, /**< nbEBands */
73 PBANDS, /**< nbPBands */
74 PITCH_END, /**< pitchEnd */
75
76 qbank0, /**< eBands */
77 pbank0, /**< pBands*/
Jean-Marc Valin36d78e62007-12-13 14:59:30 +110078
79 0.8, /**< ePredCoef */
Jean-Marc Valinf51ca492008-01-17 10:58:38 +110080
Jean-Marc Valin3cfcd052008-01-18 13:56:08 +110081 NALLOCS, /**< nbAllocVectors */
Jean-Marc Valinf51ca492008-01-17 10:58:38 +110082 bitalloc0, /**< allocVectors */
Jean-Marc Valin36d78e62007-12-13 14:59:30 +110083};
84
Jean-Marc Valinaa5bd612007-12-08 00:27:10 +110085
Jean-Marc Valin4a897682007-12-12 00:45:15 +110086/* Stereo mode around 120 kbps */
Jean-Marc Valin3cfcd052008-01-18 13:56:08 +110087static const CELTMode stereo_mode = {
88 128, /**< overlap */
Jean-Marc Valinfdca84b2008-01-09 10:44:18 +110089 256, /**< mdctSize */
90 1, /**< nbMdctBlocks */
Jean-Marc Valinffa13472007-12-10 16:54:17 +110091 2, /**< channels */
92
Jean-Marc Valin3cfcd052008-01-18 13:56:08 +110093 NBANDS, /**< nbEBands */
94 PBANDS, /**< nbPBands */
95 PITCH_END, /**< pitchEnd */
Jean-Marc Valinffa13472007-12-10 16:54:17 +110096
Jean-Marc Valinf8dda662008-01-10 17:02:36 +110097 qbank0, /**< eBands */
98 pbank0, /**< pBands*/
Jean-Marc Valin36d78e62007-12-13 14:59:30 +110099
Jean-Marc Valinf8dda662008-01-10 17:02:36 +1100100 0.8, /**< ePredCoef */
Jean-Marc Valinf51ca492008-01-17 10:58:38 +1100101
Jean-Marc Valin3cfcd052008-01-18 13:56:08 +1100102 NALLOCS, /**< nbAllocVectors */
Jean-Marc Valinf51ca492008-01-17 10:58:38 +1100103 bitalloc0, /**< allocVectors */
Jean-Marc Valinffa13472007-12-10 16:54:17 +1100104};
105
Jean-Marc Valin3cfcd052008-01-18 13:56:08 +1100106const CELTMode const *celt_mono = &mono_mode;
107const CELTMode const *celt_stereo = &stereo_mode;
Jean-Marc Valinf997ad52008-01-31 16:47:16 +1100108
109
Jean-Marc Valin6da36c02008-02-15 14:20:29 +1100110#define NBANDS51 17
111#define PBANDS51 8
112#define PITCH_END51 64
113const int qbank51[NBANDS51 +2] = {0, 4, 8, 12, 16, 20, 24, 28, 32, 38, 44, 52, 64, 78, 96,122,156,204, 256};
114const int qbank51b[NBANDS +2] = {0, 3, 6, 9, 12, 16, 20, 24, 28, 32, 38, 44, 52, 64, 78, 96,122,156,204, 256};
115
116const int pbank51[PBANDS51 +2] = {0, 4, 8, 12, 16, 24, 32, 44, PITCH_END51, 256};
117const int pbank51b[PBANDS +2] = {0, 3, 6, 9, 12, 20, 38, 52, PITCH_END51, 256};
118#define NALLOCS51 10
119int bitalloc51[NBANDS51*NALLOCS51] =
120 { 6, 5, 3, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
121 7, 6, 5, 4, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0,
122 8, 7, 6, 5, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0,
123 9, 8, 7, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0,
124 10, 9, 8, 8, 7, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0,
125 10, 9, 9, 8, 8, 8, 8, 8, 8, 8, 9, 10, 11, 10, 10, 5, 5,
126 16, 15, 14, 14, 14, 13, 13, 13, 13, 13, 15, 16, 17, 18, 20, 18, 11,
127 26, 25, 24, 22, 20, 18, 19, 19, 25, 22, 25, 30, 30, 35, 35, 35, 35,
128 32, 30, 28, 27, 25, 24, 23, 21, 29, 27, 35, 40, 42, 50, 59, 54, 51,
129 42, 40, 38, 37, 35, 34, 33, 31, 39, 37, 45, 50, 52, 60, 60, 60, 60,
130 };
131
132static const CELTMode ld51 = {
133 128, /**< overlap */
134 256, /**< mdctSize */
135 1, /**< nbMdctBlocks */
136 1, /**< channels */
137
138 NBANDS51, /**< nbEBands */
139 PBANDS51, /**< nbPBands */
140 PITCH_END51, /**< pitchEnd */
141
142 qbank51, /**< eBands */
143 pbank51, /**< pBands*/
Jean-Marc Valin6da36c02008-02-15 14:20:29 +1100144
145 0.8, /**< ePredCoef */
Jean-Marc Valin6da36c02008-02-15 14:20:29 +1100146
147 NALLOCS51, /**< nbAllocVectors */
148 bitalloc51, /**< allocVectors */
149};
150const CELTMode const *celt_ld51 = &ld51;
151
Jean-Marc Valinf997ad52008-01-31 16:47:16 +1100152int celt_mode_info(const CELTMode *mode, int request, celt_int32_t *value)
153{
154 switch (request)
155 {
156 case CELT_GET_FRAME_SIZE:
157 *value = mode->mdctSize;
158 break;
159 case CELT_GET_LOOKAHEAD:
160 *value = mode->overlap;
161 break;
Jean-Marc Valin4c6bc882008-01-31 17:34:27 +1100162 case CELT_GET_NB_CHANNELS:
163 *value = mode->nbChannels;
164 break;
Jean-Marc Valincb7a2a32008-02-11 16:44:48 +1100165 default:
166 return CELT_BAD_ARG;
Jean-Marc Valinf997ad52008-01-31 16:47:16 +1100167 }
Jean-Marc Valincb7a2a32008-02-11 16:44:48 +1100168 return CELT_OK;
Jean-Marc Valinf997ad52008-01-31 16:47:16 +1100169}
170
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100171#define MIN_BINS 4
172#define BARK_BANDS 25
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100173const celt_int16_t bark_freq[BARK_BANDS+1] = {
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100174 0, 101, 200, 301, 405,
175 516, 635, 766, 912, 1077,
176 1263, 1476, 1720, 2003, 2333,
177 2721, 3184, 3742, 4428, 5285,
178 6376, 7791, 9662, 12181, 15624,
179 20397};
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100180
181const celt_int16_t pitch_freq[PBANDS+1] ={0, 345, 689, 1034, 1378, 2067, 3273, 5340, 6374};
182
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100183#define BITALLOC_SIZE 10
184int band_allocation[BARK_BANDS*BITALLOC_SIZE] =
185 { 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,
186 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0,
187 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 3, 2, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0,
188 3, 2, 2, 2, 3, 3, 2, 3, 2, 2, 4, 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0,
189 3, 3, 2, 2, 3, 3, 3, 3, 3, 2, 4, 4, 7, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0,
190 3, 3, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 8, 8, 8, 8, 8, 8, 9, 10, 11, 10, 10, 5, 5,
191 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,
192 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,
193 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,
194 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,
195 };
196
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100197
198static int *compute_ebands(int Fs, int frame_size, int *nbEBands)
199{
200 int *eBands;
201 int i, res, min_width, lin, low, high;
202 res = (Fs+frame_size)/(2*frame_size);
203 min_width = MIN_BINS*res;
204 //printf ("min_width = %d\n", min_width);
205
206 /* Find where the linear part ends (i.e. where the spacing is more than min_width */
207 for (lin=0;lin<BARK_BANDS;lin++)
208 if (bark_freq[lin+1]-bark_freq[lin] >= min_width)
209 break;
210
211 //printf ("lin = %d (%d Hz)\n", lin, bark_freq[lin]);
212 low = ((bark_freq[lin]/res)+(MIN_BINS-1))/MIN_BINS;
213 high = BARK_BANDS-lin;
214 *nbEBands = low+high;
215 eBands = celt_alloc(sizeof(int)*(*nbEBands+2));
216
217 /* Linear spacing (min_width) */
218 for (i=0;i<low;i++)
219 eBands[i] = MIN_BINS*i;
220 /* Spacing follows critical bands */
221 for (i=0;i<high;i++)
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100222 eBands[i+low] = (bark_freq[lin+i]+res/2)/res;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100223 /* Enforce the minimum spacing at the boundary */
224 for (i=0;i<*nbEBands;i++)
225 if (eBands[i] < MIN_BINS*i)
226 eBands[i] = MIN_BINS*i;
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100227 eBands[*nbEBands] = (bark_freq[BARK_BANDS]+res/2)/res;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100228 eBands[*nbEBands+1] = frame_size;
229 if (eBands[*nbEBands] > eBands[*nbEBands+1])
230 eBands[*nbEBands] = eBands[*nbEBands+1];
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100231
232 /* FIXME: Remove last band if too small */
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100233 for (i=0;i<*nbEBands+2;i++)
234 printf("%d ", eBands[i]);
235 printf ("\n");
236 return eBands;
237}
238
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100239static void compute_pbands(CELTMode *mode, int res)
240{
241 int i;
242 int *pBands;
243 pBands=celt_alloc(sizeof(int)*(PBANDS+2));
244 mode->nbPBands = PBANDS;
245 for (i=0;i<PBANDS+1;i++)
246 {
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100247 pBands[i] = (pitch_freq[i]+res/2)/res;
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100248 if (pBands[i] < mode->eBands[i])
249 pBands[i] = mode->eBands[i];
250 }
251 pBands[PBANDS+1] = mode->eBands[mode->nbEBands+1];
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100252 for (i=1;i<mode->nbPBands+1;i++)
253 {
254 int j;
255 for (j=0;j<mode->nbEBands;j++)
256 if (mode->eBands[j] <= pBands[i] && mode->eBands[j+1] > pBands[i])
257 break;
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100258 //printf ("%d %d\n", i, j);
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100259 if (mode->eBands[j] != pBands[i])
260 {
261 if (pBands[i]-mode->eBands[j] < mode->eBands[j+1]-pBands[i] &&
262 mode->eBands[j] != pBands[i-1])
263 pBands[i] = mode->eBands[j];
264 else
265 pBands[i] = mode->eBands[j+1];
266 }
267 }
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100268 for (i=0;i<mode->nbPBands+2;i++)
269 printf("%d ", pBands[i]);
270 printf ("\n");
271 mode->pBands = pBands;
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100272 mode->pitchEnd = pBands[PBANDS];
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100273}
274
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100275static void compute_allocation_table(CELTMode *mode, int res)
276{
277 int i, j, eband;
278 int *allocVectors;
279
280 mode->nbAllocVectors = BITALLOC_SIZE;
281 allocVectors = celt_alloc(sizeof(int)*(BITALLOC_SIZE*mode->nbEBands));
282 for (i=0;i<BITALLOC_SIZE;i++)
283 {
284 eband = 0;
285 for (j=0;j<BARK_BANDS;j++)
286 {
287 int edge, low;
288 edge = mode->eBands[eband+1]*res;
289 if (edge < bark_freq[j+1])
290 {
291 int num, den;
292 num = band_allocation[i*BARK_BANDS+j] * (edge-bark_freq[j]);
293 den = bark_freq[j+1]-bark_freq[j];
294 //low = band_allocation[i*BARK_BANDS+j] * (edge-bark_freq[j])/(bark_freq[j+1]-bark_freq[j]);
295 low = (num+den/2)/den;
296 allocVectors[i*mode->nbEBands+eband] += low;
297 eband++;
298 allocVectors[i*mode->nbEBands+eband] += band_allocation[i*BARK_BANDS+j]-low;
299 } else {
300 allocVectors[i*mode->nbEBands+eband] += band_allocation[i*BARK_BANDS+j];
301 }
302 }
303 }
304 for (i=0;i<BITALLOC_SIZE;i++)
305 {
306 for (j=0;j<mode->nbEBands;j++)
307 printf ("%2d ", allocVectors[i*mode->nbEBands+j]);
308 printf ("\n");
309 }
310 mode->allocVectors = allocVectors;
311}
312
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100313CELTMode *celt_mode_create(int Fs, int channels, int frame_size, int overlap)
314{
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100315 int res;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100316 CELTMode *mode;
317
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100318 res = (Fs+frame_size)/(2*frame_size);
319
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100320 mode = celt_alloc(sizeof(CELTMode));
321 mode->overlap = overlap;
322 mode->mdctSize = frame_size;
323 mode->nbMdctBlocks = 1;
324 mode->nbChannels = channels;
325 mode->eBands = compute_ebands(Fs, frame_size, &mode->nbEBands);
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100326 compute_pbands(mode, res);
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100327 mode->ePredCoef = .8;
328
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100329 compute_allocation_table(mode, res);
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100330
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100331 printf ("%d bands\n", mode->nbEBands);
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100332 return mode;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100333}
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100334
335/*int main()
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100336{
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100337 celt_mode_create(44100, 1, 256, 128);
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100338 return 0;
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100339}*/
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100340