annotate src/libsndfile-1.0.25/tests/fix_this.c @ 88:fe7c3a0b0259

Add some MinGW builds
author Chris Cannam <cannam@all-day-breakfast.com>
date Wed, 20 Mar 2013 13:49:36 +0000
parents 545efbb81310
children
rev   line source
cannam@85 1 /*
cannam@85 2 ** Copyright (C) 1999-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
cannam@85 3 **
cannam@85 4 ** This program is free software; you can redistribute it and/or modify
cannam@85 5 ** it under the terms of the GNU General Public License as published by
cannam@85 6 ** the Free Software Foundation; either version 2 of the License, or
cannam@85 7 ** (at your option) any later version.
cannam@85 8 **
cannam@85 9 ** This program is distributed in the hope that it will be useful,
cannam@85 10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
cannam@85 11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
cannam@85 12 ** GNU General Public License for more details.
cannam@85 13 **
cannam@85 14 ** You should have received a copy of the GNU General Public License
cannam@85 15 ** along with this program; if not, write to the Free Software
cannam@85 16 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
cannam@85 17 */
cannam@85 18
cannam@85 19 #include <stdio.h>
cannam@85 20 #include <stdlib.h>
cannam@85 21 #include <string.h>
cannam@85 22 #include <unistd.h>
cannam@85 23 #include <math.h>
cannam@85 24
cannam@85 25 #include <sndfile.h>
cannam@85 26
cannam@85 27 #include "utils.h"
cannam@85 28
cannam@85 29 #define BUFFER_SIZE (1<<14) /* Should be (1<<14) */
cannam@85 30 #define SAMPLE_RATE (11025)
cannam@85 31
cannam@85 32 #ifndef M_PI
cannam@85 33 #define M_PI 3.14159265358979323846264338
cannam@85 34 #endif
cannam@85 35
cannam@85 36 static void lcomp_test_int (const char *str, const char *filename, int filetype, double margin) ;
cannam@85 37
cannam@85 38 static int error_function (double data, double orig, double margin) ;
cannam@85 39 static int decay_response (int k) ;
cannam@85 40
cannam@85 41 static void gen_signal_double (double *data, double scale, int datalen) ;
cannam@85 42
cannam@85 43 /* Force the start of these buffers to be double aligned. Sparc-solaris will
cannam@85 44 ** choke if they are not.
cannam@85 45 */
cannam@85 46
cannam@85 47 typedef union
cannam@85 48 { double d [BUFFER_SIZE + 1] ;
cannam@85 49 int i [BUFFER_SIZE + 1] ;
cannam@85 50 } BUFFER ;
cannam@85 51
cannam@85 52 static BUFFER data_buffer ;
cannam@85 53 static BUFFER orig_buffer ;
cannam@85 54
cannam@85 55 int
cannam@85 56 main (void)
cannam@85 57 { const char *filename = "test.au" ;
cannam@85 58
cannam@85 59 lcomp_test_int ("au_g721", filename, SF_ENDIAN_BIG | SF_FORMAT_AU | SF_FORMAT_G721_32, 0.06) ;
cannam@85 60
cannam@85 61 return 0 ;
cannam@85 62 } /* main */
cannam@85 63
cannam@85 64 /*============================================================================================
cannam@85 65 ** Here are the test functions.
cannam@85 66 */
cannam@85 67
cannam@85 68 static void
cannam@85 69 lcomp_test_int (const char *str, const char *filename, int filetype, double margin)
cannam@85 70 { SNDFILE *file ;
cannam@85 71 SF_INFO sfinfo ;
cannam@85 72 int k, m, *orig, *data, sum_abs ;
cannam@85 73 long datalen, seekpos ;
cannam@85 74 double scale ;
cannam@85 75
cannam@85 76 printf ("\nThis is program is not part of the libsndfile test suite.\n\n") ;
cannam@85 77
cannam@85 78 printf (" lcomp_test_int : %s ... ", str) ;
cannam@85 79 fflush (stdout) ;
cannam@85 80
cannam@85 81 datalen = BUFFER_SIZE ;
cannam@85 82
cannam@85 83 scale = 1.0 * 0x10000 ;
cannam@85 84
cannam@85 85 data = data_buffer.i ;
cannam@85 86 orig = orig_buffer.i ;
cannam@85 87
cannam@85 88 gen_signal_double (orig_buffer.d, 32000.0 * scale, datalen) ;
cannam@85 89 for (k = 0 ; k < datalen ; k++)
cannam@85 90 orig [k] = orig_buffer.d [k] ;
cannam@85 91
cannam@85 92
cannam@85 93 sfinfo.samplerate = SAMPLE_RATE ;
cannam@85 94 sfinfo.frames = 123456789 ; /* Ridiculous value. */
cannam@85 95 sfinfo.channels = 1 ;
cannam@85 96 sfinfo.format = filetype ;
cannam@85 97
cannam@85 98 if (! (file = sf_open (filename, SFM_WRITE, &sfinfo)))
cannam@85 99 { printf ("sf_open_write failed with error : ") ;
cannam@85 100 puts (sf_strerror (NULL)) ;
cannam@85 101 exit (1) ;
cannam@85 102 } ;
cannam@85 103
cannam@85 104 if ((k = sf_writef_int (file, orig, datalen)) != datalen)
cannam@85 105 { printf ("sf_writef_int failed with short write (%ld => %d).\n", datalen, k) ;
cannam@85 106 exit (1) ;
cannam@85 107 } ;
cannam@85 108 sf_close (file) ;
cannam@85 109
cannam@85 110 memset (data, 0, datalen * sizeof (int)) ;
cannam@85 111
cannam@85 112 if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
cannam@85 113 memset (&sfinfo, 0, sizeof (sfinfo)) ;
cannam@85 114
cannam@85 115 if (! (file = sf_open (filename, SFM_READ, &sfinfo)))
cannam@85 116 { printf ("sf_open_read failed with error : ") ;
cannam@85 117 puts (sf_strerror (NULL)) ;
cannam@85 118 exit (1) ;
cannam@85 119 } ;
cannam@85 120
cannam@85 121 if ((sfinfo.format & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)) != (filetype & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)))
cannam@85 122 { printf ("Line %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, filetype, sfinfo.format) ;
cannam@85 123 exit (1) ;
cannam@85 124 } ;
cannam@85 125
cannam@85 126 if (sfinfo.frames < datalen)
cannam@85 127 { printf ("Too few.frames in file. (%ld should be a little more than %ld)\n", datalen, SF_COUNT_TO_LONG (sfinfo.frames)) ;
cannam@85 128 exit (1) ;
cannam@85 129 } ;
cannam@85 130
cannam@85 131 if (sfinfo.frames > (datalen + datalen / 2))
cannam@85 132 { printf ("Too many.frames in file. (%ld should be a little more than %ld)\n", datalen, SF_COUNT_TO_LONG (sfinfo.frames)) ;
cannam@85 133 exit (1) ;
cannam@85 134 } ;
cannam@85 135
cannam@85 136 if (sfinfo.channels != 1)
cannam@85 137 { printf ("Incorrect number of channels in file.\n") ;
cannam@85 138 exit (1) ;
cannam@85 139 } ;
cannam@85 140
cannam@85 141 check_log_buffer_or_die (file, __LINE__) ;
cannam@85 142
cannam@85 143 if ((k = sf_readf_int (file, data, datalen)) != datalen)
cannam@85 144 { printf ("Line %d: short read (%d should be %ld).\n", __LINE__, k, datalen) ;
cannam@85 145 exit (1) ;
cannam@85 146 } ;
cannam@85 147
cannam@85 148 sum_abs = 0 ;
cannam@85 149 for (k = 0 ; k < datalen ; k++)
cannam@85 150 { if (error_function (data [k] / scale, orig [k] / scale, margin))
cannam@85 151 { printf ("Line %d: Incorrect sample (#%d : %f should be %f).\n", __LINE__, k, data [k] / scale, orig [k] / scale) ;
cannam@85 152 oct_save_int (orig, data, datalen) ;
cannam@85 153 exit (1) ;
cannam@85 154 } ;
cannam@85 155 sum_abs = abs (sum_abs + abs (data [k])) ;
cannam@85 156 } ;
cannam@85 157
cannam@85 158 if (sum_abs < 1.0)
cannam@85 159 { printf ("Line %d: Signal is all zeros.\n", __LINE__) ;
cannam@85 160 exit (1) ;
cannam@85 161 } ;
cannam@85 162
cannam@85 163 if ((k = sf_readf_int (file, data, datalen)) != sfinfo.frames - datalen)
cannam@85 164 { printf ("Line %d: Incorrect read length (%ld should be %d).\n", __LINE__, SF_COUNT_TO_LONG (sfinfo.frames - datalen), k) ;
cannam@85 165 exit (1) ;
cannam@85 166 } ;
cannam@85 167
cannam@85 168 /* This check is only for block based encoders which must append silence
cannam@85 169 ** to the end of a file so as to fill out a block.
cannam@85 170 */
cannam@85 171 if ((sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_MS_ADPCM)
cannam@85 172 for (k = 0 ; k < sfinfo.frames - datalen ; k++)
cannam@85 173 if (abs (data [k] / scale) > decay_response (k))
cannam@85 174 { printf ("Line %d : Incorrect sample B (#%d : abs (%d) should be < %d).\n", __LINE__, k, data [k], decay_response (k)) ;
cannam@85 175 exit (1) ;
cannam@85 176 } ;
cannam@85 177
cannam@85 178 if (! sfinfo.seekable)
cannam@85 179 { printf ("ok\n") ;
cannam@85 180 return ;
cannam@85 181 } ;
cannam@85 182
cannam@85 183 /* Now test sf_seek function. */
cannam@85 184
cannam@85 185 if ((k = sf_seek (file, 0, SEEK_SET)) != 0)
cannam@85 186 { printf ("Line %d: Seek to start of file failed (%d).\n", __LINE__, k) ;
cannam@85 187 exit (1) ;
cannam@85 188 } ;
cannam@85 189
cannam@85 190 for (m = 0 ; m < 3 ; m++)
cannam@85 191 { int n ;
cannam@85 192
cannam@85 193 if ((k = sf_readf_int (file, data, 11)) != 11)
cannam@85 194 { printf ("Line %d: Incorrect read length (11 => %d).\n", __LINE__, k) ;
cannam@85 195 exit (1) ;
cannam@85 196 } ;
cannam@85 197
cannam@85 198 for (k = 0 ; k < 11 ; k++)
cannam@85 199 if (error_function (data [k] / scale, orig [k + m * 11] / scale, margin))
cannam@85 200 { printf ("Line %d: Incorrect sample (m = %d) (#%d : %d => %d).\n", __LINE__, m, k + m * 11, orig [k + m * 11], data [k]) ;
cannam@85 201 for (n = 0 ; n < 1 ; n++)
cannam@85 202 printf ("%d ", data [n]) ;
cannam@85 203 printf ("\n") ;
cannam@85 204 exit (1) ;
cannam@85 205 } ;
cannam@85 206 } ;
cannam@85 207
cannam@85 208 seekpos = BUFFER_SIZE / 10 ;
cannam@85 209
cannam@85 210 /* Check seek from start of file. */
cannam@85 211 if ((k = sf_seek (file, seekpos, SEEK_SET)) != seekpos)
cannam@85 212 { printf ("Seek to start of file + %ld failed (%d).\n", seekpos, k) ;
cannam@85 213 exit (1) ;
cannam@85 214 } ;
cannam@85 215
cannam@85 216 if ((k = sf_readf_int (file, data, 1)) != 1)
cannam@85 217 { printf ("Line %d: sf_readf_int (file, data, 1) returned %d.\n", __LINE__, k) ;
cannam@85 218 exit (1) ;
cannam@85 219 } ;
cannam@85 220
cannam@85 221 if (error_function ((double) data [0], (double) orig [seekpos], margin))
cannam@85 222 { printf ("Line %d: sf_seek (SEEK_SET) followed by sf_readf_int failed (%d, %d).\n", __LINE__, orig [1], data [0]) ;
cannam@85 223 exit (1) ;
cannam@85 224 } ;
cannam@85 225
cannam@85 226 if ((k = sf_seek (file, 0, SEEK_CUR)) != seekpos + 1)
cannam@85 227 { printf ("Line %d: sf_seek (SEEK_CUR) with 0 offset failed (%d should be %ld)\n", __LINE__, k, seekpos + 1) ;
cannam@85 228 exit (1) ;
cannam@85 229 } ;
cannam@85 230
cannam@85 231 seekpos = sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ;
cannam@85 232 k = sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ;
cannam@85 233 sf_readf_int (file, data, 1) ;
cannam@85 234 if (error_function ((double) data [0], (double) orig [seekpos], margin) || k != seekpos)
cannam@85 235 { printf ("Line %d: sf_seek (forwards, SEEK_CUR) followed by sf_readf_int failed (%d, %d) (%d, %ld).\n", __LINE__, data [0], orig [seekpos], k, seekpos + 1) ;
cannam@85 236 exit (1) ;
cannam@85 237 } ;
cannam@85 238
cannam@85 239 seekpos = sf_seek (file, 0, SEEK_CUR) - 20 ;
cannam@85 240 /* Check seek backward from current position. */
cannam@85 241 k = sf_seek (file, -20, SEEK_CUR) ;
cannam@85 242 sf_readf_int (file, data, 1) ;
cannam@85 243 if (error_function ((double) data [0], (double) orig [seekpos], margin) || k != seekpos)
cannam@85 244 { printf ("sf_seek (backwards, SEEK_CUR) followed by sf_readf_int failed (%d, %d) (%d, %ld).\n", data [0], orig [seekpos], k, seekpos) ;
cannam@85 245 exit (1) ;
cannam@85 246 } ;
cannam@85 247
cannam@85 248 /* Check that read past end of file returns number of items. */
cannam@85 249 sf_seek (file, (int) sfinfo.frames, SEEK_SET) ;
cannam@85 250
cannam@85 251 if ((k = sf_readf_int (file, data, datalen)) != 0)
cannam@85 252 { printf ("Line %d: Return value from sf_readf_int past end of file incorrect (%d).\n", __LINE__, k) ;
cannam@85 253 exit (1) ;
cannam@85 254 } ;
cannam@85 255
cannam@85 256 /* Check seek backward from end. */
cannam@85 257 if ((k = sf_seek (file, 5 - (int) sfinfo.frames, SEEK_END)) != 5)
cannam@85 258 { printf ("sf_seek (SEEK_END) returned %d instead of %d.\n", k, 5) ;
cannam@85 259 exit (1) ;
cannam@85 260 } ;
cannam@85 261
cannam@85 262 sf_readf_int (file, data, 1) ;
cannam@85 263 if (error_function (data [0] / scale, orig [5] / scale, margin))
cannam@85 264 { printf ("Line %d: sf_seek (SEEK_END) followed by sf_readf_short failed (%d should be %d).\n", __LINE__, data [0], orig [5]) ;
cannam@85 265 exit (1) ;
cannam@85 266 } ;
cannam@85 267
cannam@85 268 sf_close (file) ;
cannam@85 269
cannam@85 270 printf ("ok\n") ;
cannam@85 271 } /* lcomp_test_int */
cannam@85 272
cannam@85 273 /*========================================================================================
cannam@85 274 ** Auxiliary functions
cannam@85 275 */
cannam@85 276
cannam@85 277 #define SIGNAL_MAXVAL 30000.0
cannam@85 278 #define DECAY_COUNT 800
cannam@85 279
cannam@85 280 static int
cannam@85 281 decay_response (int k)
cannam@85 282 { if (k < 1)
cannam@85 283 return (int) (1.2 * SIGNAL_MAXVAL) ;
cannam@85 284 if (k > DECAY_COUNT)
cannam@85 285 return 0 ;
cannam@85 286 return (int) (1.2 * SIGNAL_MAXVAL * (DECAY_COUNT - k) / (1.0 * DECAY_COUNT)) ;
cannam@85 287 } /* decay_response */
cannam@85 288
cannam@85 289 static void
cannam@85 290 gen_signal_double (double *data, double scale, int datalen)
cannam@85 291 { int k, ramplen ;
cannam@85 292 double amp = 0.0 ;
cannam@85 293
cannam@85 294 ramplen = datalen / 18 ;
cannam@85 295
cannam@85 296 for (k = 0 ; k < datalen ; k++)
cannam@85 297 { if (k <= ramplen)
cannam@85 298 amp = scale * k / ((double) ramplen) ;
cannam@85 299 else if (k > datalen - ramplen)
cannam@85 300 amp = scale * (datalen - k) / ((double) ramplen) ;
cannam@85 301
cannam@85 302 data [k] = amp * (0.4 * sin (33.3 * 2.0 * M_PI * ((double) (k + 1)) / ((double) SAMPLE_RATE))
cannam@85 303 + 0.3 * cos (201.1 * 2.0 * M_PI * ((double) (k + 1)) / ((double) SAMPLE_RATE))) ;
cannam@85 304 } ;
cannam@85 305
cannam@85 306 return ;
cannam@85 307 } /* gen_signal_double */
cannam@85 308
cannam@85 309 static int
cannam@85 310 error_function (double data, double orig, double margin)
cannam@85 311 { double error ;
cannam@85 312
cannam@85 313 if (fabs (orig) <= 500.0)
cannam@85 314 error = fabs (fabs (data) - fabs (orig)) / 2000.0 ;
cannam@85 315 else if (fabs (orig) <= 1000.0)
cannam@85 316 error = fabs (data - orig) / 3000.0 ;
cannam@85 317 else
cannam@85 318 error = fabs (data - orig) / fabs (orig) ;
cannam@85 319
cannam@85 320 if (error > margin)
cannam@85 321 { printf ("\n\n*******************\nError : %f\n", error) ;
cannam@85 322 return 1 ;
cannam@85 323 } ;
cannam@85 324 return 0 ;
cannam@85 325 } /* error_function */
cannam@85 326