Properly compute redundancy_bytes
[opus.git] / celt / dump_modes / 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    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
20    OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #include <stdlib.h>
34 #include <stdio.h>
35 #include "modes.h"
36 #include "celt.h"
37 #include "rate.h"
38 #include "dump_modes_arch.h"
39
40 #define INT16 "%d"
41 #define INT32 "%d"
42 #define FLOAT "%#0.8gf"
43
44 #ifdef FIXED_POINT
45 #define WORD16 INT16
46 #define WORD32 INT32
47 #else
48 #define WORD16 FLOAT
49 #define WORD32 FLOAT
50 #endif
51
52 void dump_modes(FILE *file, CELTMode **modes, int nb_modes)
53 {
54    int i, j, k;
55    int mdct_twiddles_size;
56    fprintf(file, "/* The contents of this file was automatically generated by dump_modes.c\n");
57    fprintf(file, "   with arguments:");
58    for (i=0;i<nb_modes;i++)
59    {
60       CELTMode *mode = modes[i];
61       fprintf(file, " %d %d",mode->Fs,mode->shortMdctSize*mode->nbShortMdcts);
62    }
63    fprintf(file, "\n   It contains static definitions for some pre-defined modes. */\n");
64    fprintf(file, "#include \"modes.h\"\n");
65    fprintf(file, "#include \"rate.h\"\n");
66    fprintf(file, "\n#ifdef HAVE_ARM_NE10\n");
67    fprintf(file, "#define OVERRIDE_FFT 1\n");
68    fprintf(file, "#include \"%s\"\n", ARM_NE10_ARCH_FILE_NAME);
69    fprintf(file, "#endif\n");
70
71    fprintf(file, "\n");
72
73    for (i=0;i<nb_modes;i++)
74    {
75       CELTMode *mode = modes[i];
76       int mdctSize;
77       int standard, framerate;
78
79       mdctSize = mode->shortMdctSize*mode->nbShortMdcts;
80       standard = (mode->Fs == 400*(opus_int32)mode->shortMdctSize);
81       framerate = mode->Fs/mode->shortMdctSize;
82
83       if (!standard)
84       {
85          fprintf(file, "#ifndef DEF_EBANDS%d_%d\n", mode->Fs, mdctSize);
86          fprintf(file, "#define DEF_EBANDS%d_%d\n", mode->Fs, mdctSize);
87          fprintf (file, "static const opus_int16 eBands%d_%d[%d] = {\n", mode->Fs, mdctSize, mode->nbEBands+2);
88          for (j=0;j<mode->nbEBands+2;j++)
89             fprintf (file, "%d, ", mode->eBands[j]);
90          fprintf (file, "};\n");
91          fprintf(file, "#endif\n");
92          fprintf(file, "\n");
93       }
94
95       fprintf(file, "#ifndef DEF_WINDOW%d\n", mode->overlap);
96       fprintf(file, "#define DEF_WINDOW%d\n", mode->overlap);
97       fprintf (file, "static const opus_val16 window%d[%d] = {\n", mode->overlap, mode->overlap);
98       for (j=0;j<mode->overlap;j++)
99          fprintf (file, WORD16 ",%c", mode->window[j],(j+6)%5==0?'\n':' ');
100       fprintf (file, "};\n");
101       fprintf(file, "#endif\n");
102       fprintf(file, "\n");
103
104       if (!standard)
105       {
106          fprintf(file, "#ifndef DEF_ALLOC_VECTORS%d_%d\n", mode->Fs, mdctSize);
107          fprintf(file, "#define DEF_ALLOC_VECTORS%d_%d\n", mode->Fs, mdctSize);
108          fprintf (file, "static const unsigned char allocVectors%d_%d[%d] = {\n", mode->Fs, mdctSize, mode->nbEBands*mode->nbAllocVectors);
109          for (j=0;j<mode->nbAllocVectors;j++)
110          {
111             for (k=0;k<mode->nbEBands;k++)
112                fprintf (file, "%2d, ", mode->allocVectors[j*mode->nbEBands+k]);
113             fprintf (file, "\n");
114          }
115          fprintf (file, "};\n");
116          fprintf(file, "#endif\n");
117          fprintf(file, "\n");
118       }
119
120       fprintf(file, "#ifndef DEF_LOGN%d\n", framerate);
121       fprintf(file, "#define DEF_LOGN%d\n", framerate);
122       fprintf (file, "static const opus_int16 logN%d[%d] = {\n", framerate, mode->nbEBands);
123       for (j=0;j<mode->nbEBands;j++)
124          fprintf (file, "%d, ", mode->logN[j]);
125       fprintf (file, "};\n");
126       fprintf(file, "#endif\n");
127       fprintf(file, "\n");
128
129       /* Pulse cache */
130       fprintf(file, "#ifndef DEF_PULSE_CACHE%d\n", mode->Fs/mdctSize);
131       fprintf(file, "#define DEF_PULSE_CACHE%d\n", mode->Fs/mdctSize);
132       fprintf (file, "static const opus_int16 cache_index%d[%d] = {\n", mode->Fs/mdctSize, (mode->maxLM+2)*mode->nbEBands);
133       for (j=0;j<mode->nbEBands*(mode->maxLM+2);j++)
134          fprintf (file, "%d,%c", mode->cache.index[j],(j+16)%15==0?'\n':' ');
135       fprintf (file, "};\n");
136       fprintf (file, "static const unsigned char cache_bits%d[%d] = {\n", mode->Fs/mdctSize, mode->cache.size);
137       for (j=0;j<mode->cache.size;j++)
138          fprintf (file, "%d,%c", mode->cache.bits[j],(j+16)%15==0?'\n':' ');
139       fprintf (file, "};\n");
140       fprintf (file, "static const unsigned char cache_caps%d[%d] = {\n", mode->Fs/mdctSize, (mode->maxLM+1)*2*mode->nbEBands);
141       for (j=0;j<(mode->maxLM+1)*2*mode->nbEBands;j++)
142          fprintf (file, "%d,%c", mode->cache.caps[j],(j+16)%15==0?'\n':' ');
143       fprintf (file, "};\n");
144
145       fprintf(file, "#endif\n");
146       fprintf(file, "\n");
147
148       /* FFT twiddles */
149       fprintf(file, "#ifndef FFT_TWIDDLES%d_%d\n", mode->Fs, mdctSize);
150       fprintf(file, "#define FFT_TWIDDLES%d_%d\n", mode->Fs, mdctSize);
151       fprintf (file, "static const kiss_twiddle_cpx fft_twiddles%d_%d[%d] = {\n",
152             mode->Fs, mdctSize, mode->mdct.kfft[0]->nfft);
153       for (j=0;j<mode->mdct.kfft[0]->nfft;j++)
154          fprintf (file, "{" WORD16 ", " WORD16 "},%c", mode->mdct.kfft[0]->twiddles[j].r, mode->mdct.kfft[0]->twiddles[j].i,(j+3)%2==0?'\n':' ');
155       fprintf (file, "};\n");
156
157 #ifdef OVERRIDE_FFT
158       dump_mode_arch(mode);
159 #endif
160       /* FFT Bitrev tables */
161       for (k=0;k<=mode->mdct.maxshift;k++)
162       {
163          fprintf(file, "#ifndef FFT_BITREV%d\n", mode->mdct.kfft[k]->nfft);
164          fprintf(file, "#define FFT_BITREV%d\n", mode->mdct.kfft[k]->nfft);
165          fprintf (file, "static const opus_int16 fft_bitrev%d[%d] = {\n",
166                mode->mdct.kfft[k]->nfft, mode->mdct.kfft[k]->nfft);
167          for (j=0;j<mode->mdct.kfft[k]->nfft;j++)
168             fprintf (file, "%d,%c", mode->mdct.kfft[k]->bitrev[j],(j+16)%15==0?'\n':' ');
169          fprintf (file, "};\n");
170
171          fprintf(file, "#endif\n");
172          fprintf(file, "\n");
173       }
174
175       /* FFT States */
176       for (k=0;k<=mode->mdct.maxshift;k++)
177       {
178          fprintf(file, "#ifndef FFT_STATE%d_%d_%d\n", mode->Fs, mdctSize, k);
179          fprintf(file, "#define FFT_STATE%d_%d_%d\n", mode->Fs, mdctSize, k);
180          fprintf (file, "static const kiss_fft_state fft_state%d_%d_%d = {\n",
181                mode->Fs, mdctSize, k);
182          fprintf (file, "%d,    /* nfft */\n", mode->mdct.kfft[k]->nfft);
183          fprintf (file, WORD16 ",    /* scale */\n", mode->mdct.kfft[k]->scale);
184 #ifdef FIXED_POINT
185          fprintf (file, "%d,    /* scale_shift */\n", mode->mdct.kfft[k]->scale_shift);
186 #endif
187          fprintf (file, "%d,    /* shift */\n", mode->mdct.kfft[k]->shift);
188          fprintf (file, "{");
189          for (j=0;j<2*MAXFACTORS;j++)
190             fprintf (file, "%d, ", mode->mdct.kfft[k]->factors[j]);
191          fprintf (file, "},    /* factors */\n");
192          fprintf (file, "fft_bitrev%d,    /* bitrev */\n", mode->mdct.kfft[k]->nfft);
193          fprintf (file, "fft_twiddles%d_%d,    /* bitrev */\n", mode->Fs, mdctSize);
194
195          fprintf (file, "#ifdef OVERRIDE_FFT\n");
196          fprintf (file, "(arch_fft_state *)&cfg_arch_%d,\n", mode->mdct.kfft[k]->nfft);
197          fprintf (file, "#else\n");
198          fprintf (file, "NULL,\n");
199          fprintf(file, "#endif\n");
200
201          fprintf (file, "};\n");
202
203          fprintf(file, "#endif\n");
204          fprintf(file, "\n");
205       }
206
207       fprintf(file, "#endif\n");
208       fprintf(file, "\n");
209
210       /* MDCT twiddles */
211       mdct_twiddles_size = mode->mdct.n-(mode->mdct.n/2>>mode->mdct.maxshift);
212       fprintf(file, "#ifndef MDCT_TWIDDLES%d\n", mdctSize);
213       fprintf(file, "#define MDCT_TWIDDLES%d\n", mdctSize);
214       fprintf (file, "static const opus_val16 mdct_twiddles%d[%d] = {\n",
215             mdctSize, mdct_twiddles_size);
216       for (j=0;j<mdct_twiddles_size;j++)
217          fprintf (file, WORD16 ",%c", mode->mdct.trig[j],(j+6)%5==0?'\n':' ');
218       fprintf (file, "};\n");
219
220       fprintf(file, "#endif\n");
221       fprintf(file, "\n");
222
223
224       /* Print the actual mode data */
225       fprintf(file, "static const CELTMode mode%d_%d_%d = {\n", mode->Fs, mdctSize, mode->overlap);
226       fprintf(file, INT32 ",    /* Fs */\n", mode->Fs);
227       fprintf(file, "%d,    /* overlap */\n", mode->overlap);
228       fprintf(file, "%d,    /* nbEBands */\n", mode->nbEBands);
229       fprintf(file, "%d,    /* effEBands */\n", mode->effEBands);
230       fprintf(file, "{");
231       for (j=0;j<4;j++)
232          fprintf(file, WORD16 ", ", mode->preemph[j]);
233       fprintf(file, "},    /* preemph */\n");
234       if (standard)
235          fprintf(file, "eband5ms,    /* eBands */\n");
236       else
237          fprintf(file, "eBands%d_%d,    /* eBands */\n", mode->Fs, mdctSize);
238
239       fprintf(file, "%d,    /* maxLM */\n", mode->maxLM);
240       fprintf(file, "%d,    /* nbShortMdcts */\n", mode->nbShortMdcts);
241       fprintf(file, "%d,    /* shortMdctSize */\n", mode->shortMdctSize);
242
243       fprintf(file, "%d,    /* nbAllocVectors */\n", mode->nbAllocVectors);
244       if (standard)
245          fprintf(file, "band_allocation,    /* allocVectors */\n");
246       else
247          fprintf(file, "allocVectors%d_%d,    /* allocVectors */\n", mode->Fs, mdctSize);
248
249       fprintf(file, "logN%d,    /* logN */\n", framerate);
250       fprintf(file, "window%d,    /* window */\n", mode->overlap);
251       fprintf(file, "{%d, %d, {", mode->mdct.n, mode->mdct.maxshift);
252       for (k=0;k<=mode->mdct.maxshift;k++)
253          fprintf(file, "&fft_state%d_%d_%d, ", mode->Fs, mdctSize, k);
254       fprintf (file, "}, mdct_twiddles%d},    /* mdct */\n", mdctSize);
255
256       fprintf(file, "{%d, cache_index%d, cache_bits%d, cache_caps%d},    /* cache */\n",
257             mode->cache.size, mode->Fs/mdctSize, mode->Fs/mdctSize, mode->Fs/mdctSize);
258       fprintf(file, "};\n");
259    }
260    fprintf(file, "\n");
261    fprintf(file, "/* List of all the available modes */\n");
262    fprintf(file, "#define TOTAL_MODES %d\n", nb_modes);
263    fprintf(file, "static const CELTMode * const static_mode_list[TOTAL_MODES] = {\n");
264    for (i=0;i<nb_modes;i++)
265    {
266       CELTMode *mode = modes[i];
267       int mdctSize;
268       mdctSize = mode->shortMdctSize*mode->nbShortMdcts;
269       fprintf(file, "&mode%d_%d_%d,\n", mode->Fs, mdctSize, mode->overlap);
270    }
271    fprintf(file, "};\n");
272 }
273
274 void dump_header(FILE *file, CELTMode **modes, int nb_modes)
275 {
276    int i;
277    int channels = 0;
278    int frame_size = 0;
279    int overlap = 0;
280    fprintf (file, "/* This header file is generated automatically*/\n");
281    for (i=0;i<nb_modes;i++)
282    {
283       CELTMode *mode = modes[i];
284       if (frame_size==0)
285          frame_size = mode->shortMdctSize*mode->nbShortMdcts;
286       else if (frame_size != mode->shortMdctSize*mode->nbShortMdcts)
287          frame_size = -1;
288       if (overlap==0)
289          overlap = mode->overlap;
290       else if (overlap != mode->overlap)
291          overlap = -1;
292    }
293    if (channels>0)
294    {
295       fprintf (file, "#define CHANNELS(mode) %d\n", channels);
296       if (channels==1)
297          fprintf (file, "#define DISABLE_STEREO\n");
298    }
299    if (frame_size>0)
300    {
301       fprintf (file, "#define FRAMESIZE(mode) %d\n", frame_size);
302    }
303    if (overlap>0)
304    {
305       fprintf (file, "#define OVERLAP(mode) %d\n", overlap);
306    }
307 }
308
309 #ifdef FIXED_POINT
310 #define BASENAME "static_modes_fixed"
311 #else
312 #define BASENAME "static_modes_float"
313 #endif
314
315 int main(int argc, char **argv)
316 {
317    int i, nb;
318    FILE *file;
319    CELTMode **m;
320    if (argc%2 != 1 || argc<3)
321    {
322       fprintf (stderr, "Usage: %s rate frame_size [rate frame_size] [rate frame_size]...\n",argv[0]);
323       return 1;
324    }
325    nb = (argc-1)/2;
326    m = malloc(nb*sizeof(CELTMode*));
327    for (i=0;i<nb;i++)
328    {
329       int Fs, frame;
330       Fs      = atoi(argv[2*i+1]);
331       frame   = atoi(argv[2*i+2]);
332       m[i] = opus_custom_mode_create(Fs, frame, NULL);
333       if (m[i]==NULL)
334       {
335          fprintf(stderr,"Error creating mode with Fs=%s, frame_size=%s\n",
336                argv[2*i+1],argv[2*i+2]);
337          return EXIT_FAILURE;
338       }
339    }
340    file = fopen(BASENAME ".h", "w");
341 #ifdef OVERRIDE_FFT
342    dump_modes_arch_init(m, nb);
343 #endif
344    dump_modes(file, m, nb);
345    fclose(file);
346 #ifdef OVERRIDE_FFT
347    dump_modes_arch_finalize();
348 #endif
349    for (i=0;i<nb;i++)
350       opus_custom_mode_destroy(m[i]);
351    free(m);
352    return 0;
353 }