340dcfca6c470a4b6c17d608207e4a4c47143290
[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_LOGN%d\n", framerate);
113       fprintf(file, "#define DEF_LOGN%d\n", framerate);
114       fprintf (file, "static const celt_int16 logN%d[%d] = {\n", framerate, mode->nbEBands);
115       for (j=0;j<mode->nbEBands;j++)
116          fprintf (file, "%d, ", mode->logN[j]);
117       fprintf (file, "};\n");
118       fprintf(file, "#endif\n");
119       fprintf(file, "\n");
120
121       /* Pulse cache */
122       fprintf(file, "#ifndef DEF_PULSE_CACHE%d\n", mode->Fs/mdctSize);
123       fprintf(file, "#define DEF_PULSE_CACHE%d\n", mode->Fs/mdctSize);
124       fprintf (file, "static const celt_int16 cache_index%d[%d] = {\n", mode->Fs/mdctSize, (mode->maxLM+2)*mode->nbEBands);
125       for (j=0;j<mode->nbEBands*(mode->maxLM+2);j++)
126          fprintf (file, "%d, ", mode->cache.index[j]);
127       fprintf (file, "};\n");
128       fprintf (file, "static const unsigned char cache_bits%d[%d] = {\n", mode->Fs/mdctSize, mode->cache.size);
129       for (j=0;j<mode->cache.size;j++)
130          fprintf (file, "%d, ", mode->cache.bits[j]);
131       fprintf (file, "};\n");
132       fprintf (file, "static const unsigned char cache_caps%d[%d] = {\n", mode->Fs/mdctSize, (mode->maxLM+1)*2*mode->nbEBands);
133       for (j=0;j<(mode->maxLM+1)*2*mode->nbEBands;j++)
134          fprintf (file, "%d, ", mode->cache.caps[j]);
135       fprintf (file, "};\n");
136
137       fprintf(file, "#endif\n");
138       fprintf(file, "\n");
139
140       /* FFT twiddles */
141       fprintf(file, "#ifndef FFT_TWIDDLES%d_%d\n", mode->Fs, mdctSize);
142       fprintf(file, "#define FFT_TWIDDLES%d_%d\n", mode->Fs, mdctSize);
143       fprintf (file, "static const kiss_twiddle_cpx fft_twiddles%d_%d[%d] = {\n",
144             mode->Fs, mdctSize, mode->mdct.kfft[0]->nfft);
145       for (j=0;j<mode->mdct.kfft[0]->nfft;j++)
146          fprintf (file, "{" WORD16 ", " WORD16 "}, ", mode->mdct.kfft[0]->twiddles[j].r, mode->mdct.kfft[0]->twiddles[j].i);
147       fprintf (file, "};\n");
148
149       /* FFT Bitrev tables */
150       for (k=0;k<=mode->mdct.maxshift;k++)
151       {
152          fprintf(file, "#ifndef FFT_BITREV%d\n", mode->mdct.kfft[k]->nfft);
153          fprintf(file, "#define FFT_BITREV%d\n", mode->mdct.kfft[k]->nfft);
154          fprintf (file, "static const celt_int16 fft_bitrev%d[%d] = {\n",
155                mode->mdct.kfft[k]->nfft, mode->mdct.kfft[k]->nfft);
156          for (j=0;j<mode->mdct.kfft[k]->nfft;j++)
157             fprintf (file, "%d, ", mode->mdct.kfft[k]->bitrev[j]);
158          fprintf (file, "};\n");
159
160          fprintf(file, "#endif\n");
161          fprintf(file, "\n");
162       }
163
164       /* FFT States */
165       for (k=0;k<=mode->mdct.maxshift;k++)
166       {
167          fprintf(file, "#ifndef FFT_STATE%d_%d_%d\n", mode->Fs, mdctSize, k);
168          fprintf(file, "#define FFT_STATE%d_%d_%d\n", mode->Fs, mdctSize, k);
169          fprintf (file, "static const kiss_fft_state fft_state%d_%d_%d = {\n",
170                mode->Fs, mdctSize, k);
171          fprintf (file, "%d,\t/* nfft */\n", mode->mdct.kfft[k]->nfft);
172 #ifndef FIXED_POINT
173          fprintf (file, "%f,\t/* scale */\n", mode->mdct.kfft[k]->scale);
174 #endif
175          fprintf (file, "%d,\t/* shift */\n", mode->mdct.kfft[k]->shift);
176          fprintf (file, "{");
177          for (j=0;j<2*MAXFACTORS;j++)
178             fprintf (file, "%d, ", mode->mdct.kfft[k]->factors[j]);
179          fprintf (file, "},\t/* factors */\n");
180          fprintf (file, "fft_bitrev%d,\t/* bitrev */\n", mode->mdct.kfft[k]->nfft);
181          fprintf (file, "fft_twiddles%d_%d,\t/* bitrev */\n", mode->Fs, mdctSize);
182          fprintf (file, "};\n");
183
184          fprintf(file, "#endif\n");
185          fprintf(file, "\n");
186       }
187
188       fprintf(file, "#endif\n");
189       fprintf(file, "\n");
190
191       /* MDCT twiddles */
192       fprintf(file, "#ifndef MDCT_TWIDDLES%d\n", mdctSize);
193       fprintf(file, "#define MDCT_TWIDDLES%d\n", mdctSize);
194       fprintf (file, "static const celt_word16 mdct_twiddles%d[%d] = {\n",
195             mdctSize, mode->mdct.n/4+1);
196       for (j=0;j<=mode->mdct.n/4;j++)
197          fprintf (file, WORD16 ", ", mode->mdct.trig[j]);
198       fprintf (file, "};\n");
199
200       fprintf(file, "#endif\n");
201       fprintf(file, "\n");
202
203
204       /* Print the actual mode data */
205       fprintf(file, "static const CELTMode mode%d_%d_%d = {\n", mode->Fs, mdctSize, mode->overlap);
206       fprintf(file, INT32 ",\t/* Fs */\n", mode->Fs);
207       fprintf(file, "%d,\t/* overlap */\n", mode->overlap);
208       fprintf(file, "%d,\t/* nbEBands */\n", mode->nbEBands);
209       fprintf(file, "%d,\t/* effEBands */\n", mode->effEBands);
210       fprintf(file, "{");
211       for (j=0;j<4;j++)
212          fprintf(file, WORD16 ", ", mode->preemph[j]);
213       fprintf(file, "},\t/* preemph */\n");
214       if (standard)
215          fprintf(file, "eband5ms,\t/* eBands */\n");
216       else
217          fprintf(file, "eBands%d_%d,\t/* eBands */\n", mode->Fs, mdctSize);
218       fprintf(file, "%d,\t/* nbAllocVectors */\n", mode->nbAllocVectors);
219       if (standard)
220          fprintf(file, "band_allocation,\t/* allocVectors */\n");
221       else
222          fprintf(file, "allocVectors%d_%d,\t/* allocVectors */\n", mode->Fs, mdctSize);
223
224       fprintf(file, "{%d, %d, {", mode->mdct.n, mode->mdct.maxshift);
225       for (k=0;k<=mode->mdct.maxshift;k++)
226          fprintf(file, "&fft_state%d_%d_%d, ", mode->Fs, mdctSize, k);
227       fprintf (file, "}, mdct_twiddles%d},\t/* mdct */\n", mdctSize);
228
229       fprintf(file, "window%d,\t/* window */\n", mode->overlap);
230       fprintf(file, "%d,\t/* maxLM */\n", mode->maxLM);
231       fprintf(file, "%d,\t/* nbShortMdcts */\n", mode->nbShortMdcts);
232       fprintf(file, "%d,\t/* shortMdctSize */\n", mode->shortMdctSize);
233       fprintf(file, "logN%d,\t/* logN */\n", framerate);
234       fprintf(file, "{%d, cache_index%d, cache_bits%d, cache_caps%d},\t/* cache */\n",
235             mode->cache.size, mode->Fs/mdctSize, mode->Fs/mdctSize, mode->Fs/mdctSize);
236       fprintf(file, "};\n");
237    }
238    fprintf(file, "\n");
239    fprintf(file, "/* List of all the available modes */\n");
240    fprintf(file, "#define TOTAL_MODES %d\n", nb_modes);
241    fprintf(file, "static const CELTMode * const static_mode_list[TOTAL_MODES] = {\n");
242    for (i=0;i<nb_modes;i++)
243    {
244       CELTMode *mode = modes[i];
245       int mdctSize;
246       mdctSize = mode->shortMdctSize*mode->nbShortMdcts;
247       fprintf(file, "&mode%d_%d_%d,\n", mode->Fs, mdctSize, mode->overlap);
248    }
249    fprintf(file, "};\n");
250 }
251
252 void dump_header(FILE *file, CELTMode **modes, int nb_modes)
253 {
254    int i;
255    int channels = 0;
256    int frame_size = 0;
257    int overlap = 0;
258    fprintf (file, "/* This header file is generated automatically*/\n");
259    for (i=0;i<nb_modes;i++)
260    {
261       CELTMode *mode = modes[i];
262       if (frame_size==0)
263          frame_size = mode->shortMdctSize*mode->nbShortMdcts;
264       else if (frame_size != mode->shortMdctSize*mode->nbShortMdcts)
265          frame_size = -1;
266       if (overlap==0)
267          overlap = mode->overlap;
268       else if (overlap != mode->overlap)
269          overlap = -1;
270    }
271    if (channels>0)
272    {
273       fprintf (file, "#define CHANNELS(mode) %d\n", channels);
274       if (channels==1)
275          fprintf (file, "#define DISABLE_STEREO\n");
276    }
277    if (frame_size>0)
278    {
279       fprintf (file, "#define FRAMESIZE(mode) %d\n", frame_size);
280    }
281    if (overlap>0)
282    {
283       fprintf (file, "#define OVERLAP(mode) %d\n", overlap);
284    }
285 }
286
287 #ifdef FIXED_POINT
288 #define BASENAME "static_modes_fixed"
289 #else
290 #define BASENAME "static_modes_float"
291 #endif
292
293 int main(int argc, char **argv)
294 {
295    int i, nb;
296    FILE *file;
297    CELTMode **m;
298    if (argc%2 != 1)
299    {
300       fprintf (stderr, "must have a multiple of 2 arguments\n");
301       return 1;
302    }
303    nb = (argc-1)/2;
304    m = malloc(nb*sizeof(CELTMode*));
305    for (i=0;i<nb;i++)
306    {
307       int Fs, frame;
308       Fs      = atoi(argv[2*i+1]);
309       frame   = atoi(argv[2*i+2]);
310       m[i] = celt_mode_create(Fs, frame, NULL);
311    }
312    file = fopen(BASENAME ".c", "w");
313    dump_modes(file, m, nb);
314    fclose(file);
315    /*file = fopen(BASENAME ".h", "w");
316    dump_header(file, m, nb);
317    fclose(file);*/
318    for (i=0;i<nb;i++)
319       celt_mode_destroy(m[i]);
320    free(m);
321    return 0;
322 }