Fix dump_modes when requesting multiple 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       mdctSize = mode->shortMdctSize*mode->nbShortMdcts;
70       fprintf(file, "#ifndef DEF_EBANDS%d_%d\n", mode->Fs, mdctSize);
71       fprintf(file, "#define DEF_EBANDS%d_%d\n", mode->Fs, mdctSize);
72       fprintf (file, "static const celt_int16 eBands%d_%d[%d] = {\n", mode->Fs, mdctSize, mode->nbEBands+2);
73       for (j=0;j<mode->nbEBands+2;j++)
74          fprintf (file, "%d, ", mode->eBands[j]);
75       fprintf (file, "};\n");
76       fprintf(file, "#endif\n");
77       fprintf(file, "\n");
78       
79       
80       fprintf(file, "#ifndef DEF_WINDOW%d\n", mode->overlap);
81       fprintf(file, "#define DEF_WINDOW%d\n", mode->overlap);
82       fprintf (file, "static const celt_word16 window%d[%d] = {\n", mode->overlap, mode->overlap);
83       for (j=0;j<mode->overlap;j++)
84          fprintf (file, WORD16 ", ", mode->window[j]);
85       fprintf (file, "};\n");
86       fprintf(file, "#endif\n");
87       fprintf(file, "\n");
88       
89       fprintf(file, "#ifndef DEF_ALLOC_VECTORS%d_%d\n", mode->Fs, mdctSize);
90       fprintf(file, "#define DEF_ALLOC_VECTORS%d_%d\n", mode->Fs, mdctSize);
91       fprintf (file, "static const unsigned char allocVectors%d_%d[%d] = {\n", mode->Fs, mdctSize, mode->nbEBands*mode->nbAllocVectors);
92       for (j=0;j<mode->nbAllocVectors;j++)
93       {
94          for (k=0;k<mode->nbEBands;k++)
95             fprintf (file, "%2d, ", mode->allocVectors[j*mode->nbEBands+k]);
96          fprintf (file, "\n");
97       }
98       fprintf (file, "};\n");
99       fprintf(file, "#endif\n");
100       fprintf(file, "\n");
101
102       for (k=0;(1<<k>>1)<=mode->nbShortMdcts;k++)
103       {
104          int mdctSize2 = mode->shortMdctSize;
105          if (k>=1)
106             mdctSize2 <<= k-1;
107          else
108             mdctSize2 >>= 1;
109          fprintf(file, "#ifndef DEF_ALLOC_CACHE%d_%d\n", mode->Fs, mdctSize2);
110          fprintf(file, "#define DEF_ALLOC_CACHE%d_%d\n", mode->Fs, mdctSize2);
111          for (j=0;j<mode->nbEBands;j++)
112          {
113             int m;
114             if (mode->_bits[k][j]==NULL)
115             {
116                fprintf (file, "#define allocCache_band%d_%d_%d NULL\n", j, mode->Fs, mdctSize2);
117                continue;
118             }
119             if (j==0 || (mode->_bits[k][j] != mode->_bits[k][j-1]))
120             {
121                fprintf (file, "static const celt_int16 allocCache_band%d_%d_%d[MAX_PSEUDO] = {\n", j, mode->Fs, mdctSize2);
122                for (m=0;m<MAX_PSEUDO;m++)
123                   fprintf (file, "%2d, ", mode->_bits[k][j][m]);
124                fprintf (file, "};\n");
125             } else {
126                fprintf (file, "#define allocCache_band%d_%d_%d allocCache_band%d_%d_%d\n", j, mode->Fs, mdctSize2, j-1, mode->Fs, mdctSize2);
127             }
128          }
129          fprintf (file, "static const celt_int16 *allocCache%d_%d[%d] = {\n", mode->Fs, mdctSize2, mode->nbEBands);
130          for (j=0;j<mode->nbEBands;j++)
131          {
132             fprintf (file, "allocCache_band%d_%d_%d, ", j, mode->Fs, mdctSize2);
133          }
134          fprintf (file, "};\n");
135          fprintf(file, "#endif\n");
136          fprintf(file, "\n");
137       }
138
139       fprintf(file, "#ifndef DEF_LOGN%d_%d\n", mode->Fs, mdctSize);
140       fprintf(file, "#define DEF_LOGN%d_%d\n", mode->Fs, mdctSize);
141       fprintf (file, "static const celt_int16 logN%d_%d[%d] = {\n", mode->Fs, mdctSize, mode->nbEBands);
142       for (j=0;j<mode->nbEBands;j++)
143          fprintf (file, "%d, ", mode->logN[j]);
144       fprintf (file, "};\n");
145       fprintf(file, "#endif\n");
146       fprintf(file, "\n");
147
148       fprintf(file, "static const CELTMode mode%d_%d_%d = {\n", mode->Fs, mdctSize, mode->overlap);
149       fprintf(file, "0x%x,\t/* marker */\n", 0xa110ca7e);
150       fprintf(file, INT32 ",\t/* Fs */\n", mode->Fs);
151       fprintf(file, "%d,\t/* overlap */\n", mode->overlap);
152       fprintf(file, "%d,\t/* nbEBands */\n", mode->nbEBands);
153       fprintf(file, "%d,\t/* effEBands */\n", mode->effEBands);
154       fprintf(file, "{");
155       for (j=0;j<4;j++)
156          fprintf(file, WORD16 ", ", mode->preemph[j]);
157       fprintf(file, "},\t/* preemph */\n");
158       fprintf(file, "eBands%d_%d,\t/* eBands */\n", mode->Fs, mdctSize);
159       fprintf(file, "%d,\t/* nbAllocVectors */\n", mode->nbAllocVectors);
160       fprintf(file, "allocVectors%d_%d,\t/* allocVectors */\n", mode->Fs, mdctSize);
161       fprintf(file, "NULL,\t/* bits */\n");
162       fprintf (file, "{ ");
163       for (k=0;(1<<k>>1)<=mode->nbShortMdcts;k++)
164       {
165          int mdctSize2 = mode->shortMdctSize;
166          if (k>=1)
167             mdctSize2 <<= k-1;
168          else
169             mdctSize2 >>= 1;
170          fprintf (file, "allocCache%d_%d, ", mode->Fs, mdctSize2);
171       }
172       fprintf (file, "}, /* _bits */\n");
173
174       fprintf(file, "{%d, 0, 0, 0},\t", 2*mode->shortMdctSize*mode->nbShortMdcts);
175       fprintf (file, "/* mdct */\n");
176
177       fprintf(file, "window%d,\t/* window */\n", mode->overlap);
178       fprintf(file, "%d,\t/* maxLM */\n", mode->maxLM);
179       fprintf(file, "%d,\t/* nbShortMdcts */\n", mode->nbShortMdcts);
180       fprintf(file, "%d,\t/* shortMdctSize */\n", mode->shortMdctSize);
181       fprintf(file, "0,\t/* prob */\n");
182       fprintf(file, "logN%d_%d,\t/* logN */\n", mode->Fs, mdctSize);
183       fprintf(file, "0x%x,\t/* marker */\n", 0xa110ca7e);
184       fprintf(file, "};\n");
185    }
186    fprintf(file, "\n");
187    fprintf(file, "/* List of all the available modes */\n");
188    fprintf(file, "#define TOTAL_MODES %d\n", nb_modes);
189    fprintf(file, "static const CELTMode * const static_mode_list[TOTAL_MODES] = {\n");
190    for (i=0;i<nb_modes;i++)
191    {
192       CELTMode *mode = modes[i];
193       int mdctSize;
194       mdctSize = mode->shortMdctSize*mode->nbShortMdcts;
195       fprintf(file, "&mode%d_%d_%d,\n", mode->Fs, mdctSize, mode->overlap);
196    }
197    fprintf(file, "};\n");
198 }
199
200 void dump_header(FILE *file, CELTMode **modes, int nb_modes)
201 {
202    int i;
203    int channels = 0;
204    int frame_size = 0;
205    int overlap = 0;
206    fprintf (file, "/* This header file is generated automatically*/\n");
207    for (i=0;i<nb_modes;i++)
208    {
209       CELTMode *mode = modes[i];
210       if (frame_size==0)
211          frame_size = mode->shortMdctSize*mode->nbShortMdcts;
212       else if (frame_size != mode->shortMdctSize*mode->nbShortMdcts)
213          frame_size = -1;
214       if (overlap==0)
215          overlap = mode->overlap;
216       else if (overlap != mode->overlap)
217          overlap = -1;
218    }
219    if (channels>0)
220    {
221       fprintf (file, "#define CHANNELS(mode) %d\n", channels);
222       if (channels==1)
223          fprintf (file, "#define DISABLE_STEREO\n");
224    }
225    if (frame_size>0)
226    {
227       fprintf (file, "#define FRAMESIZE(mode) %d\n", frame_size);
228    }
229    if (overlap>0)
230    {
231       fprintf (file, "#define OVERLAP(mode) %d\n", overlap);
232    }
233 }
234
235 int main(int argc, char **argv)
236 {
237    int i, nb;
238    FILE *file;
239    CELTMode **m;
240    if (argc%2 != 1)
241    {
242       fprintf (stderr, "must have a multiple of 2 arguments\n");
243       return 1;
244    }
245    nb = (argc-1)/2;
246    m = malloc(nb*sizeof(CELTMode*));
247    for (i=0;i<nb;i++)
248    {
249       int Fs, frame;
250       Fs      = atoi(argv[2*i+1]);
251       frame   = atoi(argv[2*i+2]);
252       m[i] = celt_mode_create(Fs, frame, NULL);
253    }
254    file = fopen("static_modes.c", "w");
255    dump_modes(file, m, nb);
256    fclose(file);
257    file = fopen("static_modes.h", "w");
258    dump_header(file, m, nb);
259    fclose(file);
260    for (i=0;i<nb;i++)
261       celt_mode_destroy(m[i]);
262    free(m);
263    return 0;
264 }