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
52void 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
274void 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
315int 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}
354