blob: 3b64dd68a4532e2a5667f574261d0996b5d6416d [file] [log] [blame]
Jean-Marc Valin8b2ff0d2009-10-17 21:40:10 -04001/* Copyright (c) 2007-2008 CSIRO
2 Copyright (c) 2007-2009 Xiph.Org Foundation
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04003 Copyright (c) 2008 Gregory Maxwell
Jean-Marc Valin8b2ff0d2009-10-17 21:40:10 -04004 Written by Jean-Marc Valin and Gregory Maxwell */
Jean-Marc Valinecb36a32007-12-05 01:31:49 +11005/*
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
8 are met:
Gregory Maxwell71d39ad2011-07-30 00:00:29 -04009
Jean-Marc Valinecb36a32007-12-05 01:31:49 +110010 - Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
Gregory Maxwell71d39ad2011-07-30 00:00:29 -040012
Jean-Marc Valinecb36a32007-12-05 01:31:49 +110013 - Redistributions in binary form must reproduce the above copyright
14 notice, this list of conditions and the following disclaimer in the
15 documentation and/or other materials provided with the distribution.
Gregory Maxwell71d39ad2011-07-30 00:00:29 -040016
Jean-Marc Valinecb36a32007-12-05 01:31:49 +110017 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
21 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*/
29
Jean-Marc Valin02fa9132008-02-20 12:09:29 +110030#ifdef HAVE_CONFIG_H
31#include "config.h"
32#endif
33
Jean-Marc Valin65d57e62008-02-18 15:49:37 +110034#include "celt.h"
Jean-Marc Valinecb36a32007-12-05 01:31:49 +110035#include "modes.h"
Jean-Marc Valin472a5f02008-02-19 13:12:32 +110036#include "rate.h"
Jean-Marc Valin81a82952008-02-17 22:41:29 +110037#include "os_support.h"
Jean-Marc Valinf7cec832008-04-18 17:29:56 +100038#include "stack_alloc.h"
Jean-Marc Valin4ce92052008-04-23 13:42:10 +100039#include "quant_bands.h"
Jean-Marc Valinecb36a32007-12-05 01:31:49 +110040
Jean-Marc Valind77d6a52011-07-29 17:33:06 -040041static const opus_int16 eband5ms[] = {
Jean-Marc Valin9cc56bf2011-02-01 22:03:26 -050042/*0 200 400 600 800 1k 1.2 1.4 1.6 2k 2.4 2.8 3.2 4k 4.8 5.6 6.8 8k 9.6 12k 15.6 */
Jean-Marc Valin8ccda882010-10-04 18:01:45 -040043 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 34, 40, 48, 60, 78, 100
Jean-Marc Valine0c25452010-09-03 11:52:38 -040044};
45
Jean-Marc Valin54d84c02010-11-19 11:45:37 -050046/* Alternate tuning (partially derived from Vorbis) */
Timothy B. Terriberryce6d0902011-02-01 17:41:12 -080047#define BITALLOC_SIZE 11
Jean-Marc Valin94491652010-10-21 17:10:24 -040048/* Bit allocation table in units of 1/32 bit/sample (0.1875 dB SNR) */
49static const unsigned char band_allocation[] = {
Jean-Marc Valin54d84c02010-11-19 11:45:37 -050050/*0 200 400 600 800 1k 1.2 1.4 1.6 2k 2.4 2.8 3.2 4k 4.8 5.6 6.8 8k 9.6 12k 15.6 */
Jean-Marc Valin94491652010-10-21 17:10:24 -040051 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
Jean-Marc Valinc992a0d2010-11-19 14:06:10 -050052 90, 80, 75, 69, 63, 56, 49, 40, 34, 29, 20, 18, 10, 0, 0, 0, 0, 0, 0, 0, 0,
Jean-Marc Valin54d84c02010-11-19 11:45:37 -050053110,100, 90, 84, 78, 71, 65, 58, 51, 45, 39, 32, 26, 20, 12, 0, 0, 0, 0, 0, 0,
Jean-Marc Valinc992a0d2010-11-19 14:06:10 -050054118,110,103, 93, 86, 80, 75, 70, 65, 59, 53, 47, 40, 31, 23, 15, 4, 0, 0, 0, 0,
55126,119,112,104, 95, 89, 83, 78, 72, 66, 60, 54, 47, 39, 32, 25, 17, 12, 1, 0, 0,
Jean-Marc Valin54d84c02010-11-19 11:45:37 -050056134,127,120,114,103, 97, 91, 85, 78, 72, 66, 60, 54, 47, 41, 35, 29, 23, 16, 10, 1,
Jean-Marc Valindd4bf632010-11-30 15:31:45 -050057144,137,130,124,113,107,101, 95, 88, 82, 76, 70, 64, 57, 51, 45, 39, 33, 26, 15, 1,
58152,145,138,132,123,117,111,105, 98, 92, 86, 80, 74, 67, 61, 55, 49, 43, 36, 20, 1,
59162,155,148,142,133,127,121,115,108,102, 96, 90, 84, 77, 71, 65, 59, 53, 46, 30, 1,
60172,165,158,152,143,137,131,125,118,112,106,100, 94, 87, 81, 75, 69, 63, 56, 45, 20,
Timothy B. Terriberry89039a32011-01-30 22:27:13 -080061200,200,200,200,200,200,200,200,198,193,188,183,178,173,168,163,158,153,148,129,104,
Jean-Marc Valin94491652010-10-21 17:10:24 -040062};
Jean-Marc Valin78ea9fd2010-09-24 08:27:28 -040063
Jean-Marc Valin665da0b2011-01-30 12:15:12 -050064#ifndef CUSTOM_MODES_ONLY
65 #ifdef FIXED_POINT
Gregory Maxwell63fd63d2011-08-02 17:13:06 -040066 #include "static_modes_fixed.h"
Jean-Marc Valin665da0b2011-01-30 12:15:12 -050067 #else
Gregory Maxwell63fd63d2011-08-02 17:13:06 -040068 #include "static_modes_float.h"
Jean-Marc Valin665da0b2011-01-30 12:15:12 -050069 #endif
70#endif /* CUSTOM_MODES_ONLY */
Jean-Marc Valinf39e8692008-03-10 12:13:23 +110071
Jean-Marc Valind748cd52008-03-01 07:27:03 +110072#ifndef M_PI
73#define M_PI 3.141592653
74#endif
75
Jean-Marc Valin5ad35bf2011-01-28 22:42:09 -050076#ifdef CUSTOM_MODES
Jean-Marc Valin5588d522008-03-10 15:07:58 +110077
Jean-Marc Valin17683eb2008-02-18 21:45:19 +110078/* Defining 25 critical bands for the full 0-20 kHz audio bandwidth
79 Taken from http://ccrma.stanford.edu/~jos/bbt/Bark_Frequency_Scale.html */
Jean-Marc Valin81a82952008-02-17 22:41:29 +110080#define BARK_BANDS 25
Jean-Marc Valind77d6a52011-07-29 17:33:06 -040081static const opus_int16 bark_freq[BARK_BANDS+1] = {
Jean-Marc Valin17683eb2008-02-18 21:45:19 +110082 0, 100, 200, 300, 400,
83 510, 630, 770, 920, 1080,
84 1270, 1480, 1720, 2000, 2320,
85 2700, 3150, 3700, 4400, 5300,
86 6400, 7700, 9500, 12000, 15500,
87 20000};
88
Jean-Marc Valind77d6a52011-07-29 17:33:06 -040089static opus_int16 *compute_ebands(opus_int32 Fs, int frame_size, int res, int *nbEBands)
Jean-Marc Valin81a82952008-02-17 22:41:29 +110090{
Jean-Marc Valind77d6a52011-07-29 17:33:06 -040091 opus_int16 *eBands;
Timothy B. Terriberrycb8f3662011-02-01 12:32:34 -080092 int i, j, lin, low, high, nBark, offset=0;
Jean-Marc Valin81a82952008-02-17 22:41:29 +110093
Jean-Marc Valin3b0df0d2010-07-16 15:55:30 -040094 /* All modes that have 2.5 ms short blocks use the same definition */
Jean-Marc Valind77d6a52011-07-29 17:33:06 -040095 if (Fs == 400*(opus_int32)frame_size)
Jean-Marc Valin20639c42010-05-19 16:10:12 -040096 {
97 *nbEBands = sizeof(eband5ms)/sizeof(eband5ms[0])-1;
Jean-Marc Valin07f88402011-08-29 15:08:51 -040098 eBands = opus_alloc(sizeof(opus_int16)*(*nbEBands+1));
Jean-Marc Valin8952c452010-07-16 21:48:44 -040099 for (i=0;i<*nbEBands+1;i++)
Jean-Marc Valin20639c42010-05-19 16:10:12 -0400100 eBands[i] = eband5ms[i];
Jean-Marc Valin20639c42010-05-19 16:10:12 -0400101 return eBands;
102 }
Gregory Maxwellcbaf67e2008-09-28 04:19:19 -0400103 /* Find the number of critical bands supported by our sampling rate */
104 for (nBark=1;nBark<BARK_BANDS;nBark++)
105 if (bark_freq[nBark+1]*2 >= Fs)
106 break;
107
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100108 /* Find where the linear part ends (i.e. where the spacing is more than min_width */
Gregory Maxwellcbaf67e2008-09-28 04:19:19 -0400109 for (lin=0;lin<nBark;lin++)
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400110 if (bark_freq[lin+1]-bark_freq[lin] >= res)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100111 break;
Jean-Marc Valin4fb95682010-04-20 23:30:22 -0400112
Jean-Marc Valin65ee67a2010-04-26 07:08:44 -0400113 low = (bark_freq[lin]+res/2)/res;
Gregory Maxwellcbaf67e2008-09-28 04:19:19 -0400114 high = nBark-lin;
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100115 *nbEBands = low+high;
Jean-Marc Valin07f88402011-08-29 15:08:51 -0400116 eBands = opus_alloc(sizeof(opus_int16)*(*nbEBands+2));
Gregory Maxwell71d39ad2011-07-30 00:00:29 -0400117
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400118 if (eBands==NULL)
119 return NULL;
Gregory Maxwell71d39ad2011-07-30 00:00:29 -0400120
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100121 /* Linear spacing (min_width) */
122 for (i=0;i<low;i++)
Jean-Marc Valin65ee67a2010-04-26 07:08:44 -0400123 eBands[i] = i;
Jean-Marc Valinbe8d1252010-04-21 18:09:07 -0400124 if (low>0)
125 offset = eBands[low-1]*res - bark_freq[lin-1];
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100126 /* Spacing follows critical bands */
127 for (i=0;i<high;i++)
Jean-Marc Valin39f68ac2009-10-03 23:27:52 -0400128 {
129 int target = bark_freq[lin+i];
Jean-Marc Valin44203902011-01-12 09:22:29 -0500130 /* Round to an even value */
131 eBands[i+low] = (target+offset/2+res)/(2*res)*2;
Jean-Marc Valin39f68ac2009-10-03 23:27:52 -0400132 offset = eBands[i+low]*res - target;
133 }
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100134 /* Enforce the minimum spacing at the boundary */
135 for (i=0;i<*nbEBands;i++)
Jean-Marc Valin65ee67a2010-04-26 07:08:44 -0400136 if (eBands[i] < i)
137 eBands[i] = i;
Jean-Marc Valin44203902011-01-12 09:22:29 -0500138 /* Round to an even value */
139 eBands[*nbEBands] = (bark_freq[nBark]+res)/(2*res)*2;
Jean-Marc Valin8952c452010-07-16 21:48:44 -0400140 if (eBands[*nbEBands] > frame_size)
141 eBands[*nbEBands] = frame_size;
Jean-Marc Valinfbfddf72009-07-19 21:07:12 -0400142 for (i=1;i<*nbEBands-1;i++)
143 {
144 if (eBands[i+1]-eBands[i] < eBands[i]-eBands[i-1])
145 {
Jean-Marc Valin65ee67a2010-04-26 07:08:44 -0400146 eBands[i] -= (2*eBands[i]-eBands[i-1]-eBands[i+1])/2;
Jean-Marc Valinfbfddf72009-07-19 21:07:12 -0400147 }
148 }
Timothy B. Terriberrycb8f3662011-02-01 12:32:34 -0800149 /* Remove any empty bands. */
150 for (i=j=0;i<*nbEBands;i++)
151 if(eBands[i+1]>eBands[j])
152 eBands[++j]=eBands[i+1];
153 *nbEBands=j;
154
Timothy B. Terriberry2799c292011-02-01 12:53:05 -0800155 for (i=1;i<*nbEBands;i++)
156 {
157 /* Every band must be smaller than the last band. */
158 celt_assert(eBands[i]-eBands[i-1]<=eBands[*nbEBands]-eBands[*nbEBands-1]);
159 /* Each band must be no larger than twice the size of the previous one. */
160 celt_assert(eBands[i+1]-eBands[i]<=2*(eBands[i]-eBands[i-1]));
161 }
162
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100163 return eBands;
164}
165
Jean-Marc Valine3e2c262011-01-26 13:09:53 -0500166static void compute_allocation_table(CELTMode *mode)
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100167{
Jean-Marc Valin2f6c5fe2010-06-28 17:22:37 -0400168 int i, j;
Jean-Marc Valin01b54b92010-06-03 23:29:35 -0400169 unsigned char *allocVectors;
Jean-Marc Valinc51e98b2010-06-03 22:11:41 -0400170 int maxBands = sizeof(eband5ms)/sizeof(eband5ms[0])-1;
Jean-Marc Valin36e6e012008-08-02 22:25:19 -0400171
Jean-Marc Valin12e851d2010-06-03 08:12:11 -0400172 mode->nbAllocVectors = BITALLOC_SIZE;
Jean-Marc Valin07f88402011-08-29 15:08:51 -0400173 allocVectors = opus_alloc(sizeof(unsigned char)*(BITALLOC_SIZE*mode->nbEBands));
Jean-Marc Valin12e851d2010-06-03 08:12:11 -0400174 if (allocVectors==NULL)
175 return;
176
Jean-Marc Valinc51e98b2010-06-03 22:11:41 -0400177 /* Check for standard mode */
Jean-Marc Valind77d6a52011-07-29 17:33:06 -0400178 if (mode->Fs == 400*(opus_int32)mode->shortMdctSize)
Jean-Marc Valin12e851d2010-06-03 08:12:11 -0400179 {
180 for (i=0;i<BITALLOC_SIZE*mode->nbEBands;i++)
Jean-Marc Valinffe50612010-06-04 00:13:19 -0400181 allocVectors[i] = band_allocation[i];
Jean-Marc Valin12e851d2010-06-03 08:12:11 -0400182 mode->allocVectors = allocVectors;
183 return;
184 }
Jean-Marc Valinc51e98b2010-06-03 22:11:41 -0400185 /* If not the standard mode, interpolate */
Jean-Marc Valin36e6e012008-08-02 22:25:19 -0400186 /* Compute per-codec-band allocation from per-critical-band matrix */
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100187 for (i=0;i<BITALLOC_SIZE;i++)
188 {
Jean-Marc Valin1bfa18c2010-12-01 16:11:38 -0500189 for (j=0;j<mode->nbEBands;j++)
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100190 {
Jean-Marc Valin1bfa18c2010-12-01 16:11:38 -0500191 int k;
192 for (k=0;k<maxBands;k++)
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100193 {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -0400194 if (400*(opus_int32)eband5ms[k] > mode->eBands[j]*(opus_int32)mode->Fs/mode->shortMdctSize)
Jean-Marc Valin1bfa18c2010-12-01 16:11:38 -0500195 break;
Jean-Marc Valin137f3362010-04-14 17:42:22 -0400196 }
Jean-Marc Valinfa74ae22011-02-11 21:56:11 -0500197 if (k>maxBands-1)
Jean-Marc Valin1bfa18c2010-12-01 16:11:38 -0500198 allocVectors[i*mode->nbEBands+j] = band_allocation[i*maxBands + maxBands-1];
199 else {
Jean-Marc Valind77d6a52011-07-29 17:33:06 -0400200 opus_int32 a0, a1;
201 a1 = mode->eBands[j]*(opus_int32)mode->Fs/mode->shortMdctSize - 400*(opus_int32)eband5ms[k-1];
202 a0 = 400*(opus_int32)eband5ms[k] - mode->eBands[j]*(opus_int32)mode->Fs/mode->shortMdctSize;
Jean-Marc Valin1bfa18c2010-12-01 16:11:38 -0500203 allocVectors[i*mode->nbEBands+j] = (a0*band_allocation[i*maxBands+k-1]
204 + a1*band_allocation[i*maxBands+k])/(a0+a1);
205 }
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400206 }
Jean-Marc Valin9838fec2008-02-18 14:45:11 +1100207 }
Jean-Marc Valin1bfa18c2010-12-01 16:11:38 -0500208
Jean-Marc Valinc51e98b2010-06-03 22:11:41 -0400209 /*printf ("\n");
210 for (i=0;i<BITALLOC_SIZE;i++)
Jean-Marc Valinbb8fa1f2010-06-03 00:33:42 -0400211 {
212 for (j=0;j<mode->nbEBands;j++)
213 printf ("%d ", allocVectors[i*mode->nbEBands+j]);
214 printf ("\n");
215 }
216 exit(0);*/
217
Jean-Marc Valin36e6e012008-08-02 22:25:19 -0400218 mode->allocVectors = allocVectors;
Jean-Marc Valinad637192008-05-07 13:44:39 +1000219}
220
Jean-Marc Valin5ad35bf2011-01-28 22:42:09 -0500221#endif /* CUSTOM_MODES */
Jean-Marc Valin36e6e012008-08-02 22:25:19 -0400222
Jean-Marc Valin06237d72011-09-01 13:20:40 -0400223CELTMode *opus_custom_mode_create(opus_int32 Fs, int frame_size, int *error)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100224{
Jean-Marc Valin47c248a2008-04-26 08:16:12 +1000225 int i;
Gregory Maxwell95becbe2011-02-03 21:06:43 -0500226#ifdef CUSTOM_MODES
Jean-Marc Valinff96b162011-03-21 11:32:50 -0400227 CELTMode *mode=NULL;
Gregory Maxwell95becbe2011-02-03 21:06:43 -0500228 int res;
Jean-Marc Valinff5f7222011-07-29 18:59:12 -0400229 opus_val16 *window;
Jean-Marc Valind77d6a52011-07-29 17:33:06 -0400230 opus_int16 *logN;
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400231 int LM;
Jean-Marc Valinf7cec832008-04-18 17:29:56 +1000232 ALLOC_STACK;
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400233#if !defined(VAR_ARRAYS) && !defined(USE_ALLOCA)
234 if (global_stack==NULL)
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400235 goto failure;
Gregory Maxwell71d39ad2011-07-30 00:00:29 -0400236#endif
Jean-Marc Valin7e983192011-02-01 18:00:29 -0500237#endif
Jean-Marc Valin3dbc1d02008-03-08 15:21:24 +1100238
Jean-Marc Valin665da0b2011-01-30 12:15:12 -0500239#ifndef CUSTOM_MODES_ONLY
Jean-Marc Valin5ad35bf2011-01-28 22:42:09 -0500240 for (i=0;i<TOTAL_MODES;i++)
241 {
Jean-Marc Valinc97b2582011-01-28 23:07:32 -0500242 int j;
243 for (j=0;j<4;j++)
Jean-Marc Valin5ad35bf2011-01-28 22:42:09 -0500244 {
Jean-Marc Valinc97b2582011-01-28 23:07:32 -0500245 if (Fs == static_mode_list[i]->Fs &&
246 (frame_size<<j) == static_mode_list[i]->shortMdctSize*static_mode_list[i]->nbShortMdcts)
247 {
248 if (error)
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -0400249 *error = OPUS_OK;
Jean-Marc Valinc97b2582011-01-28 23:07:32 -0500250 return (CELTMode*)static_mode_list[i];
251 }
Jean-Marc Valin5ad35bf2011-01-28 22:42:09 -0500252 }
253 }
Jean-Marc Valin665da0b2011-01-30 12:15:12 -0500254#endif /* CUSTOM_MODES_ONLY */
255
Jean-Marc Valin5ad35bf2011-01-28 22:42:09 -0500256#ifndef CUSTOM_MODES
257 if (error)
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -0400258 *error = OPUS_BAD_ARG;
Jean-Marc Valin5ad35bf2011-01-28 22:42:09 -0500259 return NULL;
260#else
261
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100262 /* The good thing here is that permutation of the arguments will automatically be invalid */
Gregory Maxwell71d39ad2011-07-30 00:00:29 -0400263
Jean-Marc Valin223b69d2010-07-16 11:47:50 -0400264 if (Fs < 8000 || Fs > 96000)
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100265 {
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100266 if (error)
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -0400267 *error = OPUS_BAD_ARG;
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100268 return NULL;
269 }
Jean-Marc Valin223b69d2010-07-16 11:47:50 -0400270 if (frame_size < 40 || frame_size > 1024 || frame_size%2!=0)
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100271 {
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100272 if (error)
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -0400273 *error = OPUS_BAD_ARG;
Jean-Marc Valin75e9c862008-02-18 17:04:15 +1100274 return NULL;
275 }
Timothy B. Terriberryaa6fec62011-02-01 15:36:59 -0800276 /* Frames of less than 1ms are not supported. */
Jean-Marc Valind77d6a52011-07-29 17:33:06 -0400277 if ((opus_int32)frame_size*1000 < Fs)
Timothy B. Terriberryaa6fec62011-02-01 15:36:59 -0800278 {
279 if (error)
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -0400280 *error = OPUS_BAD_ARG;
Timothy B. Terriberryaa6fec62011-02-01 15:36:59 -0800281 return NULL;
282 }
283
Jean-Marc Valind77d6a52011-07-29 17:33:06 -0400284 if ((opus_int32)frame_size*75 >= Fs && (frame_size%16)==0)
Timothy B. Terriberryaa6fec62011-02-01 15:36:59 -0800285 {
286 LM = 3;
Jean-Marc Valind77d6a52011-07-29 17:33:06 -0400287 } else if ((opus_int32)frame_size*150 >= Fs && (frame_size%8)==0)
Timothy B. Terriberryaa6fec62011-02-01 15:36:59 -0800288 {
289 LM = 2;
Jean-Marc Valind77d6a52011-07-29 17:33:06 -0400290 } else if ((opus_int32)frame_size*300 >= Fs && (frame_size%4)==0)
Timothy B. Terriberryaa6fec62011-02-01 15:36:59 -0800291 {
292 LM = 1;
Timothy B. Terriberrycf5d3a82011-02-02 11:42:33 -0800293 } else
Timothy B. Terriberryaa6fec62011-02-01 15:36:59 -0800294 {
295 LM = 0;
296 }
Timothy B. Terriberrycf5d3a82011-02-02 11:42:33 -0800297
Timothy B. Terriberryaa6fec62011-02-01 15:36:59 -0800298 /* Shorts longer than 3.3ms are not supported. */
Jean-Marc Valind77d6a52011-07-29 17:33:06 -0400299 if ((opus_int32)(frame_size>>LM)*300 > Fs)
Timothy B. Terriberryaa6fec62011-02-01 15:36:59 -0800300 {
301 if (error)
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -0400302 *error = OPUS_BAD_ARG;
Timothy B. Terriberryaa6fec62011-02-01 15:36:59 -0800303 return NULL;
304 }
305
Jean-Marc Valin07f88402011-08-29 15:08:51 -0400306 mode = opus_alloc(sizeof(CELTMode));
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400307 if (mode==NULL)
308 goto failure;
Jean-Marc Valine6b74652008-02-20 18:01:08 +1100309 mode->Fs = Fs;
Gregory Maxwell23e654f2008-09-27 16:20:03 -0400310
Jean-Marc Valin223b69d2010-07-16 11:47:50 -0400311 /* Pre/de-emphasis depends on sampling rate. The "standard" pre-emphasis
312 is defined as A(z) = 1 - 0.85*z^-1 at 48 kHz. Other rates should
313 approximate that. */
314 if(Fs < 12000) /* 8 kHz */
315 {
Jean-Marc Valin49f76802011-01-27 17:01:59 -0500316 mode->preemph[0] = QCONST16(0.3500061035f, 15);
317 mode->preemph[1] = -QCONST16(0.1799926758f, 15);
Jean-Marc Valin09213de2011-01-27 21:43:24 -0500318 mode->preemph[2] = QCONST16(0.2719968125f, SIG_SHIFT); /* exact 1/preemph[3] */
Jean-Marc Valin49f76802011-01-27 17:01:59 -0500319 mode->preemph[3] = QCONST16(3.6765136719f, 13);
Jean-Marc Valin223b69d2010-07-16 11:47:50 -0400320 } else if(Fs < 24000) /* 16 kHz */
321 {
Jean-Marc Valin49f76802011-01-27 17:01:59 -0500322 mode->preemph[0] = QCONST16(0.6000061035f, 15);
323 mode->preemph[1] = -QCONST16(0.1799926758f, 15);
Jean-Marc Valin09213de2011-01-27 21:43:24 -0500324 mode->preemph[2] = QCONST16(0.4424998650f, SIG_SHIFT); /* exact 1/preemph[3] */
325 mode->preemph[3] = QCONST16(2.2598876953f, 13);
Jean-Marc Valin223b69d2010-07-16 11:47:50 -0400326 } else if(Fs < 40000) /* 32 kHz */
327 {
Jean-Marc Valin49f76802011-01-27 17:01:59 -0500328 mode->preemph[0] = QCONST16(0.7799987793f, 15);
329 mode->preemph[1] = -QCONST16(0.1000061035f, 15);
Jean-Marc Valin09213de2011-01-27 21:43:24 -0500330 mode->preemph[2] = QCONST16(0.7499771125f, SIG_SHIFT); /* exact 1/preemph[3] */
Jean-Marc Valin49f76802011-01-27 17:01:59 -0500331 mode->preemph[3] = QCONST16(1.3333740234f, 13);
Jean-Marc Valin223b69d2010-07-16 11:47:50 -0400332 } else /* 48 kHz */
333 {
Jean-Marc Valin49f76802011-01-27 17:01:59 -0500334 mode->preemph[0] = QCONST16(0.8500061035f, 15);
335 mode->preemph[1] = QCONST16(0.0f, 15);
Jean-Marc Valin223b69d2010-07-16 11:47:50 -0400336 mode->preemph[2] = QCONST16(1.f, SIG_SHIFT);
337 mode->preemph[3] = QCONST16(1.f, 13);
338 }
339
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400340 mode->maxLM = LM;
341 mode->nbShortMdcts = 1<<LM;
Jean-Marc Valin60ff9992010-06-27 13:49:38 -0400342 mode->shortMdctSize = frame_size/mode->nbShortMdcts;
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400343 res = (mode->Fs+mode->shortMdctSize)/(2*mode->shortMdctSize);
344
345 mode->eBands = compute_ebands(Fs, mode->shortMdctSize, res, &mode->nbEBands);
Jean-Marc Valinfbfddf72009-07-19 21:07:12 -0400346 if (mode->eBands==NULL)
347 goto failure;
Jean-Marc Valinfbfddf72009-07-19 21:07:12 -0400348
Jean-Marc Valin85f41b22010-07-16 18:12:45 -0400349 mode->effEBands = mode->nbEBands;
350 while (mode->eBands[mode->effEBands] > mode->shortMdctSize)
351 mode->effEBands--;
Gregory Maxwell71d39ad2011-07-30 00:00:29 -0400352
Jean-Marc Valin08192e32009-07-02 13:28:55 -0400353 /* Overlap must be divisible by 4 */
Jean-Marc Valin70d30ff2010-12-13 13:50:29 -0500354 mode->overlap = ((mode->shortMdctSize>>2)<<2);
Jean-Marc Valin7f1c9422010-04-29 11:24:11 -0400355
Jean-Marc Valine3e2c262011-01-26 13:09:53 -0500356 compute_allocation_table(mode);
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400357 if (mode->allocVectors==NULL)
358 goto failure;
Gregory Maxwell71d39ad2011-07-30 00:00:29 -0400359
Jean-Marc Valin07f88402011-08-29 15:08:51 -0400360 window = (opus_val16*)opus_alloc(mode->overlap*sizeof(opus_val16));
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400361 if (window==NULL)
362 goto failure;
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100363
Jean-Marc Valinf28062f2008-03-03 13:24:01 +1100364#ifndef FIXED_POINT
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100365 for (i=0;i<mode->overlap;i++)
Jean-Marc Valin3dbc1d02008-03-08 15:21:24 +1100366 window[i] = Q15ONE*sin(.5*M_PI* sin(.5*M_PI*(i+.5)/mode->overlap) * sin(.5*M_PI*(i+.5)/mode->overlap));
Jean-Marc Valinf28062f2008-03-03 13:24:01 +1100367#else
368 for (i=0;i<mode->overlap;i++)
Jean-Marc Valin8974f002010-03-20 00:41:39 -0400369 window[i] = MIN32(32767,floor(.5+32768.*sin(.5*M_PI* sin(.5*M_PI*(i+.5)/mode->overlap) * sin(.5*M_PI*(i+.5)/mode->overlap))));
Jean-Marc Valinf28062f2008-03-03 13:24:01 +1100370#endif
Jean-Marc Valin3dbc1d02008-03-08 15:21:24 +1100371 mode->window = window;
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100372
Jean-Marc Valin07f88402011-08-29 15:08:51 -0400373 logN = (opus_int16*)opus_alloc(mode->nbEBands*sizeof(opus_int16));
Jean-Marc Valinf400a3c2010-04-05 23:58:44 -0400374 if (logN==NULL)
375 goto failure;
376
377 for (i=0;i<mode->nbEBands;i++)
Jean-Marc Valinaead79b2010-05-11 07:34:24 -0400378 logN[i] = log2_frac(mode->eBands[i+1]-mode->eBands[i], BITRES);
Jean-Marc Valinf400a3c2010-04-05 23:58:44 -0400379 mode->logN = logN;
Jean-Marc Valin3ad8db42010-08-25 13:11:09 -0400380
381 compute_pulse_cache(mode, mode->maxLM);
Jean-Marc Valin640f7fd2009-06-21 09:47:51 -0400382
Jean-Marc Valin27169ca2011-05-16 14:10:04 -0400383 if (clt_mdct_init(&mode->mdct, 2*mode->shortMdctSize*mode->nbShortMdcts,
384 mode->maxLM) == 0)
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400385 goto failure;
386
Jean-Marc Valin680a9ec2008-03-10 14:52:18 +1100387 if (error)
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -0400388 *error = OPUS_OK;
Jean-Marc Valin40603b22010-08-25 23:02:49 -0400389
Jean-Marc Valin4991a562008-02-18 13:37:40 +1100390 return mode;
Jean-Marc Valin27169ca2011-05-16 14:10:04 -0400391failure:
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400392 if (error)
Jean-Marc Valinf9e701a2011-08-31 17:47:48 -0400393 *error = OPUS_ALLOC_FAIL;
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400394 if (mode!=NULL)
Jean-Marc Valin06237d72011-09-01 13:20:40 -0400395 opus_custom_mode_destroy(mode);
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400396 return NULL;
Jean-Marc Valin5ad35bf2011-01-28 22:42:09 -0500397#endif /* !CUSTOM_MODES */
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100398}
Jean-Marc Valin2a8c3712008-02-18 12:16:41 +1100399
Jean-Marc Valin06237d72011-09-01 13:20:40 -0400400void opus_custom_mode_destroy(CELTMode *mode)
Jean-Marc Valin81a82952008-02-17 22:41:29 +1100401{
Jean-Marc Valin5ad35bf2011-01-28 22:42:09 -0500402#ifdef CUSTOM_MODES
403 int i;
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400404 if (mode == NULL)
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400405 return;
Jean-Marc Valin665da0b2011-01-30 12:15:12 -0500406#ifndef CUSTOM_MODES_ONLY
Jean-Marc Valin5ad35bf2011-01-28 22:42:09 -0500407 for (i=0;i<TOTAL_MODES;i++)
408 {
409 if (mode == static_mode_list[i])
410 {
411 return;
412 }
413 }
Jean-Marc Valin665da0b2011-01-30 12:15:12 -0500414#endif /* CUSTOM_MODES_ONLY */
Jean-Marc Valin07f88402011-08-29 15:08:51 -0400415 opus_free((opus_int16*)mode->eBands);
416 opus_free((opus_int16*)mode->allocVectors);
Gregory Maxwell71d39ad2011-07-30 00:00:29 -0400417
Jean-Marc Valin07f88402011-08-29 15:08:51 -0400418 opus_free((opus_val16*)mode->window);
419 opus_free((opus_int16*)mode->logN);
Jean-Marc Valin81b38c22008-02-29 21:08:49 +1100420
Jean-Marc Valin07f88402011-08-29 15:08:51 -0400421 opus_free((opus_int16*)mode->cache.index);
422 opus_free((unsigned char*)mode->cache.bits);
423 opus_free((unsigned char*)mode->cache.caps);
Jean-Marc Valin72513f32010-07-07 21:26:38 -0400424 clt_mdct_clear(&mode->mdct);
Jean-Marc Valin073d0bc2010-05-05 21:37:53 -0400425
Jean-Marc Valin07f88402011-08-29 15:08:51 -0400426 opus_free((CELTMode *)mode);
Jean-Marc Valin40603b22010-08-25 23:02:49 -0400427#endif
Jean-Marc Valin2ca8fc32008-02-18 16:27:49 +1100428}