OS/2 fixes (SF#1229495: https://sourceforge.net/tracker/index.php?func=detail&aid...
[platform/upstream/flac.git] / src / test_streams / main.c
1 /* test_streams - Simple test pattern generator
2  * Copyright (C) 2000,2001,2002,2003,2004,2005,2006,2007  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 #if HAVE_CONFIG_H
20 #  include <config.h>
21 #endif
22
23 #include <math.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #if defined _MSC_VER || defined __MINGW32__
27 #include <time.h>
28 #else
29 #include <sys/time.h>
30 #endif
31 #include "FLAC/assert.h"
32 #include "FLAC/ordinals.h"
33
34 #ifndef M_PI
35 /* math.h in VC++ doesn't seem to have this (how Microsoft is that?) */
36 #define M_PI 3.14159265358979323846
37 #endif
38
39 #if !defined _MSC_VER && !defined __MINGW32__
40 #define GET_RANDOM_BYTE (((unsigned)random()) & 0xff)
41 #else
42 #define GET_RANDOM_BYTE (((unsigned)rand()) & 0xff)
43 #endif
44
45 static FLAC__bool is_big_endian_host;
46
47
48 static FLAC__bool write_little_endian(FILE *f, FLAC__int32 x, size_t bytes)
49 {
50         while(bytes) {
51                 if(fputc(x, f) == EOF)
52                         return false;
53                 x >>= 8;
54                 bytes--;
55         }
56         return true;
57 }
58
59 static FLAC__bool write_little_endian_uint16(FILE *f, FLAC__uint16 x)
60 {
61         return
62                 fputc(x, f) != EOF &&
63                 fputc(x >> 8, f) != EOF
64         ;
65 }
66
67 static FLAC__bool write_little_endian_int16(FILE *f, FLAC__int16 x)
68 {
69         return write_little_endian_uint16(f, (FLAC__uint16)x);
70 }
71
72 static FLAC__bool write_little_endian_uint24(FILE *f, FLAC__uint32 x)
73 {
74         return
75                 fputc(x, f) != EOF &&
76                 fputc(x >> 8, f) != EOF &&
77                 fputc(x >> 16, f) != EOF
78         ;
79 }
80
81 static FLAC__bool write_little_endian_int24(FILE *f, FLAC__int32 x)
82 {
83         return write_little_endian_uint24(f, (FLAC__uint32)x);
84 }
85
86 static FLAC__bool write_little_endian_uint32(FILE *f, FLAC__uint32 x)
87 {
88         return
89                 fputc(x, f) != EOF &&
90                 fputc(x >> 8, f) != EOF &&
91                 fputc(x >> 16, f) != EOF &&
92                 fputc(x >> 24, f) != EOF
93         ;
94 }
95
96 #if 0
97 /* @@@ not used (yet) */
98 static FLAC__bool write_little_endian_int32(FILE *f, FLAC__int32 x)
99 {
100         return write_little_endian_uint32(f, (FLAC__uint32)x);
101 }
102 #endif
103
104 static FLAC__bool write_big_endian(FILE *f, FLAC__int32 x, size_t bytes)
105 {
106         if(bytes < 4)
107                 x <<= 8*(4-bytes);
108         while(bytes) {
109                 if(fputc(x>>24, f) == EOF)
110                         return false;
111                 x <<= 8;
112                 bytes--;
113         }
114         return true;
115 }
116
117 static FLAC__bool write_big_endian_uint16(FILE *f, FLAC__uint16 x)
118 {
119         return
120                 fputc(x >> 8, f) != EOF &&
121                 fputc(x, f) != EOF
122         ;
123 }
124
125 #if 0
126 /* @@@ not used (yet) */
127 static FLAC__bool write_big_endian_int16(FILE *f, FLAC__int16 x)
128 {
129         return write_big_endian_uint16(f, (FLAC__uint16)x);
130 }
131 #endif
132
133 #if 0
134 /* @@@ not used (yet) */
135 static FLAC__bool write_big_endian_uint24(FILE *f, FLAC__uint32 x)
136 {
137         return
138                 fputc(x >> 16, f) != EOF &&
139                 fputc(x >> 8, f) != EOF &&
140                 fputc(x, f) != EOF
141         ;
142 }
143 #endif
144
145 #if 0
146 /* @@@ not used (yet) */
147 static FLAC__bool write_big_endian_int24(FILE *f, FLAC__int32 x)
148 {
149         return write_big_endian_uint24(f, (FLAC__uint32)x);
150 }
151 #endif
152
153 static FLAC__bool write_big_endian_uint32(FILE *f, FLAC__uint32 x)
154 {
155         return
156                 fputc(x >> 24, f) != EOF &&
157                 fputc(x >> 16, f) != EOF &&
158                 fputc(x >> 8, f) != EOF &&
159                 fputc(x, f) != EOF
160         ;
161 }
162
163 #if 0
164 /* @@@ not used (yet) */
165 static FLAC__bool write_big_endian_int32(FILE *f, FLAC__int32 x)
166 {
167         return write_big_endian_uint32(f, (FLAC__uint32)x);
168 }
169 #endif
170
171 static FLAC__bool write_sane_extended(FILE *f, unsigned val)
172         /* Write to 'f' a SANE extended representation of 'val'.  Return false if
173         * the write succeeds; return true otherwise.
174         *
175         * SANE extended is an 80-bit IEEE-754 representation with sign bit, 15 bits
176         * of exponent, and 64 bits of significand (mantissa).  Unlike most IEEE-754
177         * representations, it does not imply a 1 above the MSB of the significand.
178         *
179         * Preconditions:
180         *  val!=0U
181         */
182 {
183         unsigned int shift, exponent;
184
185         FLAC__ASSERT(val!=0U); /* handling 0 would require a special case */
186
187         for(shift= 0U; (val>>(31-shift))==0U; ++shift)
188                 ;
189         val<<= shift;
190         exponent= 63U-(shift+32U); /* add 32 for unused second word */
191
192         if(!write_big_endian_uint16(f, (FLAC__uint16)(exponent+0x3FFF)))
193                 return false;
194         if(!write_big_endian_uint32(f, val))
195                 return false;
196         if(!write_big_endian_uint32(f, 0)) /* unused second word */
197                 return false;
198
199         return true;
200 }
201
202 /* a mono one-sample 16bps stream */
203 static FLAC__bool generate_01(void)
204 {
205         FILE *f;
206         FLAC__int16 x = -32768;
207
208         if(0 == (f = fopen("test01.raw", "wb")))
209                 return false;
210
211         if(!write_little_endian_int16(f, x))
212                 goto foo;
213
214         fclose(f);
215         return true;
216 foo:
217         fclose(f);
218         return false;
219 }
220
221 /* a stereo one-sample 16bps stream */
222 static FLAC__bool generate_02(void)
223 {
224         FILE *f;
225         FLAC__int16 xl = -32768, xr = 32767;
226
227         if(0 == (f = fopen("test02.raw", "wb")))
228                 return false;
229
230         if(!write_little_endian_int16(f, xl))
231                 goto foo;
232         if(!write_little_endian_int16(f, xr))
233                 goto foo;
234
235         fclose(f);
236         return true;
237 foo:
238         fclose(f);
239         return false;
240 }
241
242 /* a mono five-sample 16bps stream */
243 static FLAC__bool generate_03(void)
244 {
245         FILE *f;
246         FLAC__int16 x[] = { -25, 0, 25, 50, 100 };
247         unsigned i;
248
249         if(0 == (f = fopen("test03.raw", "wb")))
250                 return false;
251
252         for(i = 0; i < 5; i++)
253                 if(!write_little_endian_int16(f, x[i]))
254                         goto foo;
255
256         fclose(f);
257         return true;
258 foo:
259         fclose(f);
260         return false;
261 }
262
263 /* a stereo five-sample 16bps stream */
264 static FLAC__bool generate_04(void)
265 {
266         FILE *f;
267         FLAC__int16 x[] = { -25, 500, 0, 400, 25, 300, 50, 200, 100, 100 };
268         unsigned i;
269
270         if(0 == (f = fopen("test04.raw", "wb")))
271                 return false;
272
273         for(i = 0; i < 10; i++)
274                 if(!write_little_endian_int16(f, x[i]))
275                         goto foo;
276
277         fclose(f);
278         return true;
279 foo:
280         fclose(f);
281         return false;
282 }
283
284 /* a mono full-scale deflection 8bps stream */
285 static FLAC__bool generate_fsd8(const char *fn, const int pattern[], unsigned reps)
286 {
287         FILE *f;
288         unsigned rep, p;
289
290         FLAC__ASSERT(pattern != 0);
291
292         if(0 == (f = fopen(fn, "wb")))
293                 return false;
294
295         for(rep = 0; rep < reps; rep++) {
296                 for(p = 0; pattern[p]; p++) {
297                         signed char x = pattern[p] > 0? 127 : -128;
298                         if(fwrite(&x, sizeof(x), 1, f) < 1)
299                                 goto foo;
300                 }
301         }
302
303         fclose(f);
304         return true;
305 foo:
306         fclose(f);
307         return false;
308 }
309
310 /* a mono full-scale deflection 16bps stream */
311 static FLAC__bool generate_fsd16(const char *fn, const int pattern[], unsigned reps)
312 {
313         FILE *f;
314         unsigned rep, p;
315
316         FLAC__ASSERT(pattern != 0);
317
318         if(0 == (f = fopen(fn, "wb")))
319                 return false;
320
321         for(rep = 0; rep < reps; rep++) {
322                 for(p = 0; pattern[p]; p++) {
323                         FLAC__int16 x = pattern[p] > 0? 32767 : -32768;
324                         if(!write_little_endian_int16(f, x))
325                                 goto foo;
326                 }
327         }
328
329         fclose(f);
330         return true;
331 foo:
332         fclose(f);
333         return false;
334 }
335
336 /* a stereo wasted-bits-per-sample 16bps stream */
337 static FLAC__bool generate_wbps16(const char *fn, unsigned samples)
338 {
339         FILE *f;
340         unsigned sample;
341
342         if(0 == (f = fopen(fn, "wb")))
343                 return false;
344
345         for(sample = 0; sample < samples; sample++) {
346                 FLAC__int16 l = (sample % 2000) << 2;
347                 FLAC__int16 r = (sample % 1000) << 3;
348                 if(!write_little_endian_int16(f, l))
349                         goto foo;
350                 if(!write_little_endian_int16(f, r))
351                         goto foo;
352         }
353
354         fclose(f);
355         return true;
356 foo:
357         fclose(f);
358         return false;
359 }
360
361 /* a mono full-scale deflection 24bps stream */
362 static FLAC__bool generate_fsd24(const char *fn, const int pattern[], unsigned reps)
363 {
364         FILE *f;
365         unsigned rep, p;
366
367         FLAC__ASSERT(pattern != 0);
368
369         if(0 == (f = fopen(fn, "wb")))
370                 return false;
371
372         for(rep = 0; rep < reps; rep++) {
373                 for(p = 0; pattern[p]; p++) {
374                         FLAC__int32 x = pattern[p] > 0? 8388607 : -8388608;
375                         if(!write_little_endian_int24(f, x))
376                                 goto foo;
377                 }
378         }
379
380         fclose(f);
381         return true;
382 foo:
383         fclose(f);
384         return false;
385 }
386
387 /* a mono sine-wave 8bps stream */
388 static FLAC__bool generate_sine8_1(const char *fn, const double sample_rate, const unsigned samples, const double f1, const double a1, const double f2, const double a2)
389 {
390         const FLAC__int8 full_scale = 127;
391         const double delta1 = 2.0 * M_PI / ( sample_rate / f1);
392         const double delta2 = 2.0 * M_PI / ( sample_rate / f2);
393         FILE *f;
394         double theta1, theta2;
395         unsigned i;
396
397         if(0 == (f = fopen(fn, "wb")))
398                 return false;
399
400         for(i = 0, theta1 = theta2 = 0.0; i < samples; i++, theta1 += delta1, theta2 += delta2) {
401                 double val = (a1*sin(theta1) + a2*sin(theta2))*(double)full_scale;
402                 FLAC__int8 v = (FLAC__int8)(val + 0.5);
403                 if(fwrite(&v, sizeof(v), 1, f) < 1)
404                         goto foo;
405         }
406
407         fclose(f);
408         return true;
409 foo:
410         fclose(f);
411         return false;
412 }
413
414 /* a stereo sine-wave 8bps stream */
415 static FLAC__bool generate_sine8_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)
416 {
417         const FLAC__int8 full_scale = 127;
418         const double delta1 = 2.0 * M_PI / ( sample_rate / f1);
419         const double delta2 = 2.0 * M_PI / ( sample_rate / f2);
420         FILE *f;
421         double theta1, theta2;
422         unsigned i;
423
424         if(0 == (f = fopen(fn, "wb")))
425                 return false;
426
427         for(i = 0, theta1 = theta2 = 0.0; i < samples; i++, theta1 += delta1, theta2 += delta2) {
428                 double val = (a1*sin(theta1) + a2*sin(theta2))*(double)full_scale;
429                 FLAC__int8 v = (FLAC__int8)(val + 0.5);
430                 if(fwrite(&v, sizeof(v), 1, f) < 1)
431                         goto foo;
432                 val = -(a1*sin(theta1*fmult) + a2*sin(theta2*fmult))*(double)full_scale;
433                 v = (FLAC__int8)(val + 0.5);
434                 if(fwrite(&v, sizeof(v), 1, f) < 1)
435                         goto foo;
436         }
437
438         fclose(f);
439         return true;
440 foo:
441         fclose(f);
442         return false;
443 }
444
445 /* a mono sine-wave 16bps stream */
446 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)
447 {
448         const FLAC__int16 full_scale = 32767;
449         const double delta1 = 2.0 * M_PI / ( sample_rate / f1);
450         const double delta2 = 2.0 * M_PI / ( sample_rate / f2);
451         FILE *f;
452         double theta1, theta2;
453         unsigned i;
454
455         if(0 == (f = fopen(fn, "wb")))
456                 return false;
457
458         for(i = 0, theta1 = theta2 = 0.0; i < samples; i++, theta1 += delta1, theta2 += delta2) {
459                 double val = (a1*sin(theta1) + a2*sin(theta2))*(double)full_scale;
460                 FLAC__int16 v = (FLAC__int16)(val + 0.5);
461                 if(!write_little_endian_int16(f, v))
462                         goto foo;
463         }
464
465         fclose(f);
466         return true;
467 foo:
468         fclose(f);
469         return false;
470 }
471
472 /* a stereo sine-wave 16bps stream */
473 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)
474 {
475         const FLAC__int16 full_scale = 32767;
476         const double delta1 = 2.0 * M_PI / ( sample_rate / f1);
477         const double delta2 = 2.0 * M_PI / ( sample_rate / f2);
478         FILE *f;
479         double theta1, theta2;
480         unsigned i;
481
482         if(0 == (f = fopen(fn, "wb")))
483                 return false;
484
485         for(i = 0, theta1 = theta2 = 0.0; i < samples; i++, theta1 += delta1, theta2 += delta2) {
486                 double val = (a1*sin(theta1) + a2*sin(theta2))*(double)full_scale;
487                 FLAC__int16 v = (FLAC__int16)(val + 0.5);
488                 if(!write_little_endian_int16(f, v))
489                         goto foo;
490                 val = -(a1*sin(theta1*fmult) + a2*sin(theta2*fmult))*(double)full_scale;
491                 v = (FLAC__int16)(val + 0.5);
492                 if(!write_little_endian_int16(f, v))
493                         goto foo;
494         }
495
496         fclose(f);
497         return true;
498 foo:
499         fclose(f);
500         return false;
501 }
502
503 /* a mono sine-wave 24bps stream */
504 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)
505 {
506         const FLAC__int32 full_scale = 0x7fffff;
507         const double delta1 = 2.0 * M_PI / ( sample_rate / f1);
508         const double delta2 = 2.0 * M_PI / ( sample_rate / f2);
509         FILE *f;
510         double theta1, theta2;
511         unsigned i;
512
513         if(0 == (f = fopen(fn, "wb")))
514                 return false;
515
516         for(i = 0, theta1 = theta2 = 0.0; i < samples; i++, theta1 += delta1, theta2 += delta2) {
517                 double val = (a1*sin(theta1) + a2*sin(theta2))*(double)full_scale;
518                 FLAC__int32 v = (FLAC__int32)(val + 0.5);
519                 if(!write_little_endian_int24(f, v))
520                         goto foo;
521         }
522
523         fclose(f);
524         return true;
525 foo:
526         fclose(f);
527         return false;
528 }
529
530 /* a stereo sine-wave 24bps stream */
531 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)
532 {
533         const FLAC__int32 full_scale = 0x7fffff;
534         const double delta1 = 2.0 * M_PI / ( sample_rate / f1);
535         const double delta2 = 2.0 * M_PI / ( sample_rate / f2);
536         FILE *f;
537         double theta1, theta2;
538         unsigned i;
539
540         if(0 == (f = fopen(fn, "wb")))
541                 return false;
542
543         for(i = 0, theta1 = theta2 = 0.0; i < samples; i++, theta1 += delta1, theta2 += delta2) {
544                 double val = (a1*sin(theta1) + a2*sin(theta2))*(double)full_scale;
545                 FLAC__int32 v = (FLAC__int32)(val + 0.5);
546                 if(!write_little_endian_int24(f, v))
547                         goto foo;
548                 val = -(a1*sin(theta1*fmult) + a2*sin(theta2*fmult))*(double)full_scale;
549                 v = (FLAC__int32)(val + 0.5);
550                 if(!write_little_endian_int24(f, v))
551                         goto foo;
552         }
553
554         fclose(f);
555         return true;
556 foo:
557         fclose(f);
558         return false;
559 }
560
561 static FLAC__bool generate_noise(const char *fn, unsigned bytes)
562 {
563         FILE *f;
564         unsigned b;
565
566         if(0 == (f = fopen(fn, "wb")))
567                 return false;
568
569         for(b = 0; b < bytes; b++) {
570 #if !defined _MSC_VER && !defined __MINGW32__
571                 FLAC__byte x = (FLAC__byte)(((unsigned)random()) & 0xff);
572 #else
573                 FLAC__byte x = (FLAC__byte)(((unsigned)rand()) & 0xff);
574 #endif
575                 if(fwrite(&x, sizeof(x), 1, f) < 1)
576                         goto foo;
577         }
578
579         fclose(f);
580         return true;
581 foo:
582         fclose(f);
583         return false;
584 }
585
586 static FLAC__bool generate_raw(const char *filename, unsigned channels, unsigned bytes_per_sample, unsigned samples)
587 {
588         const FLAC__int32 full_scale = (1 << (bytes_per_sample*8-1)) - 1;
589         const double f1 = 441.0, a1 = 0.61, f2 = 661.5, a2 = 0.37;
590         const double delta1 = 2.0 * M_PI / ( 44100.0 / f1);
591         const double delta2 = 2.0 * M_PI / ( 44100.0 / f2);
592         double theta1, theta2;
593         FILE *f;
594         unsigned i, j;
595
596         if(0 == (f = fopen(filename, "wb")))
597                 return false;
598
599         for(i = 0, theta1 = theta2 = 0.0; i < samples; i++, theta1 += delta1, theta2 += delta2) {
600                 for(j = 0; j < channels; j++) {
601                         double val = (a1*sin(theta1) + a2*sin(theta2))*(double)full_scale;
602                         FLAC__int32 v = (FLAC__int32)(val + 0.5) + ((GET_RANDOM_BYTE>>4)-8);
603                         if(!write_little_endian(f, v, bytes_per_sample))
604                                 goto foo;
605                 }
606         }
607
608         fclose(f);
609         return true;
610 foo:
611         fclose(f);
612         return false;
613 }
614
615 static FLAC__bool generate_aiff(const char *filename, unsigned sample_rate, unsigned channels, unsigned bps, unsigned samples)
616 {
617         const unsigned bytes_per_sample = (bps+7)/8;
618         const unsigned true_size = channels * bytes_per_sample * samples;
619         const unsigned padded_size = (true_size + 1) & (~1u);
620         const unsigned shift = (bps%8)? 8 - (bps%8) : 0;
621         const FLAC__int32 full_scale = (1 << (bps-1)) - 1;
622         const double f1 = 441.0, a1 = 0.61, f2 = 661.5, a2 = 0.37;
623         const double delta1 = 2.0 * M_PI / ( sample_rate / f1);
624         const double delta2 = 2.0 * M_PI / ( sample_rate / f2);
625         double theta1, theta2;
626         FILE *f;
627         unsigned i, j;
628
629         if(0 == (f = fopen(filename, "wb")))
630                 return false;
631         if(fwrite("FORM", 1, 4, f) < 4)
632                 goto foo;
633         if(!write_big_endian_uint32(f, padded_size + 46))
634                 goto foo;
635         if(fwrite("AIFFCOMM\000\000\000\022", 1, 12, f) < 12)
636                 goto foo;
637         if(!write_big_endian_uint16(f, (FLAC__uint16)channels))
638                 goto foo;
639         if(!write_big_endian_uint32(f, samples))
640                 goto foo;
641         if(!write_big_endian_uint16(f, (FLAC__uint16)bps))
642                 goto foo;
643         if(!write_sane_extended(f, sample_rate))
644                 goto foo;
645         if(fwrite("SSND", 1, 4, f) < 4)
646                 goto foo;
647         if(!write_big_endian_uint32(f, true_size + 8))
648                 goto foo;
649         if(fwrite("\000\000\000\000\000\000\000\000", 1, 8, f) < 8)
650                 goto foo;
651
652         for(i = 0, theta1 = theta2 = 0.0; i < samples; i++, theta1 += delta1, theta2 += delta2) {
653                 for(j = 0; j < channels; j++) {
654                         double val = (a1*sin(theta1) + a2*sin(theta2))*(double)full_scale;
655                         FLAC__int32 v = ((FLAC__int32)(val + 0.5) + ((GET_RANDOM_BYTE>>4)-8)) << shift;
656                         if(!write_big_endian(f, v, bytes_per_sample))
657                                 goto foo;
658                 }
659         }
660         for(i = true_size; i < padded_size; i++)
661                 if(fputc(0, f) == EOF)
662                         goto foo;
663
664         fclose(f);
665         return true;
666 foo:
667         fclose(f);
668         return false;
669 }
670
671 static FLAC__bool generate_wav(const char *filename, unsigned sample_rate, unsigned channels, unsigned bps, unsigned samples, FLAC__bool strict)
672 {
673         const FLAC__bool waveformatextensible = strict && (channels > 2 || (bps%8));
674         /*                                                                 ^^^^^^^
675          * (bps%8) allows 24 bps which is technically supposed to be WAVEFORMATEXTENSIBLE but we
676          * write 24bps as WAVEFORMATEX since it's unambiguous and matches how flac writes it
677          */
678         const unsigned bytes_per_sample = (bps+7)/8;
679         const unsigned true_size = channels * bytes_per_sample * samples;
680         const unsigned padded_size = (true_size + 1) & (~1u);
681         const unsigned shift = (bps%8)? 8 - (bps%8) : 0;
682         const FLAC__int32 full_scale = (1 << (bps-1)) - 1;
683         const double f1 = 441.0, a1 = 0.61, f2 = 661.5, a2 = 0.37;
684         const double delta1 = 2.0 * M_PI / ( sample_rate / f1);
685         const double delta2 = 2.0 * M_PI / ( sample_rate / f2);
686         double theta1, theta2;
687         FILE *f;
688         unsigned i, j;
689
690         if(0 == (f = fopen(filename, "wb")))
691                 return false;
692         if(fwrite("RIFF", 1, 4, f) < 4)
693                 goto foo;
694         if(!write_little_endian_uint32(f, padded_size + (waveformatextensible?60:36)))
695                 goto foo;
696         if(fwrite("WAVEfmt ", 1, 8, f) < 8)
697                 goto foo;
698         if(!write_little_endian_uint32(f, waveformatextensible?40:16))
699                 goto foo;
700         if(!write_little_endian_uint16(f, (FLAC__uint16)(waveformatextensible?65534:1)))
701                 goto foo;
702         if(!write_little_endian_uint16(f, (FLAC__uint16)channels))
703                 goto foo;
704         if(!write_little_endian_uint32(f, sample_rate))
705                 goto foo;
706         if(!write_little_endian_uint32(f, sample_rate * channels * bytes_per_sample))
707                 goto foo;
708         if(!write_little_endian_uint16(f, (FLAC__uint16)(channels * bytes_per_sample))) /* block align */
709                 goto foo;
710         if(!write_little_endian_uint16(f, (FLAC__uint16)(bps+shift)))
711                 goto foo;
712         if(waveformatextensible) {
713                 if(!write_little_endian_uint16(f, (FLAC__uint16)22)) /* cbSize */
714                         goto foo;
715                 if(!write_little_endian_uint16(f, (FLAC__uint16)bps)) /* validBitsPerSample */
716                         goto foo;
717                 if(!write_little_endian_uint32(f, 0)) /* channelMask */
718                         goto foo;
719                 /* GUID = {0x00000001, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}} */
720                 if(fwrite("\x01\x00\x00\x00\x00\x00\x10\x00\x80\x00\x00\xaa\x00\x38\x9b\x71", 1, 16, f) != 16)
721                         goto foo;
722         }
723         if(fwrite("data", 1, 4, f) < 4)
724                 goto foo;
725         if(!write_little_endian_uint32(f, true_size))
726                 goto foo;
727
728         for(i = 0, theta1 = theta2 = 0.0; i < samples; i++, theta1 += delta1, theta2 += delta2) {
729                 for(j = 0; j < channels; j++) {
730                         double val = (a1*sin(theta1) + a2*sin(theta2))*(double)full_scale;
731                         FLAC__int32 v = ((FLAC__int32)(val + 0.5) + ((GET_RANDOM_BYTE>>4)-8)) << shift;
732                         if(!write_little_endian(f, v, bytes_per_sample))
733                                 goto foo;
734                 }
735         }
736         for(i = true_size; i < padded_size; i++)
737                 if(fputc(0, f) == EOF)
738                         goto foo;
739
740         fclose(f);
741         return true;
742 foo:
743         fclose(f);
744         return false;
745 }
746
747 static FLAC__bool generate_wackywavs(void)
748 {
749         FILE *f;
750         FLAC__byte wav[] = {
751                 'R', 'I', 'F', 'F',  76,   0,   0,   0,
752                 'W', 'A', 'V', 'E', 'f', 'a', 'c', 't',
753                   4,   0,   0,  0 , 'b', 'l', 'a', 'h',
754                 'p', 'a', 'd', ' ',   4,   0,   0,   0,
755                 'B', 'L', 'A', 'H', 'f', 'm', 't', ' ',
756                  16,   0,   0,   0,   1,   0,   1,   0,
757                 0x44,0xAC,  0,   0,   0,   0,   0,   0,
758                   2,   0,  16,   0, 'd', 'a', 't', 'a',
759                  16,   0,   0,   0,   0,   0,   1,   0,
760                   4,   0,   9,   0,  16,   0,  25,   0,
761                  36,   0,  49,   0, 'p', 'a', 'd', ' ',
762                   4,   0,   0,   0, 'b', 'l', 'a', 'h'
763         };
764
765         if(0 == (f = fopen("wacky1.wav", "wb")))
766                 return false;
767         if(fwrite(wav, 1, 84, f) < 84)
768                 goto foo;
769         fclose(f);
770
771         wav[4] += 12;
772         if(0 == (f = fopen("wacky2.wav", "wb")))
773                 return false;
774         if(fwrite(wav, 1, 96, f) < 96)
775                 goto foo;
776         fclose(f);
777
778         return true;
779 foo:
780         fclose(f);
781         return false;
782 }
783
784 int main(int argc, char *argv[])
785 {
786         FLAC__uint32 test = 1;
787         unsigned channels;
788
789         int pattern01[] = { 1, -1, 0 };
790         int pattern02[] = { 1, 1, -1, 0 };
791         int pattern03[] = { 1, -1, -1, 0 };
792         int pattern04[] = { 1, -1, 1, -1, 0 };
793         int pattern05[] = { 1, -1, -1, 1, 0 };
794         int pattern06[] = { 1, -1, 1, 1, -1, 0 };
795         int pattern07[] = { 1, -1, -1, 1, -1, 0 };
796
797         (void)argc;
798         (void)argv;
799         is_big_endian_host = (*((FLAC__byte*)(&test)))? false : true;
800
801 #if !defined _MSC_VER && !defined __MINGW32__
802         {
803                 struct timeval tv;
804
805                 if(gettimeofday(&tv, 0) < 0) {
806                         fprintf(stderr, "WARNING: couldn't seed RNG with time\n");
807                         tv.tv_usec = 4321;
808                 }
809                 srandom(tv.tv_usec);
810         }
811 #else
812         srand((unsigned)time(0));
813 #endif
814
815         if(!generate_01()) return 1;
816         if(!generate_02()) return 1;
817         if(!generate_03()) return 1;
818         if(!generate_04()) return 1;
819
820         if(!generate_fsd8("fsd8-01.raw", pattern01, 100)) return 1;
821         if(!generate_fsd8("fsd8-02.raw", pattern02, 100)) return 1;
822         if(!generate_fsd8("fsd8-03.raw", pattern03, 100)) return 1;
823         if(!generate_fsd8("fsd8-04.raw", pattern04, 100)) return 1;
824         if(!generate_fsd8("fsd8-05.raw", pattern05, 100)) return 1;
825         if(!generate_fsd8("fsd8-06.raw", pattern06, 100)) return 1;
826         if(!generate_fsd8("fsd8-07.raw", pattern07, 100)) return 1;
827
828         if(!generate_fsd16("fsd16-01.raw", pattern01, 100)) return 1;
829         if(!generate_fsd16("fsd16-02.raw", pattern02, 100)) return 1;
830         if(!generate_fsd16("fsd16-03.raw", pattern03, 100)) return 1;
831         if(!generate_fsd16("fsd16-04.raw", pattern04, 100)) return 1;
832         if(!generate_fsd16("fsd16-05.raw", pattern05, 100)) return 1;
833         if(!generate_fsd16("fsd16-06.raw", pattern06, 100)) return 1;
834         if(!generate_fsd16("fsd16-07.raw", pattern07, 100)) return 1;
835
836         if(!generate_fsd24("fsd24-01.raw", pattern01, 100)) return 1;
837         if(!generate_fsd24("fsd24-02.raw", pattern02, 100)) return 1;
838         if(!generate_fsd24("fsd24-03.raw", pattern03, 100)) return 1;
839         if(!generate_fsd24("fsd24-04.raw", pattern04, 100)) return 1;
840         if(!generate_fsd24("fsd24-05.raw", pattern05, 100)) return 1;
841         if(!generate_fsd24("fsd24-06.raw", pattern06, 100)) return 1;
842         if(!generate_fsd24("fsd24-07.raw", pattern07, 100)) return 1;
843
844         if(!generate_wbps16("wbps16-01.raw", 1000)) return 1;
845
846         if(!generate_sine8_1("sine8-00.raw", 48000.0, 200000, 441.0, 0.50, 441.0, 0.49)) return 1;
847         if(!generate_sine8_1("sine8-01.raw", 96000.0, 200000, 441.0, 0.61, 661.5, 0.37)) return 1;
848         if(!generate_sine8_1("sine8-02.raw", 44100.0, 200000, 441.0, 0.50, 882.0, 0.49)) return 1;
849         if(!generate_sine8_1("sine8-03.raw", 44100.0, 200000, 441.0, 0.50, 4410.0, 0.49)) return 1;
850         if(!generate_sine8_1("sine8-04.raw", 44100.0, 200000, 8820.0, 0.70, 4410.0, 0.29)) return 1;
851
852         if(!generate_sine8_2("sine8-10.raw", 48000.0, 200000, 441.0, 0.50, 441.0, 0.49, 1.0)) return 1;
853         if(!generate_sine8_2("sine8-11.raw", 48000.0, 200000, 441.0, 0.61, 661.5, 0.37, 1.0)) return 1;
854         if(!generate_sine8_2("sine8-12.raw", 96000.0, 200000, 441.0, 0.50, 882.0, 0.49, 1.0)) return 1;
855         if(!generate_sine8_2("sine8-13.raw", 44100.0, 200000, 441.0, 0.50, 4410.0, 0.49, 1.0)) return 1;
856         if(!generate_sine8_2("sine8-14.raw", 44100.0, 200000, 8820.0, 0.70, 4410.0, 0.29, 1.0)) return 1;
857         if(!generate_sine8_2("sine8-15.raw", 44100.0, 200000, 441.0, 0.50, 441.0, 0.49, 0.5)) return 1;
858         if(!generate_sine8_2("sine8-16.raw", 44100.0, 200000, 441.0, 0.61, 661.5, 0.37, 2.0)) return 1;
859         if(!generate_sine8_2("sine8-17.raw", 44100.0, 200000, 441.0, 0.50, 882.0, 0.49, 0.7)) return 1;
860         if(!generate_sine8_2("sine8-18.raw", 44100.0, 200000, 441.0, 0.50, 4410.0, 0.49, 1.3)) return 1;
861         if(!generate_sine8_2("sine8-19.raw", 44100.0, 200000, 8820.0, 0.70, 4410.0, 0.29, 0.1)) return 1;
862
863         if(!generate_sine16_1("sine16-00.raw", 48000.0, 200000, 441.0, 0.50, 441.0, 0.49)) return 1;
864         if(!generate_sine16_1("sine16-01.raw", 96000.0, 200000, 441.0, 0.61, 661.5, 0.37)) return 1;
865         if(!generate_sine16_1("sine16-02.raw", 44100.0, 200000, 441.0, 0.50, 882.0, 0.49)) return 1;
866         if(!generate_sine16_1("sine16-03.raw", 44100.0, 200000, 441.0, 0.50, 4410.0, 0.49)) return 1;
867         if(!generate_sine16_1("sine16-04.raw", 44100.0, 200000, 8820.0, 0.70, 4410.0, 0.29)) return 1;
868
869         if(!generate_sine16_2("sine16-10.raw", 48000.0, 200000, 441.0, 0.50, 441.0, 0.49, 1.0)) return 1;
870         if(!generate_sine16_2("sine16-11.raw", 48000.0, 200000, 441.0, 0.61, 661.5, 0.37, 1.0)) return 1;
871         if(!generate_sine16_2("sine16-12.raw", 96000.0, 200000, 441.0, 0.50, 882.0, 0.49, 1.0)) return 1;
872         if(!generate_sine16_2("sine16-13.raw", 44100.0, 200000, 441.0, 0.50, 4410.0, 0.49, 1.0)) return 1;
873         if(!generate_sine16_2("sine16-14.raw", 44100.0, 200000, 8820.0, 0.70, 4410.0, 0.29, 1.0)) return 1;
874         if(!generate_sine16_2("sine16-15.raw", 44100.0, 200000, 441.0, 0.50, 441.0, 0.49, 0.5)) return 1;
875         if(!generate_sine16_2("sine16-16.raw", 44100.0, 200000, 441.0, 0.61, 661.5, 0.37, 2.0)) return 1;
876         if(!generate_sine16_2("sine16-17.raw", 44100.0, 200000, 441.0, 0.50, 882.0, 0.49, 0.7)) return 1;
877         if(!generate_sine16_2("sine16-18.raw", 44100.0, 200000, 441.0, 0.50, 4410.0, 0.49, 1.3)) return 1;
878         if(!generate_sine16_2("sine16-19.raw", 44100.0, 200000, 8820.0, 0.70, 4410.0, 0.29, 0.1)) return 1;
879
880         if(!generate_sine24_1("sine24-00.raw", 48000.0, 200000, 441.0, 0.50, 441.0, 0.49)) return 1;
881         if(!generate_sine24_1("sine24-01.raw", 96000.0, 200000, 441.0, 0.61, 661.5, 0.37)) return 1;
882         if(!generate_sine24_1("sine24-02.raw", 44100.0, 200000, 441.0, 0.50, 882.0, 0.49)) return 1;
883         if(!generate_sine24_1("sine24-03.raw", 44100.0, 200000, 441.0, 0.50, 4410.0, 0.49)) return 1;
884         if(!generate_sine24_1("sine24-04.raw", 44100.0, 200000, 8820.0, 0.70, 4410.0, 0.29)) return 1;
885
886         if(!generate_sine24_2("sine24-10.raw", 48000.0, 200000, 441.0, 0.50, 441.0, 0.49, 1.0)) return 1;
887         if(!generate_sine24_2("sine24-11.raw", 48000.0, 200000, 441.0, 0.61, 661.5, 0.37, 1.0)) return 1;
888         if(!generate_sine24_2("sine24-12.raw", 96000.0, 200000, 441.0, 0.50, 882.0, 0.49, 1.0)) return 1;
889         if(!generate_sine24_2("sine24-13.raw", 44100.0, 200000, 441.0, 0.50, 4410.0, 0.49, 1.0)) return 1;
890         if(!generate_sine24_2("sine24-14.raw", 44100.0, 200000, 8820.0, 0.70, 4410.0, 0.29, 1.0)) return 1;
891         if(!generate_sine24_2("sine24-15.raw", 44100.0, 200000, 441.0, 0.50, 441.0, 0.49, 0.5)) return 1;
892         if(!generate_sine24_2("sine24-16.raw", 44100.0, 200000, 441.0, 0.61, 661.5, 0.37, 2.0)) return 1;
893         if(!generate_sine24_2("sine24-17.raw", 44100.0, 200000, 441.0, 0.50, 882.0, 0.49, 0.7)) return 1;
894         if(!generate_sine24_2("sine24-18.raw", 44100.0, 200000, 441.0, 0.50, 4410.0, 0.49, 1.3)) return 1;
895         if(!generate_sine24_2("sine24-19.raw", 44100.0, 200000, 8820.0, 0.70, 4410.0, 0.29, 0.1)) return 1;
896
897         /* WATCHOUT: the size of noise.raw is hardcoded into test/test_flac.sh */
898         if(!generate_noise("noise.raw", 65536 * 8 * 3)) return 1;
899         if(!generate_noise("noise8m32.raw", 32)) return 1;
900         if(!generate_wackywavs()) return 1;
901         for(channels = 1; channels <= 8; channels++) {
902                 unsigned bits_per_sample;
903                 for(bits_per_sample = 4; bits_per_sample <= 24; bits_per_sample++) {
904                         static const unsigned nsamples[] = { 1, 111, 4777 } ;
905                         unsigned samples;
906                         for(samples = 0; samples < sizeof(nsamples)/sizeof(nsamples[0]); samples++) {
907                                 char fn[64];
908
909                                 sprintf(fn, "rt-%u-%u-%u.aiff", channels, bits_per_sample, nsamples[samples]);
910                                 if(!generate_aiff(fn, 44100, channels, bits_per_sample, nsamples[samples]))
911                                         return 1;
912
913                                 sprintf(fn, "rt-%u-%u-%u.wav", channels, bits_per_sample, nsamples[samples]);
914                                 if(!generate_wav(fn, 44100, channels, bits_per_sample, nsamples[samples], /*strict=*/true))
915                                         return 1;
916
917                                 if(bits_per_sample % 8 == 0) {
918                                         sprintf(fn, "rt-%u-%u-%u.raw", channels, bits_per_sample, nsamples[samples]);
919                                         if(!generate_raw(fn, channels, bits_per_sample/8, nsamples[samples]))
920                                                 return 1;
921                                 }
922                         }
923                 }
924         }
925
926         return 0;
927 }