blob: 21e937baac3bc895400fd807a760075f09d81a0c [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
32#include "modes.h"
Jean-Marc Valin81a82952008-02-17 22:41:29 +110033#include "os_support.h"
Jean-Marc Valinecb36a32007-12-05 01:31:49 +110034
Jean-Marc Valin36d78e62007-12-13 14:59:30 +110035#define NBANDS 18
Jean-Marc Valin2875f6b2008-01-05 13:32:32 +110036#define PBANDS 8
Jean-Marc Valin95c59ea2008-01-08 16:22:37 +110037#define PITCH_END 74
Jean-Marc Valin36d78e62007-12-13 14:59:30 +110038
Jean-Marc Valinecb36a32007-12-05 01:31:49 +110039#define NBANDS128 15
Jean-Marc Valin2875f6b2008-01-05 13:32:32 +110040#define PBANDS128 8
41#define PITCH_END128 45
Jean-Marc Valinecb36a32007-12-05 01:31:49 +110042
Jean-Marc Valin36d78e62007-12-13 14:59:30 +110043static const float means[15] = {
44 14.8621, 12.6918, 10.2978, 9.5862, 10.3784,
45 10.4555, 9.1594, 9.0280, 8.3291, 8.3410,
46 8.5737, 8.5614, 9.0107, 7.6809, 7.0665};
Jean-Marc Valinecb36a32007-12-05 01:31:49 +110047
Jean-Marc Valin36d78e62007-12-13 14:59:30 +110048static const float means18[18] = {
49 9.9067, 8.4524, 6.8577, 6.3804, 6.1786, 5.9815,
50 6.2068, 6.1076, 5.7711, 5.7734, 5.7935, 5.3981,
51 5.1992, 5.7214, 5.9656, 5.7548, 5.0802, 4.2626};
Jean-Marc Valinecb36a32007-12-05 01:31:49 +110052
Jean-Marc Valin36d78e62007-12-13 14:59:30 +110053static const int decay[15] = {
54 14800, 13800, 12600, 12000, 11000, 10000, 9800, 8400, 8000, 7500, 7000, 7000, 7000, 6000, 6000
55};
Jean-Marc Valinecb36a32007-12-05 01:31:49 +110056
Jean-Marc Valin36d78e62007-12-13 14:59:30 +110057static const int decay18[18] = {
58 14800, 13800, 12600, 12000, 11000, 11000, 10000, 10000, 9800, 8400, 8400, 8000, 7500, 7000, 7000, 7000, 6000, 6000
59};
60
Jean-Marc Valin95c59ea2008-01-08 16:22:37 +110061const int qbank0[NBANDS +2] = {0, 4, 8, 12, 16, 20, 24, 28, 32, 38, 44, 52, 62, 74, 90,112,142,182, 232,256};
62const int pbank0[PBANDS +2] = {0, 4, 8, 12, 16, 24, 38, 62, PITCH_END, 256};
Jean-Marc Valin2875f6b2008-01-05 13:32:32 +110063//const int pbank0[PBANDS +2] = {0, 4, 8, 12, 19, PITCH_END, 128};
Jean-Marc Valinec71aee2008-01-12 23:38:01 +110064const int qpulses0[NBANDS ] = {7, 6, 6, 5, 5, 5, 5, 4, 3, 3, 3, 3, 3, 3, -3, -2, 0, 0};
Jean-Marc Valin36d78e62007-12-13 14:59:30 +110065//const int qpulses0[NBANDS ] = {7, 5, 5, 5, 4, 4, 3, 3, 3, 3, 4, 3, 3, -2, 0, 0, 0, 0};
66
67
68const int qbank1[NBANDS128+2] = {0, 2, 4, 6, 8, 12, 16, 20, 24, 28, 36, 44, 52, 68, 84, 116, 128};
69
Jean-Marc Valin2875f6b2008-01-05 13:32:32 +110070const int qpulses1[NBANDS128] = {7, 5, 5, 5, 4, 5, 4, 5, 5, 4, 2, 0, 0, 0, 0};
Jean-Marc Valina2482ac2008-01-11 11:24:22 +110071const int qpulses2[NBANDS] = {28,25,23,20,18,15, 13, 11, 10, 8,8, 7, 7, -6, -5, -4, -1, -1};
72//const int qpulses2[NBANDS128] = {28,24,20,16,24,20, 18, 12, 10, 10,-7, -4, 1, 1, 1, 1, 1, 1};
Jean-Marc Valin36d78e62007-12-13 14:59:30 +110073const int qpulses2s[NBANDS128] ={38,30,24,20,24,20, 18, 16, 14, 20,-20,-14, -8, -8, -5};
74
Jean-Marc Valina2482ac2008-01-11 11:24:22 +110075const int qpulses4s[NBANDS] ={38,31,25,21,18,16, 14, 12, 14, 12,14,15, 14, 15, 16, 12, 10, 6};
Jean-Marc Valinf8dda662008-01-10 17:02:36 +110076
77//const int qpulses4s[NBANDS128] ={38,35,30,27,24,22, 21, 20, 22, 20,20,20, 20, 20, 14, 12, 12, 12};
78
Jean-Marc Valin2875f6b2008-01-05 13:32:32 +110079const int pbank1[PBANDS128+2] = {0, 2, 4, 6, 8, 12, 20, 28, PITCH_END128, 128};
80//const int pbank1[PBANDS128+2] = {0, 4, 8, 12, 20, PITCH_END128, 128};
Jean-Marc Valin36d78e62007-12-13 14:59:30 +110081
Jean-Marc Valin4fbd18d2008-01-17 14:07:55 +110082#define NALLOCS 7
83int bitalloc0[NBANDS*NALLOCS] =
84 { 5, 4, 4, 4, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0,
85 8, 7, 7, 6, 6, 6, 5, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
86 10, 9, 9, 8, 8, 8, 8, 8, 8, 8, 9, 10, 11, 12, 17, 15, 6, 7,
87 16, 15, 14, 14, 14, 13, 13, 13, 13, 13, 15, 16, 17, 18, 20, 18, 11, 12,
88 26, 25, 24, 22, 20, 18, 19, 19, 25, 22, 25, 30, 30, 35, 35, 35, 35, 25,
89 32, 30, 28, 27, 25, 24, 23, 21, 29, 27, 35, 40, 42, 50, 59, 54, 51, 36,
90 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 +110091};
Jean-Marc Valina5431bf2008-01-03 20:53:01 +110092
Jean-Marc Valin4fbd18d2008-01-17 14:07:55 +110093
Jean-Marc Valina5431bf2008-01-03 20:53:01 +110094#define NBANDS256 15
Jean-Marc Valin2875f6b2008-01-05 13:32:32 +110095#define PBANDS256 8
96#define PITCH_END256 88
Jean-Marc Valina4833ff2008-01-10 15:34:00 +110097const 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 +110098//const int pbank3[PBANDS256+2] = {0, 8, 16, 24, 40, PITCH_END256, 256};
Jean-Marc Valina4833ff2008-01-10 15:34:00 +110099const int pbank3[PBANDS256+2] = {0, 4, 8, 12, 16, 24, 40, 56, PITCH_END256, 256};
Jean-Marc Valin36d78e62007-12-13 14:59:30 +1100100
Jean-Marc Valin3cfcd052008-01-18 13:56:08 +1100101static const CELTMode mono_mode = {
Jean-Marc Valina5431bf2008-01-03 20:53:01 +1100102 128, /**< overlap */
Jean-Marc Valin95c59ea2008-01-08 16:22:37 +1100103 256, /**< mdctSize */
104 1, /**< nbMdctBlocks */
Jean-Marc Valin36d78e62007-12-13 14:59:30 +1100105 1, /**< channels */
106
107 NBANDS, /**< nbEBands */
108 PBANDS, /**< nbPBands */
109 PITCH_END, /**< pitchEnd */
110
111 qbank0, /**< eBands */
112 pbank0, /**< pBands*/
113 qpulses0, /**< nbPulses */
114
115 0.8, /**< ePredCoef */
116 means18, /**< eMeans */
117 decay18, /**< eDecay */
Jean-Marc Valinf51ca492008-01-17 10:58:38 +1100118
Jean-Marc Valin3cfcd052008-01-18 13:56:08 +1100119 NALLOCS, /**< nbAllocVectors */
Jean-Marc Valinf51ca492008-01-17 10:58:38 +1100120 bitalloc0, /**< allocVectors */
Jean-Marc Valin36d78e62007-12-13 14:59:30 +1100121};
122
Jean-Marc Valinaa5bd612007-12-08 00:27:10 +1100123
Jean-Marc Valin4a897682007-12-12 00:45:15 +1100124/* Stereo mode around 120 kbps */
Jean-Marc Valin3cfcd052008-01-18 13:56:08 +1100125static const CELTMode stereo_mode = {
126 128, /**< overlap */
Jean-Marc Valinfdca84b2008-01-09 10:44:18 +1100127 256, /**< mdctSize */
128 1, /**< nbMdctBlocks */
Jean-Marc Valinffa13472007-12-10 16:54:17 +1100129 2, /**< channels */
130
Jean-Marc Valin3cfcd052008-01-18 13:56:08 +1100131 NBANDS, /**< nbEBands */
132 PBANDS, /**< nbPBands */
133 PITCH_END, /**< pitchEnd */
Jean-Marc Valinffa13472007-12-10 16:54:17 +1100134
Jean-Marc Valinf8dda662008-01-10 17:02:36 +1100135 qbank0, /**< eBands */
136 pbank0, /**< pBands*/
137 qpulses4s, /**< nbPulses */
Jean-Marc Valin36d78e62007-12-13 14:59:30 +1100138
Jean-Marc Valinf8dda662008-01-10 17:02:36 +1100139 0.8, /**< ePredCoef */
Jean-Marc Valin3cfcd052008-01-18 13:56:08 +1100140 means18, /**< eMeans */
141 decay18, /**< eDecay */
Jean-Marc Valinf51ca492008-01-17 10:58:38 +1100142
Jean-Marc Valin3cfcd052008-01-18 13:56:08 +1100143 NALLOCS, /**< nbAllocVectors */
Jean-Marc Valinf51ca492008-01-17 10:58:38 +1100144 bitalloc0, /**< allocVectors */
Jean-Marc Valinffa13472007-12-10 16:54:17 +1100145};
146
Jean-Marc Valin3cfcd052008-01-18 13:56:08 +1100147const CELTMode const *celt_mono = &mono_mode;
148const CELTMode const *celt_stereo = &stereo_mode;
Jean-Marc Valinf997ad52008-01-31 16:47:16 +1100149
150
Jean-Marc Valin6da36c02008-02-15 14:20:29 +1100151#define NBANDS51 17
152#define PBANDS51 8
153#define PITCH_END51 64
154const int qbank51[NBANDS51 +2] = {0, 4, 8, 12, 16, 20, 24, 28, 32, 38, 44, 52, 64, 78, 96,122,156,204, 256};
155const int qbank51b[NBANDS +2] = {0, 3, 6, 9, 12, 16, 20, 24, 28, 32, 38, 44, 52, 64, 78, 96,122,156,204, 256};
156
157const int pbank51[PBANDS51 +2] = {0, 4, 8, 12, 16, 24, 32, 44, PITCH_END51, 256};
158const int pbank51b[PBANDS +2] = {0, 3, 6, 9, 12, 20, 38, 52, PITCH_END51, 256};
159#define NALLOCS51 10
160int bitalloc51[NBANDS51*NALLOCS51] =
161 { 6, 5, 3, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
162 7, 6, 5, 4, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0,
163 8, 7, 6, 5, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0,
164 9, 8, 7, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0,
165 10, 9, 8, 8, 7, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0,
166 10, 9, 9, 8, 8, 8, 8, 8, 8, 8, 9, 10, 11, 10, 10, 5, 5,
167 16, 15, 14, 14, 14, 13, 13, 13, 13, 13, 15, 16, 17, 18, 20, 18, 11,
168 26, 25, 24, 22, 20, 18, 19, 19, 25, 22, 25, 30, 30, 35, 35, 35, 35,
169 32, 30, 28, 27, 25, 24, 23, 21, 29, 27, 35, 40, 42, 50, 59, 54, 51,
170 42, 40, 38, 37, 35, 34, 33, 31, 39, 37, 45, 50, 52, 60, 60, 60, 60,
171 };
172
173static const CELTMode ld51 = {
174 128, /**< overlap */
175 256, /**< mdctSize */
176 1, /**< nbMdctBlocks */
177 1, /**< channels */
178
179 NBANDS51, /**< nbEBands */
180 PBANDS51, /**< nbPBands */
181 PITCH_END51, /**< pitchEnd */
182
183 qbank51, /**< eBands */
184 pbank51, /**< pBands*/
185 0, /**< nbPulses */
186
187 0.8, /**< ePredCoef */
188 means18, /**< eMeans */
189 decay18, /**< eDecay */
190
191 NALLOCS51, /**< nbAllocVectors */
192 bitalloc51, /**< allocVectors */
193};
194const CELTMode const *celt_ld51 = &ld51;
195
Jean-Marc Valinf997ad52008-01-31 16:47:16 +1100196int celt_mode_info(const CELTMode *mode, int request, celt_int32_t *value)
197{
198 switch (request)
199 {
200 case CELT_GET_FRAME_SIZE:
201 *value = mode->mdctSize;
202 break;
203 case CELT_GET_LOOKAHEAD:
204 *value = mode->overlap;
205 break;
Jean-Marc Valin4c6bc882008-01-31 17:34:27 +1100206 case CELT_GET_NB_CHANNELS:
207 *value = mode->nbChannels;
208 break;
Jean-Marc Valincb7a2a32008-02-11 16:44:48 +1100209 default:
210 return CELT_BAD_ARG;
Jean-Marc Valinf997ad52008-01-31 16:47:16 +1100211 }
Jean-Marc Valincb7a2a32008-02-11 16:44:48 +1100212 return CELT_OK;
Jean-Marc Valinf997ad52008-01-31 16:47:16 +1100213}
214
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100215#define MIN_BINS 4
216#define BARK_BANDS 25
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100217const celt_int16_t bark_freq[BARK_BANDS+1] = {
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100218 0, 101, 200, 301, 405,
219 516, 635, 766, 912, 1077,
220 1263, 1476, 1720, 2003, 2333,
221 2721, 3184, 3742, 4428, 5285,
222 6376, 7791, 9662, 12181, 15624,
223 20397};
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100224
225const celt_int16_t pitch_freq[PBANDS+1] ={0, 345, 689, 1034, 1378, 2067, 3273, 5340, 6374};
226
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100227
228static int *compute_ebands(int Fs, int frame_size, int *nbEBands)
229{
230 int *eBands;
231 int i, res, min_width, lin, low, high;
232 res = (Fs+frame_size)/(2*frame_size);
233 min_width = MIN_BINS*res;
234 //printf ("min_width = %d\n", min_width);
235
236 /* Find where the linear part ends (i.e. where the spacing is more than min_width */
237 for (lin=0;lin<BARK_BANDS;lin++)
238 if (bark_freq[lin+1]-bark_freq[lin] >= min_width)
239 break;
240
241 //printf ("lin = %d (%d Hz)\n", lin, bark_freq[lin]);
242 low = ((bark_freq[lin]/res)+(MIN_BINS-1))/MIN_BINS;
243 high = BARK_BANDS-lin;
244 *nbEBands = low+high;
245 eBands = celt_alloc(sizeof(int)*(*nbEBands+2));
246
247 /* Linear spacing (min_width) */
248 for (i=0;i<low;i++)
249 eBands[i] = MIN_BINS*i;
250 /* Spacing follows critical bands */
251 for (i=0;i<high;i++)
252 eBands[i+low] = bark_freq[lin+i]/res;
253 /* Enforce the minimum spacing at the boundary */
254 for (i=0;i<*nbEBands;i++)
255 if (eBands[i] < MIN_BINS*i)
256 eBands[i] = MIN_BINS*i;
257 eBands[*nbEBands] = bark_freq[BARK_BANDS]/res;
258 eBands[*nbEBands+1] = frame_size;
259 if (eBands[*nbEBands] > eBands[*nbEBands+1])
260 eBands[*nbEBands] = eBands[*nbEBands+1];
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100261
262 /* FIXME: Remove last band if too small */
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100263 for (i=0;i<*nbEBands+2;i++)
264 printf("%d ", eBands[i]);
265 printf ("\n");
266 return eBands;
267}
268
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100269static void compute_pbands(CELTMode *mode, int res)
270{
271 int i;
272 int *pBands;
273 pBands=celt_alloc(sizeof(int)*(PBANDS+2));
274 mode->nbPBands = PBANDS;
275 for (i=0;i<PBANDS+1;i++)
276 {
277 pBands[i] = pitch_freq[i]/res;
278 if (pBands[i] < mode->eBands[i])
279 pBands[i] = mode->eBands[i];
280 }
281 pBands[PBANDS+1] = mode->eBands[mode->nbEBands+1];
282 for (i=0;i<mode->nbPBands+2;i++)
283 printf("%d ", pBands[i]);
284 printf ("\n");
285 mode->pBands = pBands;
286}
287
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100288CELTMode *celt_mode_create(int Fs, int channels, int frame_size, int overlap)
289{
290 int i, res, min_width, lin, low, high;
291 CELTMode *mode;
292
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100293 res = (Fs+frame_size)/(2*frame_size);
294
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100295 mode = celt_alloc(sizeof(CELTMode));
296 mode->overlap = overlap;
297 mode->mdctSize = frame_size;
298 mode->nbMdctBlocks = 1;
299 mode->nbChannels = channels;
300 mode->eBands = compute_ebands(Fs, frame_size, &mode->nbEBands);
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100301 compute_pbands(mode, res);
302
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100303 printf ("%d bands\n", mode->nbEBands);
304}
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100305
306/*int main()
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100307{
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100308 celt_mode_create(44100, 1, 256, 128);
309}*/
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100310