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
45static FLAC__bool is_big_endian_host;
46
47
48static 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
59static 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
67static FLAC__bool write_little_endian_int16(FILE *f, FLAC__int16 x)
68{
69	return write_little_endian_uint16(f, (FLAC__uint16)x);
70}
71
72static 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
81static FLAC__bool write_little_endian_int24(FILE *f, FLAC__int32 x)
82{
83	return write_little_endian_uint24(f, (FLAC__uint32)x);
84}
85
86static 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) */
98static 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
104static 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
117static 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) */
127static 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) */
135static 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) */
147static 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
153static 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) */
165static 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
171static 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 */
203static 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;
216foo:
217	fclose(f);
218	return false;
219}
220
221/* a stereo one-sample 16bps stream */
222static 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;
237foo:
238	fclose(f);
239	return false;
240}
241
242/* a mono five-sample 16bps stream */
243static 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;
258foo:
259	fclose(f);
260	return false;
261}
262
263/* a stereo five-sample 16bps stream */
264static 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;
279foo:
280	fclose(f);
281	return false;
282}
283
284/* a mono full-scale deflection 8bps stream */
285static 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;
305foo:
306	fclose(f);
307	return false;
308}
309
310/* a mono full-scale deflection 16bps stream */
311static 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;
331foo:
332	fclose(f);
333	return false;
334}
335
336/* a stereo wasted-bits-per-sample 16bps stream */
337static 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;
356foo:
357	fclose(f);
358	return false;
359}
360
361/* a mono full-scale deflection 24bps stream */
362static 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;
382foo:
383	fclose(f);
384	return false;
385}
386
387/* a mono sine-wave 8bps stream */
388static 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;
409foo:
410	fclose(f);
411	return false;
412}
413
414/* a stereo sine-wave 8bps stream */
415static 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;
440foo:
441	fclose(f);
442	return false;
443}
444
445/* a mono sine-wave 16bps stream */
446static 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;
467foo:
468	fclose(f);
469	return false;
470}
471
472/* a stereo sine-wave 16bps stream */
473static 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;
498foo:
499	fclose(f);
500	return false;
501}
502
503/* a mono sine-wave 24bps stream */
504static 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;
525foo:
526	fclose(f);
527	return false;
528}
529
530/* a stereo sine-wave 24bps stream */
531static 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;
556foo:
557	fclose(f);
558	return false;
559}
560
561static 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;
581foo:
582	fclose(f);
583	return false;
584}
585
586static 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;
610foo:
611	fclose(f);
612	return false;
613}
614
615static 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;
666foo:
667	fclose(f);
668	return false;
669}
670
671static 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;
742foo:
743	fclose(f);
744	return false;
745}
746
747static 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;
779foo:
780	fclose(f);
781	return false;
782}
783
784int 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}
928