static void write_file_at_end (int fd, int filetype, int channels, int file_num) { SNDFILE *sndfile ; SF_INFO sfinfo ; int frames, k ; lseek (fd, 0, SEEK_END) ; for (k = 0 ; k < DATA_LENGTH ; k++) data [k] = k ; frames = DATA_LENGTH / channels ; sfinfo.format = filetype ; sfinfo.channels = channels ; sfinfo.samplerate = 44100 ; if ((sndfile = sf_open_fd (fd, SFM_WRITE, &sfinfo, SF_FALSE)) == NULL) { printf ("\n\nLine %d: sf_open_fd failed\n", __LINE__) ; printf ("Embedded file number : %d\n", file_num) ; puts (sf_strerror (sndfile)) ; dump_log_buffer (sndfile) ; exit (1) ; } ; if (sf_writef_short (sndfile, data, frames) != frames) { printf ("\n\nLine %d: short write\n", __LINE__) ; printf ("Embedded file number : %d\n", file_num) ; exit (1) ; } ; sf_close (sndfile) ; } /* write_file_at_end */
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 update_header_sub (const char *filename, int typemajor, int write_mode) { SNDFILE *outfile, *infile ; SF_INFO sfinfo ; int k, frames ; sfinfo.samplerate = 44100 ; sfinfo.format = (typemajor | SF_FORMAT_PCM_16) ; sfinfo.channels = 1 ; sfinfo.frames = 0 ; frames = BUFFER_LEN / sfinfo.channels ; outfile = test_open_file_or_die (filename, write_mode, &sfinfo, SF_TRUE, __LINE__) ; for (k = 0 ; k < BUFFER_LEN ; k++) data_out [k] = k + 1 ; test_write_int_or_die (outfile, 0, data_out, BUFFER_LEN, __LINE__) ; if (typemajor != SF_FORMAT_HTK) { /* The HTK header is not correct when the file is first written. */ infile = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; sf_close (infile) ; } ; sf_command (outfile, SFC_UPDATE_HEADER_NOW, NULL, 0) ; /* ** Open file and check log buffer for an error. If header update failed ** the the log buffer will contain errors. */ infile = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; check_log_buffer_or_die (infile, __LINE__) ; if (sfinfo.frames < BUFFER_LEN || sfinfo.frames > BUFFER_LEN + 50) { printf ("\n\nLine %d : Incorrect sample count (%ld should be %d)\n", __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), BUFFER_LEN) ; dump_log_buffer (infile) ; exit (1) ; } ; test_read_int_or_die (infile, 0, data_in, BUFFER_LEN, __LINE__) ; for (k = 0 ; k < BUFFER_LEN ; k++) if (data_out [k] != k + 1) printf ("Error : line %d\n", __LINE__) ; sf_close (infile) ; /* Set auto update on. */ sf_command (outfile, SFC_SET_UPDATE_HEADER_AUTO, NULL, SF_TRUE) ; /* Write more data_out. */ for (k = 0 ; k < BUFFER_LEN ; k++) data_out [k] = k + 2 ; test_write_int_or_die (outfile, 0, data_out, BUFFER_LEN, __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__) ; if (sfinfo.frames < 2 * BUFFER_LEN || sfinfo.frames > 2 * BUFFER_LEN + 50) { printf ("\n\nLine %d : Incorrect sample count (%ld should be %d)\n", __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), 2 * BUFFER_LEN) ; dump_log_buffer (infile) ; exit (1) ; } ; sf_close (infile) ; sf_close (outfile) ; unlink (filename) ; } /* update_header_sub */
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 multi_file_test (const char *filename, int *formats, int format_count) { SNDFILE *sndfile ; SF_INFO sfinfo ; SF_EMBED_FILE_INFO embed_info ; sf_count_t filelen ; int fd, k, file_count = 0 ; print_test_name ("multi_file_test", filename) ; unlink (filename) ; if ((fd = open (filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR)) < 0) { printf ("\n\nLine %d: open failed : %s\n", __LINE__, strerror (errno)) ; exit (1) ; } ; k = write (fd, "1234", 4) ; for (k = 0 ; k < format_count ; k++) write_file_at_end (fd, formats [k], 2, k) ; filelen = file_length_fd (fd) ; embed_info.offset = 4 ; embed_info.length = 0 ; for (file_count = 1 ; embed_info.offset + embed_info.length < filelen ; file_count ++) { if (verbose) { puts ("\n------------------------------------") ; printf ("This offset : %ld\n", SF_COUNT_TO_LONG (embed_info.offset + embed_info.length)) ; } ; if (lseek (fd, embed_info.offset + embed_info.length, SEEK_SET) < 0) { printf ("\n\nLine %d: lseek failed : %s\n", __LINE__, strerror (errno)) ; exit (1) ; } ; memset (&sfinfo, 0, sizeof (sfinfo)) ; if ((sndfile = sf_open_fd (fd, SFM_READ, &sfinfo, SF_FALSE)) == NULL) { printf ("\n\nLine %d: sf_open_fd failed\n", __LINE__) ; printf ("Embedded file number : %d offset : %ld\n", file_count, SF_COUNT_TO_LONG (embed_info.offset)) ; puts (sf_strerror (sndfile)) ; dump_log_buffer (sndfile) ; exit (1) ; } ; sf_command (sndfile, SFC_GET_EMBED_FILE_INFO, &embed_info, sizeof (embed_info)) ; sf_close (sndfile) ; if (verbose) printf ("\nNext offset : %ld\nNext length : %ld\n", SF_COUNT_TO_LONG (embed_info.offset), SF_COUNT_TO_LONG (embed_info.length)) ; } ; file_count -- ; if (file_count != format_count) { printf ("\n\nLine %d: file count (%d) not equal to %d.\n\n", __LINE__, file_count, format_count) ; printf ("Embedded file number : %d\n", file_count) ; exit (1) ; } ; close (fd) ; unlink (filename) ; printf ("ok\n") ; return ; } /* multi_file_test */
static void update_header_test (char *filename, int typemajor) { SNDFILE *outfile, *infile ; SF_INFO sfinfo ; int k, frames ; printf (" update_header_test : %s ", filename) ; fflush (stdout) ; k = abs (18 - strlen (filename)) ; PUT_DOTS (k) ; sfinfo.samplerate = 44100 ; sfinfo.format = (typemajor | SF_FORMAT_PCM_16) ; sfinfo.channels = 1 ; sfinfo.frames = 0 ; frames = BUFFER_LEN / sfinfo.channels ; outfile = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, __LINE__) ; for (k = 0 ; k < BUFFER_LEN ; k++) data_out [k] = k + 1 ; test_write_short_or_die (outfile, 0, data_out, BUFFER_LEN, __LINE__) ; infile = test_open_file_or_die (filename, SFM_READ, &sfinfo, __LINE__) ; sf_close (infile) ; sf_command (outfile, SFC_UPDATE_HEADER_NOW, NULL, 0) ; /* Open file and check log buffer for an error. If header update failed ** the the log buffer will contain errors. */ infile = test_open_file_or_die (filename, SFM_READ, &sfinfo, __LINE__) ; check_log_buffer_or_die (infile) ; if (abs (BUFFER_LEN - sfinfo.frames) > 1) { printf ("\n\nLine %d : Incorrect sample count (%ld should be %d)\n", __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), BUFFER_LEN) ; dump_log_buffer (infile) ; exit (1) ; } ; test_read_short_or_die (infile, 0, data_in, BUFFER_LEN, __LINE__) ; for (k = 0 ; k < BUFFER_LEN ; k++) if (data_out [k] != k + 1) printf ("Error : line %d\n", __LINE__) ; sf_close (infile) ; /* Set auto update on. */ sf_command (outfile, SFC_SET_UPDATE_HEADER_AUTO, NULL, SF_TRUE) ; /* Write more data_out. */ for (k = 0 ; k < BUFFER_LEN ; k++) data_out [k] = k + 2 ; test_write_short_or_die (outfile, 0, data_out, BUFFER_LEN, __LINE__) ; /* Open file again and make sure no errors in log buffer. */ infile = test_open_file_or_die (filename, SFM_READ, &sfinfo, __LINE__) ; check_log_buffer_or_die (infile) ; if (abs (2 * BUFFER_LEN - sfinfo.frames) > 1) { printf ("\n\nLine %d : Incorrect sample count (%ld should be %d)\n", __LINE__, SF_COUNT_TO_LONG (sfinfo.frames), 2 * BUFFER_LEN) ; dump_log_buffer (infile) ; exit (1) ; } ; sf_close (infile) ; sf_close (outfile) ; unlink (filename) ; puts ("ok") ; } /* update_header_test */
SNDFILE * test_open_file_or_die (const char *filename, int mode, SF_INFO *sfinfo, int line_num) { static int count = 0 ; SNDFILE *file ; const char *modestr, *func_name ; int oflags = 0, omode = 0 ; /* ** Need to test both sf_open() and sf_open_fd(). ** Do so alternately. */ switch (mode) { case SFM_READ : modestr = "SFM_READ" ; oflags = O_RDONLY ; omode = 0 ; break ; case SFM_WRITE : modestr = "SFM_WRITE" ; oflags = O_WRONLY | O_CREAT | O_TRUNC ; omode = S_IRUSR | S_IWUSR | S_IRGRP ; break ; case SFM_RDWR : modestr = "SFM_RDWR" ; oflags = O_RDWR | O_CREAT ; omode = S_IRUSR | S_IWUSR | S_IRGRP ; break ; default : printf ("\n\nLine %d: Bad mode.\n", line_num) ; fflush (stdout) ; exit (1) ; } ; #if (defined (__CYGWIN__) || defined (WIN32) || defined (_WIN32)) /* Stupid fscking windows. */ oflags |= O_BINARY ; #endif if (((++count) & 1) == 1) { int fd ; if (omode == 0) fd = open (filename, oflags) ; else fd = open (filename, oflags, omode) ; if (fd < 0) { perror ("open") ; exit (1) ; } ; func_name = "sf_open_fd" ; file = sf_open_fd (fd, mode, sfinfo, SF_TRUE) ; } else { func_name = "sf_open" ; file = sf_open (filename, mode, sfinfo) ; } ; if (file == NULL) { printf ("\n\nLine %d: %s (%s) failed : %s\n\n", line_num, func_name, modestr, sf_strerror (NULL)) ; dump_log_buffer (file) ; exit (1) ; } ; return file ; } /* test_open_file_or_die */
static void stdin_test (char *str, int typemajor, int count) { static short data [BUFFER_LEN] ; SNDFILE *file ; SF_INFO sfinfo ; int k, total ; fprintf (stderr, " %-5s : reading %d frames from stdin .... ", str, count) ; if (typemajor == SF_FORMAT_RAW) { sfinfo.samplerate = 44100 ; sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_PCM_16 ; sfinfo.channels = 1 ; sfinfo.frames = 0 ; } else sfinfo.format = 0 ; if (! (file = sf_open ("-", SFM_READ, &sfinfo))) { fprintf (stderr, "sf_open_read failed with error : ") ; puts (sf_strerror (NULL)) ; dump_log_buffer (NULL) ; exit (1) ; } ; if ((sfinfo.format & SF_FORMAT_TYPEMASK) != typemajor) { fprintf (stderr, "\n\nError : File type doesn't match\n") ; exit (1) ; } ; if (sfinfo.samplerate != 44100) { fprintf (stderr, "\n\nError : sample rate (%d) should be 44100\n", sfinfo.samplerate) ; exit (1) ; } ; if (sfinfo.channels != 1) { fprintf (stderr, "\n\nError : channels (%d) should be 1\n", sfinfo.channels) ; exit (1) ; } ; if (sfinfo.frames < count) { fprintf (stderr, "\n\nError : sample count (%ld) should be %d\n", (long) sfinfo.frames, count) ; exit (1) ; } ; total = 0 ; while ((k = sf_read_short (file, data, BUFFER_LEN))) total += k ; if (total != count) { fprintf (stderr, "\n\nError : expected (%d).frames, read %d\n", count, total) ; exit (1) ; } ; sf_close (file) ; fprintf (stderr, "ok\n") ; return ; } /* stdin_test */
static void stdin_test (int typemajor, int count) { static short data [BUFFER_LEN] ; SNDFILE *file ; SF_INFO sfinfo ; int k, total, err ; if (typemajor == SF_FORMAT_RAW) { sfinfo.samplerate = 44100 ; sfinfo.format = SF_FORMAT_RAW | SF_FORMAT_PCM_16 ; sfinfo.channels = 1 ; sfinfo.frames = 0 ; } else memset (&sfinfo, 0, sizeof (sfinfo)) ; #if USE_WINDOWS_API if ((file = sf_open_fd (fileno (stdin), SFM_READ, &sfinfo, SF_TRUE)) == NULL) #else if ((file = sf_open_fd (STDIN_FILENO, SFM_READ, &sfinfo, SF_TRUE)) == NULL) #endif { fprintf (stderr, "sf_open_fd failed with error : ") ; puts (sf_strerror (NULL)) ; dump_log_buffer (NULL) ; exit (1) ; } ; err = sf_error (file) ; if (err != SF_ERR_NO_ERROR) { printf ("Line %d : unexpected error : %s\n", __LINE__, sf_error_number (err)) ; exit (1) ; } ; if ((sfinfo.format & SF_FORMAT_TYPEMASK) != typemajor) { fprintf (stderr, "\n\nError : File type doesn't match.\n") ; exit (1) ; } ; if (sfinfo.samplerate != 44100) { fprintf (stderr, "\n\nError : Sample rate (%d) should be 44100\n", sfinfo.samplerate) ; exit (1) ; } ; if (sfinfo.channels != 1) { fprintf (stderr, "\n\nError : Channels (%d) should be 1\n", sfinfo.channels) ; exit (1) ; } ; if (sfinfo.frames < count) { fprintf (stderr, "\n\nError : Sample count (%ld) should be %d\n", (long) sfinfo.frames, count) ; exit (1) ; } ; total = 0 ; while ((k = sf_read_short (file, data + total, BUFFER_LEN - total)) > 0) total += k ; if (total != count) { fprintf (stderr, "\n\nError : Expected %d frames, read %d.\n", count, total) ; exit (1) ; } ; for (k = 0 ; k < total ; k++) if (data [k] != PIPE_INDEX (k)) { printf ("\n\nError : data [%d] == %d, should have been %d.\n\n", k, data [k], k) ; exit (1) ; } ; sf_close (file) ; return ; } /* stdin_test */
static void vorbis_test (void) { static float float_data [DFT_DATA_LENGTH] ; const char * filename = "vorbis_test.oga" ; SNDFILE * file ; SF_INFO sfinfo ; float max_abs = 0.0 ; unsigned k ; print_test_name ("vorbis_test", filename) ; /* Generate float data. */ gen_windowed_sine_float (float_data, ARRAY_LEN (float_data), 1.0) ; /* Set up output file type. */ memset (&sfinfo, 0, sizeof (sfinfo)) ; sfinfo.format = SF_FORMAT_OGG | SF_FORMAT_VORBIS ; sfinfo.channels = 1 ; sfinfo.samplerate = SAMPLE_RATE ; /* Write the output file. */ /* The Vorbis encoder has a bug on PowerPC and X86-64 with sample rates ** <= 22050. Increasing the sample rate to 32000 avoids triggering it. ** See https://trac.xiph.org/ticket/1229 */ if ((file = sf_open (filename, SFM_WRITE, &sfinfo)) == NULL) { const char * errstr ; errstr = sf_strerror (NULL) ; if (strstr (errstr, "Sample rate chosen is known to trigger a Vorbis") == NULL) { printf ("Line %d: sf_open (SFM_WRITE) failed : %s\n", __LINE__, errstr) ; dump_log_buffer (NULL) ; exit (1) ; } ; printf ("\n Sample rate -> 32kHz ") ; sfinfo.samplerate = 32000 ; file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; } ; test_write_float_or_die (file, 0, float_data, ARRAY_LEN (float_data), __LINE__) ; sf_close (file) ; memset (float_data, 0, sizeof (float_data)) ; /* Read the file back in again. */ memset (&sfinfo, 0, sizeof (sfinfo)) ; file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ; test_read_float_or_die (file, 0, float_data, ARRAY_LEN (float_data), __LINE__) ; sf_close (file) ; for (k = 0 ; k < ARRAY_LEN (float_data) ; k ++) max_abs = max_float (max_abs, fabs (float_data [k])) ; if (max_abs > 1.02) { printf ("\n\n Error : max_abs %f should be < 1.02.\n\n", max_abs) ; exit (1) ; } ; puts ("ok") ; unlink (filename) ; } /* vorbis_test */
SNDFILE * test_open_file_or_die (const char *filename, int mode, SF_INFO *sfinfo, int allow_fd, int line_num) { static int count = 0 ; SNDFILE *file ; const char *modestr, *func_name ; int oflags = 0, omode = 0 ; /* ** Need to test both sf_open() and sf_open_fd(). ** Do so alternately. */ switch (mode) { case SFM_READ : modestr = "SFM_READ" ; oflags = O_RDONLY | O_BINARY ; omode = 0 ; break ; case SFM_WRITE : modestr = "SFM_WRITE" ; oflags = O_WRONLY | O_CREAT | O_TRUNC | O_BINARY ; omode = S_IRUSR | S_IWUSR | S_IRGRP ; break ; case SFM_RDWR : modestr = "SFM_RDWR" ; oflags = O_RDWR | O_CREAT | O_BINARY ; omode = S_IRUSR | S_IWUSR | S_IRGRP ; break ; default : printf ("\n\nLine %d: Bad mode.\n", line_num) ; fflush (stdout) ; exit (1) ; } ; if (OS_IS_WIN32) { /* Windows doesn't support Unix file permissions so set it to zero. */ omode = 0 ; } ; if (allow_fd && ((++count) & 1) == 1) { int fd ; fd = open (filename, oflags, omode) ; if (fd < 0) { perror ("open") ; exit (1) ; } ; func_name = "sf_open_fd" ; file = sf_open_fd (fd, mode, sfinfo, SF_TRUE) ; } else { func_name = "sf_open" ; file = sf_open (filename, mode, sfinfo) ; } ; if (file == NULL) { printf ("\n\nLine %d: %s (%s) failed : %s\n\n", line_num, func_name, modestr, sf_strerror (NULL)) ; dump_log_buffer (file) ; exit (1) ; } ; return file ; } /* test_open_file_or_die */
static void string_start_test (const char *filename, int formattype) { const char *cptr ; SNDFILE *file ; SF_INFO sfinfo ; int errors = 0 ; int typemajor = SF_FORMAT_TYPEMASK & formattype ; print_test_name ("string_start_test", filename) ; memset (&sfinfo, 0, sizeof (sfinfo)) ; sfinfo.samplerate = 44100 ; sfinfo.channels = 1 ; sfinfo.frames = 0 ; switch (formattype) { case SF_FORMAT_OGG | SF_FORMAT_OPUS : /* Opus only supports some discrete sample rates. */ sfinfo.samplerate = 48000 ; break ; case SF_FORMAT_OGG | SF_FORMAT_VORBIS : break ; default : formattype |= SF_FORMAT_PCM_16 ; break ; } ; sfinfo.format = formattype ; 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_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) ; /* Write data to file. */ test_write_short_or_die (file, 0, data_out, BUFFER_LEN, __LINE__) ; 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 (cptr && 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) ; } ; } ; if (typemajor != SF_FORMAT_WAV && typemajor != SF_FORMAT_AIFF) { 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) ; } ; } ; if (typemajor != SF_FORMAT_WAV && typemajor != SF_FORMAT_AIFF && typemajor != SF_FORMAT_RF64) { 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) ; } ; } ; 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_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 */
SNDFILE * test_open_file_or_die (const char *filename, int mode, SF_INFO *sfinfo, int allow_fd, int line_num) { static int count = 0 ; SNDFILE *file ; const char *modestr, *func_name ; int oflags = 0, omode = 0, err ; /* ** Need to test both sf_open() and sf_open_fd(). ** Do so alternately. */ switch (mode) { case SFM_READ : modestr = "SFM_READ" ; oflags = O_RDONLY | O_BINARY ; omode = 0 ; break ; case SFM_WRITE : modestr = "SFM_WRITE" ; oflags = O_WRONLY | O_CREAT | O_TRUNC | O_BINARY ; omode = S_IRUSR | S_IWUSR | S_IRGRP ; break ; case SFM_RDWR : modestr = "SFM_RDWR" ; oflags = O_RDWR | O_CREAT | O_BINARY ; omode = S_IRUSR | S_IWUSR | S_IRGRP ; break ; default : printf ("\n\nLine %d: Bad mode.\n", line_num) ; fflush (stdout) ; exit (1) ; } ; if (OS_IS_WIN32) { /* Windows does not understand and ignores the S_IRGRP flag, but Wine ** gives a run time warning message, so just clear it. */ omode &= ~S_IRGRP ; } ; if (allow_fd && ((++count) & 1) == 1) { int fd ; /* Only use the three argument open() function if omode != 0. */ fd = (omode == 0) ? open (filename, oflags) : open (filename, oflags, omode) ; if (fd < 0) { printf ("\n\n%s : open failed : %s\n", __func__, strerror (errno)) ; exit (1) ; } ; func_name = "sf_open_fd" ; file = sf_open_fd (fd, mode, sfinfo, SF_TRUE) ; } else { func_name = "sf_open" ; file = sf_open (filename, mode, sfinfo) ; } ; if (file == NULL) { printf ("\n\nLine %d: %s (%s) failed : %s\n\n", line_num, func_name, modestr, sf_strerror (NULL)) ; dump_log_buffer (file) ; exit (1) ; } ; err = sf_error (file) ; if (err != SF_ERR_NO_ERROR) { printf ("\n\nLine %d : sf_error : %s\n\n", line_num, sf_error_number (err)) ; dump_log_buffer (file) ; exit (1) ; } ; return file ; } /* test_open_file_or_die */