static void zero_length_test (const char *filename) { SNDFILE *sndfile ; SF_INFO sfinfo ; FILE *file ; print_test_name (__func__, filename) ; /* Create a zero length file. */ file = fopen (filename, "w") ; exit_if_true (file == NULL, "\n\nLine %d : fopen ('%s') failed.\n", __LINE__, filename) ; fclose (file) ; memset (&sfinfo, 0, sizeof (sfinfo)) ; sndfile = sf_open (filename, SFM_READ, &sfinfo) ; exit_if_true (sndfile != NULL, "\n\nLine %d : should not have received a valid SNDFILE* pointer.\n", __LINE__) ; exit_if_true (0 && sf_error (NULL) != SF_ERR_UNRECOGNISED_FORMAT, "\n\nLine %3d : Error : %s\n should be : %s\n", __LINE__, sf_strerror (NULL), sf_error_number (SF_ERR_UNRECOGNISED_FORMAT)) ; unlink (filename) ; puts ("ok") ; } /* zero_length_test */
static void software_string_test (const char *filename) { size_t k ; print_test_name (__func__, filename) ; for (k = 0 ; k < 50 ; k++) { const char *result ; char sfname [64] = "" ; SNDFILE *file ; SF_INFO info ; sf_info_setup (&info, SF_FORMAT_WAV | SF_FORMAT_PCM_16, 44100, 1) ; file = test_open_file_or_die (filename, SFM_WRITE, &info, SF_TRUE, __LINE__) ; snprintf (sfname, MIN (k, sizeof (sfname)), "%s", "abcdefghijklmnopqrestvwxyz0123456789abcdefghijklmnopqrestvwxyz") ; exit_if_true (sf_set_string (file, SF_STR_SOFTWARE, sfname), "\n\nLine %d : sf_set_string (f, SF_STR_SOFTWARE, '%s') failed : %s\n", __LINE__, sfname, sf_strerror (file)) ; sf_close (file) ; file = test_open_file_or_die (filename, SFM_READ, &info, SF_TRUE, __LINE__) ; result = sf_get_string (file, SF_STR_SOFTWARE) ; exit_if_true (result == NULL, "\n\nLine %d : sf_get_string (file, SF_STR_SOFTWARE) returned NULL.\n\n", __LINE__) ; exit_if_true (strstr (result, sfname) != result, "\n\nLine %d : Can't fine string '%s' in '%s'\n\n", __LINE__, sfname, result) ; sf_close (file) ; } ; unlink (filename) ; puts ("ok") ; } /* software_string_test */
static void major_format_test (void) { SF_FORMAT_INFO info ; int have_ogg = 0, have_flac = 0 ; int m, major_count ; print_test_name (__func__, NULL) ; sf_command (NULL, SFC_GET_FORMAT_MAJOR_COUNT, &major_count, sizeof (int)) ; for (m = 0 ; m < major_count ; m++) { info.format = m ; sf_command (NULL, SFC_GET_FORMAT_MAJOR, &info, sizeof (info)) ; have_flac = info.format == SF_FORMAT_FLAC ? 1 : have_flac ; have_ogg = info.format == SF_FORMAT_OGG ? 1 : have_ogg ; } ; if (HAVE_EXTERNAL_LIBS) { exit_if_true (have_flac == 0, "\n\nLine %d : FLAC should be available.\n\n", __LINE__) ; exit_if_true (have_ogg == 0, "\n\nLine %d : Ogg/Vorbis should be available.\n\n", __LINE__) ; } else { exit_if_true (have_flac, "\n\nLine %d : FLAC should not be available.\n\n", __LINE__) ; exit_if_true (have_ogg, "\n\nLine %d : Ogg/Vorbis should not be available.\n\n", __LINE__) ; } ; puts ("ok") ; } /* major_format_test */
static void wchar_test (void) { #if OS_IS_WIN32 SNDFILE * file ; SF_INFO info ; LPCWSTR filename = L"test.wav" ; print_test_name (__func__, "test.wav") ; info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16 ; info.channels = 1 ; info.samplerate = 44100 ; file = sf_wchar_open (filename, SFM_WRITE, &info) ; exit_if_true (file == NULL, "\n\nLine %d : sf_wchar_open failed : %s\n\n", __LINE__, sf_strerror (NULL)) ; sf_close (file) ; /* This should check that the file did in fact get created with a ** wchar_t * filename. */ exit_if_true ( GetFileAttributesW (filename) == INVALID_FILE_ATTRIBUTES, "\n\nLine %d : GetFileAttributes failed.\n\n", __LINE__ ) ; /* Use this because the file was created with CreateFileW. */ DeleteFileW (filename) ; puts ("ok") ; #endif } /* wchar_test */
static void large_free_test (const char *filename, int format, size_t chunk_size) { SNDFILE * file ; SF_INFO sfinfo ; SF_CHUNK_INFO chunk_info ; char chunk_data [20002] ; short audio [16] ; int err ; print_test_name (__func__, filename) ; exit_if_true (sizeof (chunk_data) <= chunk_size, "\n\nLine %d : sizeof (data) < chunk_size\n\n", __LINE__) ; memset (chunk_data, 53, sizeof (chunk_data)) ; chunk_data [chunk_size] = 0 ; sfinfo.samplerate = 44100 ; sfinfo.channels = 1 ; sfinfo.frames = 0 ; sfinfo.format = format ; file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; /* Set up the chunk to write. */ memset (&chunk_info, 0, sizeof (chunk_info)) ; snprintf (chunk_info.id, sizeof (chunk_info.id), "free") ; chunk_info.id_size = 4 ; chunk_info.data = chunk_data ; chunk_info.datalen = chunk_size ; err = sf_set_chunk (file, &chunk_info) ; exit_if_true ( err != SF_ERR_NO_ERROR, "\n\nLine %d : sf_set_chunk returned for testdata : %s\n\n", __LINE__, sf_error_number (err) ) ; memset (chunk_info.data, 0, chunk_info.datalen) ; /* Add some audio data. */ memset (audio, 0, sizeof (audio)) ; sf_write_short (file, audio, ARRAY_LEN (audio)) ; sf_close (file) ; file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; exit_if_true ( sfinfo.frames != ARRAY_LEN (audio), "\n\nLine %d : Incorrect sample count (%d should be %d)\n", __LINE__, (int) sfinfo.frames, (int) ARRAY_LEN (audio) ) ; if (chunk_size < 512) check_log_buffer_or_die (file, __LINE__) ; sf_close (file) ; unlink (filename) ; puts ("ok") ; } /* large_free_test */
static void read_write_peak_test (const char *filename, int filetype) { SNDFILE *file ; SF_INFO sfinfo ; double small_data [10] ; double max_peak = 0.0 ; unsigned k ; print_test_name (__func__, filename) ; for (k = 0 ; k < ARRAY_LEN (small_data) ; k ++) small_data [k] = 0.1 ; sfinfo.samplerate = 44100 ; sfinfo.channels = 2 ; sfinfo.format = filetype ; sfinfo.frames = 0 ; /* Open the file, add peak chunk and write samples with value 0.1. */ file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ; sf_command (file, SFC_SET_ADD_PEAK_CHUNK, NULL, SF_TRUE) ; test_write_double_or_die (file, 0, small_data, ARRAY_LEN (small_data), __LINE__) ; sf_close (file) ; /* Open the fiel RDWR, write sample valied 1.25. */ file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, SF_FALSE, __LINE__) ; for (k = 0 ; k < ARRAY_LEN (small_data) ; k ++) small_data [k] = 1.0 ; test_write_double_or_die (file, 0, small_data, ARRAY_LEN (small_data), __LINE__) ; sf_command (file, SFC_GET_SIGNAL_MAX, &max_peak, sizeof (max_peak)) ; sf_close (file) ; exit_if_true (max_peak < 0.1, "\n\nLine %d : max peak (%5.3f) should not be 0.1.\n\n", __LINE__, max_peak) ; /* Open the file and test the values written to the PEAK chunk. */ file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ; exit_if_true (sfinfo.channels * sfinfo.frames != 2 * ARRAY_LEN (small_data), "Line %d : frame count is %ld, should be %d\n", __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), 2 * ARRAY_LEN (small_data)) ; sf_command (file, SFC_GET_SIGNAL_MAX, &max_peak, sizeof (double)) ; sf_close (file) ; exit_if_true (max_peak < 1.0, "\n\nLine %d : max peak (%5.3f) should be 1.0.\n\n", __LINE__, max_peak) ; unlink (filename) ; puts ("ok") ; } /* read_write_peak_test */
static void string_rdwr_grow_test (const char *filename, int typemajor) { SNDFILE *file ; SF_INFO sfinfo ; sf_count_t frames ; const char * str ; print_test_name (__func__, filename) ; /* Create a file that contains some strings. Then open the file in RDWR mode and grow the file by writing more audio data to it. Check that the audio data has been added to the file, and that the strings are still there. */ /* Create a short file that contains a string. */ memset (&sfinfo, 0, sizeof (sfinfo)) ; sfinfo.samplerate = 44100 ; sfinfo.channels = 2 ; sfinfo.frames = 0 ; sfinfo.format = typemajor | SF_FORMAT_PCM_16 ; file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; /* Write data to file. */ test_write_short_or_die (file, 0, data_out, BUFFER_LEN, __LINE__) ; /* Write some strings at end of file. */ sf_set_string (file, SF_STR_TITLE , title) ; sf_set_string (file, SF_STR_COMMENT, comment) ; sf_close (file) ; /* Now open file again in SFM_RDWR mode and write more audio data to it. */ file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, SF_TRUE, __LINE__) ; /* Write more data to file. */ test_write_short_or_die (file, 0, data_out, BUFFER_LEN, __LINE__) ; sf_close (file) ; /* Now open file again. It should now contain two BUFFER_LEN's worth of frames and the strings. */ frames = 2 * BUFFER_LEN / sfinfo.channels ; file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; exit_if_true (frames != sfinfo.frames, "\n\nLine %d : Frame count %" PRId64 " should be %" PRId64 ".\n", __LINE__, sfinfo.frames, frames) ; /* Check the strings */ str = sf_get_string (file, SF_STR_TITLE) ; exit_if_true (str == NULL, "\n\nLine %d : SF_STR_TITLE string is NULL.\n", __LINE__) ; exit_if_true (strcmp (str, title) != 0, "\n\nLine %d : SF_STR_TITLE doesn't match what was written.\n", __LINE__) ; str = sf_get_string (file, SF_STR_COMMENT) ; exit_if_true (str == NULL, "\n\nLine %d : SF_STR_COMMENT string is NULL.\n", __LINE__) ; exit_if_true (strcmp (str, comment) != 0, "\n\nLine %d : SF_STR_COMMENT doesn't match what was written.\n", __LINE__) ; sf_close (file) ; unlink (filename) ; puts ("ok") ; } /* string_rdwr_grow_test */
static void channel_map_test (const char *filename, int filetype) { SNDFILE *file ; SF_INFO sfinfo ; int channel_map_read [4], channel_map_write [4] = { SF_CHANNEL_MAP_FRONT_LEFT, SF_CHANNEL_MAP_FRONT_CENTER, SF_CHANNEL_MAP_REAR_LEFT, SF_CHANNEL_MAP_REAR_RIGHT } ; print_test_name ("channel_map_test", filename) ; memset (&sfinfo, 0, sizeof (sfinfo)) ; sfinfo.samplerate = 11025 ; sfinfo.format = filetype ; sfinfo.channels = ARRAY_LEN (channel_map_read) ; /* Write file without channel map. */ file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ; sf_close (file) ; /* Read file making sure no channel map exists. */ file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; exit_if_true ( sf_command (file, SFC_GET_CHANNEL_MAP_INFO, channel_map_read, sizeof (channel_map_read)) != SF_FALSE, "\n\nLine %d : sf_command (SFC_GET_CHANNEL_MAP_INFO) should have failed.\n\n", __LINE__ ) ; check_log_buffer_or_die (file, __LINE__) ; sf_close (file) ; /* Write file with a channel map. */ file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ; exit_if_true ( sf_command (file, SFC_SET_CHANNEL_MAP_INFO, channel_map_write, sizeof (channel_map_write)) == SF_FALSE, "\n\nLine %d : sf_command (SFC_SET_CHANNEL_MAP_INFO) failed.\n\n", __LINE__ ) ; sf_close (file) ; /* Read file making sure no channel map exists. */ file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; exit_if_true ( sf_command (file, SFC_GET_CHANNEL_MAP_INFO, channel_map_read, sizeof (channel_map_read)) != SF_TRUE, "\n\nLine %d : sf_command (SFC_GET_CHANNEL_MAP_INFO) failed.\n\n", __LINE__ ) ; check_log_buffer_or_die (file, __LINE__) ; sf_close (file) ; exit_if_true ( memcmp (channel_map_read, channel_map_write, sizeof (channel_map_read)) != 0, "\n\nLine %d : Channel map read does not match channel map written.\n\n", __LINE__ ) ; unlink (filename) ; puts ("ok") ; } /* channel_map_test */
static void rf64_long_file_downgrade_test (const char *filename) { static int output [BUFFER_LEN] ; static int input [1] = { 0 } ; SNDFILE *file ; SF_INFO sfinfo ; sf_count_t output_frames = 0 ; print_test_name (__func__, filename) ; sf_info_clear (&sfinfo) ; memset (output, 0, sizeof (output)) ; output [0] = 0x1020304 ; sfinfo.samplerate = 44100 ; sfinfo.frames = ARRAY_LEN (output) ; sfinfo.channels = 1 ; sfinfo.format = SF_FORMAT_RF64 | SF_FORMAT_PCM_32 ; file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; exit_if_true (sf_command (file, SFC_RF64_AUTO_DOWNGRADE, NULL, SF_TRUE) != SF_TRUE, "\n\nLine %d: sf_command failed.\n", __LINE__) ; while (output_frames * sizeof (output [0]) < 0x100000000) { test_write_int_or_die (file, 0, output, ARRAY_LEN (output), __LINE__) ; output_frames += ARRAY_LEN (output) ; } ; sf_close (file) ; sf_info_clear (&sfinfo) ; file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; exit_if_true (sfinfo.format != (SF_FORMAT_RF64 | SF_FORMAT_PCM_32), "\n\nLine %d: RF64 to WAV downgrade should have failed.\n", __LINE__) ; exit_if_true (sfinfo.channels != 1, "\n\nLine %d: Incorrect number of channels in file.\n", __LINE__) ; exit_if_true (sfinfo.frames != output_frames, "\n\nLine %d: Incorrect number of frames in file (%d should be %d).\n", __LINE__, (int) sfinfo.frames, (int) output_frames) ; /* Check that the first sample read is the same as the first written. */ test_read_int_or_die (file, 0, input, ARRAY_LEN (input), __LINE__) ; exit_if_true (input [0] != output [0], "\n\nLine %d: Bad first sample (0x%08x).\n", __LINE__, input [0]) ; check_log_buffer_or_die (file, __LINE__) ; sf_close (file) ; puts ("ok") ; unlink (filename) ; return ; } /* rf64_long_file_downgrade_test */
static void string_short_rdwr_test (const char *filename, int typemajor) { SNDFILE *file ; SF_INFO sfinfo ; sf_count_t frames = BUFFER_LEN ; const char * str ; print_test_name (__func__, filename) ; memset (&sfinfo, 0, sizeof (sfinfo)) ; sfinfo.format = typemajor | SF_FORMAT_PCM_16 ; sfinfo.samplerate = 44100 ; sfinfo.channels = 1 ; sfinfo.frames = 0 ; file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ; /* Write data to file. */ test_write_short_or_die (file, 0, data_out, BUFFER_LEN, __LINE__) ; sf_set_string (file, SF_STR_TITLE, long_title) ; sf_set_string (file, SF_STR_ARTIST, long_artist) ; sf_close (file) ; /* Open the file RDWR. */ file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, SF_FALSE, __LINE__) ; exit_if_true (frames != sfinfo.frames, "\n\nLine %d : Frame count %" PRId64 " should be %" PRId64 ".\n", __LINE__, sfinfo.frames, frames) ; str = sf_get_string (file, SF_STR_TITLE) ; exit_if_true (str == NULL, "\n\nLine %d : SF_STR_TITLE string is NULL.\n", __LINE__) ; exit_if_true (strcmp (str, long_title) != 0, "\n\nLine %d : SF_STR_TITLE doesn't match what was written.\n", __LINE__) ; str = sf_get_string (file, SF_STR_ARTIST) ; exit_if_true (str == NULL, "\n\nLine %d : SF_STR_TITLE string is NULL.\n", __LINE__) ; exit_if_true (strcmp (str, long_artist) != 0, "\n\nLine %d : SF_STR_ARTIST doesn't match what was written.\n", __LINE__) ; /* Change title and artist. */ sf_set_string (file, SF_STR_TITLE, title) ; sf_set_string (file, SF_STR_ARTIST, artist) ; sf_close (file) ; file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ; check_log_buffer_or_die (file, __LINE__) ; str = sf_get_string (file, SF_STR_TITLE) ; exit_if_true (str == NULL, "\n\nLine %d : SF_STR_TITLE string is NULL.\n", __LINE__) ; exit_if_true (strcmp (str, title) != 0, "\n\nLine %d : SF_STR_TITLE doesn't match what was written.\n", __LINE__) ; str = sf_get_string (file, SF_STR_ARTIST) ; exit_if_true (str == NULL, "\n\nLine %d : SF_STR_ARTIST string is NULL.\n", __LINE__) ; exit_if_true (strcmp (str, artist) != 0, "\n\nLine %d : SF_STR_ARTIST doesn't match what was written.\n", __LINE__) ; sf_close (file) ; unlink (filename) ; puts ("ok") ; } /* string_short_rdwr_test */
static void double_scaled_test (const char *filename, int allow_exit, int replace_float, int filetype, double target_snr) { SNDFILE *file ; SF_INFO sfinfo ; double snr ; int byterate ; print_test_name ("double_scaled_test", filename) ; gen_windowed_sine_double (double_data, DFT_DATA_LENGTH, 0.9999) ; sfinfo.samplerate = SAMPLE_RATE ; sfinfo.frames = DFT_DATA_LENGTH ; sfinfo.channels = 1 ; sfinfo.format = filetype ; file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; sf_command (file, SFC_TEST_IEEE_FLOAT_REPLACE, NULL, replace_float) ; test_write_double_or_die (file, 0, double_data, DFT_DATA_LENGTH, __LINE__) ; sf_close (file) ; memset (double_test, 0, sizeof (double_test)) ; file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; sf_command (file, SFC_TEST_IEEE_FLOAT_REPLACE, NULL, replace_float) ; exit_if_true (sfinfo.format != filetype, "\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, filetype, sfinfo.format) ; exit_if_true (sfinfo.frames < DFT_DATA_LENGTH, "\n\nLine %d: Incorrect number of frames in file (too short). (%" PRId64 " should be %d)\n", __LINE__, sfinfo.frames, DFT_DATA_LENGTH) ; exit_if_true (sfinfo.channels != 1, "\n\nLine %d: Incorrect number of channels in file.\n", __LINE__) ; check_log_buffer_or_die (file, __LINE__) ; test_read_double_or_die (file, 0, double_test, DFT_DATA_LENGTH, __LINE__) ; byterate = sf_current_byterate (file) ; exit_if_true (byterate <= 0, "\n\nLine %d: byterate is zero.\n", __LINE__) ; sf_close (file) ; snr = dft_cmp_double (__LINE__, double_data, double_test, DFT_DATA_LENGTH, target_snr, allow_exit) ; exit_if_true (snr > target_snr, "% 6.1fdB SNR\n\n Error : should be better than % 6.1fdB\n\n", snr, target_snr) ; printf ("% 6.1fdB SNR ... ok\n", snr) ; unlink (filename) ; return ; } /* double_scaled_test */
static void current_sf_info_test (const char *filename) { SNDFILE *outfile, *infile ; SF_INFO outinfo, ininfo ; sf_count_t last_count ; print_test_name ("current_sf_info_test", filename) ; outinfo.samplerate = 44100 ; outinfo.format = (SF_FORMAT_WAV | SF_FORMAT_PCM_16) ; outinfo.channels = 1 ; outinfo.frames = 0 ; outfile = test_open_file_or_die (filename, SFM_WRITE, &outinfo, SF_TRUE, __LINE__) ; sf_command (outfile, SFC_SET_UPDATE_HEADER_AUTO, NULL, 0) ; exit_if_true (outinfo.frames != 0, "\n\nLine %d : Initial sfinfo.frames is not zero.\n\n", __LINE__ ) ; test_write_double_or_die (outfile, 0, double_data, BUFFER_LEN, __LINE__) ; sf_command (outfile, SFC_GET_CURRENT_SF_INFO, &outinfo, sizeof (outinfo)) ; exit_if_true (outinfo.frames != BUFFER_LEN, "\n\nLine %d : Initial sfinfo.frames (%ld) should be %d.\n\n", __LINE__, SF_COUNT_TO_LONG (outinfo.frames), BUFFER_LEN ) ; /* Read file making sure no channel map exists. */ memset (&ininfo, 0, sizeof (ininfo)) ; infile = test_open_file_or_die (filename, SFM_READ, &ininfo, SF_TRUE, __LINE__) ; last_count = ininfo.frames ; test_write_double_or_die (outfile, 0, double_data, BUFFER_LEN, __LINE__) ; sf_command (infile, SFC_GET_CURRENT_SF_INFO, &ininfo, sizeof (ininfo)) ; exit_if_true (ininfo.frames != BUFFER_LEN, "\n\nLine %d : Initial sfinfo.frames (%ld) should be %d.\n\n", __LINE__, SF_COUNT_TO_LONG (ininfo.frames), BUFFER_LEN ) ; sf_close (outfile) ; sf_close (infile) ; unlink (filename) ; puts ("ok") ; } /* current_sf_info_test */
static void bad_wav_test (const char * filename) { SNDFILE *sndfile ; SF_INFO sfinfo ; FILE *file ; const char data [] = "RIFF WAVEfmt " ; print_test_name (__func__, filename) ; if ((file = fopen (filename, "w")) == NULL) { printf ("\n\nLine %d : fopen returned NULL.\n", __LINE__) ; exit (1) ; } ; exit_if_true (fwrite (data, sizeof (data), 1, file) != 1, "\n\nLine %d : fwrite failed.\n", __LINE__) ; fclose (file) ; memset (&sfinfo, 0, sizeof (sfinfo)) ; sndfile = sf_open (filename, SFM_READ, &sfinfo) ; if (sndfile) { printf ("\n\nLine %d : should not have received a valid SNDFILE* pointer.\n", __LINE__) ; exit (1) ; } ; unlink (filename) ; puts ("ok") ; } /* bad_wav_test */
static void wavex_amb_test (const char *filename) { static short buffer [800] ; SNDFILE *file ; SF_INFO sfinfo ; sf_count_t frames ; print_test_name (__func__, filename) ; sfinfo.samplerate = 44100 ; sfinfo.format = SF_FORMAT_WAVEX | SF_FORMAT_PCM_16 ; sfinfo.channels = 4 ; frames = ARRAY_LEN (buffer) / sfinfo.channels ; file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; sf_command (file, SFC_WAVEX_SET_AMBISONIC, NULL, SF_AMBISONIC_B_FORMAT) ; test_writef_short_or_die (file, 0, buffer, frames, __LINE__) ; sf_close (file) ; memset (&sfinfo, 0, sizeof (sfinfo)) ; file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; exit_if_true ( sf_command (file, SFC_WAVEX_GET_AMBISONIC, NULL, 0) != SF_AMBISONIC_B_FORMAT, "\n\nLine %d : Error, this file should be in Ambisonic B format.\n", __LINE__ ) ; sf_close (file) ; unlink (filename) ; puts ("ok") ; } /* wavex_amb_test */
static void string_rdwr_test (const char *filename, int typemajor) { SNDFILE *file ; SF_INFO sfinfo ; sf_count_t frames ; const char * str ; print_test_name (__func__, filename) ; create_short_sndfile (filename, typemajor | SF_FORMAT_PCM_16, 2) ; memset (&sfinfo, 0, sizeof (sfinfo)) ; file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, SF_FALSE, __LINE__) ; frames = sfinfo.frames ; sf_set_string (file, SF_STR_TITLE, title) ; sf_close (file) ; file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ; exit_if_true (frames != sfinfo.frames, "\n\nLine %d : Frame count %" PRId64 " should be %" PRId64 ".\n", __LINE__, sfinfo.frames, frames) ; str = sf_get_string (file, SF_STR_TITLE) ; exit_if_true (str == NULL, "\n\nLine %d : SF_STR_TITLE string is NULL.\n", __LINE__) ; exit_if_true (strcmp (str, title) != 0, "\n\nLine %d : SF_STR_TITLE doesn't match what was written.\n", __LINE__) ; sf_close (file) ; file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, SF_FALSE, __LINE__) ; frames = sfinfo.frames ; sf_set_string (file, SF_STR_TITLE, title) ; sf_close (file) ; file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, SF_FALSE, __LINE__) ; str = sf_get_string (file, SF_STR_TITLE) ; exit_if_true (str == NULL, "\n\nLine %d : SF_STR_TITLE string is NULL.\n", __LINE__) ; sf_set_string (file, SF_STR_ARTIST, artist) ; sf_close (file) ; file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ; str = sf_get_string (file, SF_STR_ARTIST) ; exit_if_true (str == NULL, "\n\nLine %d : SF_STR_ARTIST string is NULL.\n", __LINE__) ; exit_if_true (strcmp (str, artist) != 0, "\n\nLine %d : SF_STR_ARTIST doesn't match what was written.\n", __LINE__) ; str = sf_get_string (file, SF_STR_TITLE) ; exit_if_true (str == NULL, "\n\nLine %d : SF_STR_TITLE string is NULL.\n", __LINE__) ; exit_if_true (strcmp (str, title) != 0, "\n\nLine %d : SF_STR_TITLE doesn't match what was written.\n", __LINE__) ; exit_if_true (frames != sfinfo.frames, "\n\nLine %d : Frame count %" PRId64 " should be %" PRId64 ".\n", __LINE__, sfinfo.frames, frames) ; sf_close (file) ; unlink (filename) ; puts ("ok") ; } /* string_rdwr_test */
static void rf64_downgrade_test (const char *filename) { static short output [BUFFER_LEN] ; static short input [BUFFER_LEN] ; SNDFILE *file ; SF_INFO sfinfo ; unsigned k ; print_test_name (__func__, filename) ; sf_info_clear (&sfinfo) ; sfinfo.samplerate = 44100 ; sfinfo.frames = ARRAY_LEN (output) ; sfinfo.channels = 1 ; sfinfo.format = SF_FORMAT_RF64 | SF_FORMAT_PCM_16 ; file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; exit_if_true (sf_command (file, SFC_RF64_AUTO_DOWNGRADE, NULL, SF_FALSE) != SF_FALSE, "\n\nLine %d: sf_command failed.\n", __LINE__) ; exit_if_true (sf_command (file, SFC_RF64_AUTO_DOWNGRADE, NULL, SF_TRUE) != SF_TRUE, "\n\nLine %d: sf_command failed.\n", __LINE__) ; test_write_short_or_die (file, 0, output, ARRAY_LEN (output), __LINE__) ; exit_if_true (sf_command (file, SFC_RF64_AUTO_DOWNGRADE, NULL, SF_FALSE) != SF_TRUE, "\n\nLine %d: sf_command failed.\n", __LINE__) ; exit_if_true (sf_command (file, SFC_RF64_AUTO_DOWNGRADE, NULL, SF_TRUE) != SF_TRUE, "\n\nLine %d: sf_command failed.\n", __LINE__) ; sf_close (file) ; memset (input, 0, sizeof (input)) ; sf_info_clear (&sfinfo) ; file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; exit_if_true (sfinfo.format != (SF_FORMAT_WAVEX | SF_FORMAT_PCM_16), "\n\nLine %d: RF64 to WAV downgrade failed.\n", __LINE__) ; exit_if_true (sfinfo.frames != ARRAY_LEN (output), "\n\nLine %d: Incorrect number of frames in file (too short). (%d should be %d)\n", __LINE__, (int) sfinfo.frames, (int) ARRAY_LEN (output)) ; exit_if_true (sfinfo.channels != 1, "\n\nLine %d: Incorrect number of channels in file.\n", __LINE__) ; check_log_buffer_or_die (file, __LINE__) ; test_read_short_or_die (file, 0, input, ARRAY_LEN (input), __LINE__) ; sf_close (file) ; for (k = 0 ; k < ARRAY_LEN (input) ; k++) exit_if_true (input [k] != output [k], "\n\nLine: %d: Error on input %d, expected %d, got %d\n", __LINE__, k, output [k], input [k]) ; puts ("ok") ; unlink (filename) ; return ; } /* rf64_downgrade_test */
int main (void) { int k ; if (file_exists ("libsndfile.spec.in")) exit_if_true (chdir ("tests") != 0, "\n Error : chdir ('tests') failed.\n") ; for (k = 0 ; filetypes [k] ; k++) stdio_test (filetypes [k]) ; return 0 ; } /* main */
static void subtype_format_test (void) { SF_FORMAT_INFO info ; int have_vorbis = 0 ; int s, subtype_count ; print_test_name (__func__, NULL) ; sf_command (NULL, SFC_GET_FORMAT_SUBTYPE_COUNT, &subtype_count, sizeof (int)) ; for (s = 0 ; s < subtype_count ; s++) { info.format = s ; sf_command (NULL, SFC_GET_FORMAT_SUBTYPE, &info, sizeof (info)) ; have_vorbis = info.format == SF_FORMAT_VORBIS ? 1 : have_vorbis ; } ; if (HAVE_EXTERNAL_LIBS) exit_if_true (have_vorbis == 0, "\n\nLine %d : Ogg/Vorbis should be available.\n\n", __LINE__) ; else exit_if_true (have_vorbis, "\n\nLine %d : Ogg/Vorbis should not be available.\n\n", __LINE__) ; puts ("ok") ; } /* subtype_format_test */
static void no_file_test (const char * filename) { SNDFILE *sndfile ; SF_INFO sfinfo ; print_test_name (__func__, filename) ; unlink (filename) ; memset (&sfinfo, 0, sizeof (sfinfo)) ; sndfile = sf_open (filename, SFM_READ, &sfinfo) ; exit_if_true (sndfile != NULL, "\n\nLine %d : should not have received a valid SNDFILE* pointer.\n", __LINE__) ; unlink (filename) ; puts ("ok") ; } /* no_file_test */
static void simple_format_test (void) { SF_FORMAT_INFO info ; int have_flac = 0, have_ogg = 0, have_vorbis = 0 ; int s, simple_count ; print_test_name (__func__, NULL) ; sf_command (NULL, SFC_GET_SIMPLE_FORMAT_COUNT, &simple_count, sizeof (int)) ; for (s = 0 ; s < simple_count ; s++) { info.format = s ; sf_command (NULL, SFC_GET_SIMPLE_FORMAT, &info, sizeof (info)) ; switch (info.format & SF_FORMAT_TYPEMASK) { case SF_FORMAT_FLAC : have_flac = 1 ; break ; case SF_FORMAT_OGG : have_ogg = 1 ; break ; default : break ; } ; switch (info.format & SF_FORMAT_SUBMASK) { case SF_FORMAT_VORBIS : have_vorbis = 1 ; break ; default : break ; } ; } ; if (HAVE_EXTERNAL_LIBS) { exit_if_true (have_flac == 0, "\n\nLine %d : FLAC should be available.\n\n", __LINE__) ; exit_if_true (have_ogg == 0, "\n\nLine %d : Ogg/Vorbis should be available.\n\n", __LINE__) ; exit_if_true (have_vorbis == 0, "\n\nLine %d : Ogg/Vorbis should be available.\n\n", __LINE__) ; } else { exit_if_true (have_flac, "\n\nLine %d : FLAC should not be available.\n\n", __LINE__) ; exit_if_true (have_ogg, "\n\nLine %d : Ogg/Vorbis should not be available.\n\n", __LINE__) ; exit_if_true (have_vorbis, "\n\nLine %d : Ogg/Vorbis should not be available.\n\n", __LINE__) ; } ; puts ("ok") ; } /* simple_format_test */
int main (void) { int k ; if (file_exists ("libsndfile.spec.in")) exit_if_true (chdir ("tests") != 0, "\n Error : chdir ('tests') failed.\n") ; for (k = 0 ; read_only_types [k].format ; k++) pipe_read_test (read_only_types [k].format, read_only_types [k].ext) ; for (k = 0 ; read_write_types [k].format ; k++) pipe_write_test (read_write_types [k].ext) ; for (k = 0 ; read_write_types [k].format ; k++) useek_pipe_rw_test (read_write_types [k].format, read_write_types [k].ext) ; if (0) pipe_test_others (read_write_types, read_only_types) ; return 0 ; } /* main */
static void broadcast_rdwr_test (const char *filename, int filetype) { SF_BROADCAST_INFO binfo ; SNDFILE *file ; SF_INFO sfinfo ; sf_count_t frames ; print_test_name (__func__, filename) ; create_short_sndfile (filename, filetype, 2) ; memset (&sfinfo, 0, sizeof (sfinfo)) ; memset (&binfo, 0, sizeof (binfo)) ; snprintf (binfo.description, sizeof (binfo.description), "Test description") ; snprintf (binfo.originator, sizeof (binfo.originator), "Test originator") ; snprintf (binfo.originator_reference, sizeof (binfo.originator_reference), "%08x-%08x", (unsigned int) time (NULL), (unsigned int) (~ time (NULL))) ; snprintf (binfo.origination_date, sizeof (binfo.origination_date), "%d/%02d/%02d", 2006, 3, 30) ; snprintf (binfo.origination_time, sizeof (binfo.origination_time), "%02d:%02d:%02d", 20, 27, 0) ; snprintf (binfo.umid, sizeof (binfo.umid), "Some umid") ; binfo.coding_history_size = 0 ; file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, SF_TRUE, __LINE__) ; frames = sfinfo.frames ; if (sf_command (file, SFC_SET_BROADCAST_INFO, &binfo, sizeof (binfo)) != SF_FALSE) { printf ("\n\nLine %d : sf_command (SFC_SET_BROADCAST_INFO) should have failed but didn't.\n\n", __LINE__) ; exit (1) ; } ; sf_close (file) ; file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; sf_close (file) ; exit_if_true (frames != sfinfo.frames, "\n\nLine %d : Frame count %lld should be %lld.\n", __LINE__, sfinfo.frames, frames) ; unlink (filename) ; puts ("ok") ; } /* broadcast_rdwr_test */
static void multichunk_test_helper (const char *filename, int format, const char * testdata [], size_t testdata_len) { SNDFILE *file ; SF_INFO sfinfo ; SF_CHUNK_INFO chunk_info ; SF_CHUNK_ITERATOR * iterator ; uint32_t length_before [16] ; int err, allow_fd ; size_t i ; exit_if_true ( ARRAY_LEN (length_before) < testdata_len, "\n\nLine %d : Bad array length.\n\n", __LINE__ ) ; sfinfo.samplerate = 44100 ; sfinfo.channels = 1 ; sfinfo.frames = 0 ; sfinfo.format = format ; switch (format & SF_FORMAT_SUBMASK) { case SF_FORMAT_ALAC_16 : allow_fd = SF_FALSE ; break ; default : allow_fd = SF_TRUE ; break ; } ; file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, allow_fd, __LINE__) ; /* Set up the chunk to write. */ for (i = 0 ; i < testdata_len ; i++) { memset (&chunk_info, 0, sizeof (chunk_info)) ; snprintf (chunk_info.id, sizeof (chunk_info.id), "Test") ; chunk_info.id_size = 4 ; chunk_info.data = strdup (testdata [i]) ; chunk_info.datalen = strlen (chunk_info.data) ; length_before [i] = chunk_info.datalen ; err = sf_set_chunk (file, &chunk_info) ; exit_if_true ( err != SF_ERR_NO_ERROR, "\n\nLine %d : sf_set_chunk returned for testdata[%d] '%s' : %s\n\n", __LINE__, (int) i, testdata [i], sf_error_number (err) ) ; memset (chunk_info.data, 0, chunk_info.datalen) ; free (chunk_info.data) ; } sf_close (file) ; file = test_open_file_or_die (filename, SFM_READ, &sfinfo, allow_fd, __LINE__) ; memset (&chunk_info, 0, sizeof (chunk_info)) ; snprintf (chunk_info.id, sizeof (chunk_info.id), "Test") ; chunk_info.id_size = 4 ; iterator = sf_get_chunk_iterator (file, &chunk_info) ; i = 0 ; while (iterator) { memset (&chunk_info, 0, sizeof (chunk_info)) ; err = sf_get_chunk_size (iterator, &chunk_info) ; exit_if_true ( i > testdata_len, "\n\nLine %d : iterated to chunk #%d, but only %d chunks have been written\n\n", __LINE__, (int) i, (int) testdata_len ) ; exit_if_true ( err != SF_ERR_NO_ERROR, "\n\nLine %d : sf_get_chunk_size returned for testdata[%d] '%s' : %s\n\n", __LINE__, (int) i, testdata [i], sf_error_number (err) ) ; exit_if_true ( length_before [i] > chunk_info.datalen || chunk_info.datalen - length_before [i] > 4, "\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] ) ; chunk_info.data = malloc (chunk_info.datalen) ; err = sf_get_chunk_data (iterator, &chunk_info) ; exit_if_true ( err != SF_ERR_NO_ERROR, "\n\nLine %d : sf_get_chunk_size returned for testdata[%d] '%s' : %s\n\n", __LINE__, (int) i, testdata [i], sf_error_number (err) ) ; exit_if_true ( 4 != chunk_info.id_size, "\n\nLine %d : testdata[%d] : Bad ID length %u (previous length %u)\n\n", __LINE__, (int) i, chunk_info.id_size, 4 ) ; exit_if_true ( memcmp ("Test", chunk_info.id, 4), "\n\nLine %d : ID compare failed at %d.\n %s\n %s\n\n", __LINE__, (int) i, "Test", (char*) chunk_info.id ) ; exit_if_true ( memcmp (testdata [i], chunk_info.data, length_before [i]), "\n\nLine %d : Data compare failed at %d.\n %s\n %s\n\n", __LINE__, (int) i, testdata [i], (char*) chunk_info.data ) ; free (chunk_info.data) ; iterator = sf_next_chunk_iterator (iterator) ; i++ ; } sf_close (file) ; unlink (filename) ; } /* multichunk_test_helper */
static void broadcast_coding_history_size (const char *filename) { /* SF_BROADCAST_INFO struct with coding_history field of 1024 bytes. */ static SF_BROADCAST_INFO_VAR (1024) bc_write ; static SF_BROADCAST_INFO_VAR (1024) bc_read ; SNDFILE *file ; SF_INFO sfinfo ; int k ; print_test_name (__func__, filename) ; sfinfo.samplerate = 22050 ; sfinfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16 ; sfinfo.channels = 1 ; memset (&bc_write, 0, sizeof (bc_write)) ; snprintf (bc_write.description, sizeof (bc_write.description), "Test description") ; snprintf (bc_write.originator, sizeof (bc_write.originator), "Test originator") ; snprintf (bc_write.originator_reference, sizeof (bc_write.originator_reference), "%08x-%08x", (unsigned int) time (NULL), (unsigned int) (~ time (NULL))) ; snprintf (bc_write.origination_date, sizeof (bc_write.origination_date), "%d/%02d/%02d", 2006, 3, 30) ; snprintf (bc_write.origination_time, sizeof (bc_write.origination_time), "%02d:%02d:%02d", 20, 27, 0) ; snprintf (bc_write.umid, sizeof (bc_write.umid), "Some umid") ; bc_write.coding_history_size = 0 ; for (k = 0 ; bc_write.coding_history_size < 512 ; k++) { snprintf (bc_write.coding_history + bc_write.coding_history_size, sizeof (bc_write.coding_history) - bc_write.coding_history_size, "line %4d\n", k) ; bc_write.coding_history_size = strlen (bc_write.coding_history) ; } ; exit_if_true (bc_write.coding_history_size < 512, "\n\nLine %d : bc_write.coding_history_size (%d) should be > 512.\n\n", __LINE__, bc_write.coding_history_size) ; file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; if (sf_command (file, SFC_SET_BROADCAST_INFO, &bc_write, sizeof (bc_write)) == SF_FALSE) { printf ("\n\nLine %d : sf_command (SFC_SET_BROADCAST_INFO) failed.\n\n", __LINE__) ; exit (1) ; } ; test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ; sf_close (file) ; memset (&bc_read, 0, sizeof (bc_read)) ; file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; if (sf_command (file, SFC_GET_BROADCAST_INFO, &bc_read, sizeof (bc_read)) == SF_FALSE) { printf ("\n\nLine %d : sf_command (SFC_SET_BROADCAST_INFO) failed.\n\n", __LINE__) ; exit (1) ; } ; check_log_buffer_or_die (file, __LINE__) ; sf_close (file) ; exit_if_true (bc_read.coding_history_size < 512, "\n\nLine %d : unexpected coding history size %d (should be > 512).\n\n", __LINE__, bc_read.coding_history_size) ; exit_if_true (strstr (bc_read.coding_history, "libsndfile") == NULL, "\n\nLine %d : coding history incomplete (should contain 'libsndfile').\n\n", __LINE__) ; unlink (filename) ; puts ("ok") ; } /* broadcast_coding_history_size */
static void raw_needs_endswap_test (const char *filename, int filetype) { static int subtypes [] = { SF_FORMAT_FLOAT, SF_FORMAT_DOUBLE, SF_FORMAT_PCM_16, SF_FORMAT_PCM_24, SF_FORMAT_PCM_32 } ; SNDFILE *file ; SF_INFO sfinfo ; unsigned k ; int needs_endswap ; print_test_name (__func__, filename) ; for (k = 0 ; k < ARRAY_LEN (subtypes) ; k++) { if (filetype == (SF_ENDIAN_LITTLE | SF_FORMAT_AIFF)) switch (subtypes [k]) { /* Little endian AIFF does not AFAIK support fl32 and fl64. */ case SF_FORMAT_FLOAT : case SF_FORMAT_DOUBLE : continue ; default : break ; } ; memset (&sfinfo, 0, sizeof (sfinfo)) ; sfinfo.samplerate = 11025 ; sfinfo.format = filetype | subtypes [k] ; sfinfo.channels = 1 ; file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; test_write_double_or_die (file, 0, double_data, BUFFER_LEN, __LINE__) ; sf_close (file) ; memset (&sfinfo, 0, sizeof (sfinfo)) ; file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; needs_endswap = sf_command (file, SFC_RAW_DATA_NEEDS_ENDSWAP, NULL, 0) ; switch (filetype) { case SF_FORMAT_WAV : case SF_FORMAT_WAVEX : case SF_FORMAT_AIFF | SF_ENDIAN_LITTLE : exit_if_true (needs_endswap != CPU_IS_BIG_ENDIAN, "\n\nLine %d : SFC_RAW_DATA_NEEDS_ENDSWAP failed for (%d | %d).\n\n", __LINE__, filetype, k) ; break ; case SF_FORMAT_AIFF : case SF_FORMAT_WAV | SF_ENDIAN_BIG : exit_if_true (needs_endswap != CPU_IS_LITTLE_ENDIAN, "\n\nLine %d : SFC_RAW_DATA_NEEDS_ENDSWAP failed for (%d | %d).\n\n", __LINE__, filetype, k) ; break ; default : printf ("\n\nLine %d : bad format value %d.\n\n", __LINE__, filetype) ; exit (1) ; break ; } ; sf_close (file) ; } ; unlink (filename) ; puts ("ok") ; } /* raw_needs_endswap_test */
static void useek_pipe_rw_double (const char * ext, SF_INFO * psfinfo_write, SF_INFO * psfinfo_read) { static double buffer [PIPE_TEST_LEN] ; static double data [PIPE_TEST_LEN] ; SNDFILE *outfile ; SNDFILE *infile_piped ; int k, status = 0 ; int pipefd [2] ; pid_t pida ; for (k = 0 ; k < PIPE_TEST_LEN ; k++) data [k] = PIPE_INDEX (k) ; /* ** Create the pipe. */ exit_if_true (pipe (pipefd) != 0, "\n\n%s %d : pipe failed : %s\n", __func__, __LINE__, strerror (errno)) ; /* ** Attach the write end of the pipe to be written to. */ if ((outfile = sf_open_fd (pipefd [1], SFM_WRITE, psfinfo_write, SF_TRUE)) == NULL) { printf ("\n\n%s %d : unable to create unseekable pipe for write type \"%s\".\n", __func__, __LINE__, ext) ; printf ("\t%s\n\n", sf_strerror (outfile)) ; exit (1) ; } ; if (sf_error (outfile) != SF_ERR_NO_ERROR) { printf ("\n\n%s %d : unable to open unseekable pipe for write type \"%s\".\n\n", __func__, __LINE__, ext) ; exit (1) ; } ; /* ** Attach the read end of the pipe to be read from. */ if ((infile_piped = sf_open_fd (pipefd [0], SFM_READ, psfinfo_read, SF_TRUE)) == NULL) { printf ("\n\n%s %d : unable to create unseekable pipe for read type. \"%s\".\n\n", __func__, __LINE__, ext) ; exit (1) ; } ; if (sf_error (infile_piped) != SF_ERR_NO_ERROR) { printf ("\n\n%s %d : unable to open unseekable pipe for read type \"%s\".\n\n", __func__, __LINE__, ext) ; exit (1) ; } ; /* Fork a child process that will write directly into the pipe. */ if ((pida = fork ()) == 0) /* child process */ { test_writef_double_or_die (outfile, 0, data, PIPE_TEST_LEN, __LINE__) ; exit (0) ; } ; /* In the parent process, read from the pipe and compare what is read ** to what is written, if they match everything went as planned. */ test_readf_double_or_die (infile_piped, 0, buffer, PIPE_TEST_LEN, __LINE__) ; if (memcmp (buffer, data, sizeof (buffer)) != 0) { printf ("\n\n%s %d : unseekable pipe test failed for file type \"%s\".\n\n", __func__, __LINE__, ext) ; exit (1) ; } ; /* Wait for the child process to return. */ waitpid (pida, &status, 0) ; status = WEXITSTATUS (status) ; sf_close (outfile) ; sf_close (infile_piped) ; if (status != 0) { printf ("\n\n%s %d : status of child process is %d for file type %s.\n\n", __func__, __LINE__, status, ext) ; exit (1) ; } ; return ; } /* useek_pipe_rw_double */
static void string_multi_set_test (const char *filename, int typemajor) { static const char new_software [] = "new software (libsndfile-X.Y.Z)", new_copyright [] = "Copyright (c) 2001 New Artist", new_artist [] = "The New Artist", new_title [] = "This is the new title" ; static char buffer [2048] ; SNDFILE *file ; SF_INFO sfinfo ; int count ; print_test_name (__func__, filename) ; memset (&sfinfo, 0, sizeof (sfinfo)) ; sfinfo.format = typemajor | SF_FORMAT_PCM_16 ; sfinfo.samplerate = 44100 ; sfinfo.channels = 1 ; sfinfo.frames = 0 ; 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, title) ; sf_set_string (file, SF_STR_SOFTWARE, software) ; sf_set_string (file, SF_STR_ARTIST, artist) ; /* Write data to file. */ test_write_short_or_die (file, 0, data_out, BUFFER_LEN, __LINE__) ; /* Write it all again. */ sf_set_string (file, SF_STR_TITLE, new_title) ; sf_set_string (file, SF_STR_SOFTWARE, new_software) ; sf_set_string (file, SF_STR_ARTIST, new_artist) ; 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_set_string (file, SF_STR_COPYRIGHT, new_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__) ; sf_command (file, SFC_GET_LOG_INFO, buffer, sizeof (buffer)) ; sf_close (file) ; count = str_count (buffer, new_title) ; exit_if_true (count < 1, "\n\nLine %d : Could not find new_title in :\n%s\n", __LINE__, buffer) ; exit_if_true (count > 1, "\n\nLine %d : new_title appears %d times in :\n\n%s\n", __LINE__, count, buffer) ; count = str_count (buffer, software) ; exit_if_true (count < 1, "\n\nLine %d : Could not find new_software in :\n%s\n", __LINE__, buffer) ; exit_if_true (count > 1, "\n\nLine %d : new_software appears %d times in :\n\n%s\n", __LINE__, count, buffer) ; count = str_count (buffer, new_artist) ; exit_if_true (count < 1, "\n\nLine %d : Could not find new_artist in :\n%s\n", __LINE__, buffer) ; exit_if_true (count > 1, "\n\nLine %d : new_artist appears %d times in :\n\n%s\n", __LINE__, count, buffer) ; count = str_count (buffer, new_copyright) ; exit_if_true (count < 1, "\n\nLine %d : Could not find new_copyright in :\n%s\n", __LINE__, buffer) ; exit_if_true (count > 1, "\n\nLine %d : new_copyright appears %d times in :\n\n%s\n", __LINE__, count, buffer) ; unlink (filename) ; puts ("ok") ; } /* string_multi_set_test */
static void string_header_update (const char *filename, int typemajor) { SNDFILE *file , *file1 ; SF_INFO sfinfo , sfinfo1 ; sf_count_t frames ; const char * str ; const int GROW_BUFFER_AMOUNT = 4 ; /* this should be less than half the size of the string header */ print_test_name (__func__, filename) ; /* Create a short file. */ memset (&sfinfo, 0, sizeof (sfinfo)) ; sfinfo.samplerate = 44100 ; sfinfo.channels = 2 ; sfinfo.frames = 0 ; sfinfo.format = typemajor | SF_FORMAT_PCM_16 ; file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; test_write_short_or_die (file, 0, data_out, BUFFER_LEN, __LINE__) ; sf_set_string (file, SF_STR_TITLE, long_title) ; sf_close (file) ; /* Check that SFC_UPDATE_HEADER_NOW correctly calculates datalength. */ file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, SF_TRUE, __LINE__) ; /* Write a very small amount of new audio data that doesn't completely overwrite the existing header. */ test_write_short_or_die (file, 0, data_out, GROW_BUFFER_AMOUNT, __LINE__) ; /* Update the header without closing the file. */ sf_command (file, SFC_UPDATE_HEADER_NOW, NULL, 0) ; /* The file should now contain BUFFER_LEN + GROW_BUFFER_AMOUNT frames. Open a second handle to the file and check the reported length. */ memset (&sfinfo1, 0, sizeof (sfinfo1)) ; file1 = test_open_file_or_die (filename, SFM_READ, &sfinfo1, SF_TRUE, __LINE__) ; frames = (BUFFER_LEN + GROW_BUFFER_AMOUNT) / sfinfo.channels ; exit_if_true (frames != sfinfo1.frames, "\n\nLine %d : Frame count %" PRId64 " should be %" PRId64 ".\n", __LINE__, sfinfo1.frames, frames) ; /* The strings are probably not readable by the second soundfile handle because write_tailer has not yet been called. It's a design decision whether SFC_UPDATE_HEADER_NOW should write the tailer. I think it's fine that it doesn't. */ sf_close (file1) ; sf_close (file) ; /* Check that sf_close correctly calculates datalength. */ file = test_open_file_or_die (filename, SFM_RDWR, &sfinfo, SF_TRUE, __LINE__) ; /* Write a very small amount of new audio data that doesn't completely overwrite the existing header. */ test_write_short_or_die (file, 0, data_out, GROW_BUFFER_AMOUNT, __LINE__) ; sf_close (file) ; /* Open file again and verify data and string. */ file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; frames = (BUFFER_LEN + 2*GROW_BUFFER_AMOUNT) / sfinfo.channels ; exit_if_true (frames != sfinfo.frames, "\n\nLine %d : Frame count %" PRId64 " should be %" PRId64 ".\n", __LINE__, sfinfo.frames, frames) ; str = sf_get_string (file, SF_STR_TITLE) ; exit_if_true (str == NULL, "\n\nLine %d : SF_STR_TITLE string is NULL.\n", __LINE__) ; exit_if_true (strcmp (str, long_title) != 0, "\n\nLine %d : SF_STR_TITLE doesn't match what was written.\n", __LINE__) ; sf_close (file) ; unlink (filename) ; puts ("ok") ; } /* string_header_update */
static void wav_subchunk_test (size_t chunk_size) { SNDFILE * file ; SF_INFO sfinfo ; SF_CHUNK_INFO chunk_info ; char filename [256] ; char chunk_data [10240] ; short audio [16] ; int err, value ; snprintf (filename, sizeof (filename), "subchunk_%04d.wav", (int) chunk_size) ; print_test_name (__func__, filename) ; exit_if_true (sizeof (chunk_data) < chunk_size, "\n\nLine %d : sizeof (data) < chunk_size\n\n", __LINE__) ; memset (chunk_data, 53, sizeof (chunk_data)) ; chunk_data [chunk_size] = 0 ; /* Fill in the chunk data. */ value = MAKE_MARKER ('a', 'd', 't', 'l') ; memcpy (chunk_data, &value, sizeof (value)) ; value = MAKE_MARKER ('n', 'o', 't', 'e') ; memcpy (chunk_data + 4, &value, sizeof (value)) ; value = H2LE_32 (chunk_size - 12) ; memcpy (chunk_data + 8, &value, sizeof (value)) ; sfinfo.samplerate = 44100 ; sfinfo.channels = 1 ; sfinfo.frames = 0 ; sfinfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16 ; file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; /* Set up the chunk to write. */ memset (&chunk_info, 0, sizeof (chunk_info)) ; snprintf (chunk_info.id, sizeof (chunk_info.id), "LIST") ; chunk_info.id_size = 4 ; chunk_info.data = chunk_data ; chunk_info.datalen = chunk_size ; err = sf_set_chunk (file, &chunk_info) ; exit_if_true ( err != SF_ERR_NO_ERROR, "\n\nLine %d : sf_set_chunk returned for testdata : %s\n\n", __LINE__, sf_error_number (err) ) ; memset (chunk_info.data, 0, chunk_info.datalen) ; /* Add some audio data. */ memset (audio, 0, sizeof (audio)) ; sf_write_short (file, audio, ARRAY_LEN (audio)) ; sf_close (file) ; file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; exit_if_true ( sfinfo.frames != ARRAY_LEN (audio), "\n\nLine %d : Incorrect sample count (%d should be %d)\n", __LINE__, (int) sfinfo.frames, (int) ARRAY_LEN (audio) ) ; if (chunk_size < 512) check_log_buffer_or_die (file, __LINE__) ; sf_close (file) ; unlink (filename) ; puts ("ok") ; } /* wav_subchunk_test */
static void chunk_test_helper (const char *filename, int typemajor, const char * testdata) { SNDFILE *file ; SF_INFO sfinfo ; SF_CHUNK_INFO chunk_info ; uint32_t length_before ; int err ; sfinfo.samplerate = 44100 ; sfinfo.channels = 1 ; sfinfo.frames = 0 ; switch (typemajor) { case SF_FORMAT_OGG : sfinfo.format = typemajor | SF_FORMAT_VORBIS ; break ; default : sfinfo.format = typemajor | SF_FORMAT_PCM_16 ; break ; } ; file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; /* Set up the chunk to write. */ memset (&chunk_info, 0, sizeof (chunk_info)) ; snprintf (chunk_info.id, sizeof (chunk_info.id), "Test") ; chunk_info.id_size = 4 ; chunk_info.data = strdup (testdata) ; chunk_info.datalen = strlen (chunk_info.data) ; length_before = chunk_info.datalen ; err = sf_set_chunk (file, &chunk_info) ; exit_if_true ( err != SF_ERR_NO_ERROR, "\n\nLine %d : sf_set_chunk returned for testdata '%s' : %s\n", __LINE__, testdata, sf_error_number (err) ) ; memset (chunk_info.data, 0, chunk_info.datalen) ; free (chunk_info.data) ; sf_close (file) ; file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; memset (&chunk_info, 0, sizeof (chunk_info)) ; snprintf (chunk_info.id, sizeof (chunk_info.id), "Test") ; chunk_info.id_size = 4 ; err = sf_get_chunk_size (file, &chunk_info) ; exit_if_true ( err != SF_ERR_NO_ERROR, "\n\nLine %d : sf_get_chunk_size returned for testdata '%s' : %s", __LINE__, testdata, sf_error_number (err) ) ; exit_if_true ( length_before > chunk_info.datalen || chunk_info.datalen - length_before > 4, "\n\nLine %d : testdata '%s' : Bad chunk length %u (previous length %u)\n", __LINE__, testdata, chunk_info.datalen, length_before ) ; chunk_info.data = malloc (chunk_info.datalen) ; err = sf_get_chunk_data (file, &chunk_info) ; exit_if_true ( err != SF_ERR_NO_ERROR, "\n\nLine %d : sf_get_chunk_size returned for testdata '%s' : %s", __LINE__, testdata, sf_error_number (err) ) ; exit_if_true ( memcmp (testdata, chunk_info.data, length_before), "\n\nLine %d : Data compare failed.\n %s\n %s\n\n", __LINE__, testdata, (char*) chunk_info.data ) ; free (chunk_info.data) ; sf_close (file) ; unlink (filename) ; } /* chunk_test_helper */