pbands code seems to work, cleaned up useless junk in mode definitions
[opus.git] / libcelt / modes.c
1 /* (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"
33 #include "os_support.h"
34
35 #define NBANDS 18
36 #define PBANDS 8
37 #define PITCH_END 74
38
39 #define NBANDS128 15
40 #define PBANDS128 8
41 #define PITCH_END128 45
42
43 const int qbank0[NBANDS   +2] = {0,  4,  8, 12, 16, 20, 24, 28, 32, 38, 44, 52, 62, 74, 90,112,142,182, 232,256};
44 const int pbank0[PBANDS   +2] = {0,  4,  8, 12, 16,     24,         38,         62, PITCH_END, 256};
45
46 #define NALLOCS 7
47 int 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,
55 };
56
57
58 #define NBANDS256 15
59 #define PBANDS256 8
60 #define PITCH_END256 88
61 const int qbank3[NBANDS256+2] = {0, 4, 8, 12, 16, 24, 32, 40, 48, 56, 72, 88, 104, 136, 168, 232, 256};
62 //const int pbank3[PBANDS256+2] = {0, 8, 16, 24, 40, PITCH_END256, 256};
63 const int pbank3[PBANDS256+2] = {0, 4, 8, 12, 16, 24, 40, 56, PITCH_END256, 256};
64
65 static const CELTMode mono_mode = {
66    128,         /**< overlap */
67    256,         /**< mdctSize */
68    1,           /**< nbMdctBlocks */
69    1,           /**< channels */
70    
71    NBANDS,      /**< nbEBands */
72    PBANDS,      /**< nbPBands */
73    PITCH_END,   /**< pitchEnd */
74    
75    qbank0,      /**< eBands */
76    pbank0,      /**< pBands*/
77    
78    0.8,         /**< ePredCoef */
79    
80    NALLOCS,     /**< nbAllocVectors */
81    bitalloc0,   /**< allocVectors */
82 };
83
84
85 /* Stereo mode around 120 kbps */
86 static const CELTMode stereo_mode = {
87    128,         /**< overlap */
88    256,         /**< mdctSize */
89    1,           /**< nbMdctBlocks */
90    2,           /**< channels */
91    
92    NBANDS,      /**< nbEBands */
93    PBANDS,      /**< nbPBands */
94    PITCH_END,   /**< pitchEnd */
95    
96    qbank0,      /**< eBands */
97    pbank0,      /**< pBands*/
98    
99    0.8,         /**< ePredCoef */
100    
101    NALLOCS,     /**< nbAllocVectors */
102    bitalloc0,   /**< allocVectors */
103 };
104
105 const CELTMode const *celt_mono = &mono_mode;
106 const CELTMode const *celt_stereo = &stereo_mode;
107
108
109 #define NBANDS51 17
110 #define PBANDS51 8
111 #define PITCH_END51 64
112 const int qbank51[NBANDS51 +2] = {0,  4,  8, 12, 16, 20, 24, 28, 32, 38, 44, 52, 64, 78, 96,122,156,204, 256};
113 const 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
115 const int pbank51[PBANDS51 +2] = {0,  4,  8, 12, 16,     24,     32,     44,     PITCH_END51, 256};
116 const int pbank51b[PBANDS +2] = {0,  3,  6, 9, 12,     20,     38,     52,     PITCH_END51, 256};
117 #define NALLOCS51 10
118 int 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
131 static 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*/
143    
144    0.8,         /**< ePredCoef */
145    
146    NALLOCS51,   /**< nbAllocVectors */
147    bitalloc51,  /**< allocVectors */
148 };
149 const CELTMode const *celt_ld51 = &ld51;
150
151 int 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;
161       case CELT_GET_NB_CHANNELS:
162          *value = mode->nbChannels;
163          break;
164       default:
165          return CELT_BAD_ARG;
166    }
167    return CELT_OK;
168 }
169
170 #define MIN_BINS 4
171 #define BARK_BANDS 25
172 const celt_int16_t bark_freq[BARK_BANDS+1] = {
173       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};
179    
180 const celt_int16_t pitch_freq[PBANDS+1] ={0, 345, 689, 1034, 1378, 2067, 3273, 5340, 6374};
181
182
183 static 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++)
207       eBands[i+low] = (bark_freq[lin+i]+res/2)/res;
208    /* 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;
212    eBands[*nbEBands] = (bark_freq[BARK_BANDS]+res/2)/res;
213    eBands[*nbEBands+1] = frame_size;
214    if (eBands[*nbEBands] > eBands[*nbEBands+1])
215       eBands[*nbEBands] = eBands[*nbEBands+1];
216    
217    /* FIXME: Remove last band if too small */
218    for (i=0;i<*nbEBands+2;i++)
219       printf("%d ", eBands[i]);
220    printf ("\n");
221    return eBands;
222 }
223
224 static 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    {
232       pBands[i] = (pitch_freq[i]+res/2)/res;
233       if (pBands[i] < mode->eBands[i])
234          pBands[i] = mode->eBands[i];
235    }
236    pBands[PBANDS+1] = mode->eBands[mode->nbEBands+1];
237    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    }
253    for (i=0;i<mode->nbPBands+2;i++)
254       printf("%d ", pBands[i]);
255    printf ("\n");
256    mode->pBands = pBands;
257    mode->pitchEnd = pBands[PBANDS];
258 }
259
260 CELTMode *celt_mode_create(int Fs, int channels, int frame_size, int overlap)
261 {
262    int res;
263    CELTMode *mode;
264
265    res = (Fs+frame_size)/(2*frame_size);
266    
267    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);
273    compute_pbands(mode, res);
274    mode->ePredCoef = .8;
275    
276    
277    printf ("%d bands\n", mode->nbEBands);
278    return mode;
279 }
280
281 /*int main()
282 {
283    celt_mode_create(44100, 1, 256, 128);
284    return 0;
285 }*/
286