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