| Chris@0 | 1 /* | 
| Chris@0 | 2 ** Copyright (C) 1999-2011 Erik de Castro Lopo <erikd@mega-nerd.com> | 
| Chris@0 | 3 ** | 
| Chris@0 | 4 ** This program is free software; you can redistribute it and/or modify | 
| Chris@0 | 5 ** it under the terms of the GNU General Public License as published by | 
| Chris@0 | 6 ** the Free Software Foundation; either version 2 of the License, or | 
| Chris@0 | 7 ** (at your option) any later version. | 
| Chris@0 | 8 ** | 
| Chris@0 | 9 ** This program is distributed in the hope that it will be useful, | 
| Chris@0 | 10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of | 
| Chris@0 | 11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
| Chris@0 | 12 ** GNU General Public License for more details. | 
| Chris@0 | 13 ** | 
| Chris@0 | 14 ** You should have received a copy of the GNU General Public License | 
| Chris@0 | 15 ** along with this program; if not, write to the Free Software | 
| Chris@0 | 16 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | 
| Chris@0 | 17 */ | 
| Chris@0 | 18 | 
| Chris@0 | 19 #include "sfconfig.h" | 
| Chris@0 | 20 | 
| Chris@0 | 21 #include <stdio.h> | 
| Chris@0 | 22 #include <stdlib.h> | 
| Chris@0 | 23 #include <string.h> | 
| Chris@0 | 24 | 
| Chris@0 | 25 #if HAVE_UNISTD_H | 
| Chris@0 | 26 #include <unistd.h> | 
| Chris@0 | 27 #endif | 
| Chris@0 | 28 | 
| Chris@0 | 29 #if OS_IS_WIN32 | 
| Chris@0 | 30 #include <windows.h> | 
| Chris@0 | 31 #endif | 
| Chris@0 | 32 | 
| Chris@0 | 33 #include <sndfile.h> | 
| Chris@0 | 34 | 
| Chris@0 | 35 #include "utils.h" | 
| Chris@0 | 36 | 
| Chris@0 | 37 #define	BUFFER_SIZE		(1<<15) | 
| Chris@0 | 38 #define	SHORT_BUFFER	(256) | 
| Chris@0 | 39 | 
| Chris@0 | 40 static void | 
| Chris@0 | 41 error_number_test (void) | 
| Chris@0 | 42 {	const char 	*noerror, *errstr ; | 
| Chris@0 | 43 	int			k ; | 
| Chris@0 | 44 | 
| Chris@0 | 45 	print_test_name ("error_number_test", "") ; | 
| Chris@0 | 46 | 
| Chris@0 | 47 	noerror = sf_error_number (0) ; | 
| Chris@0 | 48 | 
| Chris@0 | 49 	for (k = 1 ; k < 300 ; k++) | 
| Chris@0 | 50 	{	errstr = sf_error_number (k) ; | 
| Chris@0 | 51 | 
| Chris@0 | 52 		/* Test for termination condition. */ | 
| Chris@0 | 53 		if (errstr == noerror) | 
| Chris@0 | 54 			break ; | 
| Chris@0 | 55 | 
| Chris@0 | 56 		/* Test for error. */ | 
| Chris@0 | 57 		if (strstr (errstr, "This is a bug in libsndfile.")) | 
| Chris@0 | 58 		{	printf ("\n\nError : error number %d : %s\n\n\n", k, errstr) ; | 
| Chris@0 | 59 			exit (1) ; | 
| Chris@0 | 60 			} ; | 
| Chris@0 | 61 		} ; | 
| Chris@0 | 62 | 
| Chris@0 | 63 | 
| Chris@0 | 64 	puts ("ok") ; | 
| Chris@0 | 65 	return ; | 
| Chris@0 | 66 } /* error_number_test */ | 
| Chris@0 | 67 | 
| Chris@0 | 68 static void | 
| Chris@0 | 69 error_value_test (void) | 
| Chris@0 | 70 {	static unsigned char aiff_data [0x1b0] = | 
| Chris@0 | 71 	{	'F' , 'O' , 'R' , 'M' , | 
| Chris@0 | 72 		0x00, 0x00, 0x01, 0xA8, /* FORM length */ | 
| Chris@0 | 73 | 
| Chris@0 | 74 		'A' , 'I' , 'F' , 'C' , | 
| Chris@0 | 75 		} ; | 
| Chris@0 | 76 | 
| Chris@0 | 77 	const char *filename = "error.aiff" ; | 
| Chris@0 | 78 	SNDFILE *file ; | 
| Chris@0 | 79 	SF_INFO sfinfo ; | 
| Chris@0 | 80 	int error_num ; | 
| Chris@0 | 81 | 
| Chris@0 | 82 	print_test_name ("error_value_test", filename) ; | 
| Chris@0 | 83 | 
| Chris@0 | 84 	dump_data_to_file (filename, aiff_data, sizeof (aiff_data)) ; | 
| Chris@0 | 85 | 
| Chris@0 | 86 	file = sf_open (filename, SFM_READ, &sfinfo) ; | 
| Chris@0 | 87 	if (file != NULL) | 
| Chris@0 | 88 	{	printf ("\n\nLine %d : Should not have been able to open this file.\n\n", __LINE__) ; | 
| Chris@0 | 89 		exit (1) ; | 
| Chris@0 | 90 		} ; | 
| Chris@0 | 91 | 
| Chris@0 | 92 	if ((error_num = sf_error (NULL)) <= 1 || error_num > 300) | 
| Chris@0 | 93 	{	printf ("\n\nLine %d : Should not have had an error number of %d.\n\n", __LINE__, error_num) ; | 
| Chris@0 | 94 		exit (1) ; | 
| Chris@0 | 95 		} ; | 
| Chris@0 | 96 | 
| Chris@0 | 97 	remove (filename) ; | 
| Chris@0 | 98 	puts ("ok") ; | 
| Chris@0 | 99 	return ; | 
| Chris@0 | 100 } /* error_value_test */ | 
| Chris@0 | 101 | 
| Chris@0 | 102 static void | 
| Chris@0 | 103 no_file_test (const char * filename) | 
| Chris@0 | 104 {	SNDFILE		*sndfile ; | 
| Chris@0 | 105 	SF_INFO		sfinfo ; | 
| Chris@0 | 106 | 
| Chris@0 | 107 	print_test_name (__func__, filename) ; | 
| Chris@0 | 108 | 
| Chris@0 | 109 	unlink (filename) ; | 
| Chris@0 | 110 | 
| Chris@0 | 111 	memset (&sfinfo, 0, sizeof (sfinfo)) ; | 
| Chris@0 | 112 	sndfile = sf_open (filename, SFM_READ, &sfinfo) ; | 
| Chris@0 | 113 | 
| Chris@0 | 114 	exit_if_true (sndfile != NULL, "\n\nLine %d : should not have received a valid SNDFILE* pointer.\n", __LINE__) ; | 
| Chris@0 | 115 | 
| Chris@0 | 116 	unlink (filename) ; | 
| Chris@0 | 117 	puts ("ok") ; | 
| Chris@0 | 118 } /* no_file_test */ | 
| Chris@0 | 119 | 
| Chris@0 | 120 static void | 
| Chris@0 | 121 zero_length_test (const char *filename) | 
| Chris@0 | 122 {	SNDFILE		*sndfile ; | 
| Chris@0 | 123 	SF_INFO		sfinfo ; | 
| Chris@0 | 124 	FILE		*file ; | 
| Chris@0 | 125 | 
| Chris@0 | 126 	print_test_name (__func__, filename) ; | 
| Chris@0 | 127 | 
| Chris@0 | 128 	/* Create a zero length file. */ | 
| Chris@0 | 129 	file = fopen (filename, "w") ; | 
| Chris@0 | 130 	exit_if_true (file == NULL, "\n\nLine %d : fopen ('%s') failed.\n", __LINE__, filename) ; | 
| Chris@0 | 131 	fclose (file) ; | 
| Chris@0 | 132 | 
| Chris@0 | 133 	memset (&sfinfo, 0, sizeof (sfinfo)) ; | 
| Chris@0 | 134 	sndfile = sf_open (filename, SFM_READ, &sfinfo) ; | 
| Chris@0 | 135 | 
| Chris@0 | 136 	exit_if_true (sndfile != NULL, "\n\nLine %d : should not have received a valid SNDFILE* pointer.\n", __LINE__) ; | 
| Chris@0 | 137 | 
| Chris@0 | 138 	exit_if_true (0 && sf_error (NULL) != SF_ERR_UNRECOGNISED_FORMAT, | 
| Chris@0 | 139 		"\n\nLine %3d : Error : %s\n       should be : %s\n", __LINE__, | 
| Chris@0 | 140 		sf_strerror (NULL), sf_error_number (SF_ERR_UNRECOGNISED_FORMAT)) ; | 
| Chris@0 | 141 | 
| Chris@0 | 142 	unlink (filename) ; | 
| Chris@0 | 143 	puts ("ok") ; | 
| Chris@0 | 144 } /* zero_length_test */ | 
| Chris@0 | 145 | 
| Chris@0 | 146 static void | 
| Chris@0 | 147 bad_wav_test (const char * filename) | 
| Chris@0 | 148 {	SNDFILE		*sndfile ; | 
| Chris@0 | 149 	SF_INFO		sfinfo ; | 
| Chris@0 | 150 | 
| Chris@0 | 151 	FILE		*file ; | 
| Chris@0 | 152 	const char	data [] = "RIFF    WAVEfmt            " ; | 
| Chris@0 | 153 | 
| Chris@0 | 154 	print_test_name (__func__, filename) ; | 
| Chris@0 | 155 | 
| Chris@0 | 156 	if ((file = fopen (filename, "w")) == NULL) | 
| Chris@0 | 157 	{	printf ("\n\nLine %d : fopen returned NULL.\n", __LINE__) ; | 
| Chris@0 | 158 		exit (1) ; | 
| Chris@0 | 159 		} ; | 
| Chris@0 | 160 | 
| Chris@0 | 161 	exit_if_true (fwrite (data, sizeof (data), 1, file) != 1, "\n\nLine %d : fwrite failed.\n", __LINE__) ; | 
| Chris@0 | 162 	fclose (file) ; | 
| Chris@0 | 163 | 
| Chris@0 | 164 	memset (&sfinfo, 0, sizeof (sfinfo)) ; | 
| Chris@0 | 165 	sndfile = sf_open (filename, SFM_READ, &sfinfo) ; | 
| Chris@0 | 166 | 
| Chris@0 | 167 	if (sndfile) | 
| Chris@0 | 168 	{	printf ("\n\nLine %d : should not have received a valid SNDFILE* pointer.\n", __LINE__) ; | 
| Chris@0 | 169 		exit (1) ; | 
| Chris@0 | 170 		} ; | 
| Chris@0 | 171 | 
| Chris@0 | 172 	unlink (filename) ; | 
| Chris@0 | 173 	puts ("ok") ; | 
| Chris@0 | 174 } /* bad_wav_test */ | 
| Chris@0 | 175 | 
| Chris@0 | 176 static void | 
| Chris@0 | 177 error_close_test (void) | 
| Chris@0 | 178 {	static short buffer [SHORT_BUFFER] ; | 
| Chris@0 | 179 	const char	*filename = "error_close.wav" ; | 
| Chris@0 | 180 	SNDFILE		*sndfile ; | 
| Chris@0 | 181 	SF_INFO		sfinfo ; | 
| Chris@0 | 182 	FILE		*file ; | 
| Chris@0 | 183 | 
| Chris@0 | 184 	print_test_name (__func__, filename) ; | 
| Chris@0 | 185 | 
| Chris@0 | 186 	/* Open a FILE* from which we will extract a file descriptor. */ | 
| Chris@0 | 187 	if ((file = fopen (filename, "w")) == NULL) | 
| Chris@0 | 188 	{	printf ("\n\nLine %d : fopen returned NULL.\n", __LINE__) ; | 
| Chris@0 | 189 		exit (1) ; | 
| Chris@0 | 190 		} ; | 
| Chris@0 | 191 | 
| Chris@0 | 192 	/* Set parameters for writing the file. */ | 
| Chris@0 | 193 	memset (&sfinfo, 0, sizeof (sfinfo)) ; | 
| Chris@0 | 194 	sfinfo.channels = 1 ; | 
| Chris@0 | 195 	sfinfo.samplerate = 44100 ; | 
| Chris@0 | 196 	sfinfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16 ; | 
| Chris@0 | 197 | 
| Chris@0 | 198 	sndfile = sf_open_fd (fileno (file), SFM_WRITE, &sfinfo, SF_TRUE) ; | 
| Chris@0 | 199 	if (sndfile == NULL) | 
| Chris@0 | 200 	{	printf ("\n\nLine %d : sf_open_fd failed : %s\n", __LINE__, sf_strerror (NULL)) ; | 
| Chris@0 | 201 		exit (1) ; | 
| Chris@0 | 202 		} ; | 
| Chris@0 | 203 | 
| Chris@0 | 204 	test_write_short_or_die (sndfile, 0, buffer, ARRAY_LEN (buffer), __LINE__) ; | 
| Chris@0 | 205 | 
| Chris@0 | 206 	/* Now close the fd associated with file before calling sf_close. */ | 
| Chris@0 | 207 	fclose (file) ; | 
| Chris@0 | 208 | 
| Chris@0 | 209 	if (sf_close (sndfile) == 0) | 
| Chris@0 | 210 	{ | 
| Chris@0 | 211 #if OS_IS_WIN32 | 
| Chris@0 | 212 		OSVERSIONINFOEX osvi ; | 
| Chris@0 | 213 | 
| Chris@0 | 214 		memset (&osvi, 0, sizeof (OSVERSIONINFOEX)) ; | 
| Chris@0 | 215 		osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX) ; | 
| Chris@0 | 216 | 
| Chris@0 | 217 		if (GetVersionEx ((OSVERSIONINFO *) &osvi)) | 
| Chris@0 | 218 		{	printf ("\n\nLine %d : sf_close should not have returned zero.\n", __LINE__) ; | 
| Chris@0 | 219 			printf ("\nHowever, this is a known bug in version %d.%d of windows so we'll ignore it.\n\n", | 
| Chris@0 | 220 					(int) osvi.dwMajorVersion, (int) osvi.dwMinorVersion) ; | 
| Chris@0 | 221 			} ; | 
| Chris@0 | 222 #else | 
| Chris@0 | 223 		printf ("\n\nLine %d : sf_close should not have returned zero.\n", __LINE__) ; | 
| Chris@0 | 224 		exit (1) ; | 
| Chris@0 | 225 #endif | 
| Chris@0 | 226 		} ; | 
| Chris@0 | 227 | 
| Chris@0 | 228 	unlink (filename) ; | 
| Chris@0 | 229 	puts ("ok") ; | 
| Chris@0 | 230 } /* error_close_test */ | 
| Chris@0 | 231 | 
| Chris@0 | 232 int | 
| Chris@0 | 233 main (void) | 
| Chris@0 | 234 { | 
| Chris@0 | 235 	error_number_test () ; | 
| Chris@0 | 236 	error_value_test () ; | 
| Chris@0 | 237 | 
| Chris@0 | 238 	error_close_test () ; | 
| Chris@0 | 239 | 
| Chris@0 | 240 	no_file_test ("no_file.wav") ; | 
| Chris@0 | 241 	zero_length_test ("zero_length.wav") ; | 
| Chris@0 | 242 	bad_wav_test ("bad_wav.wav") ; | 
| Chris@0 | 243 | 
| Chris@0 | 244 	return 0 ; | 
| Chris@0 | 245 } /* main */ | 
| Chris@0 | 246 |