1b815c7f3Sopenharmony_ci/*
2b815c7f3Sopenharmony_ci** Copyright (C) 2003-2016 Erik de Castro Lopo <erikd@mega-nerd.com>
3b815c7f3Sopenharmony_ci**
4b815c7f3Sopenharmony_ci** This program is free software; you can redistribute it and/or modify
5b815c7f3Sopenharmony_ci** it under the terms of the GNU General Public License as published by
6b815c7f3Sopenharmony_ci** the Free Software Foundation; either version 2 of the License, or
7b815c7f3Sopenharmony_ci** (at your option) any later version.
8b815c7f3Sopenharmony_ci**
9b815c7f3Sopenharmony_ci** This program is distributed in the hope that it will be useful,
10b815c7f3Sopenharmony_ci** but WITHOUT ANY WARRANTY; without even the implied warranty of
11b815c7f3Sopenharmony_ci** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12b815c7f3Sopenharmony_ci** GNU General Public License for more details.
13b815c7f3Sopenharmony_ci**
14b815c7f3Sopenharmony_ci** You should have received a copy of the GNU General Public License
15b815c7f3Sopenharmony_ci** along with this program; if not, write to the Free Software
16b815c7f3Sopenharmony_ci** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17b815c7f3Sopenharmony_ci*/
18b815c7f3Sopenharmony_ci
19b815c7f3Sopenharmony_ci#include "sfconfig.h"
20b815c7f3Sopenharmony_ci
21b815c7f3Sopenharmony_ci#include <stdio.h>
22b815c7f3Sopenharmony_ci#include <stdlib.h>
23b815c7f3Sopenharmony_ci#include <string.h>
24b815c7f3Sopenharmony_ci#include <math.h>
25b815c7f3Sopenharmony_ci
26b815c7f3Sopenharmony_ci#if HAVE_UNISTD_H
27b815c7f3Sopenharmony_ci#include <unistd.h>
28b815c7f3Sopenharmony_ci#else
29b815c7f3Sopenharmony_ci#include "sf_unistd.h"
30b815c7f3Sopenharmony_ci#endif
31b815c7f3Sopenharmony_ci
32b815c7f3Sopenharmony_ci#include	<sndfile.h>
33b815c7f3Sopenharmony_ci
34b815c7f3Sopenharmony_ci#include	"sfendian.h"
35b815c7f3Sopenharmony_ci#include	"utils.h"
36b815c7f3Sopenharmony_ci
37b815c7f3Sopenharmony_ci#define	BUFFER_LEN			(1 << 10)
38b815c7f3Sopenharmony_ci#define LOG_BUFFER_SIZE		1024
39b815c7f3Sopenharmony_ci
40b815c7f3Sopenharmony_cistatic void	chunk_test (const char *filename, int format) ;
41b815c7f3Sopenharmony_cistatic void wav_subchunk_test (unsigned int chunk_size) ;
42b815c7f3Sopenharmony_cistatic void	large_free_test (const char *filename, int format, unsigned int chunk_size) ;
43b815c7f3Sopenharmony_ci
44b815c7f3Sopenharmony_ciint
45b815c7f3Sopenharmony_cimain (int argc, char *argv [])
46b815c7f3Sopenharmony_ci{	int		do_all = 0 ;
47b815c7f3Sopenharmony_ci	int		test_count = 0, k ;
48b815c7f3Sopenharmony_ci
49b815c7f3Sopenharmony_ci	if (argc != 2)
50b815c7f3Sopenharmony_ci	{	printf ("Usage : %s <test>\n", argv [0]) ;
51b815c7f3Sopenharmony_ci		printf ("    Where <test> is one of the following:\n") ;
52b815c7f3Sopenharmony_ci		printf ("           wav  - test adding chunks to WAV files\n") ;
53b815c7f3Sopenharmony_ci		printf ("           aiff - test adding chunks to AIFF files\n") ;
54b815c7f3Sopenharmony_ci		printf ("           caf  - test adding chunks to CAF files\n") ;
55b815c7f3Sopenharmony_ci		printf ("           rf64 - test adding chunks to RF64 files\n") ;
56b815c7f3Sopenharmony_ci		printf ("           all  - perform all tests\n") ;
57b815c7f3Sopenharmony_ci		exit (1) ;
58b815c7f3Sopenharmony_ci		} ;
59b815c7f3Sopenharmony_ci
60b815c7f3Sopenharmony_ci	do_all = ! strcmp (argv [1], "all") ;
61b815c7f3Sopenharmony_ci
62b815c7f3Sopenharmony_ci	if (do_all || ! strcmp (argv [1], "wav"))
63b815c7f3Sopenharmony_ci	{	chunk_test ("chunks_pcm16.wav", SF_FORMAT_WAV | SF_FORMAT_PCM_16) ;
64b815c7f3Sopenharmony_ci		chunk_test ("chunks_pcm16.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_PCM_16) ;
65b815c7f3Sopenharmony_ci		chunk_test ("chunks_pcm16.wavex", SF_FORMAT_WAVEX | SF_FORMAT_PCM_16) ;
66b815c7f3Sopenharmony_ci
67b815c7f3Sopenharmony_ci		for (k = 100 ; k < 10000 ; k *= 4)
68b815c7f3Sopenharmony_ci			wav_subchunk_test (k) ;
69b815c7f3Sopenharmony_ci
70b815c7f3Sopenharmony_ci		test_count++ ;
71b815c7f3Sopenharmony_ci		} ;
72b815c7f3Sopenharmony_ci
73b815c7f3Sopenharmony_ci	if (do_all || ! strcmp (argv [1], "aiff"))
74b815c7f3Sopenharmony_ci	{	chunk_test ("chunks_pcm16.aiff", SF_FORMAT_AIFF | SF_FORMAT_PCM_16) ;
75b815c7f3Sopenharmony_ci		test_count++ ;
76b815c7f3Sopenharmony_ci		} ;
77b815c7f3Sopenharmony_ci
78b815c7f3Sopenharmony_ci	if (do_all || ! strcmp (argv [1], "caf"))
79b815c7f3Sopenharmony_ci	{	chunk_test ("chunks_pcm16.caf", SF_FORMAT_CAF | SF_FORMAT_PCM_16) ;
80b815c7f3Sopenharmony_ci		chunk_test ("chunks_alac.caf", SF_FORMAT_CAF | SF_FORMAT_ALAC_16) ;
81b815c7f3Sopenharmony_ci		large_free_test ("large_free.caf", SF_FORMAT_CAF | SF_FORMAT_PCM_16, 100) ;
82b815c7f3Sopenharmony_ci		large_free_test ("large_free.caf", SF_FORMAT_CAF | SF_FORMAT_PCM_16, 20000) ;
83b815c7f3Sopenharmony_ci		test_count++ ;
84b815c7f3Sopenharmony_ci		} ;
85b815c7f3Sopenharmony_ci
86b815c7f3Sopenharmony_ci	if (do_all || ! strcmp (argv [1], "rf64"))
87b815c7f3Sopenharmony_ci	{	chunk_test ("chunks_pcm16.rf64", SF_FORMAT_RF64 | SF_FORMAT_PCM_16) ;
88b815c7f3Sopenharmony_ci		test_count++ ;
89b815c7f3Sopenharmony_ci		} ;
90b815c7f3Sopenharmony_ci
91b815c7f3Sopenharmony_ci	if (test_count == 0)
92b815c7f3Sopenharmony_ci	{	printf ("Mono : ************************************\n") ;
93b815c7f3Sopenharmony_ci		printf ("Mono : *  No '%s' test defined.\n", argv [1]) ;
94b815c7f3Sopenharmony_ci		printf ("Mono : ************************************\n") ;
95b815c7f3Sopenharmony_ci		return 1 ;
96b815c7f3Sopenharmony_ci		} ;
97b815c7f3Sopenharmony_ci
98b815c7f3Sopenharmony_ci	return 0 ;
99b815c7f3Sopenharmony_ci} /* main */
100b815c7f3Sopenharmony_ci
101b815c7f3Sopenharmony_ci
102b815c7f3Sopenharmony_ci/*============================================================================================
103b815c7f3Sopenharmony_ci**	Here are the test functions.
104b815c7f3Sopenharmony_ci*/
105b815c7f3Sopenharmony_ci
106b815c7f3Sopenharmony_cistatic void
107b815c7f3Sopenharmony_cichunk_test_helper (const char *filename, int format, const char * testdata)
108b815c7f3Sopenharmony_ci{	SNDFILE			*file ;
109b815c7f3Sopenharmony_ci	SF_INFO			sfinfo ;
110b815c7f3Sopenharmony_ci	SF_CHUNK_INFO	chunk_info ;
111b815c7f3Sopenharmony_ci	SF_CHUNK_ITERATOR * iterator ;
112b815c7f3Sopenharmony_ci	uint32_t		length_before ;
113b815c7f3Sopenharmony_ci	int				err, allow_fd ;
114b815c7f3Sopenharmony_ci
115b815c7f3Sopenharmony_ci	switch (format & SF_FORMAT_SUBMASK)
116b815c7f3Sopenharmony_ci	{	case SF_FORMAT_ALAC_16 :
117b815c7f3Sopenharmony_ci			allow_fd = SF_FALSE ;
118b815c7f3Sopenharmony_ci			break ;
119b815c7f3Sopenharmony_ci		default :
120b815c7f3Sopenharmony_ci			allow_fd = SF_TRUE ;
121b815c7f3Sopenharmony_ci			break ;
122b815c7f3Sopenharmony_ci		} ;
123b815c7f3Sopenharmony_ci
124b815c7f3Sopenharmony_ci	sfinfo.samplerate	= 44100 ;
125b815c7f3Sopenharmony_ci	sfinfo.channels		= 1 ;
126b815c7f3Sopenharmony_ci	sfinfo.frames		= 0 ;
127b815c7f3Sopenharmony_ci	sfinfo.format		= format ;
128b815c7f3Sopenharmony_ci
129b815c7f3Sopenharmony_ci	file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, allow_fd, __LINE__) ;
130b815c7f3Sopenharmony_ci
131b815c7f3Sopenharmony_ci	/* Set up the chunk to write. */
132b815c7f3Sopenharmony_ci	memset (&chunk_info, 0, sizeof (chunk_info)) ;
133b815c7f3Sopenharmony_ci	snprintf (chunk_info.id, sizeof (chunk_info.id), "Test") ;
134b815c7f3Sopenharmony_ci	chunk_info.id_size = 4 ;
135b815c7f3Sopenharmony_ci	chunk_info.data = strdup (testdata) ;
136b815c7f3Sopenharmony_ci	chunk_info.datalen = (unsigned int) strlen (chunk_info.data) ;
137b815c7f3Sopenharmony_ci
138b815c7f3Sopenharmony_ci	length_before = chunk_info.datalen ;
139b815c7f3Sopenharmony_ci
140b815c7f3Sopenharmony_ci	err = sf_set_chunk (file, &chunk_info) ;
141b815c7f3Sopenharmony_ci	exit_if_true (
142b815c7f3Sopenharmony_ci		err != SF_ERR_NO_ERROR,
143b815c7f3Sopenharmony_ci		"\n\nLine %d : sf_set_chunk returned for testdata '%s' : %s\n\n", __LINE__, testdata, sf_error_number (err)
144b815c7f3Sopenharmony_ci		) ;
145b815c7f3Sopenharmony_ci
146b815c7f3Sopenharmony_ci	memset (chunk_info.data, 0, chunk_info.datalen) ;
147b815c7f3Sopenharmony_ci	free (chunk_info.data) ;
148b815c7f3Sopenharmony_ci
149b815c7f3Sopenharmony_ci	sf_close (file) ;
150b815c7f3Sopenharmony_ci
151b815c7f3Sopenharmony_ci	file = test_open_file_or_die (filename, SFM_READ, &sfinfo, allow_fd, __LINE__) ;
152b815c7f3Sopenharmony_ci
153b815c7f3Sopenharmony_ci	memset (&chunk_info, 0, sizeof (chunk_info)) ;
154b815c7f3Sopenharmony_ci	snprintf (chunk_info.id, sizeof (chunk_info.id), "Test") ;
155b815c7f3Sopenharmony_ci	chunk_info.id_size = 4 ;
156b815c7f3Sopenharmony_ci
157b815c7f3Sopenharmony_ci	iterator = sf_get_chunk_iterator (file, &chunk_info) ;
158b815c7f3Sopenharmony_ci	err = sf_get_chunk_size (iterator, &chunk_info) ;
159b815c7f3Sopenharmony_ci	exit_if_true (
160b815c7f3Sopenharmony_ci		err != SF_ERR_NO_ERROR,
161b815c7f3Sopenharmony_ci		"\n\nLine %d : sf_get_chunk_size returned for testdata '%s' : %s\n\n", __LINE__, testdata, sf_error_number (err)
162b815c7f3Sopenharmony_ci		) ;
163b815c7f3Sopenharmony_ci
164b815c7f3Sopenharmony_ci	exit_if_true (
165b815c7f3Sopenharmony_ci		length_before > chunk_info.datalen || chunk_info.datalen - length_before > 4,
166b815c7f3Sopenharmony_ci		"\n\nLine %d : testdata '%s' : Bad chunk length %u (previous length %u)\n\n", __LINE__, testdata, chunk_info.datalen, length_before
167b815c7f3Sopenharmony_ci		) ;
168b815c7f3Sopenharmony_ci
169b815c7f3Sopenharmony_ci	chunk_info.data = malloc (chunk_info.datalen) ;
170b815c7f3Sopenharmony_ci	err = sf_get_chunk_data (iterator, &chunk_info) ;
171b815c7f3Sopenharmony_ci	exit_if_true (
172b815c7f3Sopenharmony_ci		err != SF_ERR_NO_ERROR,
173b815c7f3Sopenharmony_ci		"\n\nLine %d : sf_get_chunk_size returned for testdata '%s' : %s\n\n", __LINE__, testdata, sf_error_number (err)
174b815c7f3Sopenharmony_ci		) ;
175b815c7f3Sopenharmony_ci
176b815c7f3Sopenharmony_ci	exit_if_true (
177b815c7f3Sopenharmony_ci		memcmp (testdata, chunk_info.data, length_before),
178b815c7f3Sopenharmony_ci		"\n\nLine %d : Data compare failed.\n    %s\n    %s\n\n", __LINE__, testdata, (char*) chunk_info.data
179b815c7f3Sopenharmony_ci		) ;
180b815c7f3Sopenharmony_ci
181b815c7f3Sopenharmony_ci	free (chunk_info.data) ;
182b815c7f3Sopenharmony_ci
183b815c7f3Sopenharmony_ci	sf_close (file) ;
184b815c7f3Sopenharmony_ci	unlink (filename) ;
185b815c7f3Sopenharmony_ci} /* chunk_test_helper */
186b815c7f3Sopenharmony_ci
187b815c7f3Sopenharmony_cistatic void
188b815c7f3Sopenharmony_cimultichunk_test_helper (const char *filename, int format, const char * testdata [], size_t testdata_len)
189b815c7f3Sopenharmony_ci{	SNDFILE			*file ;
190b815c7f3Sopenharmony_ci	SF_INFO			sfinfo ;
191b815c7f3Sopenharmony_ci	SF_CHUNK_INFO	chunk_info ;
192b815c7f3Sopenharmony_ci	SF_CHUNK_ITERATOR * iterator ;
193b815c7f3Sopenharmony_ci	uint32_t		length_before [16] ;
194b815c7f3Sopenharmony_ci	int				err, allow_fd ;
195b815c7f3Sopenharmony_ci	size_t			i ;
196b815c7f3Sopenharmony_ci
197b815c7f3Sopenharmony_ci
198b815c7f3Sopenharmony_ci	exit_if_true (
199b815c7f3Sopenharmony_ci		ARRAY_LEN (length_before) < testdata_len,
200b815c7f3Sopenharmony_ci		"\n\nLine %d : Bad array length.\n\n", __LINE__
201b815c7f3Sopenharmony_ci		) ;
202b815c7f3Sopenharmony_ci
203b815c7f3Sopenharmony_ci
204b815c7f3Sopenharmony_ci	sfinfo.samplerate	= 44100 ;
205b815c7f3Sopenharmony_ci	sfinfo.channels		= 1 ;
206b815c7f3Sopenharmony_ci	sfinfo.frames		= 0 ;
207b815c7f3Sopenharmony_ci	sfinfo.format		= format ;
208b815c7f3Sopenharmony_ci
209b815c7f3Sopenharmony_ci	switch (format & SF_FORMAT_SUBMASK)
210b815c7f3Sopenharmony_ci	{	case SF_FORMAT_ALAC_16 :
211b815c7f3Sopenharmony_ci			allow_fd = SF_FALSE ;
212b815c7f3Sopenharmony_ci			break ;
213b815c7f3Sopenharmony_ci		default :
214b815c7f3Sopenharmony_ci			allow_fd = SF_TRUE ;
215b815c7f3Sopenharmony_ci			break ;
216b815c7f3Sopenharmony_ci		} ;
217b815c7f3Sopenharmony_ci
218b815c7f3Sopenharmony_ci	file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, allow_fd, __LINE__) ;
219b815c7f3Sopenharmony_ci
220b815c7f3Sopenharmony_ci	/* Set up the chunk to write. */
221b815c7f3Sopenharmony_ci	for (i = 0 ; i < testdata_len ; i++)
222b815c7f3Sopenharmony_ci	{	memset (&chunk_info, 0, sizeof (chunk_info)) ;
223b815c7f3Sopenharmony_ci		snprintf (chunk_info.id, sizeof (chunk_info.id), "Test") ;
224b815c7f3Sopenharmony_ci		chunk_info.id_size = 4 ;
225b815c7f3Sopenharmony_ci
226b815c7f3Sopenharmony_ci		chunk_info.data = strdup (testdata [i]) ;
227b815c7f3Sopenharmony_ci		chunk_info.datalen = (unsigned int) strlen (chunk_info.data) ;
228b815c7f3Sopenharmony_ci
229b815c7f3Sopenharmony_ci		length_before [i] = chunk_info.datalen ;
230b815c7f3Sopenharmony_ci
231b815c7f3Sopenharmony_ci		err = sf_set_chunk (file, &chunk_info) ;
232b815c7f3Sopenharmony_ci		exit_if_true (
233b815c7f3Sopenharmony_ci			err != SF_ERR_NO_ERROR,
234b815c7f3Sopenharmony_ci			"\n\nLine %d : sf_set_chunk returned for testdata[%d] '%s' : %s\n\n", __LINE__, (int) i, testdata [i], sf_error_number (err)
235b815c7f3Sopenharmony_ci			) ;
236b815c7f3Sopenharmony_ci
237b815c7f3Sopenharmony_ci		memset (chunk_info.data, 0, chunk_info.datalen) ;
238b815c7f3Sopenharmony_ci		free (chunk_info.data) ;
239b815c7f3Sopenharmony_ci	}
240b815c7f3Sopenharmony_ci
241b815c7f3Sopenharmony_ci	sf_close (file) ;
242b815c7f3Sopenharmony_ci
243b815c7f3Sopenharmony_ci	file = test_open_file_or_die (filename, SFM_READ, &sfinfo, allow_fd, __LINE__) ;
244b815c7f3Sopenharmony_ci
245b815c7f3Sopenharmony_ci	memset (&chunk_info, 0, sizeof (chunk_info)) ;
246b815c7f3Sopenharmony_ci	snprintf (chunk_info.id, sizeof (chunk_info.id), "Test") ;
247b815c7f3Sopenharmony_ci	chunk_info.id_size = 4 ;
248b815c7f3Sopenharmony_ci
249b815c7f3Sopenharmony_ci	iterator = sf_get_chunk_iterator (file, &chunk_info) ;
250b815c7f3Sopenharmony_ci
251b815c7f3Sopenharmony_ci	i = 0 ;
252b815c7f3Sopenharmony_ci	while (iterator)
253b815c7f3Sopenharmony_ci	{	memset (&chunk_info, 0, sizeof (chunk_info)) ;
254b815c7f3Sopenharmony_ci		err = sf_get_chunk_size (iterator, &chunk_info) ;
255b815c7f3Sopenharmony_ci		exit_if_true (
256b815c7f3Sopenharmony_ci			i > testdata_len,
257b815c7f3Sopenharmony_ci			"\n\nLine %d : iterated to chunk #%d, but only %d chunks have been written\n\n", __LINE__, (int) i, (int) testdata_len
258b815c7f3Sopenharmony_ci			) ;
259b815c7f3Sopenharmony_ci
260b815c7f3Sopenharmony_ci		exit_if_true (
261b815c7f3Sopenharmony_ci			err != SF_ERR_NO_ERROR,
262b815c7f3Sopenharmony_ci			"\n\nLine %d : sf_get_chunk_size returned for testdata[%d] '%s' : %s\n\n", __LINE__, (int) i, testdata [i], sf_error_number (err)
263b815c7f3Sopenharmony_ci			) ;
264b815c7f3Sopenharmony_ci
265b815c7f3Sopenharmony_ci		exit_if_true (
266b815c7f3Sopenharmony_ci			length_before [i] > chunk_info.datalen || chunk_info.datalen - length_before [i] > 4,
267b815c7f3Sopenharmony_ci			"\n\nLine %d : testdata[%d] '%s' : Bad chunk length %u (previous length %u)\n\n", __LINE__, (int) i, testdata [i], chunk_info.datalen, length_before [i]
268b815c7f3Sopenharmony_ci			) ;
269b815c7f3Sopenharmony_ci
270b815c7f3Sopenharmony_ci		chunk_info.data = malloc (chunk_info.datalen) ;
271b815c7f3Sopenharmony_ci		err = sf_get_chunk_data (iterator, &chunk_info) ;
272b815c7f3Sopenharmony_ci		exit_if_true (
273b815c7f3Sopenharmony_ci			err != SF_ERR_NO_ERROR,
274b815c7f3Sopenharmony_ci			"\n\nLine %d : sf_get_chunk_size returned for testdata[%d] '%s' : %s\n\n", __LINE__, (int) i, testdata [i], sf_error_number (err)
275b815c7f3Sopenharmony_ci			) ;
276b815c7f3Sopenharmony_ci
277b815c7f3Sopenharmony_ci		exit_if_true (
278b815c7f3Sopenharmony_ci			4 != chunk_info.id_size,
279b815c7f3Sopenharmony_ci			"\n\nLine %d : testdata[%d] : Bad ID length %u (previous length %u)\n\n", __LINE__, (int) i, chunk_info.id_size, 4
280b815c7f3Sopenharmony_ci			) ;
281b815c7f3Sopenharmony_ci		exit_if_true (
282b815c7f3Sopenharmony_ci			memcmp ("Test", chunk_info.id, 4),
283b815c7f3Sopenharmony_ci			"\n\nLine %d : ID compare failed at %d.\n    %s\n    %s\n\n", __LINE__, (int) i, "Test", (char*) chunk_info.id
284b815c7f3Sopenharmony_ci			) ;
285b815c7f3Sopenharmony_ci
286b815c7f3Sopenharmony_ci		exit_if_true (
287b815c7f3Sopenharmony_ci			memcmp (testdata [i], chunk_info.data, length_before [i]),
288b815c7f3Sopenharmony_ci			"\n\nLine %d : Data compare failed at %d.\n    %s\n    %s\n\n", __LINE__, (int) i, testdata [i], (char*) chunk_info.data
289b815c7f3Sopenharmony_ci			) ;
290b815c7f3Sopenharmony_ci
291b815c7f3Sopenharmony_ci		free (chunk_info.data) ;
292b815c7f3Sopenharmony_ci		iterator = sf_next_chunk_iterator (iterator) ;
293b815c7f3Sopenharmony_ci		i++ ;
294b815c7f3Sopenharmony_ci	}
295b815c7f3Sopenharmony_ci
296b815c7f3Sopenharmony_ci	sf_close (file) ;
297b815c7f3Sopenharmony_ci	unlink (filename) ;
298b815c7f3Sopenharmony_ci} /* multichunk_test_helper */
299b815c7f3Sopenharmony_ci
300b815c7f3Sopenharmony_ci
301b815c7f3Sopenharmony_cistatic void
302b815c7f3Sopenharmony_cichunk_test (const char *filename, int format)
303b815c7f3Sopenharmony_ci{	const char*		testdata [] =
304b815c7f3Sopenharmony_ci	{	"There can be only one.", "", "A", "AB", "ABC", "ABCD", "ABCDE" } ;
305b815c7f3Sopenharmony_ci	uint32_t k ;
306b815c7f3Sopenharmony_ci
307b815c7f3Sopenharmony_ci	print_test_name (__func__, filename) ;
308b815c7f3Sopenharmony_ci
309b815c7f3Sopenharmony_ci	for (k = 0 ; k < ARRAY_LEN (testdata) ; k++)
310b815c7f3Sopenharmony_ci		chunk_test_helper (filename, format, testdata [k]) ;
311b815c7f3Sopenharmony_ci
312b815c7f3Sopenharmony_ci	multichunk_test_helper (filename, format, testdata, ARRAY_LEN (testdata)) ;
313b815c7f3Sopenharmony_ci
314b815c7f3Sopenharmony_ci	puts ("ok") ;
315b815c7f3Sopenharmony_ci} /* chunk_test */
316b815c7f3Sopenharmony_ci
317b815c7f3Sopenharmony_ci
318b815c7f3Sopenharmony_cistatic void
319b815c7f3Sopenharmony_ciwav_subchunk_test (unsigned int chunk_size)
320b815c7f3Sopenharmony_ci{	SNDFILE 		* file ;
321b815c7f3Sopenharmony_ci	SF_INFO			sfinfo ;
322b815c7f3Sopenharmony_ci	SF_CHUNK_INFO	chunk_info ;
323b815c7f3Sopenharmony_ci	char filename [256] ;
324b815c7f3Sopenharmony_ci	char chunk_data [10240] ;
325b815c7f3Sopenharmony_ci	short audio [16] ;
326b815c7f3Sopenharmony_ci	int	err, value ;
327b815c7f3Sopenharmony_ci
328b815c7f3Sopenharmony_ci	snprintf (filename, sizeof (filename), "subchunk_%04u.wav", chunk_size) ;
329b815c7f3Sopenharmony_ci	print_test_name (__func__, filename) ;
330b815c7f3Sopenharmony_ci
331b815c7f3Sopenharmony_ci	exit_if_true (sizeof (chunk_data) < chunk_size, "\n\nLine %d : sizeof (data) < chunk_size\n\n", __LINE__) ;
332b815c7f3Sopenharmony_ci
333b815c7f3Sopenharmony_ci	memset (chunk_data, 53, sizeof (chunk_data)) ;
334b815c7f3Sopenharmony_ci	chunk_data [chunk_size] = 0 ;
335b815c7f3Sopenharmony_ci
336b815c7f3Sopenharmony_ci	/* Fill in the chunk data. */
337b815c7f3Sopenharmony_ci	value = MAKE_MARKER ('a', 'd', 't', 'l') ;
338b815c7f3Sopenharmony_ci	memcpy (chunk_data, &value, sizeof (value)) ;
339b815c7f3Sopenharmony_ci	value = MAKE_MARKER ('n', 'o', 't', 'e') ;
340b815c7f3Sopenharmony_ci	memcpy (chunk_data + 4, &value, sizeof (value)) ;
341b815c7f3Sopenharmony_ci	value = H2LE_32 (chunk_size - 12) ;
342b815c7f3Sopenharmony_ci	memcpy (chunk_data + 8, &value, sizeof (value)) ;
343b815c7f3Sopenharmony_ci
344b815c7f3Sopenharmony_ci	sfinfo.samplerate	= 44100 ;
345b815c7f3Sopenharmony_ci	sfinfo.channels		= 1 ;
346b815c7f3Sopenharmony_ci	sfinfo.frames		= 0 ;
347b815c7f3Sopenharmony_ci	sfinfo.format		= SF_FORMAT_WAV | SF_FORMAT_PCM_16 ;
348b815c7f3Sopenharmony_ci
349b815c7f3Sopenharmony_ci	file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
350b815c7f3Sopenharmony_ci
351b815c7f3Sopenharmony_ci	/* Set up the chunk to write. */
352b815c7f3Sopenharmony_ci	memset (&chunk_info, 0, sizeof (chunk_info)) ;
353b815c7f3Sopenharmony_ci	snprintf (chunk_info.id, sizeof (chunk_info.id), "LIST") ;
354b815c7f3Sopenharmony_ci	chunk_info.id_size = 4 ;
355b815c7f3Sopenharmony_ci	chunk_info.data = chunk_data ;
356b815c7f3Sopenharmony_ci	chunk_info.datalen = (unsigned int) chunk_size ;
357b815c7f3Sopenharmony_ci
358b815c7f3Sopenharmony_ci	err = sf_set_chunk (file, &chunk_info) ;
359b815c7f3Sopenharmony_ci	exit_if_true (
360b815c7f3Sopenharmony_ci		err != SF_ERR_NO_ERROR,
361b815c7f3Sopenharmony_ci		"\n\nLine %d : sf_set_chunk returned for testdata : %s\n\n", __LINE__, sf_error_number (err)
362b815c7f3Sopenharmony_ci		) ;
363b815c7f3Sopenharmony_ci
364b815c7f3Sopenharmony_ci	memset (chunk_info.data, 0, chunk_info.datalen) ;
365b815c7f3Sopenharmony_ci
366b815c7f3Sopenharmony_ci	/* Add some audio data. */
367b815c7f3Sopenharmony_ci	memset (audio, 0, sizeof (audio)) ;
368b815c7f3Sopenharmony_ci	sf_write_short (file, audio, ARRAY_LEN (audio)) ;
369b815c7f3Sopenharmony_ci
370b815c7f3Sopenharmony_ci	sf_close (file) ;
371b815c7f3Sopenharmony_ci
372b815c7f3Sopenharmony_ci	file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
373b815c7f3Sopenharmony_ci
374b815c7f3Sopenharmony_ci	exit_if_true (
375b815c7f3Sopenharmony_ci		sfinfo.frames != ARRAY_LEN (audio),
376b815c7f3Sopenharmony_ci		"\n\nLine %d : Incorrect sample count (%d should be %d)\n", __LINE__, (int) sfinfo.frames, (int) ARRAY_LEN (audio)
377b815c7f3Sopenharmony_ci		) ;
378b815c7f3Sopenharmony_ci
379b815c7f3Sopenharmony_ci	if (chunk_size < 512)
380b815c7f3Sopenharmony_ci		check_log_buffer_or_die (file, __LINE__) ;
381b815c7f3Sopenharmony_ci
382b815c7f3Sopenharmony_ci	sf_close (file) ;
383b815c7f3Sopenharmony_ci
384b815c7f3Sopenharmony_ci	unlink (filename) ;
385b815c7f3Sopenharmony_ci	puts ("ok") ;
386b815c7f3Sopenharmony_ci} /* wav_subchunk_test */
387b815c7f3Sopenharmony_ci
388b815c7f3Sopenharmony_cistatic void
389b815c7f3Sopenharmony_cilarge_free_test (const char *filename, int format, unsigned int chunk_size)
390b815c7f3Sopenharmony_ci{	SNDFILE 		* file ;
391b815c7f3Sopenharmony_ci	SF_INFO			sfinfo ;
392b815c7f3Sopenharmony_ci	SF_CHUNK_INFO	chunk_info ;
393b815c7f3Sopenharmony_ci	char chunk_data [20002] ;
394b815c7f3Sopenharmony_ci	short audio [16] ;
395b815c7f3Sopenharmony_ci	int	err ;
396b815c7f3Sopenharmony_ci
397b815c7f3Sopenharmony_ci	print_test_name (__func__, filename) ;
398b815c7f3Sopenharmony_ci
399b815c7f3Sopenharmony_ci	exit_if_true (sizeof (chunk_data) <= chunk_size, "\n\nLine %d : sizeof (data) < chunk_size\n\n", __LINE__) ;
400b815c7f3Sopenharmony_ci
401b815c7f3Sopenharmony_ci	memset (chunk_data, 53, sizeof (chunk_data)) ;
402b815c7f3Sopenharmony_ci	chunk_data [chunk_size] = 0 ;
403b815c7f3Sopenharmony_ci
404b815c7f3Sopenharmony_ci	sfinfo.samplerate	= 44100 ;
405b815c7f3Sopenharmony_ci	sfinfo.channels		= 1 ;
406b815c7f3Sopenharmony_ci	sfinfo.frames		= 0 ;
407b815c7f3Sopenharmony_ci	sfinfo.format		= format ;
408b815c7f3Sopenharmony_ci
409b815c7f3Sopenharmony_ci	file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
410b815c7f3Sopenharmony_ci
411b815c7f3Sopenharmony_ci	/* Set up the chunk to write. */
412b815c7f3Sopenharmony_ci	memset (&chunk_info, 0, sizeof (chunk_info)) ;
413b815c7f3Sopenharmony_ci	snprintf (chunk_info.id, sizeof (chunk_info.id), "free") ;
414b815c7f3Sopenharmony_ci	chunk_info.id_size = 4 ;
415b815c7f3Sopenharmony_ci	chunk_info.data = chunk_data ;
416b815c7f3Sopenharmony_ci	chunk_info.datalen = chunk_size ;
417b815c7f3Sopenharmony_ci
418b815c7f3Sopenharmony_ci	err = sf_set_chunk (file, &chunk_info) ;
419b815c7f3Sopenharmony_ci	exit_if_true (
420b815c7f3Sopenharmony_ci		err != SF_ERR_NO_ERROR,
421b815c7f3Sopenharmony_ci		"\n\nLine %d : sf_set_chunk returned for testdata : %s\n\n", __LINE__, sf_error_number (err)
422b815c7f3Sopenharmony_ci		) ;
423b815c7f3Sopenharmony_ci
424b815c7f3Sopenharmony_ci	memset (chunk_info.data, 0, chunk_info.datalen) ;
425b815c7f3Sopenharmony_ci
426b815c7f3Sopenharmony_ci	/* Add some audio data. */
427b815c7f3Sopenharmony_ci	memset (audio, 0, sizeof (audio)) ;
428b815c7f3Sopenharmony_ci	sf_write_short (file, audio, ARRAY_LEN (audio)) ;
429b815c7f3Sopenharmony_ci
430b815c7f3Sopenharmony_ci	sf_close (file) ;
431b815c7f3Sopenharmony_ci
432b815c7f3Sopenharmony_ci	file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ;
433b815c7f3Sopenharmony_ci
434b815c7f3Sopenharmony_ci	exit_if_true (
435b815c7f3Sopenharmony_ci		sfinfo.frames != ARRAY_LEN (audio),
436b815c7f3Sopenharmony_ci		"\n\nLine %d : Incorrect sample count (%d should be %d)\n", __LINE__, (int) sfinfo.frames, (int) ARRAY_LEN (audio)
437b815c7f3Sopenharmony_ci		) ;
438b815c7f3Sopenharmony_ci
439b815c7f3Sopenharmony_ci	if (chunk_size < 512)
440b815c7f3Sopenharmony_ci		check_log_buffer_or_die (file, __LINE__) ;
441b815c7f3Sopenharmony_ci
442b815c7f3Sopenharmony_ci	sf_close (file) ;
443b815c7f3Sopenharmony_ci
444b815c7f3Sopenharmony_ci	unlink (filename) ;
445b815c7f3Sopenharmony_ci	puts ("ok") ;
446b815c7f3Sopenharmony_ci} /* large_free_test */
447