xref: /third_party/libsnd/tests/utils.tpl (revision b815c7f3)
1b815c7f3Sopenharmony_ci[+ AutoGen5 template h c +]
2b815c7f3Sopenharmony_ci/*
3b815c7f3Sopenharmony_ci** Copyright (C) 2002-2018 Erik de Castro Lopo <erikd@mega-nerd.com>
4b815c7f3Sopenharmony_ci**
5b815c7f3Sopenharmony_ci** This program is free software; you can redistribute it and/or modify
6b815c7f3Sopenharmony_ci** it under the terms of the GNU General Public License as published by
7b815c7f3Sopenharmony_ci** the Free Software Foundation; either version 2 of the License, or
8b815c7f3Sopenharmony_ci** (at your option) any later version.
9b815c7f3Sopenharmony_ci**
10b815c7f3Sopenharmony_ci** This program is distributed in the hope that it will be useful,
11b815c7f3Sopenharmony_ci** but WITHOUT ANY WARRANTY; without even the implied warranty of
12b815c7f3Sopenharmony_ci** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13b815c7f3Sopenharmony_ci** GNU General Public License for more details.
14b815c7f3Sopenharmony_ci**
15b815c7f3Sopenharmony_ci** You should have received a copy of the GNU General Public License
16b815c7f3Sopenharmony_ci** along with this program; if not, write to the Free Software
17b815c7f3Sopenharmony_ci** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18b815c7f3Sopenharmony_ci*/
19b815c7f3Sopenharmony_ci
20b815c7f3Sopenharmony_ci/*
21b815c7f3Sopenharmony_ci**	Utility functions to make writing the test suite easier.
22b815c7f3Sopenharmony_ci**
23b815c7f3Sopenharmony_ci**	The .c and .h files were generated automagically with Autogen from
24b815c7f3Sopenharmony_ci**	the files utils.def and utils.tpl.
25b815c7f3Sopenharmony_ci*/
26b815c7f3Sopenharmony_ci
27b815c7f3Sopenharmony_ci[+ CASE (suffix) +]
28b815c7f3Sopenharmony_ci[+ ==  h  +]
29b815c7f3Sopenharmony_ci
30b815c7f3Sopenharmony_ci#ifdef __cplusplus
31b815c7f3Sopenharmony_ciextern "C" {
32b815c7f3Sopenharmony_ci#endif	/* __cplusplus */
33b815c7f3Sopenharmony_ci
34b815c7f3Sopenharmony_ci#include "sfconfig.h"
35b815c7f3Sopenharmony_ci
36b815c7f3Sopenharmony_ci#include <stdint.h>
37b815c7f3Sopenharmony_ci#include <stdarg.h>
38b815c7f3Sopenharmony_ci
39b815c7f3Sopenharmony_ci#define	ARRAY_LEN(x)		((int) (sizeof (x)) / (sizeof ((x) [0])))
40b815c7f3Sopenharmony_ci#define SIGNED_SIZEOF(x)	((int64_t) (sizeof (x)))
41b815c7f3Sopenharmony_ci#define	NOT(x)				(! (x))
42b815c7f3Sopenharmony_ci#define	ABS(x)				((x) >= 0 ? (x) : - (x))
43b815c7f3Sopenharmony_ci
44b815c7f3Sopenharmony_ci#define	PIPE_INDEX(x)	((x) + 500)
45b815c7f3Sopenharmony_ci#define	PIPE_TEST_LEN	12345
46b815c7f3Sopenharmony_ci
47b815c7f3Sopenharmony_ci
48b815c7f3Sopenharmony_ci[+ FOR float_type
49b815c7f3Sopenharmony_ci+]void gen_windowed_sine_[+ (get "name") +] ([+ (get "name") +] *data, int len, double maximum) ;
50b815c7f3Sopenharmony_ci[+ ENDFOR float_type
51b815c7f3Sopenharmony_ci+]
52b815c7f3Sopenharmony_ci
53b815c7f3Sopenharmony_civoid	create_short_sndfile (const char *filename, int format, int channels) ;
54b815c7f3Sopenharmony_ci
55b815c7f3Sopenharmony_civoid	check_file_hash_or_die	(const char *filename, uint64_t target_hash, int line_num) ;
56b815c7f3Sopenharmony_ci
57b815c7f3Sopenharmony_civoid	print_test_name (const char *test, const char *filename) ;
58b815c7f3Sopenharmony_ci
59b815c7f3Sopenharmony_civoid	dump_data_to_file (const char *filename, const void *data, unsigned int datalen) ;
60b815c7f3Sopenharmony_ci
61b815c7f3Sopenharmony_civoid	write_mono_file (const char * filename, int format, int srate, float * output, int len) ;
62b815c7f3Sopenharmony_ci
63b815c7f3Sopenharmony_ci#ifdef __GNUC__
64b815c7f3Sopenharmony_cistatic inline void
65b815c7f3Sopenharmony_ciexit_if_true (int test, const char *format, ...)
66b815c7f3Sopenharmony_ci#if (defined (__USE_MINGW_ANSI_STDIO) && __USE_MINGW_ANSI_STDIO && !defined (__clang__))
67b815c7f3Sopenharmony_ci	__attribute__ ((format (gnu_printf, 2, 3))) ;
68b815c7f3Sopenharmony_ci#else
69b815c7f3Sopenharmony_ci	__attribute__ ((format (printf, 2, 3))) ;
70b815c7f3Sopenharmony_ci#endif
71b815c7f3Sopenharmony_ci#endif
72b815c7f3Sopenharmony_ci
73b815c7f3Sopenharmony_cistatic inline void
74b815c7f3Sopenharmony_ciexit_if_true (int test, const char *format, ...)
75b815c7f3Sopenharmony_ci{	if (test)
76b815c7f3Sopenharmony_ci	{	va_list	argptr ;
77b815c7f3Sopenharmony_ci		va_start (argptr, format) ;
78b815c7f3Sopenharmony_ci		vprintf (format, argptr) ;
79b815c7f3Sopenharmony_ci		va_end (argptr) ;
80b815c7f3Sopenharmony_ci		exit (1) ;
81b815c7f3Sopenharmony_ci		} ;
82b815c7f3Sopenharmony_ci} /* exit_if_true */
83b815c7f3Sopenharmony_ci
84b815c7f3Sopenharmony_cistatic inline int32_t
85b815c7f3Sopenharmony_ciarith_shift_left (int32_t x, int shift)
86b815c7f3Sopenharmony_ci{	return (int32_t) (((uint32_t) x) << shift) ;
87b815c7f3Sopenharmony_ci} /* arith_shift_left */
88b815c7f3Sopenharmony_ci
89b815c7f3Sopenharmony_ci/*
90b815c7f3Sopenharmony_ci**	Functions for saving two vectors of data in an ascii text file which
91b815c7f3Sopenharmony_ci**	can then be loaded into GNU octave for comparison.
92b815c7f3Sopenharmony_ci*/
93b815c7f3Sopenharmony_ci
94b815c7f3Sopenharmony_ci[+ FOR io_type
95b815c7f3Sopenharmony_ci+]int	oct_save_[+ (get "io_element") +]	(const [+ (get "io_element") +] *a, const [+ (get "io_element") +] *b, int len) ;
96b815c7f3Sopenharmony_ci[+ ENDFOR io_type
97b815c7f3Sopenharmony_ci+]
98b815c7f3Sopenharmony_ci
99b815c7f3Sopenharmony_civoid	delete_file (int format, const char *filename) ;
100b815c7f3Sopenharmony_ci
101b815c7f3Sopenharmony_ciint		truncate_file_to_zero (const char *fname) ;
102b815c7f3Sopenharmony_ci
103b815c7f3Sopenharmony_civoid	count_open_files (void) ;
104b815c7f3Sopenharmony_civoid	increment_open_file_count (void) ;
105b815c7f3Sopenharmony_civoid	check_open_file_count_or_die (int lineno) ;
106b815c7f3Sopenharmony_ci
107b815c7f3Sopenharmony_civoid	get_unique_test_name (const char ** filename, const char * test) ;
108b815c7f3Sopenharmony_ci
109b815c7f3Sopenharmony_ci#ifdef SNDFILE_H
110b815c7f3Sopenharmony_ci
111b815c7f3Sopenharmony_cistatic inline void
112b815c7f3Sopenharmony_cisf_info_clear (SF_INFO * info)
113b815c7f3Sopenharmony_ci{	memset (info, 0, sizeof (SF_INFO)) ;
114b815c7f3Sopenharmony_ci} /* sf_info_clear */
115b815c7f3Sopenharmony_ci
116b815c7f3Sopenharmony_cistatic inline void
117b815c7f3Sopenharmony_cisf_info_setup (SF_INFO * info, int format, int samplerate, int channels)
118b815c7f3Sopenharmony_ci{	sf_info_clear (info) ;
119b815c7f3Sopenharmony_ci
120b815c7f3Sopenharmony_ci	info->format = format ;
121b815c7f3Sopenharmony_ci	info->samplerate = samplerate ;
122b815c7f3Sopenharmony_ci	info->channels = channels ;
123b815c7f3Sopenharmony_ci} /* sf_info_setup */
124b815c7f3Sopenharmony_ci
125b815c7f3Sopenharmony_ci
126b815c7f3Sopenharmony_civoid 	dump_log_buffer (SNDFILE *file) ;
127b815c7f3Sopenharmony_civoid 	check_log_buffer_or_die (SNDFILE *file, int line_num) ;
128b815c7f3Sopenharmony_ciint 	string_in_log_buffer (SNDFILE *file, const char *s) ;
129b815c7f3Sopenharmony_civoid	hexdump_file (const char * filename, sf_count_t offset, sf_count_t length) ;
130b815c7f3Sopenharmony_ci
131b815c7f3Sopenharmony_civoid	test_sf_format_or_die	(const SF_INFO *info, int line_num) ;
132b815c7f3Sopenharmony_ci
133b815c7f3Sopenharmony_ciSNDFILE *test_open_file_or_die
134b815c7f3Sopenharmony_ci			(const char *filename, int mode, SF_INFO *sfinfo, int allow_fd, int line_num) ;
135b815c7f3Sopenharmony_ci
136b815c7f3Sopenharmony_civoid 	test_read_write_position_or_die
137b815c7f3Sopenharmony_ci			(SNDFILE *file, int line_num, int pass, sf_count_t read_pos, sf_count_t write_pos) ;
138b815c7f3Sopenharmony_ci
139b815c7f3Sopenharmony_civoid	test_seek_or_die
140b815c7f3Sopenharmony_ci			(SNDFILE *file, sf_count_t offset, int whence, sf_count_t new_pos, int channels, int line_num) ;
141b815c7f3Sopenharmony_ci
142b815c7f3Sopenharmony_ci[+ FOR read_op +]
143b815c7f3Sopenharmony_ci[+ FOR io_type
144b815c7f3Sopenharmony_ci+]void 	test_[+ (get "op_element") +]_[+ (get "io_element") +]_or_die
145b815c7f3Sopenharmony_ci			(SNDFILE *file, int pass, [+ (get "io_element") +] *test, sf_count_t [+ (get "count_name") +], int line_num) ;
146b815c7f3Sopenharmony_ci[+ ENDFOR io_type +][+ ENDFOR read_op +]
147b815c7f3Sopenharmony_ci
148b815c7f3Sopenharmony_civoid
149b815c7f3Sopenharmony_citest_read_raw_or_die (SNDFILE *file, int pass, void *test, sf_count_t items, int line_num) ;
150b815c7f3Sopenharmony_ci
151b815c7f3Sopenharmony_ci[+ FOR write_op +]
152b815c7f3Sopenharmony_ci[+ FOR io_type
153b815c7f3Sopenharmony_ci+]void 	test_[+ (get "op_element") +]_[+ (get "io_element") +]_or_die
154b815c7f3Sopenharmony_ci			(SNDFILE *file, int pass, const [+ (get "io_element") +] *test, sf_count_t [+ (get "count_name") +], int line_num) ;
155b815c7f3Sopenharmony_ci[+ ENDFOR io_type +][+ ENDFOR write_op +]
156b815c7f3Sopenharmony_ci
157b815c7f3Sopenharmony_civoid
158b815c7f3Sopenharmony_citest_write_raw_or_die (SNDFILE *file, int pass, const void *test, sf_count_t items, int line_num) ;
159b815c7f3Sopenharmony_ci
160b815c7f3Sopenharmony_ci[+ FOR io_type
161b815c7f3Sopenharmony_ci+]void compare_[+ (get "io_element") +]_or_die (const [+ (get "io_element") +] *expected, const [+ (get "io_element") +] *actual, unsigned count, int line_num) ;
162b815c7f3Sopenharmony_ci[+ ENDFOR io_type +]
163b815c7f3Sopenharmony_ci
164b815c7f3Sopenharmony_ci
165b815c7f3Sopenharmony_civoid	gen_lowpass_signal_float (float *data, int len) ;
166b815c7f3Sopenharmony_ci
167b815c7f3Sopenharmony_cisf_count_t		file_length (const char * fname) ;
168b815c7f3Sopenharmony_cisf_count_t		file_length_fd (int fd) ;
169b815c7f3Sopenharmony_ci
170b815c7f3Sopenharmony_ci#endif
171b815c7f3Sopenharmony_ci
172b815c7f3Sopenharmony_ci#ifdef __cplusplus
173b815c7f3Sopenharmony_ci}		/* extern "C" */
174b815c7f3Sopenharmony_ci#endif	/* __cplusplus */
175b815c7f3Sopenharmony_ci
176b815c7f3Sopenharmony_ci[+  ==  c  +]
177b815c7f3Sopenharmony_ci
178b815c7f3Sopenharmony_ci#include "sfconfig.h"
179b815c7f3Sopenharmony_ci
180b815c7f3Sopenharmony_ci#include <stdio.h>
181b815c7f3Sopenharmony_ci#include <stdlib.h>
182b815c7f3Sopenharmony_ci#include <inttypes.h>
183b815c7f3Sopenharmony_ci
184b815c7f3Sopenharmony_ci#if HAVE_UNISTD_H
185b815c7f3Sopenharmony_ci#include <unistd.h>
186b815c7f3Sopenharmony_ci#endif
187b815c7f3Sopenharmony_ci
188b815c7f3Sopenharmony_ci#if (HAVE_DECL_S_IRGRP == 0)
189b815c7f3Sopenharmony_ci#include <sf_unistd.h>
190b815c7f3Sopenharmony_ci#endif
191b815c7f3Sopenharmony_ci
192b815c7f3Sopenharmony_ci#include <errno.h>
193b815c7f3Sopenharmony_ci#include <string.h>
194b815c7f3Sopenharmony_ci#include <ctype.h>
195b815c7f3Sopenharmony_ci#include <math.h>
196b815c7f3Sopenharmony_ci#include <float.h>
197b815c7f3Sopenharmony_ci#include <fcntl.h>
198b815c7f3Sopenharmony_ci#include <sys/stat.h>
199b815c7f3Sopenharmony_ci
200b815c7f3Sopenharmony_ci#include <sndfile.h>
201b815c7f3Sopenharmony_ci
202b815c7f3Sopenharmony_ci#include "utils.h"
203b815c7f3Sopenharmony_ci
204b815c7f3Sopenharmony_ci#ifndef	M_PI
205b815c7f3Sopenharmony_ci#define	M_PI		3.14159265358979323846264338
206b815c7f3Sopenharmony_ci#endif
207b815c7f3Sopenharmony_ci
208b815c7f3Sopenharmony_ci#define	LOG_BUFFER_SIZE		4096
209b815c7f3Sopenharmony_ci
210b815c7f3Sopenharmony_ci/*
211b815c7f3Sopenharmony_ci**	Neat solution to the Win32/OS2 binary file flage requirement.
212b815c7f3Sopenharmony_ci**	If O_BINARY isn't already defined by the inclusion of the system
213b815c7f3Sopenharmony_ci**	headers, set it to zero.
214b815c7f3Sopenharmony_ci*/
215b815c7f3Sopenharmony_ci#ifndef O_BINARY
216b815c7f3Sopenharmony_ci#define O_BINARY 0
217b815c7f3Sopenharmony_ci#endif
218b815c7f3Sopenharmony_ci
219b815c7f3Sopenharmony_ci
220b815c7f3Sopenharmony_ci/*
221b815c7f3Sopenharmony_ci**      Compare for equality, with epsilon
222b815c7f3Sopenharmony_ci*/
223b815c7f3Sopenharmony_cistatic inline int
224b815c7f3Sopenharmony_ciequals_short (const short a, const short b)
225b815c7f3Sopenharmony_ci{        return (a == b);
226b815c7f3Sopenharmony_ci} /* equals_short */
227b815c7f3Sopenharmony_cistatic inline int
228b815c7f3Sopenharmony_ciequals_int (const int a, const int b)
229b815c7f3Sopenharmony_ci{        return (a == b);
230b815c7f3Sopenharmony_ci} /* equals_int */
231b815c7f3Sopenharmony_cistatic inline int
232b815c7f3Sopenharmony_ciequals_float (const float a, const float b)
233b815c7f3Sopenharmony_ci{        return (fabsf(a - b) <= FLT_EPSILON);
234b815c7f3Sopenharmony_ci} /* equals_float */
235b815c7f3Sopenharmony_cistatic inline int
236b815c7f3Sopenharmony_ciequals_double (const double a, const double b)
237b815c7f3Sopenharmony_ci{       return (fabs(a - b) <= DBL_EPSILON);
238b815c7f3Sopenharmony_ci} /* equals_double */
239b815c7f3Sopenharmony_ci
240b815c7f3Sopenharmony_ci
241b815c7f3Sopenharmony_ci[+ FOR float_type +]
242b815c7f3Sopenharmony_civoid
243b815c7f3Sopenharmony_cigen_windowed_sine_[+ (get "name") +] ([+ (get "name") +] *data, int len, double maximum)
244b815c7f3Sopenharmony_ci{	int k ;
245b815c7f3Sopenharmony_ci
246b815c7f3Sopenharmony_ci	memset (data, 0, len * sizeof ([+ (get "name") +])) ;
247b815c7f3Sopenharmony_ci
248b815c7f3Sopenharmony_ci	len = (5 * len) / 6 ;
249b815c7f3Sopenharmony_ci
250b815c7f3Sopenharmony_ci	for (k = 0 ; k < len ; k++)
251b815c7f3Sopenharmony_ci	{	data [k] = sin (2.0 * k * M_PI * 1.0 / 32.0 + 0.4) ;
252b815c7f3Sopenharmony_ci
253b815c7f3Sopenharmony_ci		/* Apply Hanning Window. */
254b815c7f3Sopenharmony_ci		data [k] *= maximum * (0.5 - 0.5 * cos (2.0 * M_PI * k / ((len) - 1))) ;
255b815c7f3Sopenharmony_ci		}
256b815c7f3Sopenharmony_ci
257b815c7f3Sopenharmony_ci	return ;
258b815c7f3Sopenharmony_ci} /* gen_windowed_sine_[+ (get "name") +] */
259b815c7f3Sopenharmony_ci[+ ENDFOR float_type +]
260b815c7f3Sopenharmony_ci
261b815c7f3Sopenharmony_civoid
262b815c7f3Sopenharmony_cicreate_short_sndfile (const char *filename, int format, int channels)
263b815c7f3Sopenharmony_ci{	short data [2 * 3 * 4 * 5 * 6 * 7] = { 0, } ;
264b815c7f3Sopenharmony_ci	SNDFILE *file ;
265b815c7f3Sopenharmony_ci	SF_INFO sfinfo ;
266b815c7f3Sopenharmony_ci
267b815c7f3Sopenharmony_ci	memset (&sfinfo, 0, sizeof (sfinfo)) ;
268b815c7f3Sopenharmony_ci	sfinfo.samplerate = 44100 ;
269b815c7f3Sopenharmony_ci	sfinfo.channels = channels ;
270b815c7f3Sopenharmony_ci	sfinfo.format = format ;
271b815c7f3Sopenharmony_ci
272b815c7f3Sopenharmony_ci	if ((file = sf_open (filename, SFM_WRITE, &sfinfo)) == NULL)
273b815c7f3Sopenharmony_ci	{	printf ("Error (%s, %d) : sf_open failed : %s\n", __FILE__, __LINE__, sf_strerror (file)) ;
274b815c7f3Sopenharmony_ci		exit (1) ;
275b815c7f3Sopenharmony_ci		} ;
276b815c7f3Sopenharmony_ci
277b815c7f3Sopenharmony_ci	sf_write_short (file, data, ARRAY_LEN (data)) ;
278b815c7f3Sopenharmony_ci
279b815c7f3Sopenharmony_ci	sf_close (file) ;
280b815c7f3Sopenharmony_ci} /* create_short_sndfile */
281b815c7f3Sopenharmony_ci
282b815c7f3Sopenharmony_civoid
283b815c7f3Sopenharmony_cicheck_file_hash_or_die (const char *filename, uint64_t target_hash, int line_num)
284b815c7f3Sopenharmony_ci{	static unsigned char buf [4096] ;
285b815c7f3Sopenharmony_ci	uint64_t	cksum ;
286b815c7f3Sopenharmony_ci	FILE 		*file ;
287b815c7f3Sopenharmony_ci	int			k, read_count ;
288b815c7f3Sopenharmony_ci
289b815c7f3Sopenharmony_ci	memset (buf, 0, sizeof (buf)) ;
290b815c7f3Sopenharmony_ci
291b815c7f3Sopenharmony_ci	/* The 'b' in the mode string means binary for Win32. */
292b815c7f3Sopenharmony_ci	if ((file = fopen (filename, "rb")) == NULL)
293b815c7f3Sopenharmony_ci	{	printf ("\n\nLine %d: could not open file '%s'\n\n", line_num, filename) ;
294b815c7f3Sopenharmony_ci		exit (1) ;
295b815c7f3Sopenharmony_ci		} ;
296b815c7f3Sopenharmony_ci
297b815c7f3Sopenharmony_ci	cksum = 0 ;
298b815c7f3Sopenharmony_ci
299b815c7f3Sopenharmony_ci	while ((read_count = fread (buf, 1, sizeof (buf), file)))
300b815c7f3Sopenharmony_ci		for (k = 0 ; k < read_count ; k++)
301b815c7f3Sopenharmony_ci			cksum = (cksum * 511 + buf [k]) & 0xfffffffffffff ;
302b815c7f3Sopenharmony_ci
303b815c7f3Sopenharmony_ci	fclose (file) ;
304b815c7f3Sopenharmony_ci
305b815c7f3Sopenharmony_ci	if (target_hash == 0)
306b815c7f3Sopenharmony_ci	{	printf (" 0x%" PRIx64 "\n", cksum) ;
307b815c7f3Sopenharmony_ci		return ;
308b815c7f3Sopenharmony_ci		} ;
309b815c7f3Sopenharmony_ci
310b815c7f3Sopenharmony_ci	if (cksum != target_hash)
311b815c7f3Sopenharmony_ci	{	printf ("\n\nLine %d: incorrect hash value 0x%" PRIx64 " should be 0x%" PRIx64 ".\n\n", line_num, cksum, target_hash) ;
312b815c7f3Sopenharmony_ci		exit (1) ;
313b815c7f3Sopenharmony_ci		} ;
314b815c7f3Sopenharmony_ci
315b815c7f3Sopenharmony_ci	return ;
316b815c7f3Sopenharmony_ci} /* check_file_hash_or_die */
317b815c7f3Sopenharmony_ci
318b815c7f3Sopenharmony_civoid
319b815c7f3Sopenharmony_ciprint_test_name (const char *test, const char *filename)
320b815c7f3Sopenharmony_ci{	int count ;
321b815c7f3Sopenharmony_ci
322b815c7f3Sopenharmony_ci	if (test == NULL)
323b815c7f3Sopenharmony_ci	{	printf (__FILE__ ": bad test of filename parameter.\n") ;
324b815c7f3Sopenharmony_ci		exit (1) ;
325b815c7f3Sopenharmony_ci		} ;
326b815c7f3Sopenharmony_ci
327b815c7f3Sopenharmony_ci	if (filename == NULL || strlen (filename) == 0)
328b815c7f3Sopenharmony_ci	{	printf ("    %-30s : ", test) ;
329b815c7f3Sopenharmony_ci		count = 25 ;
330b815c7f3Sopenharmony_ci		}
331b815c7f3Sopenharmony_ci	else
332b815c7f3Sopenharmony_ci	{	printf ("    %-30s : %s ", test, filename) ;
333b815c7f3Sopenharmony_ci		count = 24 - strlen (filename) ;
334b815c7f3Sopenharmony_ci		} ;
335b815c7f3Sopenharmony_ci
336b815c7f3Sopenharmony_ci	while (count -- > 0)
337b815c7f3Sopenharmony_ci		putchar ('.') ;
338b815c7f3Sopenharmony_ci	putchar (' ') ;
339b815c7f3Sopenharmony_ci
340b815c7f3Sopenharmony_ci	fflush (stdout) ;
341b815c7f3Sopenharmony_ci} /* print_test_name */
342b815c7f3Sopenharmony_ci
343b815c7f3Sopenharmony_civoid
344b815c7f3Sopenharmony_cidump_data_to_file (const char *filename, const void *data, unsigned int datalen)
345b815c7f3Sopenharmony_ci{	FILE *file ;
346b815c7f3Sopenharmony_ci
347b815c7f3Sopenharmony_ci	if ((file = fopen (filename, "wb")) == NULL)
348b815c7f3Sopenharmony_ci	{	printf ("\n\nLine %d : could not open file : %s\n\n", __LINE__, filename) ;
349b815c7f3Sopenharmony_ci		exit (1) ;
350b815c7f3Sopenharmony_ci		} ;
351b815c7f3Sopenharmony_ci
352b815c7f3Sopenharmony_ci	if (fwrite (data, 1, datalen, file) != datalen)
353b815c7f3Sopenharmony_ci	{	printf ("\n\nLine %d : fwrite failed.\n\n", __LINE__) ;
354b815c7f3Sopenharmony_ci		exit (1) ;
355b815c7f3Sopenharmony_ci		} ;
356b815c7f3Sopenharmony_ci
357b815c7f3Sopenharmony_ci	fclose (file) ;
358b815c7f3Sopenharmony_ci
359b815c7f3Sopenharmony_ci} /* dump_data_to_file */
360b815c7f3Sopenharmony_ci
361b815c7f3Sopenharmony_ci/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
362b815c7f3Sopenharmony_ci*/
363b815c7f3Sopenharmony_ci
364b815c7f3Sopenharmony_cistatic char octfilename [] = "error.dat" ;
365b815c7f3Sopenharmony_ci
366b815c7f3Sopenharmony_ci[+ FOR io_type
367b815c7f3Sopenharmony_ci+]int
368b815c7f3Sopenharmony_cioct_save_[+ (get "io_element") +]	(const [+ (get "io_element") +] *a, const [+ (get "io_element") +] *b, int len)
369b815c7f3Sopenharmony_ci{	FILE 	*file ;
370b815c7f3Sopenharmony_ci	int		k ;
371b815c7f3Sopenharmony_ci
372b815c7f3Sopenharmony_ci	if (! (file = fopen (octfilename, "w")))
373b815c7f3Sopenharmony_ci		return 1 ;
374b815c7f3Sopenharmony_ci
375b815c7f3Sopenharmony_ci	fprintf (file, "# Not created by Octave\n") ;
376b815c7f3Sopenharmony_ci
377b815c7f3Sopenharmony_ci	fprintf (file, "# name: a\n") ;
378b815c7f3Sopenharmony_ci	fprintf (file, "# type: matrix\n") ;
379b815c7f3Sopenharmony_ci	fprintf (file, "# rows: %d\n", len) ;
380b815c7f3Sopenharmony_ci	fprintf (file, "# columns: 1\n") ;
381b815c7f3Sopenharmony_ci
382b815c7f3Sopenharmony_ci	for (k = 0 ; k < len ; k++)
383b815c7f3Sopenharmony_ci		fprintf (file, [+ (get "format_str") +] "\n", a [k]) ;
384b815c7f3Sopenharmony_ci
385b815c7f3Sopenharmony_ci	fprintf (file, "# name: b\n") ;
386b815c7f3Sopenharmony_ci	fprintf (file, "# type: matrix\n") ;
387b815c7f3Sopenharmony_ci	fprintf (file, "# rows: %d\n", len) ;
388b815c7f3Sopenharmony_ci	fprintf (file, "# columns: 1\n") ;
389b815c7f3Sopenharmony_ci
390b815c7f3Sopenharmony_ci	for (k = 0 ; k < len ; k++)
391b815c7f3Sopenharmony_ci		fprintf (file, [+ (get "format_str") +] "\n", b [k]) ;
392b815c7f3Sopenharmony_ci
393b815c7f3Sopenharmony_ci	fclose (file) ;
394b815c7f3Sopenharmony_ci	return 0 ;
395b815c7f3Sopenharmony_ci} /* oct_save_[+ (get "io_element") +] */
396b815c7f3Sopenharmony_ci[+ ENDFOR io_type
397b815c7f3Sopenharmony_ci+]
398b815c7f3Sopenharmony_ci
399b815c7f3Sopenharmony_civoid
400b815c7f3Sopenharmony_cicheck_log_buffer_or_die (SNDFILE *file, int line_num)
401b815c7f3Sopenharmony_ci{	static char	buffer [LOG_BUFFER_SIZE] ;
402b815c7f3Sopenharmony_ci	int			count ;
403b815c7f3Sopenharmony_ci
404b815c7f3Sopenharmony_ci	memset (buffer, 0, sizeof (buffer)) ;
405b815c7f3Sopenharmony_ci
406b815c7f3Sopenharmony_ci	/* Get the log buffer data. */
407b815c7f3Sopenharmony_ci	count = sf_command	(file, SFC_GET_LOG_INFO, buffer, LOG_BUFFER_SIZE) ;
408b815c7f3Sopenharmony_ci
409b815c7f3Sopenharmony_ci	if (LOG_BUFFER_SIZE - count < 2)
410b815c7f3Sopenharmony_ci	{	printf ("\n\nLine %d : Possible long log buffer.\n", line_num) ;
411b815c7f3Sopenharmony_ci		exit (1) ;
412b815c7f3Sopenharmony_ci		}
413b815c7f3Sopenharmony_ci
414b815c7f3Sopenharmony_ci	/* Look for "Should" */
415b815c7f3Sopenharmony_ci	if (strstr (buffer, "ould"))
416b815c7f3Sopenharmony_ci	{	printf ("\n\nLine %d : Log buffer contains `ould'. Dumping.\n", line_num) ;
417b815c7f3Sopenharmony_ci		puts (buffer) ;
418b815c7f3Sopenharmony_ci		exit (1) ;
419b815c7f3Sopenharmony_ci		} ;
420b815c7f3Sopenharmony_ci
421b815c7f3Sopenharmony_ci	/* Look for "**" */
422b815c7f3Sopenharmony_ci	if (strstr (buffer, "*"))
423b815c7f3Sopenharmony_ci	{	printf ("\n\nLine %d : Log buffer contains `*'. Dumping.\n", line_num) ;
424b815c7f3Sopenharmony_ci		puts (buffer) ;
425b815c7f3Sopenharmony_ci		exit (1) ;
426b815c7f3Sopenharmony_ci		} ;
427b815c7f3Sopenharmony_ci
428b815c7f3Sopenharmony_ci	/* Look for "Should" */
429b815c7f3Sopenharmony_ci	if (strstr (buffer, "nknown marker"))
430b815c7f3Sopenharmony_ci	{	printf ("\n\nLine %d : Log buffer contains `nknown marker'. Dumping.\n", line_num) ;
431b815c7f3Sopenharmony_ci		puts (buffer) ;
432b815c7f3Sopenharmony_ci		exit (1) ;
433b815c7f3Sopenharmony_ci		} ;
434b815c7f3Sopenharmony_ci
435b815c7f3Sopenharmony_ci	return ;
436b815c7f3Sopenharmony_ci} /* check_log_buffer_or_die */
437b815c7f3Sopenharmony_ci
438b815c7f3Sopenharmony_ciint
439b815c7f3Sopenharmony_cistring_in_log_buffer (SNDFILE *file, const char *s)
440b815c7f3Sopenharmony_ci{	static char	buffer [LOG_BUFFER_SIZE] ;
441b815c7f3Sopenharmony_ci	int			count ;
442b815c7f3Sopenharmony_ci
443b815c7f3Sopenharmony_ci	memset (buffer, 0, sizeof (buffer)) ;
444b815c7f3Sopenharmony_ci
445b815c7f3Sopenharmony_ci	/* Get the log buffer data. */
446b815c7f3Sopenharmony_ci	count = sf_command	(file, SFC_GET_LOG_INFO, buffer, LOG_BUFFER_SIZE) ;
447b815c7f3Sopenharmony_ci
448b815c7f3Sopenharmony_ci	if (LOG_BUFFER_SIZE - count < 2)
449b815c7f3Sopenharmony_ci	{	printf ("Possible long log buffer.\n") ;
450b815c7f3Sopenharmony_ci		exit (1) ;
451b815c7f3Sopenharmony_ci		}
452b815c7f3Sopenharmony_ci
453b815c7f3Sopenharmony_ci	/* Look for string */
454b815c7f3Sopenharmony_ci	return strstr (buffer, s) ? SF_TRUE : SF_FALSE ;
455b815c7f3Sopenharmony_ci} /* string_in_log_buffer */
456b815c7f3Sopenharmony_ci
457b815c7f3Sopenharmony_civoid
458b815c7f3Sopenharmony_cihexdump_file (const char * filename, sf_count_t offset, sf_count_t length)
459b815c7f3Sopenharmony_ci{
460b815c7f3Sopenharmony_ci	FILE * file ;
461b815c7f3Sopenharmony_ci	char buffer [16] ;
462b815c7f3Sopenharmony_ci	int k, m, ch, readcount ;
463b815c7f3Sopenharmony_ci
464b815c7f3Sopenharmony_ci	if (length > 1000000)
465b815c7f3Sopenharmony_ci	{	printf ("\n\nError : length (%" PRId64 ") too long.\n\n", offset) ;
466b815c7f3Sopenharmony_ci		exit (1) ;
467b815c7f3Sopenharmony_ci		} ;
468b815c7f3Sopenharmony_ci
469b815c7f3Sopenharmony_ci	if ((file = fopen (filename, "r")) == NULL)
470b815c7f3Sopenharmony_ci	{	printf ("\n\nError : hexdump_file (%s) could not open file for read.\n\n", filename) ;
471b815c7f3Sopenharmony_ci		exit (1) ;
472b815c7f3Sopenharmony_ci		} ;
473b815c7f3Sopenharmony_ci
474b815c7f3Sopenharmony_ci	if (fseek (file, offset, SEEK_SET) != 0)
475b815c7f3Sopenharmony_ci	{	printf ("\n\nError : fseek(file, %" PRId64 ", SEEK_SET) failed : %s\n\n", offset, strerror (errno)) ;
476b815c7f3Sopenharmony_ci		exit (1) ;
477b815c7f3Sopenharmony_ci		} ;
478b815c7f3Sopenharmony_ci
479b815c7f3Sopenharmony_ci	puts ("\n\n") ;
480b815c7f3Sopenharmony_ci
481b815c7f3Sopenharmony_ci	for (k = 0 ; k < length ; k+= sizeof (buffer))
482b815c7f3Sopenharmony_ci	{	readcount = fread (buffer, 1, sizeof (buffer), file) ;
483b815c7f3Sopenharmony_ci
484b815c7f3Sopenharmony_ci		printf ("%08" PRIx64 " : ", offset + k) ;
485b815c7f3Sopenharmony_ci
486b815c7f3Sopenharmony_ci		for (m = 0 ; m < readcount ; m++)
487b815c7f3Sopenharmony_ci			printf ("%02x ", buffer [m] & 0xFF) ;
488b815c7f3Sopenharmony_ci
489b815c7f3Sopenharmony_ci		for (m = readcount ; m < SIGNED_SIZEOF (buffer) ; m++)
490b815c7f3Sopenharmony_ci			printf ("   ") ;
491b815c7f3Sopenharmony_ci
492b815c7f3Sopenharmony_ci		printf ("  ") ;
493b815c7f3Sopenharmony_ci		for (m = 0 ; m < readcount ; m++)
494b815c7f3Sopenharmony_ci		{	ch = isprint (buffer [m]) ? buffer [m] : '.' ;
495b815c7f3Sopenharmony_ci			putchar (ch) ;
496b815c7f3Sopenharmony_ci			} ;
497b815c7f3Sopenharmony_ci
498b815c7f3Sopenharmony_ci		if (readcount < SIGNED_SIZEOF (buffer))
499b815c7f3Sopenharmony_ci			break ;
500b815c7f3Sopenharmony_ci
501b815c7f3Sopenharmony_ci		putchar ('\n') ;
502b815c7f3Sopenharmony_ci		} ;
503b815c7f3Sopenharmony_ci
504b815c7f3Sopenharmony_ci	puts ("\n") ;
505b815c7f3Sopenharmony_ci
506b815c7f3Sopenharmony_ci	fclose (file) ;
507b815c7f3Sopenharmony_ci} /* hexdump_file */
508b815c7f3Sopenharmony_ci
509b815c7f3Sopenharmony_civoid
510b815c7f3Sopenharmony_cidump_log_buffer (SNDFILE *file)
511b815c7f3Sopenharmony_ci{	static char	buffer [LOG_BUFFER_SIZE] ;
512b815c7f3Sopenharmony_ci
513b815c7f3Sopenharmony_ci	memset (buffer, 0, sizeof (buffer)) ;
514b815c7f3Sopenharmony_ci
515b815c7f3Sopenharmony_ci	/* Get the log buffer data. */
516b815c7f3Sopenharmony_ci	sf_command	(file, SFC_GET_LOG_INFO, buffer, LOG_BUFFER_SIZE) ;
517b815c7f3Sopenharmony_ci
518b815c7f3Sopenharmony_ci	if (strlen (buffer) < 1)
519b815c7f3Sopenharmony_ci		puts ("Log buffer empty.\n") ;
520b815c7f3Sopenharmony_ci	else
521b815c7f3Sopenharmony_ci		puts (buffer) ;
522b815c7f3Sopenharmony_ci
523b815c7f3Sopenharmony_ci	return ;
524b815c7f3Sopenharmony_ci} /* dump_log_buffer */
525b815c7f3Sopenharmony_ci
526b815c7f3Sopenharmony_civoid
527b815c7f3Sopenharmony_citest_sf_format_or_die (const SF_INFO *info, int line_num)
528b815c7f3Sopenharmony_ci{	int res ;
529b815c7f3Sopenharmony_ci
530b815c7f3Sopenharmony_ci	if ((res = sf_format_check (info)) != 1)
531b815c7f3Sopenharmony_ci	{	printf ("\n\nLine %d : sf_format_check returned error (%d)\n\n", line_num, res) ;
532b815c7f3Sopenharmony_ci		exit (1) ;
533b815c7f3Sopenharmony_ci		} ;
534b815c7f3Sopenharmony_ci
535b815c7f3Sopenharmony_ci	return ;
536b815c7f3Sopenharmony_ci} /* test_sf_format_or_die */
537b815c7f3Sopenharmony_ci
538b815c7f3Sopenharmony_ciSNDFILE *
539b815c7f3Sopenharmony_citest_open_file_or_die (const char *filename, int mode, SF_INFO *sfinfo, int allow_fd, int line_num)
540b815c7f3Sopenharmony_ci{	static int count = 0 ;
541b815c7f3Sopenharmony_ci
542b815c7f3Sopenharmony_ci	SNDFILE *file ;
543b815c7f3Sopenharmony_ci	const char *modestr, *func_name ;
544b815c7f3Sopenharmony_ci	int oflags = 0, omode = 0, err ;
545b815c7f3Sopenharmony_ci
546b815c7f3Sopenharmony_ci	/*
547b815c7f3Sopenharmony_ci	** Need to test both sf_open() and sf_open_fd().
548b815c7f3Sopenharmony_ci	** Do so alternately.
549b815c7f3Sopenharmony_ci	*/
550b815c7f3Sopenharmony_ci	switch (mode)
551b815c7f3Sopenharmony_ci	{	case SFM_READ :
552b815c7f3Sopenharmony_ci				modestr = "SFM_READ" ;
553b815c7f3Sopenharmony_ci				oflags = O_RDONLY | O_BINARY ;
554b815c7f3Sopenharmony_ci				omode = 0 ;
555b815c7f3Sopenharmony_ci				break ;
556b815c7f3Sopenharmony_ci
557b815c7f3Sopenharmony_ci		case SFM_WRITE :
558b815c7f3Sopenharmony_ci				modestr = "SFM_WRITE" ;
559b815c7f3Sopenharmony_ci				oflags = O_WRONLY | O_CREAT | O_TRUNC | O_BINARY ;
560b815c7f3Sopenharmony_ci				omode = S_IRUSR | S_IWUSR | S_IRGRP ;
561b815c7f3Sopenharmony_ci				break ;
562b815c7f3Sopenharmony_ci
563b815c7f3Sopenharmony_ci		case SFM_RDWR :
564b815c7f3Sopenharmony_ci				modestr = "SFM_RDWR" ;
565b815c7f3Sopenharmony_ci				oflags = O_RDWR | O_CREAT | O_BINARY ;
566b815c7f3Sopenharmony_ci				omode = S_IRUSR | S_IWUSR | S_IRGRP ;
567b815c7f3Sopenharmony_ci				break ;
568b815c7f3Sopenharmony_ci		default :
569b815c7f3Sopenharmony_ci				printf ("\n\nLine %d: Bad mode.\n", line_num) ;
570b815c7f3Sopenharmony_ci				fflush (stdout) ;
571b815c7f3Sopenharmony_ci				exit (1) ;
572b815c7f3Sopenharmony_ci		} ;
573b815c7f3Sopenharmony_ci
574b815c7f3Sopenharmony_ci	if (OS_IS_WIN32)
575b815c7f3Sopenharmony_ci	{	/* Windows does not understand and ignores the S_IRGRP flag, but Wine
576b815c7f3Sopenharmony_ci		** gives a run time warning message, so just clear it.
577b815c7f3Sopenharmony_ci		*/
578b815c7f3Sopenharmony_ci		omode &= ~S_IRGRP ;
579b815c7f3Sopenharmony_ci		} ;
580b815c7f3Sopenharmony_ci
581b815c7f3Sopenharmony_ci	if (allow_fd && ((++count) & 1) == 1)
582b815c7f3Sopenharmony_ci	{	int fd ;
583b815c7f3Sopenharmony_ci
584b815c7f3Sopenharmony_ci		/* Only use the three argument open() function if omode != 0. */
585b815c7f3Sopenharmony_ci		fd = (omode == 0) ? open (filename, oflags) : open (filename, oflags, omode) ;
586b815c7f3Sopenharmony_ci
587b815c7f3Sopenharmony_ci		if (fd < 0)
588b815c7f3Sopenharmony_ci		{	printf ("\n\n%s : open failed : %s\n", __func__, strerror (errno)) ;
589b815c7f3Sopenharmony_ci			exit (1) ;
590b815c7f3Sopenharmony_ci			} ;
591b815c7f3Sopenharmony_ci
592b815c7f3Sopenharmony_ci		func_name = "sf_open_fd" ;
593b815c7f3Sopenharmony_ci		file = sf_open_fd (fd, mode, sfinfo, SF_TRUE) ;
594b815c7f3Sopenharmony_ci		}
595b815c7f3Sopenharmony_ci	else
596b815c7f3Sopenharmony_ci	{	func_name = "sf_open" ;
597b815c7f3Sopenharmony_ci		file = sf_open (filename, mode, sfinfo) ;
598b815c7f3Sopenharmony_ci		} ;
599b815c7f3Sopenharmony_ci
600b815c7f3Sopenharmony_ci	if (file == NULL)
601b815c7f3Sopenharmony_ci	{	printf ("\n\nLine %d: %s (%s) failed : %s\n\n", line_num, func_name, modestr, sf_strerror (NULL)) ;
602b815c7f3Sopenharmony_ci		dump_log_buffer (file) ;
603b815c7f3Sopenharmony_ci		exit (1) ;
604b815c7f3Sopenharmony_ci		} ;
605b815c7f3Sopenharmony_ci
606b815c7f3Sopenharmony_ci	err = sf_error (file) ;
607b815c7f3Sopenharmony_ci	if (err != SF_ERR_NO_ERROR)
608b815c7f3Sopenharmony_ci	{	printf ("\n\nLine %d : sf_error : %s\n\n", line_num, sf_error_number (err)) ;
609b815c7f3Sopenharmony_ci		dump_log_buffer (file) ;
610b815c7f3Sopenharmony_ci		exit (1) ;
611b815c7f3Sopenharmony_ci		} ;
612b815c7f3Sopenharmony_ci
613b815c7f3Sopenharmony_ci	return file ;
614b815c7f3Sopenharmony_ci} /* test_open_file_or_die */
615b815c7f3Sopenharmony_ci
616b815c7f3Sopenharmony_civoid
617b815c7f3Sopenharmony_citest_read_write_position_or_die (SNDFILE *file, int line_num, int pass, sf_count_t read_pos, sf_count_t write_pos)
618b815c7f3Sopenharmony_ci{	sf_count_t pos ;
619b815c7f3Sopenharmony_ci
620b815c7f3Sopenharmony_ci	/* Check the current read position. */
621b815c7f3Sopenharmony_ci	if (read_pos >= 0 && (pos = sf_seek (file, 0, SEEK_CUR | SFM_READ)) != read_pos)
622b815c7f3Sopenharmony_ci	{	printf ("\n\nLine %d ", line_num) ;
623b815c7f3Sopenharmony_ci		if (pass > 0)
624b815c7f3Sopenharmony_ci			printf ("(pass %d): ", pass) ;
625b815c7f3Sopenharmony_ci		printf ("Read position (%" PRId64 ") should be %" PRId64 ".\n", pos, read_pos) ;
626b815c7f3Sopenharmony_ci		exit (1) ;
627b815c7f3Sopenharmony_ci		} ;
628b815c7f3Sopenharmony_ci
629b815c7f3Sopenharmony_ci	/* Check the current write position. */
630b815c7f3Sopenharmony_ci	if (write_pos >= 0 && (pos = sf_seek (file, 0, SEEK_CUR | SFM_WRITE)) != write_pos)
631b815c7f3Sopenharmony_ci	{	printf ("\n\nLine %d", line_num) ;
632b815c7f3Sopenharmony_ci		if (pass > 0)
633b815c7f3Sopenharmony_ci			printf (" (pass %d)", pass) ;
634b815c7f3Sopenharmony_ci		printf (" : Write position (%" PRId64 ") should be %" PRId64 ".\n", pos, write_pos) ;
635b815c7f3Sopenharmony_ci		exit (1) ;
636b815c7f3Sopenharmony_ci		} ;
637b815c7f3Sopenharmony_ci
638b815c7f3Sopenharmony_ci	return ;
639b815c7f3Sopenharmony_ci} /* test_read_write_position */
640b815c7f3Sopenharmony_ci
641b815c7f3Sopenharmony_civoid
642b815c7f3Sopenharmony_citest_seek_or_die (SNDFILE *file, sf_count_t offset, int whence, sf_count_t new_pos, int channels, int line_num)
643b815c7f3Sopenharmony_ci{	sf_count_t	position ;
644b815c7f3Sopenharmony_ci	const char	*channel_name, *whence_name ;
645b815c7f3Sopenharmony_ci
646b815c7f3Sopenharmony_ci	switch (whence)
647b815c7f3Sopenharmony_ci	{	case SEEK_SET :
648b815c7f3Sopenharmony_ci				whence_name = "SEEK_SET" ;
649b815c7f3Sopenharmony_ci				break ;
650b815c7f3Sopenharmony_ci		case SEEK_CUR :
651b815c7f3Sopenharmony_ci				whence_name = "SEEK_CUR" ;
652b815c7f3Sopenharmony_ci				break ;
653b815c7f3Sopenharmony_ci		case SEEK_END :
654b815c7f3Sopenharmony_ci				whence_name = "SEEK_END" ;
655b815c7f3Sopenharmony_ci				break ;
656b815c7f3Sopenharmony_ci
657b815c7f3Sopenharmony_ci		/* SFM_READ */
658b815c7f3Sopenharmony_ci		case SEEK_SET | SFM_READ :
659b815c7f3Sopenharmony_ci				whence_name = "SFM_READ | SEEK_SET" ;
660b815c7f3Sopenharmony_ci				break ;
661b815c7f3Sopenharmony_ci		case SEEK_CUR | SFM_READ :
662b815c7f3Sopenharmony_ci				whence_name = "SFM_READ | SEEK_CUR" ;
663b815c7f3Sopenharmony_ci				break ;
664b815c7f3Sopenharmony_ci		case SEEK_END | SFM_READ :
665b815c7f3Sopenharmony_ci				whence_name = "SFM_READ | SEEK_END" ;
666b815c7f3Sopenharmony_ci				break ;
667b815c7f3Sopenharmony_ci
668b815c7f3Sopenharmony_ci		/* SFM_WRITE */
669b815c7f3Sopenharmony_ci		case SEEK_SET | SFM_WRITE :
670b815c7f3Sopenharmony_ci				whence_name = "SFM_WRITE | SEEK_SET" ;
671b815c7f3Sopenharmony_ci				break ;
672b815c7f3Sopenharmony_ci		case SEEK_CUR | SFM_WRITE :
673b815c7f3Sopenharmony_ci				whence_name = "SFM_WRITE | SEEK_CUR" ;
674b815c7f3Sopenharmony_ci				break ;
675b815c7f3Sopenharmony_ci		case SEEK_END | SFM_WRITE :
676b815c7f3Sopenharmony_ci				whence_name = "SFM_WRITE | SEEK_END" ;
677b815c7f3Sopenharmony_ci				break ;
678b815c7f3Sopenharmony_ci
679b815c7f3Sopenharmony_ci		default :
680b815c7f3Sopenharmony_ci				printf ("\n\nLine %d: bad whence parameter.\n", line_num) ;
681b815c7f3Sopenharmony_ci				exit (1) ;
682b815c7f3Sopenharmony_ci		} ;
683b815c7f3Sopenharmony_ci
684b815c7f3Sopenharmony_ci	channel_name = (channels == 1) ? "Mono" : "Stereo" ;
685b815c7f3Sopenharmony_ci
686b815c7f3Sopenharmony_ci	if ((position = sf_seek (file, offset, whence)) != new_pos)
687b815c7f3Sopenharmony_ci	{	printf ("\n\nLine %d : %s : sf_seek (file, %" PRId64 ", %s) returned %" PRId64 " (should be %" PRId64 ").\n\n",
688b815c7f3Sopenharmony_ci					line_num, channel_name, offset, whence_name, position, new_pos) ;
689b815c7f3Sopenharmony_ci		exit (1) ;
690b815c7f3Sopenharmony_ci		} ;
691b815c7f3Sopenharmony_ci
692b815c7f3Sopenharmony_ci} /* test_seek_or_die */
693b815c7f3Sopenharmony_ci
694b815c7f3Sopenharmony_ci[+ FOR read_op +]
695b815c7f3Sopenharmony_ci[+ FOR io_type +]
696b815c7f3Sopenharmony_civoid
697b815c7f3Sopenharmony_citest_[+ (get "op_element") +]_[+ (get "io_element") +]_or_die (SNDFILE *file, int pass, [+ (get "io_element") +] *test, sf_count_t [+ (get "count_name") +], int line_num)
698b815c7f3Sopenharmony_ci{	sf_count_t count ;
699b815c7f3Sopenharmony_ci
700b815c7f3Sopenharmony_ci	if ((count = sf_[+ (get "op_element") +]_[+ (get "io_element") +] (file, test, [+ (get "count_name") +])) != [+ (get "count_name") +])
701b815c7f3Sopenharmony_ci	{	printf ("\n\nLine %d", line_num) ;
702b815c7f3Sopenharmony_ci		if (pass > 0)
703b815c7f3Sopenharmony_ci			printf (" (pass %d)", pass) ;
704b815c7f3Sopenharmony_ci		printf (" : sf_[+ (get "op_element") +]_[+ (get "io_element") +] failed with short [+ (get "op_element") +] (%" PRId64 " => %" PRId64 ").\n",
705b815c7f3Sopenharmony_ci						[+ (get "count_name") +], count) ;
706b815c7f3Sopenharmony_ci		fflush (stdout) ;
707b815c7f3Sopenharmony_ci		puts (sf_strerror (file)) ;
708b815c7f3Sopenharmony_ci		exit (1) ;
709b815c7f3Sopenharmony_ci		} ;
710b815c7f3Sopenharmony_ci
711b815c7f3Sopenharmony_ci	return ;
712b815c7f3Sopenharmony_ci} /* test_[+ (get "op_element") +]_[+ (get "io_element") +]_or_die */
713b815c7f3Sopenharmony_ci[+ ENDFOR io_type +][+ ENDFOR read_op +]
714b815c7f3Sopenharmony_ci
715b815c7f3Sopenharmony_civoid
716b815c7f3Sopenharmony_citest_read_raw_or_die (SNDFILE *file, int pass, void *test, sf_count_t items, int line_num)
717b815c7f3Sopenharmony_ci{	sf_count_t count ;
718b815c7f3Sopenharmony_ci
719b815c7f3Sopenharmony_ci	if ((count = sf_read_raw (file, test, items)) != items)
720b815c7f3Sopenharmony_ci	{	printf ("\n\nLine %d", line_num) ;
721b815c7f3Sopenharmony_ci		if (pass > 0)
722b815c7f3Sopenharmony_ci			printf (" (pass %d)", pass) ;
723b815c7f3Sopenharmony_ci		printf (" : sf_read_raw failed with short read (%" PRId64 " => %" PRId64 ").\n", items, count) ;
724b815c7f3Sopenharmony_ci		fflush (stdout) ;
725b815c7f3Sopenharmony_ci		puts (sf_strerror (file)) ;
726b815c7f3Sopenharmony_ci		exit (1) ;
727b815c7f3Sopenharmony_ci		} ;
728b815c7f3Sopenharmony_ci
729b815c7f3Sopenharmony_ci	return ;
730b815c7f3Sopenharmony_ci} /* test_read_raw_or_die */
731b815c7f3Sopenharmony_ci
732b815c7f3Sopenharmony_ci[+ FOR write_op +]
733b815c7f3Sopenharmony_ci[+ FOR io_type +]
734b815c7f3Sopenharmony_civoid
735b815c7f3Sopenharmony_citest_[+ (get "op_element") +]_[+ (get "io_element") +]_or_die (SNDFILE *file, int pass, const [+ (get "io_element") +] *test, sf_count_t [+ (get "count_name") +], int line_num)
736b815c7f3Sopenharmony_ci{	sf_count_t count ;
737b815c7f3Sopenharmony_ci
738b815c7f3Sopenharmony_ci	if ((count = sf_[+ (get "op_element") +]_[+ (get "io_element") +] (file, test, [+ (get "count_name") +])) != [+ (get "count_name") +])
739b815c7f3Sopenharmony_ci	{	printf ("\n\nLine %d", line_num) ;
740b815c7f3Sopenharmony_ci		if (pass > 0)
741b815c7f3Sopenharmony_ci			printf (" (pass %d)", pass) ;
742b815c7f3Sopenharmony_ci		printf (" : sf_[+ (get "op_element") +]_[+ (get "io_element") +] failed with short [+ (get "op_element") +] (%" PRId64 " => %" PRId64 ").\n",
743b815c7f3Sopenharmony_ci						[+ (get "count_name") +], count) ;
744b815c7f3Sopenharmony_ci		fflush (stdout) ;
745b815c7f3Sopenharmony_ci		puts (sf_strerror (file)) ;
746b815c7f3Sopenharmony_ci		exit (1) ;
747b815c7f3Sopenharmony_ci		} ;
748b815c7f3Sopenharmony_ci
749b815c7f3Sopenharmony_ci	return ;
750b815c7f3Sopenharmony_ci} /* test_[+ (get "op_element") +]_[+ (get "io_element") +]_or_die */
751b815c7f3Sopenharmony_ci[+ ENDFOR io_type +][+ ENDFOR write_op +]
752b815c7f3Sopenharmony_ci
753b815c7f3Sopenharmony_civoid
754b815c7f3Sopenharmony_citest_write_raw_or_die (SNDFILE *file, int pass, const void *test, sf_count_t items, int line_num)
755b815c7f3Sopenharmony_ci{	sf_count_t count ;
756b815c7f3Sopenharmony_ci
757b815c7f3Sopenharmony_ci	if ((count = sf_write_raw (file, test, items)) != items)
758b815c7f3Sopenharmony_ci	{	printf ("\n\nLine %d", line_num) ;
759b815c7f3Sopenharmony_ci		if (pass > 0)
760b815c7f3Sopenharmony_ci			printf (" (pass %d)", pass) ;
761b815c7f3Sopenharmony_ci		printf (" : sf_write_raw failed with short write (%" PRId64 " => %" PRId64 ").\n", items, count) ;
762b815c7f3Sopenharmony_ci		fflush (stdout) ;
763b815c7f3Sopenharmony_ci		puts (sf_strerror (file)) ;
764b815c7f3Sopenharmony_ci		exit (1) ;
765b815c7f3Sopenharmony_ci		} ;
766b815c7f3Sopenharmony_ci
767b815c7f3Sopenharmony_ci	return ;
768b815c7f3Sopenharmony_ci} /* test_write_raw_or_die */
769b815c7f3Sopenharmony_ci
770b815c7f3Sopenharmony_ci
771b815c7f3Sopenharmony_ci[+ FOR io_type
772b815c7f3Sopenharmony_ci+]void
773b815c7f3Sopenharmony_cicompare_[+ (get "io_element") +]_or_die (const [+ (get "io_element") +] *expected, const [+ (get "io_element") +] *actual, unsigned count, int line_num)
774b815c7f3Sopenharmony_ci{
775b815c7f3Sopenharmony_ci	unsigned k ;
776b815c7f3Sopenharmony_ci
777b815c7f3Sopenharmony_ci	for (k = 0 ; k < count ; k++)
778b815c7f3Sopenharmony_ci		if (!equals_[+ (get "io_element") +](expected [k], actual [k]))
779b815c7f3Sopenharmony_ci		{	printf ("\n\nLine %d : Error at index %d, got " [+ (get "format_str") +] ", should be " [+ (get "format_str") +] "(delta=" [+ (get "format_str") +] " ).\n\n", line_num, k, actual [k], expected [k], actual [k] - expected [k]) ;
780b815c7f3Sopenharmony_ci			exit (1) ;
781b815c7f3Sopenharmony_ci			} ;
782b815c7f3Sopenharmony_ci
783b815c7f3Sopenharmony_ci	return ;
784b815c7f3Sopenharmony_ci} /* compare_[+ (get "io_element") +]_or_die */
785b815c7f3Sopenharmony_ci[+ ENDFOR io_type +]
786b815c7f3Sopenharmony_ci
787b815c7f3Sopenharmony_ci
788b815c7f3Sopenharmony_civoid
789b815c7f3Sopenharmony_cidelete_file (int format, const char *filename)
790b815c7f3Sopenharmony_ci{	char rsrc_name [512], *fname ;
791b815c7f3Sopenharmony_ci
792b815c7f3Sopenharmony_ci	unlink (filename) ;
793b815c7f3Sopenharmony_ci
794b815c7f3Sopenharmony_ci	if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_SD2)
795b815c7f3Sopenharmony_ci		return ;
796b815c7f3Sopenharmony_ci
797b815c7f3Sopenharmony_ci	/*
798b815c7f3Sopenharmony_ci	** Now try for a resource fork stored as a separate file.
799b815c7f3Sopenharmony_ci	** Grab the un-adulterated filename again.
800b815c7f3Sopenharmony_ci	*/
801b815c7f3Sopenharmony_ci	snprintf (rsrc_name, sizeof (rsrc_name), "%s", filename) ;
802b815c7f3Sopenharmony_ci
803b815c7f3Sopenharmony_ci	if ((fname = strrchr (rsrc_name, '/')) != NULL)
804b815c7f3Sopenharmony_ci		fname ++ ;
805b815c7f3Sopenharmony_ci	else if ((fname = strrchr (rsrc_name, '\\')) != NULL)
806b815c7f3Sopenharmony_ci		fname ++ ;
807b815c7f3Sopenharmony_ci	else
808b815c7f3Sopenharmony_ci		fname = rsrc_name ;
809b815c7f3Sopenharmony_ci
810b815c7f3Sopenharmony_ci	memmove (fname + 2, fname, strlen (fname) + 1) ;
811b815c7f3Sopenharmony_ci	fname [0] = '.' ;
812b815c7f3Sopenharmony_ci	fname [1] = '_' ;
813b815c7f3Sopenharmony_ci
814b815c7f3Sopenharmony_ci	unlink (rsrc_name) ;
815b815c7f3Sopenharmony_ci} /* delete_file */
816b815c7f3Sopenharmony_ci
817b815c7f3Sopenharmony_ciint
818b815c7f3Sopenharmony_citruncate_file_to_zero (const char * fname)
819b815c7f3Sopenharmony_ci{	FILE * file ;
820b815c7f3Sopenharmony_ci
821b815c7f3Sopenharmony_ci	if ((file = fopen (fname, "w")) == NULL)
822b815c7f3Sopenharmony_ci		return errno ;
823b815c7f3Sopenharmony_ci	fclose (file) ;
824b815c7f3Sopenharmony_ci
825b815c7f3Sopenharmony_ci	return 0 ;
826b815c7f3Sopenharmony_ci} /* truncate_file_to_zero */
827b815c7f3Sopenharmony_ci
828b815c7f3Sopenharmony_cistatic int allowed_open_files = -1 ;
829b815c7f3Sopenharmony_ci
830b815c7f3Sopenharmony_civoid
831b815c7f3Sopenharmony_cicount_open_files (void)
832b815c7f3Sopenharmony_ci{
833b815c7f3Sopenharmony_ci#if OS_IS_WIN32
834b815c7f3Sopenharmony_ci	return ;
835b815c7f3Sopenharmony_ci#else
836b815c7f3Sopenharmony_ci	int k, count = 0 ;
837b815c7f3Sopenharmony_ci	struct stat statbuf ;
838b815c7f3Sopenharmony_ci
839b815c7f3Sopenharmony_ci	if (allowed_open_files > 0)
840b815c7f3Sopenharmony_ci		return ;
841b815c7f3Sopenharmony_ci
842b815c7f3Sopenharmony_ci	for (k = 0 ; k < 1024 ; k++)
843b815c7f3Sopenharmony_ci		if (fstat (k, &statbuf) == 0)
844b815c7f3Sopenharmony_ci			count ++ ;
845b815c7f3Sopenharmony_ci
846b815c7f3Sopenharmony_ci	allowed_open_files = count ;
847b815c7f3Sopenharmony_ci#endif
848b815c7f3Sopenharmony_ci} /* count_open_files */
849b815c7f3Sopenharmony_ci
850b815c7f3Sopenharmony_civoid
851b815c7f3Sopenharmony_ciincrement_open_file_count (void)
852b815c7f3Sopenharmony_ci{	allowed_open_files ++ ;
853b815c7f3Sopenharmony_ci} /* increment_open_file_count */
854b815c7f3Sopenharmony_ci
855b815c7f3Sopenharmony_civoid
856b815c7f3Sopenharmony_cicheck_open_file_count_or_die (int lineno)
857b815c7f3Sopenharmony_ci{
858b815c7f3Sopenharmony_ci#if OS_IS_WIN32
859b815c7f3Sopenharmony_ci	(void) lineno ;
860b815c7f3Sopenharmony_ci	return ;
861b815c7f3Sopenharmony_ci#else
862b815c7f3Sopenharmony_ci	int k, count = 0 ;
863b815c7f3Sopenharmony_ci	struct stat statbuf ;
864b815c7f3Sopenharmony_ci
865b815c7f3Sopenharmony_ci	if (allowed_open_files < 0)
866b815c7f3Sopenharmony_ci		count_open_files () ;
867b815c7f3Sopenharmony_ci
868b815c7f3Sopenharmony_ci	for (k = 0 ; k < 1024 ; k++)
869b815c7f3Sopenharmony_ci		if (fstat (k, &statbuf) == 0)
870b815c7f3Sopenharmony_ci			count ++ ;
871b815c7f3Sopenharmony_ci
872b815c7f3Sopenharmony_ci	if (count > allowed_open_files)
873b815c7f3Sopenharmony_ci	{	printf ("\nLine %d : number of open files (%d) > allowed (%d).\n\n", lineno, count, allowed_open_files) ;
874b815c7f3Sopenharmony_ci		exit (1) ;
875b815c7f3Sopenharmony_ci		} ;
876b815c7f3Sopenharmony_ci#endif
877b815c7f3Sopenharmony_ci} /* check_open_file_count_or_die */
878b815c7f3Sopenharmony_ci
879b815c7f3Sopenharmony_civoid
880b815c7f3Sopenharmony_ciget_unique_test_name (const char ** filename, const char * test)
881b815c7f3Sopenharmony_ci{	static char	buffer [1024] ;
882b815c7f3Sopenharmony_ci
883b815c7f3Sopenharmony_ci	snprintf (buffer, sizeof (buffer), "%s_%s", test, *filename) ;
884b815c7f3Sopenharmony_ci
885b815c7f3Sopenharmony_ci	*filename = buffer ;
886b815c7f3Sopenharmony_ci} /* get_unique_test_name */
887b815c7f3Sopenharmony_ci
888b815c7f3Sopenharmony_civoid
889b815c7f3Sopenharmony_ciwrite_mono_file (const char * filename, int format, int srate, float * output, int len)
890b815c7f3Sopenharmony_ci{	SNDFILE * file ;
891b815c7f3Sopenharmony_ci	SF_INFO sfinfo ;
892b815c7f3Sopenharmony_ci
893b815c7f3Sopenharmony_ci	memset (&sfinfo, 0, sizeof (sfinfo)) ;
894b815c7f3Sopenharmony_ci
895b815c7f3Sopenharmony_ci	sfinfo.samplerate = srate ;
896b815c7f3Sopenharmony_ci	sfinfo.channels = 1 ;
897b815c7f3Sopenharmony_ci	sfinfo.format = format ;
898b815c7f3Sopenharmony_ci
899b815c7f3Sopenharmony_ci	if ((file = sf_open (filename, SFM_WRITE, &sfinfo)) == NULL)
900b815c7f3Sopenharmony_ci	{	printf ("sf_open (%s) : %s\n", filename, sf_strerror (NULL)) ;
901b815c7f3Sopenharmony_ci		exit (1) ;
902b815c7f3Sopenharmony_ci		} ;
903b815c7f3Sopenharmony_ci
904b815c7f3Sopenharmony_ci	sf_write_float (file, output, len) ;
905b815c7f3Sopenharmony_ci
906b815c7f3Sopenharmony_ci	sf_close (file) ;
907b815c7f3Sopenharmony_ci} /* write_mono_file */
908b815c7f3Sopenharmony_ci
909b815c7f3Sopenharmony_civoid
910b815c7f3Sopenharmony_cigen_lowpass_signal_float (float *data, int len)
911b815c7f3Sopenharmony_ci{	int64_t value = 0x1243456 ;
912b815c7f3Sopenharmony_ci	double sample, last_val = 0.0 ;
913b815c7f3Sopenharmony_ci	int k ;
914b815c7f3Sopenharmony_ci
915b815c7f3Sopenharmony_ci	for (k = 0 ; k < len ; k++)
916b815c7f3Sopenharmony_ci	{	/* Not a crypto quality RNG. */
917b815c7f3Sopenharmony_ci		value = (11117 * value + 211231) & 0xffffffff ;
918b815c7f3Sopenharmony_ci		value = (11117 * value + 211231) & 0xffffffff ;
919b815c7f3Sopenharmony_ci		value = (11117 * value + 211231) & 0xffffffff ;
920b815c7f3Sopenharmony_ci
921b815c7f3Sopenharmony_ci		sample = value / (0x7fffffff * 1.000001) ;
922b815c7f3Sopenharmony_ci		sample = 0.2 * sample - 0.9 * last_val ;
923b815c7f3Sopenharmony_ci
924b815c7f3Sopenharmony_ci		last_val = sample ;
925b815c7f3Sopenharmony_ci
926b815c7f3Sopenharmony_ci		data [k] = 0.5 * (sample + sin (2.0 * k * M_PI * 1.0 / 32.0)) ;
927b815c7f3Sopenharmony_ci		} ;
928b815c7f3Sopenharmony_ci
929b815c7f3Sopenharmony_ci} /* gen_lowpass_signal_float */
930b815c7f3Sopenharmony_ci
931b815c7f3Sopenharmony_ci
932b815c7f3Sopenharmony_ci/*
933b815c7f3Sopenharmony_ci**	Windows is fucked.
934b815c7f3Sopenharmony_ci**	If a file is opened R/W and data is written to it, then fstat will return
935b815c7f3Sopenharmony_ci**	the correct file length, but stat will return zero.
936b815c7f3Sopenharmony_ci*/
937b815c7f3Sopenharmony_ci
938b815c7f3Sopenharmony_cisf_count_t
939b815c7f3Sopenharmony_cifile_length (const char * fname)
940b815c7f3Sopenharmony_ci{	struct stat data ;
941b815c7f3Sopenharmony_ci
942b815c7f3Sopenharmony_ci	if (stat (fname, &data) != 0)
943b815c7f3Sopenharmony_ci		return 0 ;
944b815c7f3Sopenharmony_ci
945b815c7f3Sopenharmony_ci	return (sf_count_t) data.st_size ;
946b815c7f3Sopenharmony_ci} /* file_length */
947b815c7f3Sopenharmony_ci
948b815c7f3Sopenharmony_cisf_count_t
949b815c7f3Sopenharmony_cifile_length_fd (int fd)
950b815c7f3Sopenharmony_ci{	struct stat data ;
951b815c7f3Sopenharmony_ci
952b815c7f3Sopenharmony_ci	memset (&data, 0, sizeof (data)) ;
953b815c7f3Sopenharmony_ci	if (fstat (fd, &data) != 0)
954b815c7f3Sopenharmony_ci		return 0 ;
955b815c7f3Sopenharmony_ci
956b815c7f3Sopenharmony_ci	return (sf_count_t) data.st_size ;
957b815c7f3Sopenharmony_ci} /* file_length_fd */
958b815c7f3Sopenharmony_ci
959b815c7f3Sopenharmony_ci
960b815c7f3Sopenharmony_ci[+ ESAC +]
961b815c7f3Sopenharmony_ci
962