static void file_seek_with_offset_test (const char *filename) { SF_PRIVATE sf_data, *psf ; sf_count_t real_end ; const size_t fileoffset = 64 ; print_test_name ("Testing seek with offset") ; /* Open the file created by the previous test for reading. */ memset (&sf_data, 0, sizeof (sf_data)) ; psf = &sf_data ; psf->file.mode = SFM_READ ; snprintf (psf->file.path.c, sizeof (psf->file.path.c), "%s", filename) ; test_open_or_die (psf, __LINE__) ; /* Gather basic info before setting offset. */ real_end = psf_fseek (psf, 0, SEEK_END) ; test_tell_or_die (psf, real_end, __LINE__) ; /* Set the fileoffset (usually in a real system this is due to an id3 tag). */ psf->fileoffset = fileoffset ; /* Check tell respects offset. */ test_tell_or_die (psf, real_end - fileoffset, __LINE__) ; /* Check seeking works as expected. */ test_seek_or_die (psf, 0, SEEK_SET, 0, __LINE__) ; test_seek_or_die (psf, 0, SEEK_CUR, 0, __LINE__) ; test_seek_or_die (psf, 0, SEEK_CUR, 0, __LINE__) ; test_seek_or_die (psf, 0, SEEK_END, real_end - fileoffset, __LINE__) ; test_close_or_die (psf, __LINE__) ; puts ("ok") ; } /* file_seek_with_offset_test */
static void truncate_test (const char *filename, int filetype) { SNDFILE *file ; SF_INFO sfinfo ; sf_count_t len ; print_test_name ("truncate_test", filename) ; sfinfo.samplerate = 11025 ; sfinfo.format = filetype ; sfinfo.channels = 2 ; file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, SF_TRUE, __LINE__) ; test_write_int_or_die (file, 0, int_data, BUFFER_LEN, __LINE__) ; len = 100 ; if (sf_command (file, SFC_FILE_TRUNCATE, &len, sizeof (len))) { printf ("Line %d: sf_command (SFC_FILE_TRUNCATE) returned error.\n", __LINE__) ; exit (1) ; } ; test_seek_or_die (file, 0, SEEK_CUR, len, 2, __LINE__) ; test_seek_or_die (file, 0, SEEK_END, len, 2, __LINE__) ; sf_close (file) ; unlink (filename) ; puts ("ok") ; } /* truncate_test */
static void ogg_int_test (void) { const char * filename = "vorbis_int.oga" ; SNDFILE * file ; SF_INFO sfinfo ; int seek_data [10] ; unsigned k ; print_test_name ("ogg_int_test", filename) ; /* Generate float data. */ gen_windowed_sine_float (data_out.f, ARRAY_LEN (data_out.f), 1.0 * 0x7FFF0000) ; /* Convert to integer. */ for (k = 0 ; k < ARRAY_LEN (data_out.i) ; k++) data_out.i [k] = lrintf (data_out.f [k]) ; memset (&sfinfo, 0, sizeof (sfinfo)) ; /* Set up output file type. */ sfinfo.format = SF_FORMAT_OGG | SF_FORMAT_VORBIS ; sfinfo.channels = 1 ; sfinfo.samplerate = SAMPLE_RATE ; /* Write the output file. */ file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ; test_write_int_or_die (file, 0, data_out.i, ARRAY_LEN (data_out.i), __LINE__) ; sf_close (file) ; /* Read the file in again. */ memset (&sfinfo, 0, sizeof (sfinfo)) ; file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ; test_read_int_or_die (file, 0, data_in.i, ARRAY_LEN (data_in.i), __LINE__) ; sf_close (file) ; puts ("ok") ; /* Test seeking. */ print_test_name ("ogg_seek_test", filename) ; file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ; test_seek_or_die (file, 10, SEEK_SET, 10, sfinfo.channels, __LINE__) ; test_read_int_or_die (file, 0, seek_data, ARRAY_LEN (seek_data), __LINE__) ; compare_int_or_die (seek_data, data_in.i + 10, ARRAY_LEN (seek_data), __LINE__) ; sf_close (file) ; puts ("ok") ; unlink (filename) ; } /* ogg_int_test */
static void ogg_double_test (void) { const char * filename = "vorbis_double.oga" ; SNDFILE * file ; SF_INFO sfinfo ; double seek_data [10] ; print_test_name ("ogg_double_test", filename) ; gen_windowed_sine_double (data_out.d, ARRAY_LEN (data_out.d), 0.95) ; memset (&sfinfo, 0, sizeof (sfinfo)) ; /* Set up output file type. */ sfinfo.format = SF_FORMAT_OGG | SF_FORMAT_VORBIS ; sfinfo.channels = 1 ; sfinfo.samplerate = SAMPLE_RATE ; /* Write the output file. */ file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ; test_write_double_or_die (file, 0, data_out.d, ARRAY_LEN (data_out.d), __LINE__) ; sf_close (file) ; /* Read the file in again. */ memset (&sfinfo, 0, sizeof (sfinfo)) ; file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ; test_read_double_or_die (file, 0, data_in.d, ARRAY_LEN (data_in.d), __LINE__) ; sf_close (file) ; puts ("ok") ; /* Test seeking. */ print_test_name ("ogg_seek_test", filename) ; file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ; test_seek_or_die (file, 10, SEEK_SET, 10, sfinfo.channels, __LINE__) ; test_read_double_or_die (file, 0, seek_data, ARRAY_LEN (seek_data), __LINE__) ; compare_double_or_die (seek_data, data_in.d + 10, ARRAY_LEN (seek_data), __LINE__) ; sf_close (file) ; puts ("ok") ; unlink (filename) ; } /* ogg_double_test */
static void extra_header_test (const char *filename, int filetype) { SNDFILE *outfile ; SF_INFO sfinfo ; sf_count_t frames ; short buffer [8] ; int k = 0 ; print_test_name ("extra_header_test", filename) ; sfinfo.samplerate = 44100 ; sfinfo.format = (filetype | SF_FORMAT_PCM_16) ; sfinfo.channels = 1 ; memset (buffer, 0xA0, sizeof (buffer)) ; /* Now write some frames. */ frames = ARRAY_LEN (buffer) / sfinfo.channels ; /* Test the file with extra header data. */ outfile = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, 464) ; sf_set_string (outfile, SF_STR_TITLE, filename) ; test_writef_short_or_die (outfile, k, buffer, frames, 466) ; sf_set_string (outfile, SF_STR_COPYRIGHT, "(c) 1980 Erik") ; sf_close (outfile) ; #if 1 /* ** Erik de Castro Lopo <*****@*****.**> May 23 2004. ** ** This file has extra string data in the header and therefore cannot ** currently be opened in SFM_RDWR mode. This is fixable, but its in ** a part of the code I don't want to fiddle with until the Ogg/Vorbis ** integration is done. */ if (sf_open (filename, SFM_RDWR, &sfinfo) != NULL) { printf ("\n\nError : should not be able to open this file in SFM_RDWR.\n\n") ; exit (1) ; } ; unlink (filename) ; puts ("ok") ; return ; #else hexdump_file (filename, 0, 100000) ; /* Open again for read/write. */ outfile = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, 493) ; /* ** In auto header update mode, seeking to the end of the file with ** SEEK_SET will fail from the 2nd seek on. seeking to 0, SEEK_END ** will seek to 0 anyway */ if (sf_command (outfile, SFC_SET_UPDATE_HEADER_AUTO, NULL, SF_TRUE) == 0) { printf ("\n\nError : sf_command (SFC_SET_UPDATE_HEADER_AUTO) return error : %s\n\n", sf_strerror (outfile)) ; exit (1) ; } ; /* Now write some frames. */ frames = ARRAY_LEN (buffer) / sfinfo.channels ; for (k = 1 ; k < 6 ; k++) { printf ("\n*** pass %d\n", k) ; memset (buffer, 0xA0 + k, sizeof (buffer)) ; test_seek_or_die (outfile, k * frames, SEEK_SET, k * frames, sfinfo.channels, 514) ; test_seek_or_die (outfile, 0, SEEK_END, k * frames, sfinfo.channels, 515) ; /* Open file again and make sure no errors in log buffer. */ if (0) { infile = test_open_file_or_die (filename, SFM_READ, &sfinfo, 519) ; check_log_buffer_or_die (infile, 520) ; sf_close (infile) ; } ; if (sfinfo.frames != k * frames) { printf ("\n\nLine %d : Incorrect sample count (%ld should be %ld)\n", 525, SF_COUNT_TO_LONG (sfinfo.frames), SF_COUNT_TO_LONG (k + frames)) ; dump_log_buffer (infile) ; exit (1) ; } ; if ((k & 1) == 0) test_write_short_or_die (outfile, k, buffer, sfinfo.channels * frames, 531) ; else test_writef_short_or_die (outfile, k, buffer, frames, 533) ; hexdump_file (filename, 0, 100000) ; } ; sf_close (outfile) ; unlink (filename) ; puts ("ok") ; return ; #endif } /* extra_header_test */
static void update_seek_double_test (const char *filename, int filetype) { SNDFILE *outfile, *infile ; SF_INFO sfinfo ; sf_count_t frames ; double buffer [8] ; int k ; print_test_name ("update_seek_double_test", filename) ; memset (buffer, 0, sizeof (buffer)) ; /* Create sound outfile with no data. */ sfinfo.format = filetype | SF_FORMAT_DOUBLE ; sfinfo.samplerate = 48000 ; sfinfo.channels = 2 ; if (sf_format_check (&sfinfo) == SF_FALSE) sfinfo.channels = 1 ; outfile = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; sf_close (outfile) ; /* Open again for read/write. */ outfile = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, SF_TRUE, __LINE__) ; /* ** In auto header update mode, seeking to the end of the file with ** SEEK_SET will fail from the 2nd seek on. seeking to 0, SEEK_END ** will seek to 0 anyway */ if (sf_command (outfile, SFC_SET_UPDATE_HEADER_AUTO, NULL, SF_TRUE) == 0) { printf ("\n\nError : sf_command (SFC_SET_UPDATE_HEADER_AUTO) return error : %s\n\n", sf_strerror (outfile)) ; exit (1) ; } ; /* Now write some frames. */ frames = ARRAY_LEN (buffer) / sfinfo.channels ; for (k = 0 ; k < 6 ; k++) { test_seek_or_die (outfile, k * frames, SEEK_SET, k * frames, sfinfo.channels, __LINE__) ; test_seek_or_die (outfile, 0, SEEK_END, k * frames, sfinfo.channels, __LINE__) ; /* Open file again and make sure no errors in log buffer. */ infile = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; check_log_buffer_or_die (infile, __LINE__) ; sf_close (infile) ; if (sfinfo.frames != k * frames) { printf ("\n\nLine %d : Incorrect sample count (%ld should be %ld)\n", __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), SF_COUNT_TO_LONG (k + frames)) ; dump_log_buffer (infile) ; exit (1) ; } ; if ((k & 1) == 0) test_write_double_or_die (outfile, k, buffer, sfinfo.channels * frames, __LINE__) ; else test_writef_double_or_die (outfile, k, buffer, frames, __LINE__) ; } ; sf_close (outfile) ; unlink (filename) ; puts ("ok") ; return ; } /* update_seek_double_test */
static void raw_offset_test (const char *filename, int typeminor) { SNDFILE *sndfile ; SF_INFO sfinfo ; sf_count_t start ; int k ; print_test_name ("raw_offset_test", filename) ; sfinfo.samplerate = 44100 ; sfinfo.format = SF_FORMAT_RAW | typeminor ; sfinfo.channels = 1 ; sfinfo.frames = 0 ; sndfile = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, SF_TRUE, __LINE__) ; start = 0 ; sf_command (sndfile, SFC_FILE_TRUNCATE, &start, sizeof (start)) ; for (k = 0 ; k < BUFFER_LEN ; k++) data [k] = k ; test_write_short_or_die (sndfile, 0, data, BUFFER_LEN, __LINE__) ; sf_close (sndfile) ; sndfile = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; check_log_buffer_or_die (sndfile, __LINE__) ; if (ABS (BUFFER_LEN - sfinfo.frames) > 1) { printf ("\n\nLine %d : Incorrect sample count (%" PRId64 " should be %d)\n", __LINE__, sfinfo.frames, BUFFER_LEN) ; dump_log_buffer (sndfile) ; exit (1) ; } ; memset (data, 0 , sizeof (data)) ; test_read_short_or_die (sndfile, 0, data, BUFFER_LEN, __LINE__) ; for (k = 0 ; k < BUFFER_LEN ; k++) if (data [k] != k) printf ("Error : line %d\n", __LINE__) ; /* Set dataoffset to 2 bytes from beginning of file. */ start = 2 ; sf_command (sndfile, SFC_SET_RAW_START_OFFSET, &start, sizeof (start)) ; /* Seek to new start */ test_seek_or_die (sndfile, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ; memset (data, 0 , sizeof (data)) ; test_read_short_or_die (sndfile, 0, data, BUFFER_LEN - 1, __LINE__) ; for (k = 0 ; k < BUFFER_LEN - 1 ; k++) if (data [k] != k + 1) { printf ("Error : line %d\n", __LINE__) ; exit (1) ; } ; /* Set dataoffset to 4 bytes from beginning of file. */ start = 4 ; sf_command (sndfile, SFC_SET_RAW_START_OFFSET, &start, sizeof (start)) ; /* Seek to new start */ test_seek_or_die (sndfile, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ; memset (data, 0 , sizeof (data)) ; test_read_short_or_die (sndfile, 0, data, BUFFER_LEN - 2, __LINE__) ; for (k = 0 ; k < BUFFER_LEN - 2 ; k++) if (data [k] != k + 2) { printf ("Error : line %d\n", __LINE__) ; exit (1) ; } ; /* Set dataoffset back to 0 bytes from beginning of file. */ start = 0 ; sf_command (sndfile, SFC_SET_RAW_START_OFFSET, &start, sizeof (start)) ; /* Seek to new start */ test_seek_or_die (sndfile, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ; memset (data, 0 , sizeof (data)) ; test_read_short_or_die (sndfile, 0, data, BUFFER_LEN, __LINE__) ; for (k = 0 ; k < BUFFER_LEN ; k++) if (data [k] != k) { printf ("Error : line %d\n", __LINE__) ; exit (1) ; } ; sf_close (sndfile) ; unlink (filename) ; puts ("ok") ; } /* raw_offset_test */
static void ogg_stereo_seek_test (const char * filename, int format) { static float data [SAMPLE_RATE] ; static float stereo_out [SAMPLE_RATE * 2] ; SNDFILE * file ; SF_INFO sfinfo ; sf_count_t pos ; unsigned k ; print_test_name (__func__, filename) ; gen_windowed_sine_float (data, ARRAY_LEN (data), 0.95) ; for (k = 0 ; k < ARRAY_LEN (data) ; k++) { stereo_out [2 * k] = data [k] ; stereo_out [2 * k + 1] = data [ARRAY_LEN (data) - k - 1] ; } ; memset (&sfinfo, 0, sizeof (sfinfo)) ; /* Set up output file type. */ sfinfo.format = format ; sfinfo.channels = 2 ; sfinfo.samplerate = SAMPLE_RATE ; /* Write the output file. */ file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ; test_write_float_or_die (file, 0, stereo_out, ARRAY_LEN (stereo_out), __LINE__) ; sf_close (file) ; /* Open file in again for reading. */ memset (&sfinfo, 0, sizeof (sfinfo)) ; file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ; /* Read in the whole file. */ test_read_float_or_die (file, 0, stereo_out, ARRAY_LEN (stereo_out), __LINE__) ; /* Now hammer seeking code. */ test_seek_or_die (file, 234, SEEK_SET, 234, sfinfo.channels, __LINE__) ; test_readf_float_or_die (file, 0, data, 10, __LINE__) ; compare_float_or_die (data, stereo_out + (234 * sfinfo.channels), 10, __LINE__) ; test_seek_or_die (file, 442, SEEK_SET, 442, sfinfo.channels, __LINE__) ; test_readf_float_or_die (file, 0, data, 10, __LINE__) ; compare_float_or_die (data, stereo_out + (442 * sfinfo.channels), 10, __LINE__) ; test_seek_or_die (file, 12, SEEK_CUR, 442 + 10 + 12, sfinfo.channels, __LINE__) ; test_readf_float_or_die (file, 0, data, 10, __LINE__) ; compare_float_or_die (data, stereo_out + ((442 + 10 + 12) * sfinfo.channels), 10, __LINE__) ; test_seek_or_die (file, 12, SEEK_CUR, 442 + 20 + 24, sfinfo.channels, __LINE__) ; test_readf_float_or_die (file, 0, data, 10, __LINE__) ; compare_float_or_die (data, stereo_out + ((442 + 20 + 24) * sfinfo.channels), 10, __LINE__) ; pos = 500 - sfinfo.frames ; test_seek_or_die (file, pos, SEEK_END, 500, sfinfo.channels, __LINE__) ; test_readf_float_or_die (file, 0, data, 10, __LINE__) ; compare_float_or_die (data, stereo_out + (500 * sfinfo.channels), 10, __LINE__) ; pos = 10 - sfinfo.frames ; test_seek_or_die (file, pos, SEEK_END, 10, sfinfo.channels, __LINE__) ; test_readf_float_or_die (file, 0, data, 10, __LINE__) ; compare_float_or_die (data, stereo_out + (10 * sfinfo.channels), 10, __LINE__) ; sf_close (file) ; puts ("ok") ; unlink (filename) ; } /* ogg_stereo_seek_test */
static void file_truncate_test (const char *filename) { SF_PRIVATE sf_data, *psf ; unsigned char buffer [256] ; int k ; /* ** Open a new file and write two blocks of data to the file. After each ** write, test that psf_get_filelen() returns the new length. */ printf (" %-24s : ", "file_truncate_test") ; fflush (stdout) ; memset (&sf_data, 0, sizeof (sf_data)) ; memset (buffer, 0xEE, sizeof (buffer)) ; psf = &sf_data ; strncpy (psf->filename, filename, sizeof (psf->filename)) ; /* ** Open the file write mode, write 0xEE data and then extend the file ** using truncate (the extended data should be 0x00). */ psf->mode = SFM_WRITE ; test_open_or_die (psf, __LINE__) ; test_write_or_die (psf, buffer, sizeof (buffer) / 2, 1, sizeof (buffer) / 2, __LINE__) ; psf_ftruncate (psf, sizeof (buffer)) ; test_close_or_die (psf, __LINE__) ; /* Open the file in read mode and check the data. */ psf->mode = SFM_READ ; test_open_or_die (psf, __LINE__) ; test_read_or_die (psf, buffer, sizeof (buffer), 1, sizeof (buffer), __LINE__) ; test_close_or_die (psf, __LINE__) ; for (k = 0 ; k < SIGNED_SIZEOF (buffer) / 2 ; k++) if (buffer [k] != 0xEE) { printf ("\n\nLine %d : buffer [%d] = %d (should be 0xEE)\n\n", __LINE__, k, buffer [k]) ; exit (1) ; } ; for (k = SIGNED_SIZEOF (buffer) / 2 ; k < SIGNED_SIZEOF (buffer) ; k++) if (buffer [k] != 0) { printf ("\n\nLine %d : buffer [%d] = %d (should be 0)\n\n", __LINE__, k, buffer [k]) ; exit (1) ; } ; /* Open the file in read/write and shorten the file using truncate. */ psf->mode = SFM_RDWR ; test_open_or_die (psf, __LINE__) ; psf_ftruncate (psf, sizeof (buffer) / 4) ; test_close_or_die (psf, __LINE__) ; /* Check the file length. */ psf->mode = SFM_READ ; test_open_or_die (psf, __LINE__) ; test_seek_or_die (psf, 0, SEEK_END, SIGNED_SIZEOF (buffer) / 4, __LINE__) ; test_close_or_die (psf, __LINE__) ; puts ("ok") ; } /* file_truncate_test */
static void file_read_write_test (const char *filename) { static int data_out [512] ; static int data_in [512] ; SF_PRIVATE sf_data, *psf ; sf_count_t retval ; /* ** Open a new file and write two blocks of data to the file. After each ** write, test that psf_get_filelen() returns the new length. */ printf (" %-24s : ", "file_write_test") ; fflush (stdout) ; memset (&sf_data, 0, sizeof (sf_data)) ; psf = &sf_data ; strncpy (psf->filename, filename, sizeof (psf->filename)) ; /* Test file open in write mode. */ psf->mode = SFM_WRITE ; test_open_or_die (psf, __LINE__) ; make_data (data_out, ARRAY_LEN (data_out), 1) ; test_write_or_die (psf, data_out, sizeof (data_out [0]), ARRAY_LEN (data_out), sizeof (data_out), __LINE__) ; if ((retval = psf_get_filelen (psf)) != sizeof (data_out)) { printf ("\n\nLine %d: file length after write is not correct (%ld should be %d).\n\n", __LINE__, (long) retval, (int) sizeof (data_out)) ; if (retval == 0) printf ("An fsync() may be necessary before fstat() in psf_get_filelen().\n\n") ; exit (1) ; } ; make_data (data_out, ARRAY_LEN (data_out), 2) ; test_write_or_die (psf, data_out, ARRAY_LEN (data_out), sizeof (data_out [0]), 2 * sizeof (data_out), __LINE__) ; if ((retval = psf_get_filelen (psf)) != 2 * sizeof (data_out)) { printf ("\n\nLine %d: file length after write is not correct. (%ld should be %d)\n\n", __LINE__, (long) retval, 2 * ((int) sizeof (data_out))) ; exit (1) ; } ; test_close_or_die (psf, __LINE__) ; puts ("ok") ; /* ** Now open the file in read mode, check the file length and check ** that the data is correct. */ printf (" %-24s : ", "file_read_test") ; fflush (stdout) ; /* Test file open in write mode. */ psf->mode = SFM_READ ; test_open_or_die (psf, __LINE__) ; make_data (data_out, ARRAY_LEN (data_out), 1) ; test_read_or_die (psf, data_in, 1, sizeof (data_in), sizeof (data_in), __LINE__) ; test_equal_or_die (data_out, data_in, ARRAY_LEN (data_out), __LINE__) ; make_data (data_out, ARRAY_LEN (data_out), 2) ; test_read_or_die (psf, data_in, sizeof (data_in [0]), ARRAY_LEN (data_in), 2 * sizeof (data_in), __LINE__) ; test_equal_or_die (data_out, data_in, ARRAY_LEN (data_out), __LINE__) ; test_close_or_die (psf, __LINE__) ; puts ("ok") ; /* ** Open the file in read/write mode, seek around a bit and then seek to ** the end of the file and write another block of data (3rd block). Then ** go back and check that all three blocks are correct. */ printf (" %-24s : ", "file_seek_test") ; fflush (stdout) ; /* Test file open in read/write mode. */ psf->mode = SFM_RDWR ; test_open_or_die (psf, __LINE__) ; test_seek_or_die (psf, 0, SEEK_SET, 0, __LINE__) ; test_seek_or_die (psf, 0, SEEK_END, 2 * SIGNED_SIZEOF (data_out), __LINE__) ; test_seek_or_die (psf, -1 * SIGNED_SIZEOF (data_out), SEEK_CUR, (sf_count_t) sizeof (data_out), __LINE__) ; test_seek_or_die (psf, SIGNED_SIZEOF (data_out), SEEK_CUR, 2 * SIGNED_SIZEOF (data_out), __LINE__) ; make_data (data_out, ARRAY_LEN (data_out), 3) ; test_write_or_die (psf, data_out, sizeof (data_out [0]), ARRAY_LEN (data_out), 3 * sizeof (data_out), __LINE__) ; test_seek_or_die (psf, 0, SEEK_SET, 0, __LINE__) ; make_data (data_out, ARRAY_LEN (data_out), 1) ; test_read_or_die (psf, data_in, 1, sizeof (data_in), sizeof (data_in), __LINE__) ; test_equal_or_die (data_out, data_in, ARRAY_LEN (data_out), __LINE__) ; test_seek_or_die (psf, 2 * SIGNED_SIZEOF (data_out), SEEK_SET, 2 * SIGNED_SIZEOF (data_out), __LINE__) ; make_data (data_out, ARRAY_LEN (data_out), 3) ; test_read_or_die (psf, data_in, 1, sizeof (data_in), 3 * sizeof (data_in), __LINE__) ; test_equal_or_die (data_out, data_in, ARRAY_LEN (data_out), __LINE__) ; test_seek_or_die (psf, SIGNED_SIZEOF (data_out), SEEK_SET, SIGNED_SIZEOF (data_out), __LINE__) ; make_data (data_out, ARRAY_LEN (data_out), 2) ; test_read_or_die (psf, data_in, 1, sizeof (data_in), 2 * sizeof (data_in), __LINE__) ; test_equal_or_die (data_out, data_in, ARRAY_LEN (data_out), __LINE__) ; test_close_or_die (psf, __LINE__) ; puts ("ok") ; /* ** Now test operations with a non-zero psf->fileoffset field. This field ** sets an artificial file start positions so that a seek to the start of ** the file will actually be a seek to the value given by psf->fileoffset. */ printf (" %-24s : ", "file_offset_test") ; fflush (stdout) ; /* Test file open in read/write mode. */ psf->mode = SFM_RDWR ; psf->fileoffset = sizeof (data_out [0]) * ARRAY_LEN (data_out) ; test_open_or_die (psf, __LINE__) ; if ((retval = psf_get_filelen (psf)) != 3 * sizeof (data_out)) { printf ("\n\nLine %d: file length after write is not correct. (%ld should be %d)\n\n", __LINE__, (long) retval, 3 * ((int) sizeof (data_out))) ; exit (1) ; } ; test_seek_or_die (psf, SIGNED_SIZEOF (data_out), SEEK_SET, SIGNED_SIZEOF (data_out), __LINE__) ; make_data (data_out, ARRAY_LEN (data_out), 5) ; test_write_or_die (psf, data_out, sizeof (data_out [0]), ARRAY_LEN (data_out), 2 * sizeof (data_out), __LINE__) ; test_close_or_die (psf, __LINE__) ; /* final test with psf->fileoffset == 0. */ psf->mode = SFM_RDWR ; psf->fileoffset = 0 ; test_open_or_die (psf, __LINE__) ; if ((retval = psf_get_filelen (psf)) != 3 * sizeof (data_out)) { printf ("\n\nLine %d: file length after write is not correct. (%ld should be %d)\n\n", __LINE__, (long) retval, 3 * ((int) sizeof (data_out))) ; exit (1) ; } ; make_data (data_out, ARRAY_LEN (data_out), 1) ; test_read_or_die (psf, data_in, 1, sizeof (data_in), sizeof (data_in), __LINE__) ; test_equal_or_die (data_out, data_in, ARRAY_LEN (data_out), __LINE__) ; make_data (data_out, ARRAY_LEN (data_out), 2) ; test_read_or_die (psf, data_in, 1, sizeof (data_in), 2 * sizeof (data_in), __LINE__) ; test_equal_or_die (data_out, data_in, ARRAY_LEN (data_out), __LINE__) ; make_data (data_out, ARRAY_LEN (data_out), 5) ; test_read_or_die (psf, data_in, 1, sizeof (data_in), 3 * sizeof (data_in), __LINE__) ; test_equal_or_die (data_out, data_in, ARRAY_LEN (data_out), __LINE__) ; test_close_or_die (psf, __LINE__) ; puts ("ok") ; } /* file_read_write_test */
static void string_start_end_test (const char *filename, int typemajor) { const char *cptr ; SNDFILE *file ; SF_INFO sfinfo ; int errors = 0 ; print_test_name ("string_start_end_test", filename) ; memset (&sfinfo, 0, sizeof (sfinfo)) ; sfinfo.samplerate = 44100 ; sfinfo.channels = 1 ; sfinfo.frames = 0 ; sfinfo.format = typemajor | SF_FORMAT_PCM_16 ; file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; /* Write stuff at start of file. */ sf_set_string (file, SF_STR_TITLE, filename) ; sf_set_string (file, SF_STR_SOFTWARE, software) ; sf_set_string (file, SF_STR_ARTIST, artist) ; sf_set_string (file, SF_STR_GENRE, genre) ; sf_set_string (file, SF_STR_TRACKNUMBER, trackno) ; /* Write data to file. */ test_write_short_or_die (file, 0, data_out, BUFFER_LEN, __LINE__) ; test_seek_or_die (file, 0, SEEK_SET, 0, sfinfo.channels, __LINE__) ; /* Write more stuff at end of file. */ sf_set_string (file, SF_STR_COPYRIGHT, copyright) ; sf_set_string (file, SF_STR_COMMENT, comment) ; sf_set_string (file, SF_STR_DATE, date) ; sf_set_string (file, SF_STR_ALBUM, album) ; sf_set_string (file, SF_STR_LICENSE, license) ; sf_close (file) ; file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; check_log_buffer_or_die (file, __LINE__) ; if (sfinfo.frames != BUFFER_LEN) { printf ("***** Bad frame count %d (should be %d)\n\n", (int) sfinfo.frames, BUFFER_LEN) ; errors ++ ; } ; cptr = sf_get_string (file, SF_STR_TITLE) ; if (cptr == NULL || strcmp (filename, cptr) != 0) { if (errors++ == 0) puts ("\n") ; printf (" Bad filename : %s\n", cptr) ; } ; cptr = sf_get_string (file, SF_STR_COPYRIGHT) ; if (cptr == NULL || strcmp (copyright, cptr) != 0) { if (errors++ == 0) puts ("\n") ; printf (" Bad copyright : %s\n", cptr) ; } ; cptr = sf_get_string (file, SF_STR_SOFTWARE) ; if (cptr == NULL || strstr (cptr, software) != cptr) { if (errors++ == 0) puts ("\n") ; printf (" Bad software : %s\n", cptr) ; } ; if (str_count (cptr, "libsndfile") != 1) { if (errors++ == 0) puts ("\n") ; printf (" Bad software : %s\n", cptr) ; } ; cptr = sf_get_string (file, SF_STR_ARTIST) ; if (cptr == NULL || strcmp (artist, cptr) != 0) { if (errors++ == 0) puts ("\n") ; printf (" Bad artist : %s\n", cptr) ; } ; cptr = sf_get_string (file, SF_STR_COMMENT) ; if (cptr == NULL || strcmp (comment, cptr) != 0) { if (errors++ == 0) puts ("\n") ; printf (" Bad comment : %s\n", cptr) ; } ; if (typemajor != SF_FORMAT_AIFF) { cptr = sf_get_string (file, SF_STR_DATE) ; if (cptr == NULL || strcmp (date, cptr) != 0) { if (errors++ == 0) puts ("\n") ; printf (" Bad date : %s\n", cptr) ; } ; cptr = sf_get_string (file, SF_STR_GENRE) ; if (cptr == NULL || strcmp (genre, cptr) != 0) { if (errors++ == 0) puts ("\n") ; printf (" Bad genre : %s\n", cptr) ; } ; } ; switch (typemajor) { case SF_FORMAT_AIFF : case SF_FORMAT_WAV : case SF_FORMAT_WAVEX : case SF_ENDIAN_BIG | SF_FORMAT_WAV : case SF_FORMAT_RF64 : /* These formats do not support the following. */ break ; default : cptr = sf_get_string (file, SF_STR_ALBUM) ; if (cptr == NULL || strcmp (album, cptr) != 0) { if (errors++ == 0) puts ("\n") ; printf (" Bad album : %s\n", cptr) ; } ; cptr = sf_get_string (file, SF_STR_LICENSE) ; if (cptr == NULL || strcmp (license, cptr) != 0) { if (errors++ == 0) puts ("\n") ; printf (" Bad license : %s\n", cptr) ; } ; cptr = sf_get_string (file, SF_STR_TRACKNUMBER) ; if (cptr == NULL || strcmp (trackno, cptr) != 0) { if (errors++ == 0) puts ("\n") ; printf (" Bad track no. : %s\n", cptr) ; } ; break ; } ; if (errors > 0) { printf ("\n*** Error count : %d ***\n\n", errors) ; dump_log_buffer (file) ; exit (1) ; } ; sf_close (file) ; unlink (filename) ; puts ("ok") ; } /* string_start_end_test */
static void channel_test (void) { static float float_data [1024] ; static float read_float [1024] ; static int read_int [1024] ; static short read_short [1024] ; unsigned int ch, k, position = 0 ; gen_windowed_sine_float (float_data, ARRAY_LEN (float_data), 0.9) ; for (ch = 1 ; ch <= 8 ; ch++) { SNDFILE *file ; SF_INFO wsfinfo, rsfinfo ; sf_count_t wframes = ARRAY_LEN (float_data) / ch ; double maxdiff ; char filename [256] ; snprintf (filename, sizeof (filename), "chan_%d.wav", ch) ; print_test_name (__func__, filename) ; sf_info_setup (&wsfinfo, SF_FORMAT_WAV | SF_FORMAT_FLOAT, 48000, ch) ; sf_info_clear (&rsfinfo) ; /* Write the test file. */ file = test_open_file_or_die (filename, SFM_WRITE, &wsfinfo, SF_FALSE, __LINE__) ; test_writef_float_or_die (file, 0, float_data, wframes, __LINE__) ; sf_close (file) ; /* Read it as float and test. */ file = test_open_file_or_die (filename, SFM_READ, &rsfinfo, SF_FALSE, __LINE__) ; exit_if_true (rsfinfo.frames == 0, "\n\nLine %d : Frames in file %" PRId64 ".\n\n", __LINE__, rsfinfo.frames) ; exit_if_true (wframes != rsfinfo.frames, "\n\nLine %d : Wrote %" PRId64 ", read %" PRId64 " frames.\n\n", __LINE__, wframes, rsfinfo.frames) ; sf_command (file, SFC_SET_SCALE_FLOAT_INT_READ, NULL, SF_TRUE) ; test_readf_float_or_die (file, 0, read_float, rsfinfo.frames, __LINE__) ; compare_float_or_die (float_data, read_float, ch * rsfinfo.frames, __LINE__) ; /* Read it as short and test. */ test_seek_or_die (file, 0, SEEK_SET, 0, ch, __LINE__) ; test_readf_short_or_die (file, 0, read_short, rsfinfo.frames, __LINE__) ; for (k = 0 ; k < ARRAY_LEN (read_float) ; k++) read_float [k] = read_short [k] * (0.9 / 0x8000) ; maxdiff = max_diff (float_data, read_float, ch * rsfinfo.frames, &position) ; exit_if_true (maxdiff > 0.5, "\n\nLine %d : Max diff is %f at index %u\n\n", __LINE__, maxdiff, position) ; /* Read it as int and test. */ test_seek_or_die (file, 0, SEEK_SET, 0, ch, __LINE__) ; test_readf_int_or_die (file, 0, read_int, rsfinfo.frames, __LINE__) ; for (k = 0 ; k < ARRAY_LEN (read_float) ; k++) read_float [k] = read_int [k] * (0.9 / 0x80000000) ; maxdiff = max_diff (float_data, read_float, ch * rsfinfo.frames, &position) ; exit_if_true (maxdiff > 0.5, "\n\nLine %d : Max diff is %f at index %u\n\n", __LINE__, maxdiff, position) ; sf_close (file) ; unlink (filename) ; printf ("ok\n") ; } ; return ; } /* channel_test */