1b815c7f3Sopenharmony_ci/* 2b815c7f3Sopenharmony_ci** Copyright (C) 1999-2012 Erik de Castro Lopo <erikd@mega-nerd.com> 3b815c7f3Sopenharmony_ci** 4b815c7f3Sopenharmony_ci** This program is free software; you can redistribute it and/or modify 5b815c7f3Sopenharmony_ci** it under the terms of the GNU General Public License as published by 6b815c7f3Sopenharmony_ci** the Free Software Foundation; either version 2 of the License, or 7b815c7f3Sopenharmony_ci** (at your option) any later version. 8b815c7f3Sopenharmony_ci** 9b815c7f3Sopenharmony_ci** This program is distributed in the hope that it will be useful, 10b815c7f3Sopenharmony_ci** but WITHOUT ANY WARRANTY; without even the implied warranty of 11b815c7f3Sopenharmony_ci** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12b815c7f3Sopenharmony_ci** GNU General Public License for more details. 13b815c7f3Sopenharmony_ci** 14b815c7f3Sopenharmony_ci** You should have received a copy of the GNU General Public License 15b815c7f3Sopenharmony_ci** along with this program; if not, write to the Free Software 16b815c7f3Sopenharmony_ci** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17b815c7f3Sopenharmony_ci*/ 18b815c7f3Sopenharmony_ci 19b815c7f3Sopenharmony_ci#include "sfconfig.h" 20b815c7f3Sopenharmony_ci 21b815c7f3Sopenharmony_ci#include <stdio.h> 22b815c7f3Sopenharmony_ci#include <stdlib.h> 23b815c7f3Sopenharmony_ci#include <string.h> 24b815c7f3Sopenharmony_ci#include <math.h> 25b815c7f3Sopenharmony_ci#include <inttypes.h> 26b815c7f3Sopenharmony_ci 27b815c7f3Sopenharmony_ci#if HAVE_UNISTD_H 28b815c7f3Sopenharmony_ci#include <unistd.h> 29b815c7f3Sopenharmony_ci#endif 30b815c7f3Sopenharmony_ci 31b815c7f3Sopenharmony_ci#if (HAVE_DECL_S_IRGRP == 0) 32b815c7f3Sopenharmony_ci#include <sf_unistd.h> 33b815c7f3Sopenharmony_ci#endif 34b815c7f3Sopenharmony_ci 35b815c7f3Sopenharmony_ci#include <fcntl.h> 36b815c7f3Sopenharmony_ci#include <errno.h> 37b815c7f3Sopenharmony_ci#include <sys/stat.h> 38b815c7f3Sopenharmony_ci 39b815c7f3Sopenharmony_ci#include <sndfile.h> 40b815c7f3Sopenharmony_ci 41b815c7f3Sopenharmony_ci#include "utils.h" 42b815c7f3Sopenharmony_ci 43b815c7f3Sopenharmony_ci#define DATA_LENGTH (512) 44b815c7f3Sopenharmony_ci 45b815c7f3Sopenharmony_cistatic void write_file_at_end (int fd, int filetype, int channels, int file_num) ; 46b815c7f3Sopenharmony_ci 47b815c7f3Sopenharmony_cistatic void multi_file_test (const char *filename, int *formats, int format_count) ; 48b815c7f3Sopenharmony_ci 49b815c7f3Sopenharmony_cistatic short data [DATA_LENGTH] ; 50b815c7f3Sopenharmony_ci 51b815c7f3Sopenharmony_cistatic int wav_formats [] = 52b815c7f3Sopenharmony_ci{ SF_FORMAT_WAV | SF_FORMAT_PCM_16, 53b815c7f3Sopenharmony_ci SF_FORMAT_WAV | SF_FORMAT_PCM_24, 54b815c7f3Sopenharmony_ci SF_FORMAT_WAV | SF_FORMAT_ULAW, 55b815c7f3Sopenharmony_ci SF_FORMAT_WAV | SF_FORMAT_ALAW, 56b815c7f3Sopenharmony_ci /* Lite remove start */ 57b815c7f3Sopenharmony_ci SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM, 58b815c7f3Sopenharmony_ci SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM, 59b815c7f3Sopenharmony_ci /* Lite remove end */ 60b815c7f3Sopenharmony_ci /*-SF_FORMAT_WAV | SF_FORMAT_GSM610 Doesn't work yet. -*/ 61b815c7f3Sopenharmony_ci} ; 62b815c7f3Sopenharmony_ci 63b815c7f3Sopenharmony_cistatic int aiff_formats [] = 64b815c7f3Sopenharmony_ci{ SF_FORMAT_AIFF | SF_FORMAT_PCM_16, 65b815c7f3Sopenharmony_ci SF_FORMAT_AIFF | SF_FORMAT_PCM_24, 66b815c7f3Sopenharmony_ci SF_FORMAT_AIFF | SF_FORMAT_ULAW, 67b815c7f3Sopenharmony_ci SF_FORMAT_AIFF | SF_FORMAT_ALAW 68b815c7f3Sopenharmony_ci} ; 69b815c7f3Sopenharmony_ci 70b815c7f3Sopenharmony_cistatic int au_formats [] = 71b815c7f3Sopenharmony_ci{ SF_FORMAT_AU | SF_FORMAT_PCM_16, 72b815c7f3Sopenharmony_ci SF_FORMAT_AU | SF_FORMAT_PCM_24, 73b815c7f3Sopenharmony_ci SF_FORMAT_AU | SF_FORMAT_ULAW, 74b815c7f3Sopenharmony_ci SF_FORMAT_AU | SF_FORMAT_ALAW 75b815c7f3Sopenharmony_ci} ; 76b815c7f3Sopenharmony_ci 77b815c7f3Sopenharmony_cistatic int verbose = SF_FALSE ; 78b815c7f3Sopenharmony_ci 79b815c7f3Sopenharmony_ciint 80b815c7f3Sopenharmony_cimain (int argc, char **argv) 81b815c7f3Sopenharmony_ci{ int do_all = 0 ; 82b815c7f3Sopenharmony_ci int test_count = 0 ; 83b815c7f3Sopenharmony_ci 84b815c7f3Sopenharmony_ci if (argc == 3 && strcmp (argv [2], "-v") == 0) 85b815c7f3Sopenharmony_ci { verbose = SF_TRUE ; 86b815c7f3Sopenharmony_ci argc -- ; 87b815c7f3Sopenharmony_ci } ; 88b815c7f3Sopenharmony_ci 89b815c7f3Sopenharmony_ci if (argc != 2) 90b815c7f3Sopenharmony_ci { printf ("Usage : %s <test>\n", argv [0]) ; 91b815c7f3Sopenharmony_ci printf (" Where <test> is one of the following:\n") ; 92b815c7f3Sopenharmony_ci printf (" wav - test WAV file functions (little endian)\n") ; 93b815c7f3Sopenharmony_ci printf (" aiff - test AIFF file functions (big endian)\n") ; 94b815c7f3Sopenharmony_ci printf (" au - test AU file functions\n") ; 95b815c7f3Sopenharmony_ci#if 0 96b815c7f3Sopenharmony_ci printf (" svx - test 8SVX/16SV file functions\n") ; 97b815c7f3Sopenharmony_ci printf (" nist - test NIST Sphere file functions\n") ; 98b815c7f3Sopenharmony_ci printf (" ircam - test IRCAM file functions\n") ; 99b815c7f3Sopenharmony_ci printf (" voc - Create Voice file functions\n") ; 100b815c7f3Sopenharmony_ci printf (" w64 - Sonic Foundry's W64 file functions\n") ; 101b815c7f3Sopenharmony_ci#endif 102b815c7f3Sopenharmony_ci printf (" all - perform all tests\n") ; 103b815c7f3Sopenharmony_ci exit (1) ; 104b815c7f3Sopenharmony_ci } ; 105b815c7f3Sopenharmony_ci 106b815c7f3Sopenharmony_ci do_all = !strcmp (argv [1], "all") ; 107b815c7f3Sopenharmony_ci 108b815c7f3Sopenharmony_ci if (do_all || ! strcmp (argv [1], "wav")) 109b815c7f3Sopenharmony_ci { multi_file_test ("multi_wav.dat", wav_formats, ARRAY_LEN (wav_formats)) ; 110b815c7f3Sopenharmony_ci test_count++ ; 111b815c7f3Sopenharmony_ci } ; 112b815c7f3Sopenharmony_ci 113b815c7f3Sopenharmony_ci if (do_all || ! strcmp (argv [1], "aiff")) 114b815c7f3Sopenharmony_ci { multi_file_test ("multi_aiff.dat", aiff_formats, ARRAY_LEN (aiff_formats)) ; 115b815c7f3Sopenharmony_ci test_count++ ; 116b815c7f3Sopenharmony_ci } ; 117b815c7f3Sopenharmony_ci 118b815c7f3Sopenharmony_ci if (do_all || ! strcmp (argv [1], "au")) 119b815c7f3Sopenharmony_ci { multi_file_test ("multi_au.dat", au_formats, ARRAY_LEN (au_formats)) ; 120b815c7f3Sopenharmony_ci test_count++ ; 121b815c7f3Sopenharmony_ci } ; 122b815c7f3Sopenharmony_ci 123b815c7f3Sopenharmony_ci return 0 ; 124b815c7f3Sopenharmony_ci} /* main */ 125b815c7f3Sopenharmony_ci 126b815c7f3Sopenharmony_ci/*====================================================================================== 127b815c7f3Sopenharmony_ci*/ 128b815c7f3Sopenharmony_ci 129b815c7f3Sopenharmony_cistatic void 130b815c7f3Sopenharmony_cimulti_file_test (const char *filename, int *formats, int format_count) 131b815c7f3Sopenharmony_ci{ SNDFILE *sndfile ; 132b815c7f3Sopenharmony_ci SF_INFO sfinfo ; 133b815c7f3Sopenharmony_ci SF_EMBED_FILE_INFO embed_info ; 134b815c7f3Sopenharmony_ci sf_count_t filelen ; 135b815c7f3Sopenharmony_ci int fd, k, file_count = 0 ; 136b815c7f3Sopenharmony_ci 137b815c7f3Sopenharmony_ci print_test_name ("multi_file_test", filename) ; 138b815c7f3Sopenharmony_ci 139b815c7f3Sopenharmony_ci unlink (filename) ; 140b815c7f3Sopenharmony_ci 141b815c7f3Sopenharmony_ci if ((fd = open (filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR)) < 0) 142b815c7f3Sopenharmony_ci { printf ("\n\nLine %d: open failed : %s\n", __LINE__, strerror (errno)) ; 143b815c7f3Sopenharmony_ci exit (1) ; 144b815c7f3Sopenharmony_ci } ; 145b815c7f3Sopenharmony_ci 146b815c7f3Sopenharmony_ci k = write (fd, "1234", 4) ; 147b815c7f3Sopenharmony_ci 148b815c7f3Sopenharmony_ci for (k = 0 ; k < format_count ; k++) 149b815c7f3Sopenharmony_ci write_file_at_end (fd, formats [k], 2, k) ; 150b815c7f3Sopenharmony_ci 151b815c7f3Sopenharmony_ci filelen = file_length_fd (fd) ; 152b815c7f3Sopenharmony_ci 153b815c7f3Sopenharmony_ci embed_info.offset = 4 ; 154b815c7f3Sopenharmony_ci embed_info.length = 0 ; 155b815c7f3Sopenharmony_ci 156b815c7f3Sopenharmony_ci 157b815c7f3Sopenharmony_ci for (file_count = 1 ; embed_info.offset + embed_info.length < filelen ; file_count ++) 158b815c7f3Sopenharmony_ci { 159b815c7f3Sopenharmony_ci if (verbose) 160b815c7f3Sopenharmony_ci { puts ("\n------------------------------------") ; 161b815c7f3Sopenharmony_ci printf ("This offset : %" PRId64 "\n", embed_info.offset + embed_info.length) ; 162b815c7f3Sopenharmony_ci } ; 163b815c7f3Sopenharmony_ci 164b815c7f3Sopenharmony_ci if (lseek (fd, (long) (embed_info.offset + embed_info.length), SEEK_SET) < 0) 165b815c7f3Sopenharmony_ci { printf ("\n\nLine %d: lseek failed : %s\n", __LINE__, strerror (errno)) ; 166b815c7f3Sopenharmony_ci exit (1) ; 167b815c7f3Sopenharmony_ci } ; 168b815c7f3Sopenharmony_ci 169b815c7f3Sopenharmony_ci memset (&sfinfo, 0, sizeof (sfinfo)) ; 170b815c7f3Sopenharmony_ci if ((sndfile = sf_open_fd (fd, SFM_READ, &sfinfo, SF_FALSE)) == NULL) 171b815c7f3Sopenharmony_ci { printf ("\n\nLine %d: sf_open_fd failed\n", __LINE__) ; 172b815c7f3Sopenharmony_ci printf ("Embedded file number : %d offset : %" PRId64 "\n", file_count, embed_info.offset) ; 173b815c7f3Sopenharmony_ci puts (sf_strerror (sndfile)) ; 174b815c7f3Sopenharmony_ci dump_log_buffer (sndfile) ; 175b815c7f3Sopenharmony_ci exit (1) ; 176b815c7f3Sopenharmony_ci } ; 177b815c7f3Sopenharmony_ci 178b815c7f3Sopenharmony_ci sf_command (sndfile, SFC_GET_EMBED_FILE_INFO, &embed_info, sizeof (embed_info)) ; 179b815c7f3Sopenharmony_ci 180b815c7f3Sopenharmony_ci sf_close (sndfile) ; 181b815c7f3Sopenharmony_ci 182b815c7f3Sopenharmony_ci if (verbose) 183b815c7f3Sopenharmony_ci printf ("\nNext offset : %" PRId64 "\nNext length : %" PRId64 "\n", embed_info.offset, embed_info.length) ; 184b815c7f3Sopenharmony_ci } ; 185b815c7f3Sopenharmony_ci 186b815c7f3Sopenharmony_ci file_count -- ; 187b815c7f3Sopenharmony_ci 188b815c7f3Sopenharmony_ci if (file_count != format_count) 189b815c7f3Sopenharmony_ci { printf ("\n\nLine %d: file count (%d) not equal to %d.\n\n", __LINE__, file_count, format_count) ; 190b815c7f3Sopenharmony_ci printf ("Embedded file number : %d\n", file_count) ; 191b815c7f3Sopenharmony_ci exit (1) ; 192b815c7f3Sopenharmony_ci } ; 193b815c7f3Sopenharmony_ci 194b815c7f3Sopenharmony_ci close (fd) ; 195b815c7f3Sopenharmony_ci unlink (filename) ; 196b815c7f3Sopenharmony_ci printf ("ok\n") ; 197b815c7f3Sopenharmony_ci 198b815c7f3Sopenharmony_ci return ; 199b815c7f3Sopenharmony_ci} /* multi_file_test */ 200b815c7f3Sopenharmony_ci 201b815c7f3Sopenharmony_ci/*====================================================================================== 202b815c7f3Sopenharmony_ci*/ 203b815c7f3Sopenharmony_ci 204b815c7f3Sopenharmony_cistatic void 205b815c7f3Sopenharmony_ciwrite_file_at_end (int fd, int filetype, int channels, int file_num) 206b815c7f3Sopenharmony_ci{ SNDFILE *sndfile ; 207b815c7f3Sopenharmony_ci SF_INFO sfinfo ; 208b815c7f3Sopenharmony_ci 209b815c7f3Sopenharmony_ci int frames, k ; 210b815c7f3Sopenharmony_ci 211b815c7f3Sopenharmony_ci lseek (fd, 0, SEEK_END) ; 212b815c7f3Sopenharmony_ci 213b815c7f3Sopenharmony_ci for (k = 0 ; k < DATA_LENGTH ; k++) 214b815c7f3Sopenharmony_ci data [k] = k ; 215b815c7f3Sopenharmony_ci 216b815c7f3Sopenharmony_ci frames = DATA_LENGTH / channels ; 217b815c7f3Sopenharmony_ci 218b815c7f3Sopenharmony_ci sfinfo.format = filetype ; 219b815c7f3Sopenharmony_ci sfinfo.channels = channels ; 220b815c7f3Sopenharmony_ci sfinfo.samplerate = 44100 ; 221b815c7f3Sopenharmony_ci 222b815c7f3Sopenharmony_ci if ((sndfile = sf_open_fd (fd, SFM_WRITE, &sfinfo, SF_FALSE)) == NULL) 223b815c7f3Sopenharmony_ci { printf ("\n\nLine %d: sf_open_fd failed\n", __LINE__) ; 224b815c7f3Sopenharmony_ci printf ("Embedded file number : %d\n", file_num) ; 225b815c7f3Sopenharmony_ci puts (sf_strerror (sndfile)) ; 226b815c7f3Sopenharmony_ci dump_log_buffer (sndfile) ; 227b815c7f3Sopenharmony_ci exit (1) ; 228b815c7f3Sopenharmony_ci } ; 229b815c7f3Sopenharmony_ci 230b815c7f3Sopenharmony_ci if (sf_writef_short (sndfile, data, frames) != frames) 231b815c7f3Sopenharmony_ci { printf ("\n\nLine %d: short write\n", __LINE__) ; 232b815c7f3Sopenharmony_ci printf ("Embedded file number : %d\n", file_num) ; 233b815c7f3Sopenharmony_ci exit (1) ; 234b815c7f3Sopenharmony_ci } ; 235b815c7f3Sopenharmony_ci 236b815c7f3Sopenharmony_ci sf_close (sndfile) ; 237b815c7f3Sopenharmony_ci} /* write_file_at_end */ 238b815c7f3Sopenharmony_ci 239