revamp the ordinal types
[flac.git] / src / test_streams / main.c
1 /* test_streams - Simple test pattern generator
2  * Copyright (C) 2000,2001  Josh Coalson
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17  */
18
19 #include <math.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <sys/time.h>
23 #include "FLAC/assert.h"
24 #include "FLAC/ordinals.h"
25
26 #ifdef _WIN32
27         static const char *mode = "wb";
28 #else
29         static const char *mode = "w";
30 #endif
31
32 static FLAC__bool is_big_endian_host;
33
34 static void swap16(FLAC__int16 *i)
35 {
36         unsigned char *x = (unsigned char *)i, b;
37         if(!is_big_endian_host) {
38                 b = x[0];
39                 x[0] = x[1];
40                 x[1] = b;
41         }
42 }
43
44 static void swap24(FLAC__byte *x)
45 {
46         if(is_big_endian_host) {
47                 x[0] = x[1];
48                 x[1] = x[2];
49                 x[2] = x[3];
50         }
51         else {
52                 FLAC__byte b = x[0];
53                 x[0] = x[2];
54                 x[2] = b;
55         }
56 }
57
58 /* a mono one-sample 16bps stream */
59 static FLAC__bool generate_01()
60 {
61         FILE *f;
62         FLAC__int16 x = -32768;
63
64         if(0 == (f = fopen("test01.raw", mode)))
65                 return false;
66
67         swap16(&x);
68         if(fwrite(&x, sizeof(x), 1, f) < 1)
69                 goto foo;
70
71         fclose(f);
72         return true;
73 foo:
74         fclose(f);
75         return false;
76 }
77
78 /* a stereo one-sample 16bps stream */
79 static FLAC__bool generate_02()
80 {
81         FILE *f;
82         FLAC__int16 xl = -32768, xr = 32767;
83
84         if(0 == (f = fopen("test02.raw", mode)))
85                 return false;
86
87         swap16(&xl);
88         swap16(&xr);
89
90         if(fwrite(&xl, sizeof(xl), 1, f) < 1)
91                 goto foo;
92         if(fwrite(&xr, sizeof(xr), 1, f) < 1)
93                 goto foo;
94
95         fclose(f);
96         return true;
97 foo:
98         fclose(f);
99         return false;
100 }
101
102 /* a mono five-sample 16bps stream */
103 static FLAC__bool generate_03()
104 {
105         FILE *f;
106         FLAC__int16 x[] = { -25, 0, 25, 50, 100 };
107         unsigned i;
108
109         if(0 == (f = fopen("test03.raw", mode)))
110                 return false;
111
112         for(i = 0; i < 5; i++)
113                 swap16(x+i);
114
115         if(fwrite(&x, sizeof(FLAC__int16), 5, f) < 5)
116                 goto foo;
117
118         fclose(f);
119         return true;
120 foo:
121         fclose(f);
122         return false;
123 }
124
125 /* a stereo five-sample 16bps stream */
126 static FLAC__bool generate_04()
127 {
128         FILE *f;
129         FLAC__int16 x[] = { -25, 500, 0, 400, 25, 300, 50, 200, 100, 100 };
130         unsigned i;
131
132         if(0 == (f = fopen("test04.raw", mode)))
133                 return false;
134
135         for(i = 0; i < 10; i++)
136                 swap16(x+i);
137
138         if(fwrite(&x, sizeof(FLAC__int16), 10, f) < 10)
139                 goto foo;
140
141         fclose(f);
142         return true;
143 foo:
144         fclose(f);
145         return false;
146 }
147
148 /* a mono full-scale deflection 8bps stream */
149 static FLAC__bool generate_fsd8(const char *fn, const int pattern[], unsigned reps)
150 {
151         FILE *f;
152         unsigned rep, p;
153
154         FLAC__ASSERT(pattern != 0);
155
156         if(0 == (f = fopen(fn, mode)))
157                 return false;
158
159         for(rep = 0; rep < reps; rep++) {
160                 for(p = 0; pattern[p]; p++) {
161                         signed char x = pattern[p] > 0? 127 : -128;
162                         if(fwrite(&x, sizeof(x), 1, f) < 1)
163                                 goto foo;
164                 }
165         }
166
167         fclose(f);
168         return true;
169 foo:
170         fclose(f);
171         return false;
172 }
173
174 /* a mono full-scale deflection 16bps stream */
175 static FLAC__bool generate_fsd16(const char *fn, const int pattern[], unsigned reps)
176 {
177         FILE *f;
178         unsigned rep, p;
179
180         FLAC__ASSERT(pattern != 0);
181
182         if(0 == (f = fopen(fn, mode)))
183                 return false;
184
185         for(rep = 0; rep < reps; rep++) {
186                 for(p = 0; pattern[p]; p++) {
187                         FLAC__int16 x = pattern[p] > 0? 32767 : -32768;
188                         swap16(&x);
189                         if(fwrite(&x, sizeof(x), 1, f) < 1)
190                                 goto foo;
191                 }
192         }
193
194         fclose(f);
195         return true;
196 foo:
197         fclose(f);
198         return false;
199 }
200
201 /* a stereo wasted-bits-per-sample 16bps stream */
202 static FLAC__bool generate_wbps16(const char *fn, unsigned samples)
203 {
204         FILE *f;
205         unsigned sample;
206
207         if(0 == (f = fopen(fn, mode)))
208                 return false;
209
210         for(sample = 0; sample < samples; sample++) {
211                 FLAC__int16 l = (sample % 2000) << 2;
212                 FLAC__int16 r = (sample % 1000) << 3;
213                 swap16(&l);
214                 swap16(&r);
215                 if(fwrite(&l, sizeof(l), 1, f) < 1)
216                         goto foo;
217                 if(fwrite(&r, sizeof(r), 1, f) < 1)
218                         goto foo;
219         }
220
221         fclose(f);
222         return true;
223 foo:
224         fclose(f);
225         return false;
226 }
227
228 /* a mono full-scale deflection 24bps stream */
229 static FLAC__bool generate_fsd24(const char *fn, const int pattern[], unsigned reps)
230 {
231         FILE *f;
232         unsigned rep, p;
233
234         FLAC__ASSERT(pattern != 0);
235
236         if(0 == (f = fopen(fn, mode)))
237                 return false;
238
239         for(rep = 0; rep < reps; rep++) {
240                 for(p = 0; pattern[p]; p++) {
241                         FLAC__int32 x = pattern[p] > 0? 8388607 : -8388608;
242                         FLAC__byte *b = (FLAC__byte*)(&x);
243                         swap24(b);
244                         if(fwrite(b, 3, 1, f) < 1)
245                                 goto foo;
246                 }
247         }
248
249         fclose(f);
250         return true;
251 foo:
252         fclose(f);
253         return false;
254 }
255
256 /* a mono sine-wave 16bps stream */
257 static FLAC__bool generate_sine16_1(const char *fn, const double sample_rate, const unsigned samples, const double f1, const double a1, const double f2, const double a2)
258 {
259         const FLAC__int16 full_scale = 32767;
260         const double delta1 = 2.0 * M_PI / ( sample_rate / f1);
261         const double delta2 = 2.0 * M_PI / ( sample_rate / f2);
262         FILE *f;
263         double theta1, theta2;
264         unsigned i;
265
266         if(0 == (f = fopen(fn, mode)))
267                 return false;
268
269         for(i = 0, theta1 = theta2 = 0.0; i < samples; i++, theta1 += delta1, theta2 += delta2) {
270                 double val = (a1*sin(theta1) + a2*sin(theta2))*(double)full_scale;
271                 FLAC__int16 v = (FLAC__int16)(val + 0.5);
272                 swap16(&v);
273                 if(fwrite(&v, sizeof(v), 1, f) < 1)
274                         goto foo;
275         }
276
277         fclose(f);
278         return true;
279 foo:
280         fclose(f);
281         return false;
282 }
283
284 /* a stereo sine-wave 16bps stream */
285 static FLAC__bool generate_sine16_2(const char *fn, const double sample_rate, const unsigned samples, const double f1, const double a1, const double f2, const double a2, double fmult)
286 {
287         const FLAC__int16 full_scale = 32767;
288         const double delta1 = 2.0 * M_PI / ( sample_rate / f1);
289         const double delta2 = 2.0 * M_PI / ( sample_rate / f2);
290         FILE *f;
291         double theta1, theta2;
292         unsigned i;
293
294         if(0 == (f = fopen(fn, mode)))
295                 return false;
296
297         for(i = 0, theta1 = theta2 = 0.0; i < samples; i++, theta1 += delta1, theta2 += delta2) {
298                 double val = (a1*sin(theta1) + a2*sin(theta2))*(double)full_scale;
299                 FLAC__int16 v = (FLAC__int16)(val + 0.5);
300                 swap16(&v);
301                 if(fwrite(&v, sizeof(v), 1, f) < 1)
302                         goto foo;
303                 val = -(a1*sin(theta1*fmult) + a2*sin(theta2*fmult))*(double)full_scale;
304                 v = (FLAC__int16)(val + 0.5);
305                 swap16(&v);
306                 if(fwrite(&v, sizeof(v), 1, f) < 1)
307                         goto foo;
308         }
309
310         fclose(f);
311         return true;
312 foo:
313         fclose(f);
314         return false;
315 }
316
317 /* a mono sine-wave 24bps stream */
318 static FLAC__bool generate_sine24_1(const char *fn, const double sample_rate, const unsigned samples, const double f1, const double a1, const double f2, const double a2)
319 {
320         const FLAC__int32 full_scale = 0x7fffff;
321         const double delta1 = 2.0 * M_PI / ( sample_rate / f1);
322         const double delta2 = 2.0 * M_PI / ( sample_rate / f2);
323         FILE *f;
324         double theta1, theta2;
325         unsigned i;
326
327         if(0 == (f = fopen(fn, mode)))
328                 return false;
329
330         for(i = 0, theta1 = theta2 = 0.0; i < samples; i++, theta1 += delta1, theta2 += delta2) {
331                 double val = (a1*sin(theta1) + a2*sin(theta2))*(double)full_scale;
332                 FLAC__int32 v = (FLAC__int32)(val + 0.5);
333                 FLAC__byte *b = (FLAC__byte*)(&v);
334                 swap24(b);
335                 if(fwrite(b, 3, 1, f) < 1)
336                         goto foo;
337         }
338
339         fclose(f);
340         return true;
341 foo:
342         fclose(f);
343         return false;
344 }
345
346 /* a stereo sine-wave 24bps stream */
347 static FLAC__bool generate_sine24_2(const char *fn, const double sample_rate, const unsigned samples, const double f1, const double a1, const double f2, const double a2, double fmult)
348 {
349         const FLAC__int32 full_scale = 0x7fffff;
350         const double delta1 = 2.0 * M_PI / ( sample_rate / f1);
351         const double delta2 = 2.0 * M_PI / ( sample_rate / f2);
352         FILE *f;
353         double theta1, theta2;
354         unsigned i;
355
356         if(0 == (f = fopen(fn, mode)))
357                 return false;
358
359         for(i = 0, theta1 = theta2 = 0.0; i < samples; i++, theta1 += delta1, theta2 += delta2) {
360                 double val = (a1*sin(theta1) + a2*sin(theta2))*(double)full_scale;
361                 FLAC__int32 v = (FLAC__int32)(val + 0.5);
362                 FLAC__byte *b = (FLAC__byte*)(&v);
363                 swap24(b);
364                 if(fwrite(b, 3, 1, f) < 1)
365                         goto foo;
366                 val = -(a1*sin(theta1*fmult) + a2*sin(theta2*fmult))*(double)full_scale;
367                 v = (FLAC__int32)(val + 0.5);
368                 swap24(b);
369                 if(fwrite(b, 3, 1, f) < 1)
370                         goto foo;
371         }
372
373         fclose(f);
374         return true;
375 foo:
376         fclose(f);
377         return false;
378 }
379
380 static FLAC__bool generate_noise(const char *fn, unsigned bytes)
381 {
382         FILE *f;
383         struct timeval tv;
384         unsigned b;
385
386         if(gettimeofday(&tv, 0) < 0) {
387                 fprintf(stderr, "WARNING: couldn't seed RNG with time\n");
388                 tv.tv_usec = 4321;
389         }
390         srandom(tv.tv_usec);
391
392         if(0 == (f = fopen(fn, mode)))
393                 return false;
394
395         for(b = 0; b < bytes; b++) {
396                 FLAC__byte x = (FLAC__byte)(((unsigned)random()) & 0xff);
397                 if(fwrite(&x, sizeof(x), 1, f) < 1)
398                         goto foo;
399         }
400
401         fclose(f);
402         return true;
403 foo:
404         fclose(f);
405         return false;
406 }
407
408 static FLAC__bool generate_wackywavs()
409 {
410         FILE *f;
411         FLAC__byte wav[] = {
412                 'R', 'I', 'F', 'F',  76,   0,   0,   0,
413                 'W', 'A', 'V', 'E', 'f', 'a', 'c', 't',
414                   4,   0,   0,  0 , 'b', 'l', 'a', 'h',
415                 'p', 'a', 'd', ' ',   4,   0,   0,   0,
416                 'B', 'L', 'A', 'H', 'f', 'm', 't', ' ',
417                  16,   0,   0,   0,   1,   0,   1,   0,
418                 0x44,0xAC,  0,   0,   0,   0,   0,   0,
419                   2,   0,  16,   0, 'd', 'a', 't', 'a',
420                  16,   0,   0,   0,   0,   0,   1,   0,
421                   4,   0,   9,   0,  16,   0,  25,   0,
422                  36,   0,  49,   0, 'p', 'a', 'd', ' ',
423                   4,   0,   0,   0, 'b', 'l', 'a', 'h'
424         };
425
426         if(0 == (f = fopen("wacky1.wav", mode)))
427                 return false;
428         if(fwrite(wav, 1, 84, f) < 84)
429                 goto foo;
430         fclose(f);
431
432         wav[4] += 12;
433         if(0 == (f = fopen("wacky2.wav", mode)))
434                 return false;
435         if(fwrite(wav, 1, 96, f) < 96)
436                 goto foo;
437         fclose(f);
438
439         return true;
440 foo:
441         fclose(f);
442         return false;
443 }
444
445 int main(int argc, char *argv[])
446 {
447         FLAC__uint32 test = 1;
448
449         int pattern01[] = { 1, -1, 0 };
450         int pattern02[] = { 1, 1, -1, 0 };
451         int pattern03[] = { 1, -1, -1, 0 };
452         int pattern04[] = { 1, -1, 1, -1, 0 };
453         int pattern05[] = { 1, -1, -1, 1, 0 };
454         int pattern06[] = { 1, -1, 1, 1, -1, 0 };
455         int pattern07[] = { 1, -1, -1, 1, -1, 0 };
456
457         (void)argc;
458         (void)argv;
459         is_big_endian_host = (*((FLAC__byte*)(&test)))? false : true;
460
461         if(!generate_01()) return 1;
462         if(!generate_02()) return 1;
463         if(!generate_03()) return 1;
464         if(!generate_04()) return 1;
465
466         if(!generate_fsd8("fsd8-01.raw", pattern01, 100)) return 1;
467         if(!generate_fsd8("fsd8-02.raw", pattern02, 100)) return 1;
468         if(!generate_fsd8("fsd8-03.raw", pattern03, 100)) return 1;
469         if(!generate_fsd8("fsd8-04.raw", pattern04, 100)) return 1;
470         if(!generate_fsd8("fsd8-05.raw", pattern05, 100)) return 1;
471         if(!generate_fsd8("fsd8-06.raw", pattern06, 100)) return 1;
472         if(!generate_fsd8("fsd8-07.raw", pattern07, 100)) return 1;
473
474         if(!generate_fsd16("fsd16-01.raw", pattern01, 100)) return 1;
475         if(!generate_fsd16("fsd16-02.raw", pattern02, 100)) return 1;
476         if(!generate_fsd16("fsd16-03.raw", pattern03, 100)) return 1;
477         if(!generate_fsd16("fsd16-04.raw", pattern04, 100)) return 1;
478         if(!generate_fsd16("fsd16-05.raw", pattern05, 100)) return 1;
479         if(!generate_fsd16("fsd16-06.raw", pattern06, 100)) return 1;
480         if(!generate_fsd16("fsd16-07.raw", pattern07, 100)) return 1;
481
482         if(!generate_fsd24("fsd24-01.raw", pattern01, 100)) return 1;
483         if(!generate_fsd24("fsd24-02.raw", pattern02, 100)) return 1;
484         if(!generate_fsd24("fsd24-03.raw", pattern03, 100)) return 1;
485         if(!generate_fsd24("fsd24-04.raw", pattern04, 100)) return 1;
486         if(!generate_fsd24("fsd24-05.raw", pattern05, 100)) return 1;
487         if(!generate_fsd24("fsd24-06.raw", pattern06, 100)) return 1;
488         if(!generate_fsd24("fsd24-07.raw", pattern07, 100)) return 1;
489
490         if(!generate_wbps16("wbps16-01.raw", 1000)) return 1;
491
492         if(!generate_sine16_1("sine16-00.raw", 44100.0, 80000, 441.0, 0.50, 441.0, 0.49)) return 1;
493         if(!generate_sine16_1("sine16-01.raw", 44100.0, 80000, 441.0, 0.61, 661.5, 0.37)) return 1;
494         if(!generate_sine16_1("sine16-02.raw", 44100.0, 80000, 441.0, 0.50, 882.0, 0.49)) return 1;
495         if(!generate_sine16_1("sine16-03.raw", 44100.0, 80000, 441.0, 0.50, 4410.0, 0.49)) return 1;
496         if(!generate_sine16_1("sine16-04.raw", 44100.0, 50000, 8820.0, 0.70, 4410.0, 0.29)) return 1;
497
498         if(!generate_sine16_2("sine16-10.raw", 44100.0, 80000, 441.0, 0.50, 441.0, 0.49, 1.0)) return 1;
499         if(!generate_sine16_2("sine16-11.raw", 44100.0, 80000, 441.0, 0.61, 661.5, 0.37, 1.0)) return 1;
500         if(!generate_sine16_2("sine16-12.raw", 44100.0, 80000, 441.0, 0.50, 882.0, 0.49, 1.0)) return 1;
501         if(!generate_sine16_2("sine16-13.raw", 44100.0, 80000, 441.0, 0.50, 4410.0, 0.49, 1.0)) return 1;
502         if(!generate_sine16_2("sine16-14.raw", 44100.0, 50000, 8820.0, 0.70, 4410.0, 0.29, 1.0)) return 1;
503         if(!generate_sine16_2("sine16-15.raw", 44100.0, 80000, 441.0, 0.50, 441.0, 0.49, 0.5)) return 1;
504         if(!generate_sine16_2("sine16-16.raw", 44100.0, 80000, 441.0, 0.61, 661.5, 0.37, 2.0)) return 1;
505         if(!generate_sine16_2("sine16-17.raw", 44100.0, 80000, 441.0, 0.50, 882.0, 0.49, 0.7)) return 1;
506         if(!generate_sine16_2("sine16-18.raw", 44100.0, 80000, 441.0, 0.50, 4410.0, 0.49, 1.3)) return 1;
507         if(!generate_sine16_2("sine16-19.raw", 44100.0, 50000, 8820.0, 0.70, 4410.0, 0.29, 0.1)) return 1;
508
509         if(!generate_sine24_1("sine24-00.raw", 44100.0, 80000, 441.0, 0.50, 441.0, 0.49)) return 1;
510         if(!generate_sine24_1("sine24-01.raw", 44100.0, 80000, 441.0, 0.61, 661.5, 0.37)) return 1;
511         if(!generate_sine24_1("sine24-02.raw", 44100.0, 80000, 441.0, 0.50, 882.0, 0.49)) return 1;
512         if(!generate_sine24_1("sine24-03.raw", 44100.0, 80000, 441.0, 0.50, 4410.0, 0.49)) return 1;
513         if(!generate_sine24_1("sine24-04.raw", 44100.0, 50000, 8820.0, 0.70, 4410.0, 0.29)) return 1;
514
515         if(!generate_sine24_2("sine24-10.raw", 44100.0, 80000, 441.0, 0.50, 441.0, 0.49, 1.0)) return 1;
516         if(!generate_sine24_2("sine24-11.raw", 44100.0, 80000, 441.0, 0.61, 661.5, 0.37, 1.0)) return 1;
517         if(!generate_sine24_2("sine24-12.raw", 44100.0, 80000, 441.0, 0.50, 882.0, 0.49, 1.0)) return 1;
518         if(!generate_sine24_2("sine24-13.raw", 44100.0, 80000, 441.0, 0.50, 4410.0, 0.49, 1.0)) return 1;
519         if(!generate_sine24_2("sine24-14.raw", 44100.0, 50000, 8820.0, 0.70, 4410.0, 0.29, 1.0)) return 1;
520         if(!generate_sine24_2("sine24-15.raw", 44100.0, 80000, 441.0, 0.50, 441.0, 0.49, 0.5)) return 1;
521         if(!generate_sine24_2("sine24-16.raw", 44100.0, 80000, 441.0, 0.61, 661.5, 0.37, 2.0)) return 1;
522         if(!generate_sine24_2("sine24-17.raw", 44100.0, 80000, 441.0, 0.50, 882.0, 0.49, 0.7)) return 1;
523         if(!generate_sine24_2("sine24-18.raw", 44100.0, 80000, 441.0, 0.50, 4410.0, 0.49, 1.3)) return 1;
524         if(!generate_sine24_2("sine24-19.raw", 44100.0, 50000, 8820.0, 0.70, 4410.0, 0.29, 0.1)) return 1;
525
526         if(!generate_noise("noise.raw", 65536 * 8 * 3)) return 1;
527         if(!generate_wackywavs()) return 1;
528
529         return 0;
530 }