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