blob: 48c9e007852511cc73b7d524953962cbb85dea97 [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 Valin95c59ea2008-01-08 16:22:37 +110043const int qbank0[NBANDS +2] = {0, 4, 8, 12, 16, 20, 24, 28, 32, 38, 44, 52, 62, 74, 90,112,142,182, 232,256};
44const int pbank0[PBANDS +2] = {0, 4, 8, 12, 16, 24, 38, 62, PITCH_END, 256};
Jean-Marc Valin36d78e62007-12-13 14:59:30 +110045
Jean-Marc Valin4fbd18d2008-01-17 14:07:55 +110046#define NALLOCS 7
47int bitalloc0[NBANDS*NALLOCS] =
48 { 5, 4, 4, 4, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0,
49 8, 7, 7, 6, 6, 6, 5, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
50 10, 9, 9, 8, 8, 8, 8, 8, 8, 8, 9, 10, 11, 12, 17, 15, 6, 7,
51 16, 15, 14, 14, 14, 13, 13, 13, 13, 13, 15, 16, 17, 18, 20, 18, 11, 12,
52 26, 25, 24, 22, 20, 18, 19, 19, 25, 22, 25, 30, 30, 35, 35, 35, 35, 25,
53 32, 30, 28, 27, 25, 24, 23, 21, 29, 27, 35, 40, 42, 50, 59, 54, 51, 36,
54 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 +110055};
Jean-Marc Valina5431bf2008-01-03 20:53:01 +110056
Jean-Marc Valin4fbd18d2008-01-17 14:07:55 +110057
Jean-Marc Valina5431bf2008-01-03 20:53:01 +110058#define NBANDS256 15
Jean-Marc Valin2875f6b2008-01-05 13:32:32 +110059#define PBANDS256 8
60#define PITCH_END256 88
Jean-Marc Valina4833ff2008-01-10 15:34:00 +110061const 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 +110062//const int pbank3[PBANDS256+2] = {0, 8, 16, 24, 40, PITCH_END256, 256};
Jean-Marc Valina4833ff2008-01-10 15:34:00 +110063const int pbank3[PBANDS256+2] = {0, 4, 8, 12, 16, 24, 40, 56, PITCH_END256, 256};
Jean-Marc Valin36d78e62007-12-13 14:59:30 +110064
Jean-Marc Valin3cfcd052008-01-18 13:56:08 +110065static const CELTMode mono_mode = {
Jean-Marc Valina5431bf2008-01-03 20:53:01 +110066 128, /**< overlap */
Jean-Marc Valin95c59ea2008-01-08 16:22:37 +110067 256, /**< mdctSize */
68 1, /**< nbMdctBlocks */
Jean-Marc Valin36d78e62007-12-13 14:59:30 +110069 1, /**< channels */
70
71 NBANDS, /**< nbEBands */
72 PBANDS, /**< nbPBands */
73 PITCH_END, /**< pitchEnd */
74
75 qbank0, /**< eBands */
76 pbank0, /**< pBands*/
Jean-Marc Valin36d78e62007-12-13 14:59:30 +110077
78 0.8, /**< ePredCoef */
Jean-Marc Valinf51ca492008-01-17 10:58:38 +110079
Jean-Marc Valin3cfcd052008-01-18 13:56:08 +110080 NALLOCS, /**< nbAllocVectors */
Jean-Marc Valinf51ca492008-01-17 10:58:38 +110081 bitalloc0, /**< allocVectors */
Jean-Marc Valin36d78e62007-12-13 14:59:30 +110082};
83
Jean-Marc Valinaa5bd612007-12-08 00:27:10 +110084
Jean-Marc Valin4a897682007-12-12 00:45:15 +110085/* Stereo mode around 120 kbps */
Jean-Marc Valin3cfcd052008-01-18 13:56:08 +110086static const CELTMode stereo_mode = {
87 128, /**< overlap */
Jean-Marc Valinfdca84b2008-01-09 10:44:18 +110088 256, /**< mdctSize */
89 1, /**< nbMdctBlocks */
Jean-Marc Valinffa13472007-12-10 16:54:17 +110090 2, /**< channels */
91
Jean-Marc Valin3cfcd052008-01-18 13:56:08 +110092 NBANDS, /**< nbEBands */
93 PBANDS, /**< nbPBands */
94 PITCH_END, /**< pitchEnd */
Jean-Marc Valinffa13472007-12-10 16:54:17 +110095
Jean-Marc Valinf8dda662008-01-10 17:02:36 +110096 qbank0, /**< eBands */
97 pbank0, /**< pBands*/
Jean-Marc Valin36d78e62007-12-13 14:59:30 +110098
Jean-Marc Valinf8dda662008-01-10 17:02:36 +110099 0.8, /**< ePredCoef */
Jean-Marc Valinf51ca492008-01-17 10:58:38 +1100100
Jean-Marc Valin3cfcd052008-01-18 13:56:08 +1100101 NALLOCS, /**< nbAllocVectors */
Jean-Marc Valinf51ca492008-01-17 10:58:38 +1100102 bitalloc0, /**< allocVectors */
Jean-Marc Valinffa13472007-12-10 16:54:17 +1100103};
104
Jean-Marc Valin3cfcd052008-01-18 13:56:08 +1100105const CELTMode const *celt_mono = &mono_mode;
106const CELTMode const *celt_stereo = &stereo_mode;
Jean-Marc Valinf997ad52008-01-31 16:47:16 +1100107
108
Jean-Marc Valin6da36c02008-02-15 14:20:29 +1100109#define NBANDS51 17
110#define PBANDS51 8
111#define PITCH_END51 64
112const int qbank51[NBANDS51 +2] = {0, 4, 8, 12, 16, 20, 24, 28, 32, 38, 44, 52, 64, 78, 96,122,156,204, 256};
113const int qbank51b[NBANDS +2] = {0, 3, 6, 9, 12, 16, 20, 24, 28, 32, 38, 44, 52, 64, 78, 96,122,156,204, 256};
114
115const int pbank51[PBANDS51 +2] = {0, 4, 8, 12, 16, 24, 32, 44, PITCH_END51, 256};
116const int pbank51b[PBANDS +2] = {0, 3, 6, 9, 12, 20, 38, 52, PITCH_END51, 256};
117#define NALLOCS51 10
118int bitalloc51[NBANDS51*NALLOCS51] =
119 { 6, 5, 3, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
120 7, 6, 5, 4, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0,
121 8, 7, 6, 5, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0,
122 9, 8, 7, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0,
123 10, 9, 8, 8, 7, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0,
124 10, 9, 9, 8, 8, 8, 8, 8, 8, 8, 9, 10, 11, 10, 10, 5, 5,
125 16, 15, 14, 14, 14, 13, 13, 13, 13, 13, 15, 16, 17, 18, 20, 18, 11,
126 26, 25, 24, 22, 20, 18, 19, 19, 25, 22, 25, 30, 30, 35, 35, 35, 35,
127 32, 30, 28, 27, 25, 24, 23, 21, 29, 27, 35, 40, 42, 50, 59, 54, 51,
128 42, 40, 38, 37, 35, 34, 33, 31, 39, 37, 45, 50, 52, 60, 60, 60, 60,
129 };
130
131static const CELTMode ld51 = {
132 128, /**< overlap */
133 256, /**< mdctSize */
134 1, /**< nbMdctBlocks */
135 1, /**< channels */
136
137 NBANDS51, /**< nbEBands */
138 PBANDS51, /**< nbPBands */
139 PITCH_END51, /**< pitchEnd */
140
141 qbank51, /**< eBands */
142 pbank51, /**< pBands*/
Jean-Marc Valin6da36c02008-02-15 14:20:29 +1100143
144 0.8, /**< ePredCoef */
Jean-Marc Valin6da36c02008-02-15 14:20:29 +1100145
146 NALLOCS51, /**< nbAllocVectors */
147 bitalloc51, /**< allocVectors */
148};
149const CELTMode const *celt_ld51 = &ld51;
150
Jean-Marc Valinf997ad52008-01-31 16:47:16 +1100151int celt_mode_info(const CELTMode *mode, int request, celt_int32_t *value)
152{
153 switch (request)
154 {
155 case CELT_GET_FRAME_SIZE:
156 *value = mode->mdctSize;
157 break;
158 case CELT_GET_LOOKAHEAD:
159 *value = mode->overlap;
160 break;
Jean-Marc Valin4c6bc882008-01-31 17:34:27 +1100161 case CELT_GET_NB_CHANNELS:
162 *value = mode->nbChannels;
163 break;
Jean-Marc Valincb7a2a32008-02-11 16:44:48 +1100164 default:
165 return CELT_BAD_ARG;
Jean-Marc Valinf997ad52008-01-31 16:47:16 +1100166 }
Jean-Marc Valincb7a2a32008-02-11 16:44:48 +1100167 return CELT_OK;
Jean-Marc Valinf997ad52008-01-31 16:47:16 +1100168}
169
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100170#define MIN_BINS 4
171#define BARK_BANDS 25
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100172const celt_int16_t bark_freq[BARK_BANDS+1] = {
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100173 0, 101, 200, 301, 405,
174 516, 635, 766, 912, 1077,
175 1263, 1476, 1720, 2003, 2333,
176 2721, 3184, 3742, 4428, 5285,
177 6376, 7791, 9662, 12181, 15624,
178 20397};
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100179
180const celt_int16_t pitch_freq[PBANDS+1] ={0, 345, 689, 1034, 1378, 2067, 3273, 5340, 6374};
181
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100182
183static int *compute_ebands(int Fs, int frame_size, int *nbEBands)
184{
185 int *eBands;
186 int i, res, min_width, lin, low, high;
187 res = (Fs+frame_size)/(2*frame_size);
188 min_width = MIN_BINS*res;
189 //printf ("min_width = %d\n", min_width);
190
191 /* Find where the linear part ends (i.e. where the spacing is more than min_width */
192 for (lin=0;lin<BARK_BANDS;lin++)
193 if (bark_freq[lin+1]-bark_freq[lin] >= min_width)
194 break;
195
196 //printf ("lin = %d (%d Hz)\n", lin, bark_freq[lin]);
197 low = ((bark_freq[lin]/res)+(MIN_BINS-1))/MIN_BINS;
198 high = BARK_BANDS-lin;
199 *nbEBands = low+high;
200 eBands = celt_alloc(sizeof(int)*(*nbEBands+2));
201
202 /* Linear spacing (min_width) */
203 for (i=0;i<low;i++)
204 eBands[i] = MIN_BINS*i;
205 /* Spacing follows critical bands */
206 for (i=0;i<high;i++)
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100207 eBands[i+low] = (bark_freq[lin+i]+res/2)/res;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100208 /* Enforce the minimum spacing at the boundary */
209 for (i=0;i<*nbEBands;i++)
210 if (eBands[i] < MIN_BINS*i)
211 eBands[i] = MIN_BINS*i;
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100212 eBands[*nbEBands] = (bark_freq[BARK_BANDS]+res/2)/res;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100213 eBands[*nbEBands+1] = frame_size;
214 if (eBands[*nbEBands] > eBands[*nbEBands+1])
215 eBands[*nbEBands] = eBands[*nbEBands+1];
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100216
217 /* FIXME: Remove last band if too small */
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100218 for (i=0;i<*nbEBands+2;i++)
219 printf("%d ", eBands[i]);
220 printf ("\n");
221 return eBands;
222}
223
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100224static void compute_pbands(CELTMode *mode, int res)
225{
226 int i;
227 int *pBands;
228 pBands=celt_alloc(sizeof(int)*(PBANDS+2));
229 mode->nbPBands = PBANDS;
230 for (i=0;i<PBANDS+1;i++)
231 {
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100232 pBands[i] = (pitch_freq[i]+res/2)/res;
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100233 if (pBands[i] < mode->eBands[i])
234 pBands[i] = mode->eBands[i];
235 }
236 pBands[PBANDS+1] = mode->eBands[mode->nbEBands+1];
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100237 for (i=1;i<mode->nbPBands+1;i++)
238 {
239 int j;
240 for (j=0;j<mode->nbEBands;j++)
241 if (mode->eBands[j] <= pBands[i] && mode->eBands[j+1] > pBands[i])
242 break;
243 printf ("%d %d\n", i, j);
244 if (mode->eBands[j] != pBands[i])
245 {
246 if (pBands[i]-mode->eBands[j] < mode->eBands[j+1]-pBands[i] &&
247 mode->eBands[j] != pBands[i-1])
248 pBands[i] = mode->eBands[j];
249 else
250 pBands[i] = mode->eBands[j+1];
251 }
252 }
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100253 for (i=0;i<mode->nbPBands+2;i++)
254 printf("%d ", pBands[i]);
255 printf ("\n");
256 mode->pBands = pBands;
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100257 mode->pitchEnd = pBands[PBANDS];
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100258}
259
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100260CELTMode *celt_mode_create(int Fs, int channels, int frame_size, int overlap)
261{
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100262 int res;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100263 CELTMode *mode;
264
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100265 res = (Fs+frame_size)/(2*frame_size);
266
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100267 mode = celt_alloc(sizeof(CELTMode));
268 mode->overlap = overlap;
269 mode->mdctSize = frame_size;
270 mode->nbMdctBlocks = 1;
271 mode->nbChannels = channels;
272 mode->eBands = compute_ebands(Fs, frame_size, &mode->nbEBands);
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100273 compute_pbands(mode, res);
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100274 mode->ePredCoef = .8;
275
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100276
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100277 printf ("%d bands\n", mode->nbEBands);
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100278 return mode;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100279}
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100280
281/*int main()
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100282{
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100283 celt_mode_create(44100, 1, 256, 128);
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100284 return 0;
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100285}*/
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100286