Fixes an index bug in dump_modes
[opus.git] / libcelt / dump_modes.c
1 /* Copyright (c) 2008 CSIRO
2    Copyright (c) 2008-2009 Xiph.Org Foundation
3    Written by Jean-Marc Valin */
4 /*
5    Redistribution and use in source and binary forms, with or without
6    modification, are permitted provided that the following conditions
7    are met:
8    
9    - Redistributions of source code must retain the above copyright
10    notice, this list of conditions and the following disclaimer.
11    
12    - Redistributions in binary form must reproduce the above copyright
13    notice, this list of conditions and the following disclaimer in the
14    documentation and/or other materials provided with the distribution.
15    
16    - Neither the name of the Xiph.org Foundation nor the names of its
17    contributors may be used to endorse or promote products derived from
18    this software without specific prior written permission.
19    
20    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23    A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
24    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 #ifdef HAVE_CONFIG_H
34 #include "config.h"
35 #endif
36
37 #include <stdio.h>
38 #include "modes.h"
39 #include "celt.h"
40 #include "rate.h"
41
42 #define INT16 "%d"
43 #define INT32 "%d"
44 #define FLOAT "%f"
45
46 #ifdef FIXED_POINT
47 #define WORD16 INT16
48 #define WORD32 INT32
49 #else
50 #define WORD16 FLOAT
51 #define WORD32 FLOAT
52 #endif
53
54
55 void dump_modes(FILE *file, CELTMode **modes, int nb_modes)
56 {
57    int i, j, k;
58    fprintf(file, "/* The contents of this file is automatically generated and contains static\n");
59    fprintf(file, "   definitions for some pre-defined modes */\n");
60    fprintf(file, "#include \"modes.h\"\n");
61    fprintf(file, "#include \"rate.h\"\n");
62
63    fprintf(file, "\n");
64
65    for (i=0;i<nb_modes;i++)
66    {
67       CELTMode *mode = modes[i];
68       int mdctSize;
69       int standard, framerate;
70
71       mdctSize = mode->shortMdctSize*mode->nbShortMdcts;
72       standard = (mode->Fs == 400*(celt_int32)mode->shortMdctSize);
73       framerate = mode->Fs/mode->shortMdctSize;
74
75       if (!standard)
76       {
77          fprintf(file, "#ifndef DEF_EBANDS%d_%d\n", mode->Fs, mdctSize);
78          fprintf(file, "#define DEF_EBANDS%d_%d\n", mode->Fs, mdctSize);
79          fprintf (file, "static const celt_int16 eBands%d_%d[%d] = {\n", mode->Fs, mdctSize, mode->nbEBands+2);
80          for (j=0;j<mode->nbEBands+2;j++)
81             fprintf (file, "%d, ", mode->eBands[j]);
82          fprintf (file, "};\n");
83          fprintf(file, "#endif\n");
84          fprintf(file, "\n");
85       }
86       
87       fprintf(file, "#ifndef DEF_WINDOW%d\n", mode->overlap);
88       fprintf(file, "#define DEF_WINDOW%d\n", mode->overlap);
89       fprintf (file, "static const celt_word16 window%d[%d] = {\n", mode->overlap, mode->overlap);
90       for (j=0;j<mode->overlap;j++)
91          fprintf (file, WORD16 ", ", mode->window[j]);
92       fprintf (file, "};\n");
93       fprintf(file, "#endif\n");
94       fprintf(file, "\n");
95       
96       if (!standard)
97       {
98          fprintf(file, "#ifndef DEF_ALLOC_VECTORS%d_%d\n", mode->Fs, mdctSize);
99          fprintf(file, "#define DEF_ALLOC_VECTORS%d_%d\n", mode->Fs, mdctSize);
100          fprintf (file, "static const unsigned char allocVectors%d_%d[%d] = {\n", mode->Fs, mdctSize, mode->nbEBands*mode->nbAllocVectors);
101          for (j=0;j<mode->nbAllocVectors;j++)
102          {
103             for (k=0;k<mode->nbEBands;k++)
104                fprintf (file, "%2d, ", mode->allocVectors[j*mode->nbEBands+k]);
105             fprintf (file, "\n");
106          }
107          fprintf (file, "};\n");
108          fprintf(file, "#endif\n");
109          fprintf(file, "\n");
110       }
111
112       fprintf(file, "#ifndef DEF_PROB%d\n", mode->nbEBands);
113       fprintf(file, "#define DEF_PROB%d\n", mode->nbEBands);
114       fprintf (file, "static const celt_int16 prob%d[%d] = {\n", mode->nbEBands, 4*mode->nbEBands);
115       for (j=0;j<4*mode->nbEBands;j++)
116          fprintf (file, "%d, ", mode->prob[j]);
117       fprintf (file, "};\n");
118       fprintf(file, "#endif\n");
119       fprintf(file, "\n");
120
121       fprintf(file, "#ifndef DEF_LOGN%d\n", framerate);
122       fprintf(file, "#define DEF_LOGN%d\n", framerate);
123       fprintf (file, "static const celt_int16 logN%d[%d] = {\n", framerate, mode->nbEBands);
124       for (j=0;j<mode->nbEBands;j++)
125          fprintf (file, "%d, ", mode->logN[j]);
126       fprintf (file, "};\n");
127       fprintf(file, "#endif\n");
128       fprintf(file, "\n");
129
130       /* Pulse cache */
131       fprintf(file, "#ifndef DEF_PULSE_CACHE%d\n", mode->Fs/mdctSize);
132       fprintf(file, "#define DEF_PULSE_CACHE%d\n", mode->Fs/mdctSize);
133       fprintf (file, "static const celt_int16 cache_index%d[%d] = {\n", mode->Fs/mdctSize, (mode->maxLM+2)*mode->nbEBands);
134       for (j=0;j<mode->nbEBands*(mode->maxLM+2);j++)
135          fprintf (file, "%d, ", mode->cache.index[j]);
136       fprintf (file, "};\n");
137       fprintf (file, "static const unsigned char cache_bits%d[%d] = {\n", mode->Fs/mdctSize, mode->cache.size);
138       for (j=0;j<mode->cache.size;j++)
139          fprintf (file, "%d, ", mode->cache.bits[j]);
140       fprintf (file, "};\n");
141       fprintf(file, "#endif\n");
142       fprintf(file, "\n");
143
144       /* FFT twiddles */
145       fprintf(file, "#ifndef FFT_TWIDDLES%d_%d\n", mode->Fs, mdctSize);
146       fprintf(file, "#define FFT_TWIDDLES%d_%d\n", mode->Fs, mdctSize);
147       fprintf (file, "static const kiss_twiddle_cpx fft_twiddles%d_%d[%d] = {\n",
148             mode->Fs, mdctSize, mode->mdct.kfft[0]->nfft);
149       for (j=0;j<mode->mdct.kfft[0]->nfft;j++)
150          fprintf (file, "{" WORD16 ", " WORD16 "}, ", mode->mdct.kfft[0]->twiddles[j].r, mode->mdct.kfft[0]->twiddles[j].i);
151       fprintf (file, "};\n");
152
153       /* FFT Bitrev tables */
154       for (k=0;k<=mode->mdct.maxshift;k++)
155       {
156          fprintf(file, "#ifndef FFT_BITREV%d\n", mode->mdct.kfft[k]->nfft);
157          fprintf(file, "#define FFT_BITREV%d\n", mode->mdct.kfft[k]->nfft);
158          fprintf (file, "static const celt_int16 fft_bitrev%d[%d] = {\n",
159                mode->mdct.kfft[k]->nfft, mode->mdct.kfft[k]->nfft);
160          for (j=0;j<mode->mdct.kfft[k]->nfft;j++)
161             fprintf (file, "%d, ", mode->mdct.kfft[k]->bitrev[j]);
162          fprintf (file, "};\n");
163
164          fprintf(file, "#endif\n");
165          fprintf(file, "\n");
166       }
167
168       /* FFT States */
169       for (k=0;k<=mode->mdct.maxshift;k++)
170       {
171          fprintf(file, "#ifndef FFT_STATE%d_%d_%d\n", mode->Fs, mdctSize, k);
172          fprintf(file, "#define FFT_STATE%d_%d_%d\n", mode->Fs, mdctSize, k);
173          fprintf (file, "static const kiss_fft_state fft_state%d_%d_%d = {\n",
174                mode->Fs, mdctSize, k);
175          fprintf (file, "%d,\t/* nfft */\n", mode->mdct.kfft[k]->nfft);
176 #ifndef FIXED_POINT
177          fprintf (file, "%f,\t/* scale */\n", mode->mdct.kfft[k]->scale);
178 #endif
179          fprintf (file, "%d,\t/* shift */\n", mode->mdct.kfft[k]->shift);
180          fprintf (file, "{");
181          for (j=0;j<2*MAXFACTORS;j++)
182             fprintf (file, "%d, ", mode->mdct.kfft[k]->factors[j]);
183          fprintf (file, "},\t/* factors */\n");
184          fprintf (file, "fft_bitrev%d,\t/* bitrev */\n", mode->mdct.kfft[k]->nfft);
185          fprintf (file, "fft_twiddles%d_%d,\t/* bitrev */\n", mode->Fs, mdctSize);
186          fprintf (file, "};\n");
187
188          fprintf(file, "#endif\n");
189          fprintf(file, "\n");
190       }
191
192       fprintf(file, "#endif\n");
193       fprintf(file, "\n");
194
195       /* MDCT twiddles */
196       fprintf(file, "#ifndef MDCT_TWIDDLES%d\n", mdctSize);
197       fprintf(file, "#define MDCT_TWIDDLES%d\n", mdctSize);
198       fprintf (file, "static const celt_word16 mdct_twiddles%d[%d] = {\n",
199             mdctSize, mode->mdct.n/4+1);
200       for (j=0;j<=mode->mdct.n/4;j++)
201          fprintf (file, WORD16 ", ", mode->mdct.trig[j]);
202       fprintf (file, "};\n");
203
204       fprintf(file, "#endif\n");
205       fprintf(file, "\n");
206
207
208       /* Print the actual mode data */
209       fprintf(file, "static const CELTMode mode%d_%d_%d = {\n", mode->Fs, mdctSize, mode->overlap);
210       fprintf(file, INT32 ",\t/* Fs */\n", mode->Fs);
211       fprintf(file, "%d,\t/* overlap */\n", mode->overlap);
212       fprintf(file, "%d,\t/* nbEBands */\n", mode->nbEBands);
213       fprintf(file, "%d,\t/* effEBands */\n", mode->effEBands);
214       fprintf(file, "{");
215       for (j=0;j<4;j++)
216          fprintf(file, WORD16 ", ", mode->preemph[j]);
217       fprintf(file, "},\t/* preemph */\n");
218       if (standard)
219          fprintf(file, "eband5ms,\t/* eBands */\n");
220       else
221          fprintf(file, "eBands%d_%d,\t/* eBands */\n", mode->Fs, mdctSize);
222       fprintf(file, "%d,\t/* nbAllocVectors */\n", mode->nbAllocVectors);
223       if (standard)
224          fprintf(file, "band_allocation,\t/* allocVectors */\n");
225       else
226          fprintf(file, "allocVectors%d_%d,\t/* allocVectors */\n", mode->Fs, mdctSize);
227
228       fprintf(file, "{%d, %d, {", mode->mdct.n, mode->mdct.maxshift);
229       for (k=0;k<=mode->mdct.maxshift;k++)
230          fprintf(file, "&fft_state%d_%d_%d, ", mode->Fs, mdctSize, k);
231       fprintf (file, "}, mdct_twiddles%d},\t/* mdct */\n", mdctSize);
232
233       fprintf(file, "window%d,\t/* window */\n", mode->overlap);
234       fprintf(file, "%d,\t/* maxLM */\n", mode->maxLM);
235       fprintf(file, "%d,\t/* nbShortMdcts */\n", mode->nbShortMdcts);
236       fprintf(file, "%d,\t/* shortMdctSize */\n", mode->shortMdctSize);
237       fprintf(file, "prob%d,\t/* prob */\n", mode->nbEBands);
238       fprintf(file, "logN%d,\t/* logN */\n", framerate);
239       fprintf(file, "{%d, cache_index%d, cache_bits%d},\t/* cache */\n",
240             mode->cache.size, mode->Fs/mdctSize, mode->Fs/mdctSize);
241       fprintf(file, "};\n");
242    }
243    fprintf(file, "\n");
244    fprintf(file, "/* List of all the available modes */\n");
245    fprintf(file, "#define TOTAL_MODES %d\n", nb_modes);
246    fprintf(file, "static const CELTMode * const static_mode_list[TOTAL_MODES] = {\n");
247    for (i=0;i<nb_modes;i++)
248    {
249       CELTMode *mode = modes[i];
250       int mdctSize;
251       mdctSize = mode->shortMdctSize*mode->nbShortMdcts;
252       fprintf(file, "&mode%d_%d_%d,\n", mode->Fs, mdctSize, mode->overlap);
253    }
254    fprintf(file, "};\n");
255 }
256
257 void dump_header(FILE *file, CELTMode **modes, int nb_modes)
258 {
259    int i;
260    int channels = 0;
261    int frame_size = 0;
262    int overlap = 0;
263    fprintf (file, "/* This header file is generated automatically*/\n");
264    for (i=0;i<nb_modes;i++)
265    {
266       CELTMode *mode = modes[i];
267       if (frame_size==0)
268          frame_size = mode->shortMdctSize*mode->nbShortMdcts;
269       else if (frame_size != mode->shortMdctSize*mode->nbShortMdcts)
270          frame_size = -1;
271       if (overlap==0)
272          overlap = mode->overlap;
273       else if (overlap != mode->overlap)
274          overlap = -1;
275    }
276    if (channels>0)
277    {
278       fprintf (file, "#define CHANNELS(mode) %d\n", channels);
279       if (channels==1)
280          fprintf (file, "#define DISABLE_STEREO\n");
281    }
282    if (frame_size>0)
283    {
284       fprintf (file, "#define FRAMESIZE(mode) %d\n", frame_size);
285    }
286    if (overlap>0)
287    {
288       fprintf (file, "#define OVERLAP(mode) %d\n", overlap);
289    }
290 }
291
292 int main(int argc, char **argv)
293 {
294    int i, nb;
295    FILE *file;
296    CELTMode **m;
297    if (argc%2 != 1)
298    {
299       fprintf (stderr, "must have a multiple of 2 arguments\n");
300       return 1;
301    }
302    nb = (argc-1)/2;
303    m = malloc(nb*sizeof(CELTMode*));
304    for (i=0;i<nb;i++)
305    {
306       int Fs, frame;
307       Fs      = atoi(argv[2*i+1]);
308       frame   = atoi(argv[2*i+2]);
309       m[i] = celt_mode_create(Fs, frame, NULL);
310    }
311    file = fopen("static_modes.c", "w");
312    dump_modes(file, m, nb);
313    fclose(file);
314    file = fopen("static_modes.h", "w");
315    dump_header(file, m, nb);
316    fclose(file);
317    for (i=0;i<nb;i++)
318       celt_mode_destroy(m[i]);
319    free(m);
320    return 0;
321 }