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