Limit mode creation to supported 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 <stdlib.h>
38 #include <stdio.h>
39 #include "modes.h"
40 #include "celt.h"
41 #include "rate.h"
42
43 #define INT16 "%d"
44 #define INT32 "%d"
45 #define FLOAT "%f"
46
47 #ifdef FIXED_POINT
48 #define WORD16 INT16
49 #define WORD32 INT32
50 #else
51 #define WORD16 FLOAT
52 #define WORD32 FLOAT
53 #endif
54
55
56 void dump_modes(FILE *file, CELTMode **modes, int nb_modes)
57 {
58    int i, j, k;
59    fprintf(file, "/* The contents of this file is automatically generated and contains static\n");
60    fprintf(file, "   definitions for some pre-defined modes */\n");
61    fprintf(file, "#include \"modes.h\"\n");
62    fprintf(file, "#include \"rate.h\"\n");
63
64    fprintf(file, "\n");
65
66    for (i=0;i<nb_modes;i++)
67    {
68       CELTMode *mode = modes[i];
69       int mdctSize;
70       int standard, framerate;
71
72       mdctSize = mode->shortMdctSize*mode->nbShortMdcts;
73       standard = (mode->Fs == 400*(celt_int32)mode->shortMdctSize);
74       framerate = mode->Fs/mode->shortMdctSize;
75
76       if (!standard)
77       {
78          fprintf(file, "#ifndef DEF_EBANDS%d_%d\n", mode->Fs, mdctSize);
79          fprintf(file, "#define DEF_EBANDS%d_%d\n", mode->Fs, mdctSize);
80          fprintf (file, "static const celt_int16 eBands%d_%d[%d] = {\n", mode->Fs, mdctSize, mode->nbEBands+2);
81          for (j=0;j<mode->nbEBands+2;j++)
82             fprintf (file, "%d, ", mode->eBands[j]);
83          fprintf (file, "};\n");
84          fprintf(file, "#endif\n");
85          fprintf(file, "\n");
86       }
87       
88       fprintf(file, "#ifndef DEF_WINDOW%d\n", mode->overlap);
89       fprintf(file, "#define DEF_WINDOW%d\n", mode->overlap);
90       fprintf (file, "static const celt_word16 window%d[%d] = {\n", mode->overlap, mode->overlap);
91       for (j=0;j<mode->overlap;j++)
92          fprintf (file, WORD16 ", ", mode->window[j]);
93       fprintf (file, "};\n");
94       fprintf(file, "#endif\n");
95       fprintf(file, "\n");
96       
97       if (!standard)
98       {
99          fprintf(file, "#ifndef DEF_ALLOC_VECTORS%d_%d\n", mode->Fs, mdctSize);
100          fprintf(file, "#define DEF_ALLOC_VECTORS%d_%d\n", mode->Fs, mdctSize);
101          fprintf (file, "static const unsigned char allocVectors%d_%d[%d] = {\n", mode->Fs, mdctSize, mode->nbEBands*mode->nbAllocVectors);
102          for (j=0;j<mode->nbAllocVectors;j++)
103          {
104             for (k=0;k<mode->nbEBands;k++)
105                fprintf (file, "%2d, ", mode->allocVectors[j*mode->nbEBands+k]);
106             fprintf (file, "\n");
107          }
108          fprintf (file, "};\n");
109          fprintf(file, "#endif\n");
110          fprintf(file, "\n");
111       }
112
113       fprintf(file, "#ifndef DEF_LOGN%d\n", framerate);
114       fprintf(file, "#define DEF_LOGN%d\n", framerate);
115       fprintf (file, "static const celt_int16 logN%d[%d] = {\n", framerate, mode->nbEBands);
116       for (j=0;j<mode->nbEBands;j++)
117          fprintf (file, "%d, ", mode->logN[j]);
118       fprintf (file, "};\n");
119       fprintf(file, "#endif\n");
120       fprintf(file, "\n");
121
122       /* Pulse cache */
123       fprintf(file, "#ifndef DEF_PULSE_CACHE%d\n", mode->Fs/mdctSize);
124       fprintf(file, "#define DEF_PULSE_CACHE%d\n", mode->Fs/mdctSize);
125       fprintf (file, "static const celt_int16 cache_index%d[%d] = {\n", mode->Fs/mdctSize, (mode->maxLM+2)*mode->nbEBands);
126       for (j=0;j<mode->nbEBands*(mode->maxLM+2);j++)
127          fprintf (file, "%d, ", mode->cache.index[j]);
128       fprintf (file, "};\n");
129       fprintf (file, "static const unsigned char cache_bits%d[%d] = {\n", mode->Fs/mdctSize, mode->cache.size);
130       for (j=0;j<mode->cache.size;j++)
131          fprintf (file, "%d, ", mode->cache.bits[j]);
132       fprintf (file, "};\n");
133       fprintf (file, "static const unsigned char cache_caps%d[%d] = {\n", mode->Fs/mdctSize, (mode->maxLM+1)*2*mode->nbEBands);
134       for (j=0;j<(mode->maxLM+1)*2*mode->nbEBands;j++)
135          fprintf (file, "%d, ", mode->cache.caps[j]);
136       fprintf (file, "};\n");
137
138       fprintf(file, "#endif\n");
139       fprintf(file, "\n");
140
141       /* FFT twiddles */
142       fprintf(file, "#ifndef FFT_TWIDDLES%d_%d\n", mode->Fs, mdctSize);
143       fprintf(file, "#define FFT_TWIDDLES%d_%d\n", mode->Fs, mdctSize);
144       fprintf (file, "static const kiss_twiddle_cpx fft_twiddles%d_%d[%d] = {\n",
145             mode->Fs, mdctSize, mode->mdct.kfft[0]->nfft);
146       for (j=0;j<mode->mdct.kfft[0]->nfft;j++)
147          fprintf (file, "{" WORD16 ", " WORD16 "}, ", mode->mdct.kfft[0]->twiddles[j].r, mode->mdct.kfft[0]->twiddles[j].i);
148       fprintf (file, "};\n");
149
150       /* FFT Bitrev tables */
151       for (k=0;k<=mode->mdct.maxshift;k++)
152       {
153          fprintf(file, "#ifndef FFT_BITREV%d\n", mode->mdct.kfft[k]->nfft);
154          fprintf(file, "#define FFT_BITREV%d\n", mode->mdct.kfft[k]->nfft);
155          fprintf (file, "static const celt_int16 fft_bitrev%d[%d] = {\n",
156                mode->mdct.kfft[k]->nfft, mode->mdct.kfft[k]->nfft);
157          for (j=0;j<mode->mdct.kfft[k]->nfft;j++)
158             fprintf (file, "%d, ", mode->mdct.kfft[k]->bitrev[j]);
159          fprintf (file, "};\n");
160
161          fprintf(file, "#endif\n");
162          fprintf(file, "\n");
163       }
164
165       /* FFT States */
166       for (k=0;k<=mode->mdct.maxshift;k++)
167       {
168          fprintf(file, "#ifndef FFT_STATE%d_%d_%d\n", mode->Fs, mdctSize, k);
169          fprintf(file, "#define FFT_STATE%d_%d_%d\n", mode->Fs, mdctSize, k);
170          fprintf (file, "static const kiss_fft_state fft_state%d_%d_%d = {\n",
171                mode->Fs, mdctSize, k);
172          fprintf (file, "%d,\t/* nfft */\n", mode->mdct.kfft[k]->nfft);
173 #ifndef FIXED_POINT
174          fprintf (file, "%f,\t/* scale */\n", mode->mdct.kfft[k]->scale);
175 #endif
176          fprintf (file, "%d,\t/* shift */\n", mode->mdct.kfft[k]->shift);
177          fprintf (file, "{");
178          for (j=0;j<2*MAXFACTORS;j++)
179             fprintf (file, "%d, ", mode->mdct.kfft[k]->factors[j]);
180          fprintf (file, "},\t/* factors */\n");
181          fprintf (file, "fft_bitrev%d,\t/* bitrev */\n", mode->mdct.kfft[k]->nfft);
182          fprintf (file, "fft_twiddles%d_%d,\t/* bitrev */\n", mode->Fs, mdctSize);
183          fprintf (file, "};\n");
184
185          fprintf(file, "#endif\n");
186          fprintf(file, "\n");
187       }
188
189       fprintf(file, "#endif\n");
190       fprintf(file, "\n");
191
192       /* MDCT twiddles */
193       fprintf(file, "#ifndef MDCT_TWIDDLES%d\n", mdctSize);
194       fprintf(file, "#define MDCT_TWIDDLES%d\n", mdctSize);
195       fprintf (file, "static const celt_word16 mdct_twiddles%d[%d] = {\n",
196             mdctSize, mode->mdct.n/4+1);
197       for (j=0;j<=mode->mdct.n/4;j++)
198          fprintf (file, WORD16 ", ", mode->mdct.trig[j]);
199       fprintf (file, "};\n");
200
201       fprintf(file, "#endif\n");
202       fprintf(file, "\n");
203
204
205       /* Print the actual mode data */
206       fprintf(file, "static const CELTMode mode%d_%d_%d = {\n", mode->Fs, mdctSize, mode->overlap);
207       fprintf(file, INT32 ",\t/* Fs */\n", mode->Fs);
208       fprintf(file, "%d,\t/* overlap */\n", mode->overlap);
209       fprintf(file, "%d,\t/* nbEBands */\n", mode->nbEBands);
210       fprintf(file, "%d,\t/* effEBands */\n", mode->effEBands);
211       fprintf(file, "{");
212       for (j=0;j<4;j++)
213          fprintf(file, WORD16 ", ", mode->preemph[j]);
214       fprintf(file, "},\t/* preemph */\n");
215       if (standard)
216          fprintf(file, "eband5ms,\t/* eBands */\n");
217       else
218          fprintf(file, "eBands%d_%d,\t/* eBands */\n", mode->Fs, mdctSize);
219       fprintf(file, "%d,\t/* nbAllocVectors */\n", mode->nbAllocVectors);
220       if (standard)
221          fprintf(file, "band_allocation,\t/* allocVectors */\n");
222       else
223          fprintf(file, "allocVectors%d_%d,\t/* allocVectors */\n", mode->Fs, mdctSize);
224
225       fprintf(file, "{%d, %d, {", mode->mdct.n, mode->mdct.maxshift);
226       for (k=0;k<=mode->mdct.maxshift;k++)
227          fprintf(file, "&fft_state%d_%d_%d, ", mode->Fs, mdctSize, k);
228       fprintf (file, "}, mdct_twiddles%d},\t/* mdct */\n", mdctSize);
229
230       fprintf(file, "window%d,\t/* window */\n", mode->overlap);
231       fprintf(file, "%d,\t/* maxLM */\n", mode->maxLM);
232       fprintf(file, "%d,\t/* nbShortMdcts */\n", mode->nbShortMdcts);
233       fprintf(file, "%d,\t/* shortMdctSize */\n", mode->shortMdctSize);
234       fprintf(file, "logN%d,\t/* logN */\n", framerate);
235       fprintf(file, "{%d, cache_index%d, cache_bits%d, cache_caps%d},\t/* cache */\n",
236             mode->cache.size, mode->Fs/mdctSize, mode->Fs/mdctSize, mode->Fs/mdctSize);
237       fprintf(file, "};\n");
238    }
239    fprintf(file, "\n");
240    fprintf(file, "/* List of all the available modes */\n");
241    fprintf(file, "#define TOTAL_MODES %d\n", nb_modes);
242    fprintf(file, "static const CELTMode * const static_mode_list[TOTAL_MODES] = {\n");
243    for (i=0;i<nb_modes;i++)
244    {
245       CELTMode *mode = modes[i];
246       int mdctSize;
247       mdctSize = mode->shortMdctSize*mode->nbShortMdcts;
248       fprintf(file, "&mode%d_%d_%d,\n", mode->Fs, mdctSize, mode->overlap);
249    }
250    fprintf(file, "};\n");
251 }
252
253 void dump_header(FILE *file, CELTMode **modes, int nb_modes)
254 {
255    int i;
256    int channels = 0;
257    int frame_size = 0;
258    int overlap = 0;
259    fprintf (file, "/* This header file is generated automatically*/\n");
260    for (i=0;i<nb_modes;i++)
261    {
262       CELTMode *mode = modes[i];
263       if (frame_size==0)
264          frame_size = mode->shortMdctSize*mode->nbShortMdcts;
265       else if (frame_size != mode->shortMdctSize*mode->nbShortMdcts)
266          frame_size = -1;
267       if (overlap==0)
268          overlap = mode->overlap;
269       else if (overlap != mode->overlap)
270          overlap = -1;
271    }
272    if (channels>0)
273    {
274       fprintf (file, "#define CHANNELS(mode) %d\n", channels);
275       if (channels==1)
276          fprintf (file, "#define DISABLE_STEREO\n");
277    }
278    if (frame_size>0)
279    {
280       fprintf (file, "#define FRAMESIZE(mode) %d\n", frame_size);
281    }
282    if (overlap>0)
283    {
284       fprintf (file, "#define OVERLAP(mode) %d\n", overlap);
285    }
286 }
287
288 #ifdef FIXED_POINT
289 #define BASENAME "static_modes_fixed"
290 #else
291 #define BASENAME "static_modes_float"
292 #endif
293
294 int main(int argc, char **argv)
295 {
296    int i, nb;
297    FILE *file;
298    CELTMode **m;
299    if (argc%2 != 1)
300    {
301       fprintf (stderr, "must have a multiple of 2 arguments\n");
302       return 1;
303    }
304    nb = (argc-1)/2;
305    m = malloc(nb*sizeof(CELTMode*));
306    for (i=0;i<nb;i++)
307    {
308       int Fs, frame;
309       Fs      = atoi(argv[2*i+1]);
310       frame   = atoi(argv[2*i+2]);
311       m[i] = celt_mode_create(Fs, frame, NULL);
312       if (m[i]==NULL)
313       {
314          fprintf(stderr,"Error creating mode with Fs=%s, frame_size=%s\n",
315                argv[2*i+1],argv[2*i+2]);
316          return EXIT_FAILURE;
317       }
318    }
319    file = fopen(BASENAME ".c", "w");
320    dump_modes(file, m, nb);
321    fclose(file);
322    /*file = fopen(BASENAME ".h", "w");
323    dump_header(file, m, nb);
324    fclose(file);*/
325    for (i=0;i<nb;i++)
326       celt_mode_destroy(m[i]);
327    free(m);
328    return 0;
329 }