blob: 60aa2bd56239c19850512efc3a53ee177df9375c [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 Valin472a5f02008-02-19 13:12:32 +110034#include "rate.h"
Jean-Marc Valin81a82952008-02-17 22:41:29 +110035#include "os_support.h"
Jean-Marc Valinecb36a32007-12-05 01:31:49 +110036
Jean-Marc Valinf997ad52008-01-31 16:47:16 +110037int celt_mode_info(const CELTMode *mode, int request, celt_int32_t *value)
38{
39 switch (request)
40 {
41 case CELT_GET_FRAME_SIZE:
42 *value = mode->mdctSize;
43 break;
44 case CELT_GET_LOOKAHEAD:
45 *value = mode->overlap;
46 break;
Jean-Marc Valin4c6bc882008-01-31 17:34:27 +110047 case CELT_GET_NB_CHANNELS:
48 *value = mode->nbChannels;
49 break;
Jean-Marc Valincb7a2a32008-02-11 16:44:48 +110050 default:
51 return CELT_BAD_ARG;
Jean-Marc Valinf997ad52008-01-31 16:47:16 +110052 }
Jean-Marc Valincb7a2a32008-02-11 16:44:48 +110053 return CELT_OK;
Jean-Marc Valinf997ad52008-01-31 16:47:16 +110054}
55
Jean-Marc Valin134492a2008-02-18 16:46:22 +110056#define PBANDS 8
Jean-Marc Valin81a82952008-02-17 22:41:29 +110057#define MIN_BINS 4
Jean-Marc Valin17683eb2008-02-18 21:45:19 +110058/* Defining 25 critical bands for the full 0-20 kHz audio bandwidth
59 Taken from http://ccrma.stanford.edu/~jos/bbt/Bark_Frequency_Scale.html */
Jean-Marc Valin81a82952008-02-17 22:41:29 +110060#define BARK_BANDS 25
Jean-Marc Valin25358cd2008-02-19 12:21:32 +110061static const celt_int16_t bark_freq[BARK_BANDS+1] = {
Jean-Marc Valin17683eb2008-02-18 21:45:19 +110062 0, 100, 200, 300, 400,
63 510, 630, 770, 920, 1080,
64 1270, 1480, 1720, 2000, 2320,
65 2700, 3150, 3700, 4400, 5300,
66 6400, 7700, 9500, 12000, 15500,
67 20000};
68
Jean-Marc Valin25358cd2008-02-19 12:21:32 +110069static 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 +110070
Jean-Marc Valin75e9c862008-02-18 17:04:15 +110071/* This allocation table is per critical band. When creating a mode, the bits get added together
72 into the codec bands, which are sometimes larger than one critical band at low frequency */
Jean-Marc Valin9838fec2008-02-18 14:45:11 +110073#define BITALLOC_SIZE 10
Jean-Marc Valin25358cd2008-02-19 12:21:32 +110074static const int band_allocation[BARK_BANDS*BITALLOC_SIZE] =
Jean-Marc Valin9838fec2008-02-18 14:45:11 +110075 { 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,
76 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,
77 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,
78 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,
79 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,
80 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,
81 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,
82 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,
83 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,
84 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,
85 };
86
Jean-Marc Valin81a82952008-02-17 22:41:29 +110087
88static int *compute_ebands(int Fs, int frame_size, int *nbEBands)
89{
90 int *eBands;
91 int i, res, min_width, lin, low, high;
92 res = (Fs+frame_size)/(2*frame_size);
93 min_width = MIN_BINS*res;
94 //printf ("min_width = %d\n", min_width);
95
96 /* Find where the linear part ends (i.e. where the spacing is more than min_width */
97 for (lin=0;lin<BARK_BANDS;lin++)
98 if (bark_freq[lin+1]-bark_freq[lin] >= min_width)
99 break;
100
101 //printf ("lin = %d (%d Hz)\n", lin, bark_freq[lin]);
102 low = ((bark_freq[lin]/res)+(MIN_BINS-1))/MIN_BINS;
103 high = BARK_BANDS-lin;
104 *nbEBands = low+high;
105 eBands = celt_alloc(sizeof(int)*(*nbEBands+2));
106
107 /* Linear spacing (min_width) */
108 for (i=0;i<low;i++)
109 eBands[i] = MIN_BINS*i;
110 /* Spacing follows critical bands */
111 for (i=0;i<high;i++)
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100112 eBands[i+low] = (bark_freq[lin+i]+res/2)/res;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100113 /* Enforce the minimum spacing at the boundary */
114 for (i=0;i<*nbEBands;i++)
115 if (eBands[i] < MIN_BINS*i)
116 eBands[i] = MIN_BINS*i;
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100117 eBands[*nbEBands] = (bark_freq[BARK_BANDS]+res/2)/res;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100118 eBands[*nbEBands+1] = frame_size;
119 if (eBands[*nbEBands] > eBands[*nbEBands+1])
120 eBands[*nbEBands] = eBands[*nbEBands+1];
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100121
122 /* FIXME: Remove last band if too small */
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100123 /*for (i=0;i<*nbEBands+2;i++)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100124 printf("%d ", eBands[i]);
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100125 printf ("\n");*/
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100126 return eBands;
127}
128
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100129static void compute_pbands(CELTMode *mode, int res)
130{
131 int i;
132 int *pBands;
133 pBands=celt_alloc(sizeof(int)*(PBANDS+2));
134 mode->nbPBands = PBANDS;
135 for (i=0;i<PBANDS+1;i++)
136 {
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100137 pBands[i] = (pitch_freq[i]+res/2)/res;
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100138 if (pBands[i] < mode->eBands[i])
139 pBands[i] = mode->eBands[i];
140 }
141 pBands[PBANDS+1] = mode->eBands[mode->nbEBands+1];
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100142 for (i=1;i<mode->nbPBands+1;i++)
143 {
144 int j;
145 for (j=0;j<mode->nbEBands;j++)
146 if (mode->eBands[j] <= pBands[i] && mode->eBands[j+1] > pBands[i])
147 break;
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100148 //printf ("%d %d\n", i, j);
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100149 if (mode->eBands[j] != pBands[i])
150 {
151 if (pBands[i]-mode->eBands[j] < mode->eBands[j+1]-pBands[i] &&
152 mode->eBands[j] != pBands[i-1])
153 pBands[i] = mode->eBands[j];
154 else
155 pBands[i] = mode->eBands[j+1];
156 }
157 }
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100158 /*for (i=0;i<mode->nbPBands+2;i++)
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100159 printf("%d ", pBands[i]);
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100160 printf ("\n");*/
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100161 mode->pBands = pBands;
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100162 mode->pitchEnd = pBands[PBANDS];
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100163}
164
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100165static void compute_allocation_table(CELTMode *mode, int res)
166{
167 int i, j, eband;
168 int *allocVectors;
169
170 mode->nbAllocVectors = BITALLOC_SIZE;
171 allocVectors = celt_alloc(sizeof(int)*(BITALLOC_SIZE*mode->nbEBands));
172 for (i=0;i<BITALLOC_SIZE;i++)
173 {
174 eband = 0;
175 for (j=0;j<BARK_BANDS;j++)
176 {
177 int edge, low;
178 edge = mode->eBands[eband+1]*res;
179 if (edge < bark_freq[j+1])
180 {
181 int num, den;
182 num = band_allocation[i*BARK_BANDS+j] * (edge-bark_freq[j]);
183 den = bark_freq[j+1]-bark_freq[j];
184 //low = band_allocation[i*BARK_BANDS+j] * (edge-bark_freq[j])/(bark_freq[j+1]-bark_freq[j]);
185 low = (num+den/2)/den;
186 allocVectors[i*mode->nbEBands+eband] += low;
187 eband++;
188 allocVectors[i*mode->nbEBands+eband] += band_allocation[i*BARK_BANDS+j]-low;
189 } else {
190 allocVectors[i*mode->nbEBands+eband] += band_allocation[i*BARK_BANDS+j];
191 }
192 }
193 }
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100194 /*for (i=0;i<BITALLOC_SIZE;i++)
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100195 {
196 for (j=0;j<mode->nbEBands;j++)
197 printf ("%2d ", allocVectors[i*mode->nbEBands+j]);
198 printf ("\n");
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100199 }*/
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100200 mode->allocVectors = allocVectors;
201}
202
Jean-Marc Valin25358cd2008-02-19 12:21:32 +1100203
204
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100205CELTMode *celt_mode_create(int Fs, int channels, int frame_size, int lookahead, int *error)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100206{
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100207 int res;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100208 CELTMode *mode;
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100209
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100210 /* The good thing here is that permutation of the arguments will automatically be invalid */
211
212 if (Fs < 32000 || Fs > 64000)
213 {
214 celt_warning("Sampling rate must be between 32 kHz and 64 kHz");
215 if (error)
216 *error = CELT_BAD_ARG;
217 return NULL;
218 }
219 if (channels < 0 || channels > 2)
220 {
221 celt_warning("Only mono and stereo supported");
222 if (error)
223 *error = CELT_BAD_ARG;
224 return NULL;
225 }
226 if (frame_size < 64 || frame_size > 256 || frame_size%2!=0)
227 {
228 celt_warning("Only even frame sizes between 64 and 256 are supported");
229 if (error)
230 *error = CELT_BAD_ARG;
231 return NULL;
232 }
233 if (lookahead < 32 || lookahead > frame_size)
234 {
235 celt_warning("The overlap must be between 32 and the frame size");
236 if (error)
237 *error = CELT_BAD_ARG;
238 return NULL;
239 }
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100240 res = (Fs+frame_size)/(2*frame_size);
241
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100242 mode = celt_alloc(sizeof(CELTMode));
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100243 mode->overlap = lookahead;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100244 mode->mdctSize = frame_size;
245 mode->nbMdctBlocks = 1;
246 mode->nbChannels = channels;
247 mode->eBands = compute_ebands(Fs, frame_size, &mode->nbEBands);
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100248 compute_pbands(mode, res);
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100249 mode->ePredCoef = .8;
250
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100251 compute_allocation_table(mode, res);
Jean-Marc Valin25358cd2008-02-19 12:21:32 +1100252 compute_alloc_cache(mode);
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100253 //printf ("%d bands\n", mode->nbEBands);
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100254 return mode;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100255}
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100256
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100257void celt_mode_destroy(CELTMode *mode)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100258{
Jean-Marc Valin25358cd2008-02-19 12:21:32 +1100259 int i;
260 const int *prevPtr = NULL;
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100261 celt_free((int*)mode->eBands);
262 celt_free((int*)mode->pBands);
263 celt_free((int*)mode->allocVectors);
Jean-Marc Valin25358cd2008-02-19 12:21:32 +1100264
265 for (i=0;i<mode->nbEBands;i++)
266 {
267 if (mode->bits[i] != prevPtr)
268 {
269 prevPtr = mode->bits[i];
270 celt_free((int*)mode->bits[i]);
271 }
272 }
273 celt_free((int**)mode->bits);
274
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100275 celt_free((CELTMode *)mode);
Jean-Marc Valin25358cd2008-02-19 12:21:32 +1100276
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100277}