annotate src/libsndfile-1.0.27/tests/chunk_test.c @ 83:ae30d91d2ffe

Replace these with versions built using an older toolset (so as to avoid ABI compatibilities when linking on Ubuntu 14.04 for packaging purposes)
author Chris Cannam
date Fri, 07 Feb 2020 11:51:13 +0000
parents 1df64224f5ac
children
rev   line source
Chris@40 1 /*
Chris@40 2 ** Copyright (C) 2003-2016 Erik de Castro Lopo <erikd@mega-nerd.com>
Chris@40 3 **
Chris@40 4 ** This program is free software; you can redistribute it and/or modify
Chris@40 5 ** it under the terms of the GNU General Public License as published by
Chris@40 6 ** the Free Software Foundation; either version 2 of the License, or
Chris@40 7 ** (at your option) any later version.
Chris@40 8 **
Chris@40 9 ** This program is distributed in the hope that it will be useful,
Chris@40 10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
Chris@40 11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Chris@40 12 ** GNU General Public License for more details.
Chris@40 13 **
Chris@40 14 ** You should have received a copy of the GNU General Public License
Chris@40 15 ** along with this program; if not, write to the Free Software
Chris@40 16 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Chris@40 17 */
Chris@40 18
Chris@40 19 #include "sfconfig.h"
Chris@40 20
Chris@40 21 #include <stdio.h>
Chris@40 22 #include <stdlib.h>
Chris@40 23 #include <string.h>
Chris@40 24 #include <math.h>
Chris@40 25
Chris@40 26 #if HAVE_UNISTD_H
Chris@40 27 #include <unistd.h>
Chris@40 28 #endif
Chris@40 29
Chris@40 30 #include <sndfile.h>
Chris@40 31
Chris@40 32 #include "utils.h"
Chris@40 33
Chris@40 34 #define BUFFER_LEN (1 << 10)
Chris@40 35 #define LOG_BUFFER_SIZE 1024
Chris@40 36
Chris@40 37 static void chunk_test (const char *filename, int format) ;
Chris@40 38
Chris@40 39 static void
Chris@40 40 chunk_test_helper (const char *filename, int format, const char * testdata) ;
Chris@40 41
Chris@40 42 int
Chris@40 43 main (int argc, char *argv [])
Chris@40 44 { int do_all = 0 ;
Chris@40 45 int test_count = 0 ;
Chris@40 46
Chris@40 47 if (argc != 2)
Chris@40 48 { printf ("Usage : %s <test>\n", argv [0]) ;
Chris@40 49 printf (" Where <test> is one of the following:\n") ;
Chris@40 50 printf (" wav - test adding chunks to WAV files\n") ;
Chris@40 51 printf (" aiff - test adding chunks to AIFF files\n") ;
Chris@40 52 printf (" caf - test adding chunks to CAF files\n") ;
Chris@40 53 printf (" rf64 - test adding chunks to RF64 files\n") ;
Chris@40 54 printf (" all - perform all tests\n") ;
Chris@40 55 exit (1) ;
Chris@40 56 } ;
Chris@40 57
Chris@40 58 do_all = ! strcmp (argv [1], "all") ;
Chris@40 59
Chris@40 60 if (do_all || ! strcmp (argv [1], "wav"))
Chris@40 61 { chunk_test ("chunks_pcm16.wav", SF_FORMAT_WAV | SF_FORMAT_PCM_16) ;
Chris@40 62 chunk_test ("chunks_pcm16.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_PCM_16) ;
Chris@40 63 chunk_test ("chunks_pcm16.wavex", SF_FORMAT_WAVEX | SF_FORMAT_PCM_16) ;
Chris@40 64 test_count++ ;
Chris@40 65 } ;
Chris@40 66
Chris@40 67 if (do_all || ! strcmp (argv [1], "aiff"))
Chris@40 68 { chunk_test ("chunks_pcm16.aiff", SF_FORMAT_AIFF | SF_FORMAT_PCM_16) ;
Chris@40 69 test_count++ ;
Chris@40 70 } ;
Chris@40 71
Chris@40 72 if (do_all || ! strcmp (argv [1], "caf"))
Chris@40 73 { chunk_test ("chunks_pcm16.caf", SF_FORMAT_CAF | SF_FORMAT_PCM_16) ;
Chris@40 74 chunk_test ("chunks_alac.caf", SF_FORMAT_CAF | SF_FORMAT_ALAC_16) ;
Chris@40 75 test_count++ ;
Chris@40 76 } ;
Chris@40 77
Chris@40 78 if (do_all || ! strcmp (argv [1], "rf64"))
Chris@40 79 { chunk_test ("chunks_pcm16.rf64", SF_FORMAT_RF64 | SF_FORMAT_PCM_16) ;
Chris@40 80 test_count++ ;
Chris@40 81 } ;
Chris@40 82
Chris@40 83 if (test_count == 0)
Chris@40 84 { printf ("Mono : ************************************\n") ;
Chris@40 85 printf ("Mono : * No '%s' test defined.\n", argv [1]) ;
Chris@40 86 printf ("Mono : ************************************\n") ;
Chris@40 87 return 1 ;
Chris@40 88 } ;
Chris@40 89
Chris@40 90 return 0 ;
Chris@40 91 } /* main */
Chris@40 92
Chris@40 93
Chris@40 94 /*============================================================================================
Chris@40 95 ** Here are the test functions.
Chris@40 96 */
Chris@40 97
Chris@40 98 static void
Chris@40 99 chunk_test_helper (const char *filename, int format, const char * testdata)
Chris@40 100 { SNDFILE *file ;
Chris@40 101 SF_INFO sfinfo ;
Chris@40 102 SF_CHUNK_INFO chunk_info ;
Chris@40 103 SF_CHUNK_ITERATOR * iterator ;
Chris@40 104 uint32_t length_before ;
Chris@40 105 int err, allow_fd ;
Chris@40 106
Chris@40 107 switch (format & SF_FORMAT_SUBMASK)
Chris@40 108 { case SF_FORMAT_ALAC_16 :
Chris@40 109 allow_fd = SF_FALSE ;
Chris@40 110 break ;
Chris@40 111 default :
Chris@40 112 allow_fd = SF_TRUE ;
Chris@40 113 break ;
Chris@40 114 } ;
Chris@40 115
Chris@40 116 sfinfo.samplerate = 44100 ;
Chris@40 117 sfinfo.channels = 1 ;
Chris@40 118 sfinfo.frames = 0 ;
Chris@40 119 sfinfo.format = format ;
Chris@40 120
Chris@40 121 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, allow_fd, __LINE__) ;
Chris@40 122
Chris@40 123 /* Set up the chunk to write. */
Chris@40 124 memset (&chunk_info, 0, sizeof (chunk_info)) ;
Chris@40 125 snprintf (chunk_info.id, sizeof (chunk_info.id), "Test") ;
Chris@40 126 chunk_info.id_size = 4 ;
Chris@40 127 chunk_info.data = strdup (testdata) ;
Chris@40 128 chunk_info.datalen = strlen (chunk_info.data) ;
Chris@40 129
Chris@40 130 length_before = chunk_info.datalen ;
Chris@40 131
Chris@40 132 err = sf_set_chunk (file, &chunk_info) ;
Chris@40 133 exit_if_true (
Chris@40 134 err != SF_ERR_NO_ERROR,
Chris@40 135 "\n\nLine %d : sf_set_chunk returned for testdata '%s' : %s\n\n", __LINE__, testdata, sf_error_number (err)
Chris@40 136 ) ;
Chris@40 137
Chris@40 138 memset (chunk_info.data, 0, chunk_info.datalen) ;
Chris@40 139 free (chunk_info.data) ;
Chris@40 140
Chris@40 141 sf_close (file) ;
Chris@40 142
Chris@40 143 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, allow_fd, __LINE__) ;
Chris@40 144
Chris@40 145 memset (&chunk_info, 0, sizeof (chunk_info)) ;
Chris@40 146 snprintf (chunk_info.id, sizeof (chunk_info.id), "Test") ;
Chris@40 147 chunk_info.id_size = 4 ;
Chris@40 148
Chris@40 149 iterator = sf_get_chunk_iterator (file, &chunk_info) ;
Chris@40 150 err = sf_get_chunk_size (iterator, &chunk_info) ;
Chris@40 151 exit_if_true (
Chris@40 152 err != SF_ERR_NO_ERROR,
Chris@40 153 "\n\nLine %d : sf_get_chunk_size returned for testdata '%s' : %s\n\n", __LINE__, testdata, sf_error_number (err)
Chris@40 154 ) ;
Chris@40 155
Chris@40 156 exit_if_true (
Chris@40 157 length_before > chunk_info.datalen || chunk_info.datalen - length_before > 4,
Chris@40 158 "\n\nLine %d : testdata '%s' : Bad chunk length %u (previous length %u)\n\n", __LINE__, testdata, chunk_info.datalen, length_before
Chris@40 159 ) ;
Chris@40 160
Chris@40 161 chunk_info.data = malloc (chunk_info.datalen) ;
Chris@40 162 err = sf_get_chunk_data (iterator, &chunk_info) ;
Chris@40 163 exit_if_true (
Chris@40 164 err != SF_ERR_NO_ERROR,
Chris@40 165 "\n\nLine %d : sf_get_chunk_size returned for testdata '%s' : %s\n\n", __LINE__, testdata, sf_error_number (err)
Chris@40 166 ) ;
Chris@40 167
Chris@40 168 exit_if_true (
Chris@40 169 memcmp (testdata, chunk_info.data, length_before),
Chris@40 170 "\n\nLine %d : Data compare failed.\n %s\n %s\n\n", __LINE__, testdata, (char*) chunk_info.data
Chris@40 171 ) ;
Chris@40 172
Chris@40 173 free (chunk_info.data) ;
Chris@40 174
Chris@40 175 sf_close (file) ;
Chris@40 176 unlink (filename) ;
Chris@40 177 } /* chunk_test_helper */
Chris@40 178
Chris@40 179 static void
Chris@40 180 multichunk_test_helper (const char *filename, int format, const char * testdata [], size_t testdata_len)
Chris@40 181 { SNDFILE *file ;
Chris@40 182 SF_INFO sfinfo ;
Chris@40 183 SF_CHUNK_INFO chunk_info ;
Chris@40 184 SF_CHUNK_ITERATOR * iterator ;
Chris@40 185 uint32_t length_before [testdata_len] ;
Chris@40 186 int err, allow_fd ;
Chris@40 187 size_t i ;
Chris@40 188
Chris@40 189 sfinfo.samplerate = 44100 ;
Chris@40 190 sfinfo.channels = 1 ;
Chris@40 191 sfinfo.frames = 0 ;
Chris@40 192 sfinfo.format = format ;
Chris@40 193
Chris@40 194 switch (format & SF_FORMAT_SUBMASK)
Chris@40 195 { case SF_FORMAT_ALAC_16 :
Chris@40 196 allow_fd = SF_FALSE ;
Chris@40 197 break ;
Chris@40 198 default :
Chris@40 199 allow_fd = SF_TRUE ;
Chris@40 200 break ;
Chris@40 201 } ;
Chris@40 202
Chris@40 203 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, allow_fd, __LINE__) ;
Chris@40 204
Chris@40 205 /* Set up the chunk to write. */
Chris@40 206 for (i = 0 ; i < testdata_len ; i++)
Chris@40 207 { memset (&chunk_info, 0, sizeof (chunk_info)) ;
Chris@40 208 snprintf (chunk_info.id, sizeof (chunk_info.id), "Test") ;
Chris@40 209 chunk_info.id_size = 4 ;
Chris@40 210
Chris@40 211 chunk_info.data = strdup (testdata [i]) ;
Chris@40 212 chunk_info.datalen = strlen (chunk_info.data) ;
Chris@40 213
Chris@40 214 length_before [i] = chunk_info.datalen ;
Chris@40 215
Chris@40 216 err = sf_set_chunk (file, &chunk_info) ;
Chris@40 217 exit_if_true (
Chris@40 218 err != SF_ERR_NO_ERROR,
Chris@40 219 "\n\nLine %d : sf_set_chunk returned for testdata[%d] '%s' : %s\n\n", __LINE__, (int) i, testdata [i], sf_error_number (err)
Chris@40 220 ) ;
Chris@40 221
Chris@40 222 memset (chunk_info.data, 0, chunk_info.datalen) ;
Chris@40 223 free (chunk_info.data) ;
Chris@40 224 }
Chris@40 225
Chris@40 226 sf_close (file) ;
Chris@40 227
Chris@40 228 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, allow_fd, __LINE__) ;
Chris@40 229
Chris@40 230 memset (&chunk_info, 0, sizeof (chunk_info)) ;
Chris@40 231 snprintf (chunk_info.id, sizeof (chunk_info.id), "Test") ;
Chris@40 232 chunk_info.id_size = 4 ;
Chris@40 233
Chris@40 234 iterator = sf_get_chunk_iterator (file, &chunk_info) ;
Chris@40 235
Chris@40 236 i = 0 ;
Chris@40 237 while (iterator)
Chris@40 238 { memset (&chunk_info, 0, sizeof (chunk_info)) ;
Chris@40 239 err = sf_get_chunk_size (iterator, &chunk_info) ;
Chris@40 240 exit_if_true (
Chris@40 241 i > testdata_len,
Chris@40 242 "\n\nLine %d : iterated to chunk #%d, but only %d chunks have been written\n\n", __LINE__, (int) i, (int) testdata_len
Chris@40 243 ) ;
Chris@40 244
Chris@40 245 exit_if_true (
Chris@40 246 err != SF_ERR_NO_ERROR,
Chris@40 247 "\n\nLine %d : sf_get_chunk_size returned for testdata[%d] '%s' : %s\n\n", __LINE__, (int) i, testdata [i], sf_error_number (err)
Chris@40 248 ) ;
Chris@40 249
Chris@40 250 exit_if_true (
Chris@40 251 length_before [i] > chunk_info.datalen || chunk_info.datalen - length_before [i] > 4,
Chris@40 252 "\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]
Chris@40 253 ) ;
Chris@40 254
Chris@40 255 chunk_info.data = malloc (chunk_info.datalen) ;
Chris@40 256 err = sf_get_chunk_data (iterator, &chunk_info) ;
Chris@40 257 exit_if_true (
Chris@40 258 err != SF_ERR_NO_ERROR,
Chris@40 259 "\n\nLine %d : sf_get_chunk_size returned for testdata[%d] '%s' : %s\n\n", __LINE__, (int) i, testdata [i], sf_error_number (err)
Chris@40 260 ) ;
Chris@40 261
Chris@40 262 exit_if_true (
Chris@40 263 4 != chunk_info.id_size,
Chris@40 264 "\n\nLine %d : testdata[%d] : Bad ID length %u (previous length %u)\n\n", __LINE__, (int) i, chunk_info.id_size, 4
Chris@40 265 ) ;
Chris@40 266 exit_if_true (
Chris@40 267 memcmp ("Test", chunk_info.id, 4),
Chris@40 268 "\n\nLine %d : ID compare failed at %d.\n %s\n %s\n\n", __LINE__, (int) i, "Test", (char*) chunk_info.id
Chris@40 269 ) ;
Chris@40 270
Chris@40 271 exit_if_true (
Chris@40 272 memcmp (testdata [i], chunk_info.data, length_before [i]),
Chris@40 273 "\n\nLine %d : Data compare failed at %d.\n %s\n %s\n\n", __LINE__, (int) i, testdata [i], (char*) chunk_info.data
Chris@40 274 ) ;
Chris@40 275
Chris@40 276 free (chunk_info.data) ;
Chris@40 277 iterator = sf_next_chunk_iterator (iterator) ;
Chris@40 278 i++ ;
Chris@40 279 }
Chris@40 280
Chris@40 281 sf_close (file) ;
Chris@40 282 unlink (filename) ;
Chris@40 283 } /* multichunk_test_helper */
Chris@40 284
Chris@40 285
Chris@40 286 static void
Chris@40 287 chunk_test (const char *filename, int format)
Chris@40 288 { const char* testdata [] =
Chris@40 289 { "There can be only one.", "", "A", "AB", "ABC", "ABCD", "ABCDE" } ;
Chris@40 290 uint32_t k ;
Chris@40 291
Chris@40 292 print_test_name (__func__, filename) ;
Chris@40 293
Chris@40 294 for (k = 0 ; k < ARRAY_LEN (testdata) ; k++)
Chris@40 295 chunk_test_helper (filename, format, testdata [k]) ;
Chris@40 296
Chris@40 297 multichunk_test_helper (filename, format, testdata, ARRAY_LEN (testdata)) ;
Chris@40 298
Chris@40 299 puts ("ok") ;
Chris@40 300 } /* chunk_test */