1/* 2** Copyright (C) 1999-2016 Erik de Castro Lopo <erikd@mega-nerd.com> 3** 4** This program is free software; you can redistribute it and/or modify 5** it under the terms of the GNU General Public License as published by 6** the Free Software Foundation; either version 2 of the License, or 7** (at your option) any later version. 8** 9** This program is distributed in the hope that it will be useful, 10** but WITHOUT ANY WARRANTY; without even the implied warranty of 11** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12** GNU General Public License for more details. 13** 14** You should have received a copy of the GNU General Public License 15** along with this program; if not, write to the Free Software 16** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17*/ 18 19#include "sfconfig.h" 20 21#include <stdio.h> 22#include <stdlib.h> 23#include <string.h> 24#include <math.h> 25#include <inttypes.h> 26 27 28#if HAVE_UNISTD_H 29#include <unistd.h> 30#else 31#include "sf_unistd.h" 32#endif 33 34#include <sndfile.h> 35 36#include "utils.h" 37 38#define BUFFER_SIZE (1 << 14) 39#define SAMPLE_RATE 11025 40 41#ifndef M_PI 42#define M_PI 3.14159265358979323846264338 43#endif 44 45#define LCT_MAX(x, y) ((x) > (y) ? (x) : (y)) 46 47static const char LCT_TEST_PREFIX[] = "lct" ; 48 49static void lcomp_test_short (const char *filename, int filetype, int chan, double margin) ; 50static void lcomp_test_int (const char *filename, int filetype, int chan, double margin) ; 51static void lcomp_test_float (const char *filename, int filetype, int chan, double margin) ; 52static void lcomp_test_double (const char *filename, int filetype, int chan, double margin) ; 53 54static void sdlcomp_test_short (const char *filename, int filetype, int chan, double margin) ; 55static void sdlcomp_test_int (const char *filename, int filetype, int chan, double margin) ; 56static void sdlcomp_test_float (const char *filename, int filetype, int chan, double margin) ; 57static void sdlcomp_test_double (const char *filename, int filetype, int chan, double margin) ; 58 59static void read_raw_test (const char *filename, int filetype, int chan) ; 60 61static int error_function (double data, double orig, double margin) ; 62static int decay_response (int k) ; 63 64static void gen_signal_double (double *data, double scale, int channels, int datalen) ; 65 66static void smoothed_diff_short (short *data, unsigned int datalen) ; 67static void smoothed_diff_int (int *data, unsigned int datalen) ; 68static void smoothed_diff_float (float *data, unsigned int datalen) ; 69static void smoothed_diff_double (double *data, unsigned int datalen) ; 70 71static void check_comment (SNDFILE * file, int format, int lineno) ; 72 73static int is_lossy (int filetype) ; 74 75static int check_opus_version (SNDFILE *file) ; 76 77/* 78** Force the start of these buffers to be double aligned. Sparc-solaris will 79** choke if they are not. 80*/ 81typedef union 82{ double d [BUFFER_SIZE + 1] ; 83 float f [BUFFER_SIZE + 1] ; 84 int i [BUFFER_SIZE + 1] ; 85 short s [BUFFER_SIZE + 1] ; 86 char c [BUFFER_SIZE + 1] ; 87} BUFFER ; 88 89static BUFFER data_buffer ; 90static BUFFER orig_buffer ; 91static BUFFER smooth_buffer ; 92 93static const char *long_comment = 94 "This is really quite a long comment. It is designed to be long enough " 95 "to screw up the encoders and decoders if the file container format does " 96 "not handle things correctly. If everything is working correctly, the " 97 "decoder will only decode the actual audio data, and not this string at " 98 "the end of the file." ; 99 100int 101main (int argc, char *argv []) 102{ int do_all = 0 ; 103 int test_count = 0 ; 104 105 if (argc != 2) 106 { printf ("Usage : %s <test>\n", argv [0]) ; 107 printf (" Where <test> is one of the following:\n") ; 108 printf (" wav_ima - test IMA ADPCM WAV file functions\n") ; 109 printf (" wav_msadpcm - test MS ADPCM WAV file functions\n") ; 110 printf (" wav_gsm610 - test GSM 6.10 WAV file functions\n") ; 111 printf (" wav_ulaw - test u-law WAV file functions\n") ; 112 printf (" wav_alaw - test A-law WAV file functions\n") ; 113 printf (" wve - test Psion WVE file functions\n") ; 114 printf (" all - perform all tests\n") ; 115 exit (1) ; 116 } ; 117 118 do_all = ! strcmp (argv [1], "all") ; 119 120 if (do_all || strcmp (argv [1], "wav_pcm") == 0) 121 { /* This is just a sanity test for PCM encoding. */ 122 lcomp_test_short ("pcm.wav", SF_FORMAT_WAV | SF_FORMAT_PCM_16, 2, 1e-50) ; 123 lcomp_test_int ("pcm.wav", SF_FORMAT_WAV | SF_FORMAT_PCM_32, 2, 1e-50) ; 124 lcomp_test_short ("pcm.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_PCM_16, 2, 1e-50) ; 125 lcomp_test_int ("pcm.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_PCM_32, 2, 1e-50) ; 126 /* Lite remove start */ 127 lcomp_test_float ("pcm.wav", SF_FORMAT_WAV | SF_FORMAT_FLOAT, 2, 1e-50) ; 128 lcomp_test_double ("pcm.wav", SF_FORMAT_WAV | SF_FORMAT_DOUBLE, 2, 1e-50) ; 129 /* Lite remove end */ 130 131 read_raw_test ("pcm.wav", SF_FORMAT_WAV | SF_FORMAT_PCM_U8, 2) ; 132 test_count++ ; 133 } ; 134 135 /* For all the rest, if the file format supports more than 1 channel, use stereo. */ 136 /* Lite remove start */ 137 if (do_all || strcmp (argv [1], "wav_ima") == 0) 138 { lcomp_test_short ("ima.wav", SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM, 2, 0.18) ; 139 lcomp_test_int ("ima.wav", SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM, 2, 0.65) ; 140 lcomp_test_float ("ima.wav", SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM, 2, 0.18) ; 141 lcomp_test_double ("ima.wav", SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM, 2, 0.18) ; 142 143 lcomp_test_short ("ima.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM, 2, 0.18) ; 144 lcomp_test_int ("ima.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM, 2, 0.18) ; 145 lcomp_test_float ("ima.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM, 2, 0.18) ; 146 lcomp_test_double ("ima.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM, 2, 0.18) ; 147 148 sdlcomp_test_short ("ima.wav", SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM, 2, 0.18) ; 149 sdlcomp_test_int ("ima.wav", SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM, 2, 0.18) ; 150 sdlcomp_test_float ("ima.wav", SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM, 2, 0.18) ; 151 sdlcomp_test_double ("ima.wav", SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM, 2, 0.18) ; 152 test_count++ ; 153 } ; 154 155 if (do_all || strcmp (argv [1], "wav_msadpcm") == 0) 156 { lcomp_test_short ("msadpcm.wav", SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM, 2, 0.36) ; 157 lcomp_test_int ("msadpcm.wav", SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM, 2, 0.36) ; 158 lcomp_test_float ("msadpcm.wav", SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM, 2, 0.36) ; 159 lcomp_test_double ("msadpcm.wav", SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM, 2, 0.36) ; 160 161 lcomp_test_short ("msadpcm.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM, 2, 0.36) ; 162 lcomp_test_int ("msadpcm.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM, 2, 0.36) ; 163 lcomp_test_float ("msadpcm.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM, 2, 0.36) ; 164 lcomp_test_double ("msadpcm.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM, 2, 0.36) ; 165 166 sdlcomp_test_short ("msadpcm.wav", SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM, 2, 0.36) ; 167 sdlcomp_test_int ("msadpcm.wav", SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM, 2, 0.36) ; 168 sdlcomp_test_float ("msadpcm.wav", SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM, 2, 0.36) ; 169 sdlcomp_test_double ("msadpcm.wav", SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM, 2, 0.36) ; 170 171 test_count++ ; 172 } ; 173 174 if (do_all || strcmp (argv [1], "wav_g721") == 0) 175 { printf ("**** Fix this later : error bound should be 0.06 ****\n") ; 176 lcomp_test_short ("g721.wav", SF_FORMAT_WAV | SF_FORMAT_G721_32, 1, 0.7) ; 177 lcomp_test_int ("g721.wav", SF_FORMAT_WAV | SF_FORMAT_G721_32, 1, 0.7) ; 178 179 lcomp_test_short ("g721.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_G721_32, 1, 0.7) ; 180 lcomp_test_int ("g721.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_G721_32, 1, 0.7) ; 181 182 test_count++ ; 183 } ; 184 /* Lite remove end */ 185 186 if (do_all || strcmp (argv [1], "wav_ulaw") == 0) 187 { lcomp_test_short ("ulaw.wav", SF_FORMAT_WAV | SF_FORMAT_ULAW, 2, 0.04) ; 188 lcomp_test_int ("ulaw.wav", SF_FORMAT_WAV | SF_FORMAT_ULAW, 2, 0.04) ; 189 190 lcomp_test_short ("ulaw.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_ULAW, 2, 0.04) ; 191 lcomp_test_int ("ulaw.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_ULAW, 2, 0.04) ; 192 193 /* Lite remove start */ 194 lcomp_test_float ("ulaw.wav", SF_FORMAT_WAV | SF_FORMAT_ULAW, 2, 0.04) ; 195 lcomp_test_double ("ulaw.wav", SF_FORMAT_WAV | SF_FORMAT_ULAW, 2, 0.04) ; 196 /* Lite remove end */ 197 198 read_raw_test ("ulaw.wav", SF_FORMAT_WAV | SF_FORMAT_ULAW, 2) ; 199 test_count++ ; 200 } ; 201 202 if (do_all || strcmp (argv [1], "wav_alaw") == 0) 203 { lcomp_test_short ("alaw.wav", SF_FORMAT_WAV | SF_FORMAT_ALAW, 2, 0.04) ; 204 lcomp_test_int ("alaw.wav", SF_FORMAT_WAV | SF_FORMAT_ALAW, 2, 0.04) ; 205 /* Lite remove start */ 206 lcomp_test_float ("alaw.wav", SF_FORMAT_WAV | SF_FORMAT_ALAW, 2, 0.04) ; 207 lcomp_test_double ("alaw.wav", SF_FORMAT_WAV | SF_FORMAT_ALAW, 2, 0.04) ; 208 /* Lite remove end */ 209 210 read_raw_test ("alaw.wav", SF_FORMAT_WAV | SF_FORMAT_ALAW, 2) ; 211 test_count++ ; 212 } ; 213 214 if (do_all || strcmp (argv [1], "wav_gsm610") == 0) 215 { /* Don't do lcomp_test_XXX as the errors are too big. */ 216 sdlcomp_test_short ("gsm610.wav", SF_FORMAT_WAV | SF_FORMAT_GSM610, 1, 0.24) ; 217 sdlcomp_test_int ("gsm610.wav", SF_FORMAT_WAV | SF_FORMAT_GSM610, 1, 0.24) ; 218 219 sdlcomp_test_short ("gsm610.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_GSM610, 1, 0.24) ; 220 sdlcomp_test_int ("gsm610.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_GSM610, 1, 0.24) ; 221 222 /* Lite remove start */ 223 sdlcomp_test_float ("gsm610.wav", SF_FORMAT_WAV | SF_FORMAT_GSM610, 1, 0.24) ; 224 sdlcomp_test_double ("gsm610.wav", SF_FORMAT_WAV | SF_FORMAT_GSM610, 1, 0.24) ; 225 /* Lite remove end */ 226 test_count++ ; 227 } ; 228 229 /* Lite remove start */ 230 if (do_all || strcmp (argv [1], "wav_nmsadpcm") == 0) 231 { lcomp_test_short ("nms_16.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_16, 1, 0.37) ; 232 lcomp_test_int ("nms_16.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_16, 1, 0.31) ; 233 lcomp_test_float ("nms_16.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_16, 1, 0.34) ; 234 lcomp_test_double ("nms_16.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_16, 1, 0.34) ; 235 236 lcomp_test_short ("nms_24.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_24, 1, 0.15) ; 237 lcomp_test_int ("nms_24.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_24, 1, 0.10) ; 238 lcomp_test_float ("nms_24.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_24, 1, 0.14) ; 239 lcomp_test_double ("nms_24.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_24, 1, 0.14) ; 240 241 lcomp_test_short ("nms_32.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_32, 1, 0.036) ; 242 lcomp_test_int ("nms_32.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_32, 1, 0.045) ; 243 lcomp_test_float ("nms_32.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_32, 1, 0.035) ; 244 lcomp_test_double ("nms_32.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_32, 1, 0.035) ; 245 246 sdlcomp_test_short ("nms_16.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_16, 1, 0.16) ; 247 sdlcomp_test_int ("nms_16.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_16, 1, 0.16) ; 248 sdlcomp_test_float ("nms_16.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_16, 1, 0.16) ; 249 sdlcomp_test_double ("nms_16.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_16, 1, 0.16) ; 250 251 sdlcomp_test_short ("nms_24.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_24, 1, 0.06) ; 252 sdlcomp_test_int ("nms_24.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_24, 1, 0.06) ; 253 sdlcomp_test_float ("nms_24.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_24, 1, 0.06) ; 254 sdlcomp_test_double ("nms_24.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_24, 1, 0.06) ; 255 256 sdlcomp_test_short ("nms_32.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_32, 1, 0.017) ; 257 sdlcomp_test_int ("nms_32.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_32, 1, 0.018) ; 258 sdlcomp_test_float ("nms_32.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_32, 1, 0.018) ; 259 sdlcomp_test_double ("nms_32.wav", SF_FORMAT_WAV | SF_FORMAT_NMS_ADPCM_32, 1, 0.018) ; 260 261 test_count++ ; 262 } ; 263 /* Lite remove end */ 264 265 if (do_all || strcmp (argv [1], "aiff_ulaw") == 0) 266 { lcomp_test_short ("ulaw.aiff", SF_FORMAT_AIFF | SF_FORMAT_ULAW, 2, 0.04) ; 267 lcomp_test_int ("ulaw.aiff", SF_FORMAT_AIFF | SF_FORMAT_ULAW, 2, 0.04) ; 268 /* Lite remove start */ 269 lcomp_test_float ("ulaw.aiff", SF_FORMAT_AIFF | SF_FORMAT_ULAW, 2, 0.04) ; 270 lcomp_test_double ("ulaw.aiff", SF_FORMAT_AIFF | SF_FORMAT_ULAW, 2, 0.04) ; 271 /* Lite remove end */ 272 273 read_raw_test ("ulaw.aiff", SF_FORMAT_AIFF | SF_FORMAT_ULAW, 2) ; 274 test_count++ ; 275 } ; 276 277 if (do_all || strcmp (argv [1], "aiff_alaw") == 0) 278 { lcomp_test_short ("alaw.aiff", SF_FORMAT_AIFF | SF_FORMAT_ALAW, 2, 0.04) ; 279 lcomp_test_int ("alaw.aiff", SF_FORMAT_AIFF | SF_FORMAT_ALAW, 2, 0.04) ; 280 /* Lite remove start */ 281 lcomp_test_float ("alaw.aiff", SF_FORMAT_AIFF | SF_FORMAT_ALAW, 2, 0.04) ; 282 lcomp_test_double ("alaw.aiff", SF_FORMAT_AIFF | SF_FORMAT_ALAW, 2, 0.04) ; 283 /* Lite remove end */ 284 285 read_raw_test ("alaw.aiff", SF_FORMAT_AIFF | SF_FORMAT_ALAW, 2) ; 286 test_count++ ; 287 } ; 288 289 if (do_all || strcmp (argv [1], "aiff_gsm610") == 0) 290 { /* Don't do lcomp_test_XXX as the errors are too big. */ 291 sdlcomp_test_short ("gsm610.aiff", SF_FORMAT_AIFF | SF_FORMAT_GSM610, 1, 0.24) ; 292 sdlcomp_test_int ("gsm610.aiff", SF_FORMAT_AIFF | SF_FORMAT_GSM610, 1, 0.24) ; 293 /* Lite remove start */ 294 sdlcomp_test_float ("gsm610.aiff", SF_FORMAT_AIFF | SF_FORMAT_GSM610, 1, 0.24) ; 295 sdlcomp_test_double ("gsm610.aiff", SF_FORMAT_AIFF | SF_FORMAT_GSM610, 1, 0.24) ; 296 /* Lite remove end */ 297 test_count++ ; 298 } ; 299 300 if (strcmp (argv [1], "aiff_ima") == 0) 301 { lcomp_test_short ("ima.aiff", SF_FORMAT_AIFF | SF_FORMAT_IMA_ADPCM, 2, 0.18) ; 302 lcomp_test_int ("ima.aiff", SF_FORMAT_AIFF | SF_FORMAT_IMA_ADPCM, 2, 0.18) ; 303 /* Lite remove start */ 304 lcomp_test_float ("ima.aiff", SF_FORMAT_AIFF | SF_FORMAT_IMA_ADPCM, 2, 0.18) ; 305 lcomp_test_double ("ima.aiff", SF_FORMAT_AIFF | SF_FORMAT_IMA_ADPCM, 2, 0.18) ; 306 /* Lite remove end */ 307 } ; 308 309 if (do_all || strcmp (argv [1], "au_ulaw") == 0) 310 { lcomp_test_short ("ulaw.au", SF_ENDIAN_BIG | SF_FORMAT_AU | SF_FORMAT_ULAW, 2, 0.04) ; 311 lcomp_test_int ("ulaw.au", SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_ULAW, 2, 0.04) ; 312 /* Lite remove start */ 313 lcomp_test_float ("ulaw.au", SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_ULAW, 2, 0.04) ; 314 lcomp_test_double ("ulaw.au", SF_ENDIAN_BIG | SF_FORMAT_AU | SF_FORMAT_ULAW, 2, 0.04) ; 315 /* Lite remove end */ 316 test_count++ ; 317 } ; 318 319 if (do_all || strcmp (argv [1], "au_alaw") == 0) 320 { lcomp_test_short ("alaw.au", SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_ALAW, 2, 0.04) ; 321 lcomp_test_int ("alaw.au", SF_ENDIAN_BIG | SF_FORMAT_AU | SF_FORMAT_ALAW, 2, 0.04) ; 322 /* Lite remove start */ 323 lcomp_test_float ("alaw.au", SF_ENDIAN_BIG | SF_FORMAT_AU | SF_FORMAT_ALAW, 2, 0.04) ; 324 lcomp_test_double ("alaw.au", SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_ALAW, 2, 0.04) ; 325 /* Lite remove end */ 326 test_count++ ; 327 } ; 328 329 /* Lite remove start */ 330 if (do_all || strcmp (argv [1], "au_g721") == 0) 331 { printf ("**** Fix this later : error bound should be 0.06 ****\n") ; 332 lcomp_test_short ("g721.au", SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_G721_32, 1, 0.7) ; 333 lcomp_test_int ("g721.au", SF_ENDIAN_BIG | SF_FORMAT_AU | SF_FORMAT_G721_32, 1, 0.7) ; 334 lcomp_test_float ("g721.au", SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_G721_32, 1, 0.7) ; 335 lcomp_test_double ("g721.au", SF_ENDIAN_BIG | SF_FORMAT_AU | SF_FORMAT_G721_32, 1, 0.7) ; 336 337/*- sdlcomp_test_short ("g721.au", SF_ENDIAN_BIG | SF_FORMAT_AU | SF_FORMAT_G721_32, 1, 0.07) ; 338 sdlcomp_test_int ("g721.au", SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_G721_32, 1, 0.07) ; 339 sdlcomp_test_float ("g721.au", SF_ENDIAN_BIG | SF_FORMAT_AU | SF_FORMAT_G721_32, 1, 0.07) ; 340 sdlcomp_test_double ("g721.au", SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_G721_32, 1, 0.12) ; 341-*/ 342 test_count++ ; 343 } ; 344 345 if (do_all || strcmp (argv [1], "au_g723") == 0) 346 { printf ("**** Fix this later : error bound should be 0.16 ****\n") ; 347 lcomp_test_short ("g723_24.au", SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_G723_24, 1, 0.7) ; 348 lcomp_test_int ("g723_24.au", SF_ENDIAN_BIG | SF_FORMAT_AU | SF_FORMAT_G723_24, 1, 0.7) ; 349 lcomp_test_float ("g723_24.au", SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_G723_24, 1, 0.7) ; 350 lcomp_test_double ("g723_24.au", SF_ENDIAN_BIG | SF_FORMAT_AU | SF_FORMAT_G723_24, 1, 0.7) ; 351 352 lcomp_test_short ("g723_40.au", SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_G723_40, 1, 0.85) ; 353 lcomp_test_int ("g723_40.au", SF_ENDIAN_BIG | SF_FORMAT_AU | SF_FORMAT_G723_40, 1, 0.84) ; 354 lcomp_test_float ("g723_40.au", SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_G723_40, 1, 0.86) ; 355 lcomp_test_double ("g723_40.au", SF_ENDIAN_BIG | SF_FORMAT_AU | SF_FORMAT_G723_40, 1, 0.86) ; 356 357/*- sdlcomp_test_short ("g723.au", SF_ENDIAN_BIG | SF_FORMAT_AU | SF_FORMAT_G723_24, 1, 0.15) ; 358 sdlcomp_test_int ("g723.au", SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_G723_24, 1, 0.15) ; 359 sdlcomp_test_float ("g723.au", SF_ENDIAN_BIG | SF_FORMAT_AU | SF_FORMAT_G723_24, 1, 0.15) ; 360 sdlcomp_test_double ("g723.au", SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_G723_24, 1, 0.15) ; 361-*/ 362 test_count++ ; 363 } ; 364 /* Lite remove end */ 365 366 if (do_all || strcmp (argv [1], "caf_ulaw") == 0) 367 { lcomp_test_short ("ulaw.caf", SF_FORMAT_CAF | SF_FORMAT_ULAW, 2, 0.04) ; 368 lcomp_test_int ("ulaw.caf", SF_FORMAT_CAF | SF_FORMAT_ULAW, 2, 0.04) ; 369 /* Lite remove start */ 370 lcomp_test_float ("ulaw.caf", SF_FORMAT_CAF | SF_FORMAT_ULAW, 2, 0.04) ; 371 lcomp_test_double ("ulaw.caf", SF_FORMAT_CAF | SF_FORMAT_ULAW, 2, 0.04) ; 372 /* Lite remove end */ 373 374 read_raw_test ("ulaw.caf", SF_FORMAT_CAF | SF_FORMAT_ULAW, 2) ; 375 test_count++ ; 376 } ; 377 378 if (do_all || strcmp (argv [1], "caf_alaw") == 0) 379 { lcomp_test_short ("alaw.caf", SF_FORMAT_CAF | SF_FORMAT_ALAW, 2, 0.04) ; 380 lcomp_test_int ("alaw.caf", SF_FORMAT_CAF | SF_FORMAT_ALAW, 2, 0.04) ; 381 /* Lite remove start */ 382 lcomp_test_float ("alaw.caf", SF_FORMAT_CAF | SF_FORMAT_ALAW, 2, 0.04) ; 383 lcomp_test_double ("alaw.caf", SF_FORMAT_CAF | SF_FORMAT_ALAW, 2, 0.04) ; 384 /* Lite remove end */ 385 386 read_raw_test ("alaw.caf", SF_FORMAT_CAF | SF_FORMAT_ALAW, 2) ; 387 test_count++ ; 388 } ; 389 390 391 if (do_all || strcmp (argv [1], "raw_ulaw") == 0) 392 { lcomp_test_short ("ulaw.raw", SF_ENDIAN_LITTLE | SF_FORMAT_RAW | SF_FORMAT_ULAW, 2, 0.04) ; 393 lcomp_test_int ("ulaw.raw", SF_ENDIAN_BIG | SF_FORMAT_RAW | SF_FORMAT_ULAW, 2, 0.04) ; 394 /* Lite remove start */ 395 lcomp_test_float ("ulaw.raw", SF_ENDIAN_LITTLE | SF_FORMAT_RAW | SF_FORMAT_ULAW, 2, 0.04) ; 396 lcomp_test_double ("ulaw.raw", SF_ENDIAN_BIG | SF_FORMAT_RAW | SF_FORMAT_ULAW, 2, 0.04) ; 397 /* Lite remove end */ 398 test_count++ ; 399 } ; 400 401 if (do_all || strcmp (argv [1], "raw_alaw") == 0) 402 { lcomp_test_short ("alaw.raw", SF_ENDIAN_LITTLE | SF_FORMAT_RAW | SF_FORMAT_ALAW, 2, 0.04) ; 403 lcomp_test_int ("alaw.raw", SF_ENDIAN_BIG | SF_FORMAT_RAW | SF_FORMAT_ALAW, 2, 0.04) ; 404 /* Lite remove start */ 405 lcomp_test_float ("alaw.raw", SF_ENDIAN_LITTLE | SF_FORMAT_RAW | SF_FORMAT_ALAW, 2, 0.04) ; 406 lcomp_test_double ("alaw.raw", SF_ENDIAN_BIG | SF_FORMAT_RAW | SF_FORMAT_ALAW, 2, 0.04) ; 407 /* Lite remove end */ 408 test_count++ ; 409 } ; 410 411 if (do_all || strcmp (argv [1], "raw_gsm610") == 0) 412 { /* Don't do lcomp_test_XXX as the errors are too big. */ 413 sdlcomp_test_short ("raw.gsm", SF_FORMAT_RAW | SF_FORMAT_GSM610, 1, 0.24) ; 414 sdlcomp_test_int ("raw.gsm", SF_FORMAT_RAW | SF_FORMAT_GSM610, 1, 0.24) ; 415 sdlcomp_test_float ("raw.gsm", SF_FORMAT_RAW | SF_FORMAT_GSM610, 1, 0.24) ; 416 sdlcomp_test_double ("raw.gsm", SF_FORMAT_RAW | SF_FORMAT_GSM610, 1, 0.24) ; 417 test_count++ ; 418 } ; 419 420 /* Lite remove start */ 421 if (do_all || strcmp (argv [1], "raw_nmsadpcm") == 0) 422 { lcomp_test_short ("raw.vce16", SF_FORMAT_RAW | SF_FORMAT_NMS_ADPCM_16, 1, 0.37) ; 423 lcomp_test_int ("raw.vce16", SF_FORMAT_RAW | SF_FORMAT_NMS_ADPCM_16, 1, 0.31) ; 424 lcomp_test_float ("raw.vce16", SF_FORMAT_RAW | SF_FORMAT_NMS_ADPCM_16, 1, 0.34) ; 425 lcomp_test_double ("raw.vce16", SF_FORMAT_RAW | SF_FORMAT_NMS_ADPCM_16, 1, 0.34) ; 426 427 lcomp_test_short ("raw.vce24", SF_FORMAT_RAW | SF_FORMAT_NMS_ADPCM_24, 1, 0.15) ; 428 lcomp_test_int ("raw.vce24", SF_FORMAT_RAW | SF_FORMAT_NMS_ADPCM_24, 1, 0.10) ; 429 lcomp_test_float ("raw.vce24", SF_FORMAT_RAW | SF_FORMAT_NMS_ADPCM_24, 1, 0.14) ; 430 lcomp_test_double ("raw.vce24", SF_FORMAT_RAW | SF_FORMAT_NMS_ADPCM_24, 1, 0.14) ; 431 432 lcomp_test_short ("raw.vce32", SF_FORMAT_RAW | SF_FORMAT_NMS_ADPCM_32, 1, 0.036) ; 433 lcomp_test_int ("raw.vce32", SF_FORMAT_RAW | SF_FORMAT_NMS_ADPCM_32, 1, 0.045) ; 434 lcomp_test_float ("raw.vce32", SF_FORMAT_RAW | SF_FORMAT_NMS_ADPCM_32, 1, 0.035) ; 435 lcomp_test_double ("raw.vce32", SF_FORMAT_RAW | SF_FORMAT_NMS_ADPCM_32, 1, 0.035) ; 436 437 sdlcomp_test_short ("raw.vce16", SF_FORMAT_RAW | SF_FORMAT_NMS_ADPCM_16, 1, 0.16) ; 438 sdlcomp_test_int ("raw.vce16", SF_FORMAT_RAW | SF_FORMAT_NMS_ADPCM_16, 1, 0.16) ; 439 sdlcomp_test_float ("raw.vce16", SF_FORMAT_RAW | SF_FORMAT_NMS_ADPCM_16, 1, 0.16) ; 440 sdlcomp_test_double ("raw.vce16", SF_FORMAT_RAW | SF_FORMAT_NMS_ADPCM_16, 1, 0.16) ; 441 442 sdlcomp_test_short ("raw.vce24", SF_FORMAT_RAW | SF_FORMAT_NMS_ADPCM_24, 1, 0.06) ; 443 sdlcomp_test_int ("raw.vce24", SF_FORMAT_RAW | SF_FORMAT_NMS_ADPCM_24, 1, 0.06) ; 444 sdlcomp_test_float ("raw.vce24", SF_FORMAT_RAW | SF_FORMAT_NMS_ADPCM_24, 1, 0.06) ; 445 sdlcomp_test_double ("raw.vce24", SF_FORMAT_RAW | SF_FORMAT_NMS_ADPCM_24, 1, 0.06) ; 446 447 sdlcomp_test_short ("raw.vce32", SF_FORMAT_RAW | SF_FORMAT_NMS_ADPCM_32, 1, 0.017) ; 448 sdlcomp_test_int ("raw.vce32", SF_FORMAT_RAW | SF_FORMAT_NMS_ADPCM_32, 1, 0.018) ; 449 sdlcomp_test_float ("raw.vce32", SF_FORMAT_RAW | SF_FORMAT_NMS_ADPCM_32, 1, 0.018) ; 450 sdlcomp_test_double ("raw.vce32", SF_FORMAT_RAW | SF_FORMAT_NMS_ADPCM_32, 1, 0.018) ; 451 452 test_count++ ; 453 } ; 454 /* Lite remove end */ 455 456 if (do_all || strcmp (argv [1], "ogg_vorbis") == 0) 457 { if (HAVE_EXTERNAL_XIPH_LIBS) 458 { /* Don't do lcomp_test_XXX as the errors are too big. */ 459 sdlcomp_test_short ("vorbis.oga", SF_FORMAT_OGG | SF_FORMAT_VORBIS, 1, 0.30) ; 460 sdlcomp_test_int ("vorbis.oga", SF_FORMAT_OGG | SF_FORMAT_VORBIS, 1, 0.30) ; 461 sdlcomp_test_float ("vorbis.oga", SF_FORMAT_OGG | SF_FORMAT_VORBIS, 1, 0.30) ; 462 sdlcomp_test_double ("vorbis.oga", SF_FORMAT_OGG | SF_FORMAT_VORBIS, 1, 0.30) ; 463 } 464 else 465 puts (" No Ogg/Vorbis tests because Ogg/Vorbis support was not compiled in.") ; 466 467 test_count++ ; 468 } ; 469 470 if (do_all || strcmp (argv [1], "ogg_opus") == 0) 471 { if (HAVE_EXTERNAL_XIPH_LIBS) 472 { /* Don't do lcomp_test_XXX as the errors are too big. */ 473 sdlcomp_test_short ("opus.opus", SF_FORMAT_OGG | SF_FORMAT_OPUS, 1, 0.57) ; 474 sdlcomp_test_int ("opus.opus", SF_FORMAT_OGG | SF_FORMAT_OPUS, 1, 0.54) ; 475 sdlcomp_test_float ("opus.opus", SF_FORMAT_OGG | SF_FORMAT_OPUS, 1, 0.55) ; 476 sdlcomp_test_double ("opus.opus", SF_FORMAT_OGG | SF_FORMAT_OPUS, 1, 0.55) ; 477 } 478 else 479 puts (" No Ogg/Opus tests because Ogg/Opus support was not compiled in.") ; 480 481 test_count++ ; 482 } ; 483 484 /* Lite remove start */ 485 if (do_all || strcmp (argv [1], "ircam_ulaw") == 0) 486 { lcomp_test_short ("ulaw.ircam", SF_ENDIAN_LITTLE | SF_FORMAT_IRCAM | SF_FORMAT_ULAW, 2, 0.04) ; 487 lcomp_test_int ("ulaw.ircam", SF_ENDIAN_BIG | SF_FORMAT_IRCAM | SF_FORMAT_ULAW, 2, 0.04) ; 488 lcomp_test_float ("ulaw.ircam", SF_ENDIAN_LITTLE | SF_FORMAT_IRCAM | SF_FORMAT_ULAW, 2, 0.04) ; 489 lcomp_test_double ("ulaw.ircam", SF_ENDIAN_BIG | SF_FORMAT_IRCAM | SF_FORMAT_ULAW, 2, 0.04) ; 490 test_count++ ; 491 } ; 492 493 if (do_all || strcmp (argv [1], "ircam_alaw") == 0) 494 { lcomp_test_short ("alaw.ircam", SF_ENDIAN_LITTLE | SF_FORMAT_IRCAM | SF_FORMAT_ALAW, 2, 0.04) ; 495 lcomp_test_int ("alaw.ircam", SF_ENDIAN_BIG | SF_FORMAT_IRCAM | SF_FORMAT_ALAW, 2, 0.04) ; 496 lcomp_test_float ("alaw.ircam", SF_ENDIAN_LITTLE | SF_FORMAT_IRCAM | SF_FORMAT_ALAW, 2, 0.04) ; 497 lcomp_test_double ("alaw.ircam", SF_ENDIAN_BIG | SF_FORMAT_IRCAM | SF_FORMAT_ALAW, 2, 0.04) ; 498 test_count++ ; 499 } ; 500 501 if (do_all || strcmp (argv [1], "nist_ulaw") == 0) 502 { lcomp_test_short ("ulaw.nist", SF_ENDIAN_LITTLE | SF_FORMAT_NIST | SF_FORMAT_ULAW, 2, 0.04) ; 503 lcomp_test_int ("ulaw.nist", SF_ENDIAN_BIG | SF_FORMAT_NIST | SF_FORMAT_ULAW, 2, 0.04) ; 504 lcomp_test_float ("ulaw.nist", SF_ENDIAN_LITTLE | SF_FORMAT_NIST | SF_FORMAT_ULAW, 2, 0.04) ; 505 lcomp_test_double ("ulaw.nist", SF_ENDIAN_BIG | SF_FORMAT_NIST | SF_FORMAT_ULAW, 2, 0.04) ; 506 test_count++ ; 507 } ; 508 509 if (do_all || strcmp (argv [1], "nist_alaw") == 0) 510 { lcomp_test_short ("alaw.nist", SF_ENDIAN_LITTLE | SF_FORMAT_NIST | SF_FORMAT_ALAW, 2, 0.04) ; 511 lcomp_test_int ("alaw.nist", SF_ENDIAN_BIG | SF_FORMAT_NIST | SF_FORMAT_ALAW, 2, 0.04) ; 512 lcomp_test_float ("alaw.nist", SF_ENDIAN_LITTLE | SF_FORMAT_NIST | SF_FORMAT_ALAW, 2, 0.04) ; 513 lcomp_test_double ("alaw.nist", SF_ENDIAN_BIG | SF_FORMAT_NIST | SF_FORMAT_ALAW, 2, 0.04) ; 514 test_count++ ; 515 } ; 516 517 if (do_all || strcmp (argv [1], "voc_ulaw") == 0) 518 { lcomp_test_short ("ulaw.voc", SF_FORMAT_VOC | SF_FORMAT_ULAW, 2, 0.04) ; 519 lcomp_test_int ("ulaw.voc", SF_FORMAT_VOC | SF_FORMAT_ULAW, 2, 0.04) ; 520 lcomp_test_float ("ulaw.voc", SF_FORMAT_VOC | SF_FORMAT_ULAW, 2, 0.04) ; 521 lcomp_test_double ("ulaw.voc", SF_FORMAT_VOC | SF_FORMAT_ULAW, 2, 0.04) ; 522 test_count++ ; 523 } ; 524 525 if (do_all || strcmp (argv [1], "voc_alaw") == 0) 526 { lcomp_test_short ("alaw.voc", SF_FORMAT_VOC | SF_FORMAT_ALAW, 2, 0.04) ; 527 lcomp_test_int ("alaw.voc", SF_FORMAT_VOC | SF_FORMAT_ALAW, 2, 0.04) ; 528 lcomp_test_float ("alaw.voc", SF_FORMAT_VOC | SF_FORMAT_ALAW, 2, 0.04) ; 529 lcomp_test_double ("alaw.voc", SF_FORMAT_VOC | SF_FORMAT_ALAW, 2, 0.04) ; 530 test_count++ ; 531 } ; 532 /* Lite remove end */ 533 534 if (do_all || strcmp (argv [1], "w64_ulaw") == 0) 535 { lcomp_test_short ("ulaw.w64", SF_FORMAT_W64 | SF_FORMAT_ULAW, 2, 0.04) ; 536 lcomp_test_int ("ulaw.w64", SF_FORMAT_W64 | SF_FORMAT_ULAW, 2, 0.04) ; 537 /* Lite remove start */ 538 lcomp_test_float ("ulaw.w64", SF_FORMAT_W64 | SF_FORMAT_ULAW, 2, 0.04) ; 539 lcomp_test_double ("ulaw.w64", SF_FORMAT_W64 | SF_FORMAT_ULAW, 2, 0.04) ; 540 /* Lite remove end */ 541 542 read_raw_test ("ulaw.w64", SF_FORMAT_W64 | SF_FORMAT_ULAW, 2) ; 543 test_count++ ; 544 } ; 545 546 if (do_all || strcmp (argv [1], "w64_alaw") == 0) 547 { lcomp_test_short ("alaw.w64", SF_FORMAT_W64 | SF_FORMAT_ALAW, 2, 0.04) ; 548 lcomp_test_int ("alaw.w64", SF_FORMAT_W64 | SF_FORMAT_ALAW, 2, 0.04) ; 549 /* Lite remove start */ 550 lcomp_test_float ("alaw.w64", SF_FORMAT_W64 | SF_FORMAT_ALAW, 2, 0.04) ; 551 lcomp_test_double ("alaw.w64", SF_FORMAT_W64 | SF_FORMAT_ALAW, 2, 0.04) ; 552 /* Lite remove end */ 553 554 read_raw_test ("alaw.w64", SF_FORMAT_W64 | SF_FORMAT_ALAW, 2) ; 555 test_count++ ; 556 } ; 557 558 /* Lite remove start */ 559 if (do_all || strcmp (argv [1], "w64_ima") == 0) 560 { lcomp_test_short ("ima.w64", SF_FORMAT_W64 | SF_FORMAT_IMA_ADPCM, 2, 0.18) ; 561 lcomp_test_int ("ima.w64", SF_FORMAT_W64 | SF_FORMAT_IMA_ADPCM, 2, 0.18) ; 562 lcomp_test_float ("ima.w64", SF_FORMAT_W64 | SF_FORMAT_IMA_ADPCM, 2, 0.18) ; 563 lcomp_test_double ("ima.w64", SF_FORMAT_W64 | SF_FORMAT_IMA_ADPCM, 2, 0.18) ; 564 565 sdlcomp_test_short ("ima.w64", SF_FORMAT_W64 | SF_FORMAT_IMA_ADPCM, 2, 0.18) ; 566 sdlcomp_test_int ("ima.w64", SF_FORMAT_W64 | SF_FORMAT_IMA_ADPCM, 2, 0.18) ; 567 sdlcomp_test_float ("ima.w64", SF_FORMAT_W64 | SF_FORMAT_IMA_ADPCM, 2, 0.18) ; 568 sdlcomp_test_double ("ima.w64", SF_FORMAT_W64 | SF_FORMAT_IMA_ADPCM, 2, 0.18) ; 569 test_count++ ; 570 } ; 571 572 if (do_all || strcmp (argv [1], "w64_msadpcm") == 0) 573 { lcomp_test_short ("msadpcm.w64", SF_FORMAT_W64 | SF_FORMAT_MS_ADPCM, 2, 0.36) ; 574 lcomp_test_int ("msadpcm.w64", SF_FORMAT_W64 | SF_FORMAT_MS_ADPCM, 2, 0.36) ; 575 lcomp_test_float ("msadpcm.w64", SF_FORMAT_W64 | SF_FORMAT_MS_ADPCM, 2, 0.36) ; 576 lcomp_test_double ("msadpcm.w64", SF_FORMAT_W64 | SF_FORMAT_MS_ADPCM, 2, 0.36) ; 577 578 sdlcomp_test_short ("msadpcm.w64", SF_FORMAT_W64 | SF_FORMAT_MS_ADPCM, 2, 0.36) ; 579 sdlcomp_test_int ("msadpcm.w64", SF_FORMAT_W64 | SF_FORMAT_MS_ADPCM, 2, 0.36) ; 580 sdlcomp_test_float ("msadpcm.w64", SF_FORMAT_W64 | SF_FORMAT_MS_ADPCM, 2, 0.36) ; 581 sdlcomp_test_double ("msadpcm.w64", SF_FORMAT_W64 | SF_FORMAT_MS_ADPCM, 2, 0.36) ; 582 test_count++ ; 583 } ; 584 585 if (do_all || strcmp (argv [1], "wve") == 0) 586 { lcomp_test_short ("psion.wve", SF_FORMAT_WVE | SF_FORMAT_ALAW, 1, 0.04) ; 587 lcomp_test_int ("psion.wve", SF_FORMAT_WVE | SF_FORMAT_ALAW, 1, 0.04) ; 588 /* Lite remove start */ 589 lcomp_test_float ("psion.wve", SF_FORMAT_WVE | SF_FORMAT_ALAW, 1, 0.04) ; 590 lcomp_test_double ("psion.wve", SF_FORMAT_WVE | SF_FORMAT_ALAW, 1, 0.04) ; 591 /* Lite remove end */ 592 test_count++ ; 593 } ; 594 595 /* Lite remove end */ 596 597 if (do_all || strcmp (argv [1], "w64_gsm610") == 0) 598 { /* Don't do lcomp_test_XXX as the errors are too big. */ 599 sdlcomp_test_short ("gsm610.w64", SF_FORMAT_W64 | SF_FORMAT_GSM610, 1, 0.2) ; 600 sdlcomp_test_int ("gsm610.w64", SF_FORMAT_W64 | SF_FORMAT_GSM610, 1, 0.2) ; 601 /* Lite remove start */ 602 sdlcomp_test_float ("gsm610.w64", SF_FORMAT_W64 | SF_FORMAT_GSM610, 1, 0.2) ; 603 sdlcomp_test_double ("gsm610.w64", SF_FORMAT_W64 | SF_FORMAT_GSM610, 1, 0.2) ; 604 /* Lite remove end */ 605 test_count++ ; 606 } ; 607 608 /* Lite remove start */ 609 if (do_all || strcmp (argv [1], "vox_adpcm") == 0) 610 { lcomp_test_short ("adpcm.vox", SF_FORMAT_RAW | SF_FORMAT_VOX_ADPCM, 1, 0.17) ; 611 lcomp_test_int ("adpcm.vox", SF_FORMAT_RAW | SF_FORMAT_VOX_ADPCM, 1, 0.17) ; 612 lcomp_test_float ("adpcm.vox", SF_FORMAT_RAW | SF_FORMAT_VOX_ADPCM, 1, 0.17) ; 613 lcomp_test_double ("adpcm.vox", SF_FORMAT_RAW | SF_FORMAT_VOX_ADPCM, 1, 0.17) ; 614 615 sdlcomp_test_short ("adpcm.vox", SF_FORMAT_RAW | SF_FORMAT_VOX_ADPCM, 1, 0.072) ; 616 sdlcomp_test_int ("adpcm.vox", SF_FORMAT_RAW | SF_FORMAT_VOX_ADPCM, 1, 0.072) ; 617 sdlcomp_test_float ("adpcm.vox", SF_FORMAT_RAW | SF_FORMAT_VOX_ADPCM, 1, 0.072) ; 618 sdlcomp_test_double ("adpcm.vox", SF_FORMAT_RAW | SF_FORMAT_VOX_ADPCM, 1, 0.072) ; 619 test_count++ ; 620 } ; 621 622 if (do_all || strcmp (argv [1], "xi_dpcm") == 0) 623 { lcomp_test_short ("8bit.xi", SF_FORMAT_XI | SF_FORMAT_DPCM_8, 1, 0.25) ; 624 lcomp_test_int ("8bit.xi", SF_FORMAT_XI | SF_FORMAT_DPCM_8, 1, 0.25) ; 625 626 lcomp_test_short ("16bit.xi", SF_FORMAT_XI | SF_FORMAT_DPCM_16, 1, 0.002) ; 627 lcomp_test_int ("16bit.xi", SF_FORMAT_XI | SF_FORMAT_DPCM_16, 1, 0.002) ; 628 lcomp_test_float ("16bit.xi", SF_FORMAT_XI | SF_FORMAT_DPCM_16, 1, 0.002) ; 629 lcomp_test_double ("16bit.xi", SF_FORMAT_XI | SF_FORMAT_DPCM_16, 1, 0.002) ; 630 test_count++ ; 631 } ; 632 /* Lite remove end */ 633 634 if (test_count == 0) 635 { printf ("************************************\n") ; 636 printf ("* No '%s' test defined.\n", argv [1]) ; 637 printf ("************************************\n") ; 638 return 1 ; 639 } ; 640 641 return 0 ; 642} /* main */ 643 644/*============================================================================================ 645** Here are the test functions. 646*/ 647 648static void 649lcomp_test_short (const char *filename, int filetype, int channels, double margin) 650{ SNDFILE *file ; 651 SF_INFO sfinfo ; 652 int k, m, seekpos, half_max_abs ; 653 sf_count_t datalen ; 654 short *orig, *data ; 655 656 get_unique_test_name (&filename, LCT_TEST_PREFIX) ; 657 print_test_name ("lcomp_test_short", filename) ; 658 659 datalen = BUFFER_SIZE / channels ; 660 661 data = data_buffer.s ; 662 orig = orig_buffer.s ; 663 664 gen_signal_double (orig_buffer.d, 32000.0, channels, (int) datalen) ; 665 for (k = 0 ; k < channels * datalen ; k++) 666 orig [k] = (short) (orig_buffer.d [k]) ; 667 668 sfinfo.samplerate = SAMPLE_RATE ; 669 sfinfo.frames = 123456789 ; /* Ridiculous value. */ 670 sfinfo.channels = channels ; 671 sfinfo.format = filetype ; 672 673 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ; 674 test_writef_short_or_die (file, 0, orig, datalen, __LINE__) ; 675 sf_set_string (file, SF_STR_COMMENT, long_comment) ; 676 sf_close (file) ; 677 678 memset (data, 0, datalen * sizeof (short)) ; 679 680 if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW) 681 memset (&sfinfo, 0, sizeof (sfinfo)) ; 682 683 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ; 684 685 if ((sfinfo.format & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)) != (filetype & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK))) 686 { printf ("\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, filetype, sfinfo.format) ; 687 exit (1) ; 688 } ; 689 690 if (sfinfo.frames < datalen / channels) 691 { printf ("Too few frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", sfinfo.frames, datalen) ; 692 exit (1) ; 693 } ; 694 695 if (sfinfo.frames > (datalen + datalen / 20)) 696 { printf ("Too many frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", sfinfo.frames, datalen) ; 697 exit (1) ; 698 } ; 699 700 if (sfinfo.channels != channels) 701 { printf ("Incorrect number of channels in file.\n") ; 702 exit (1) ; 703 } ; 704 705 check_log_buffer_or_die (file, __LINE__) ; 706 707 check_comment (file, filetype, __LINE__) ; 708 709 test_readf_short_or_die (file, 0, data, datalen, __LINE__) ; 710 711 half_max_abs = 0 ; 712 for (k = 0 ; k < datalen ; k++) 713 { if (error_function (data [k], orig [k], margin)) 714 { printf ("\n\nLine %d: Incorrect sample A (#%d : %d should be %d).\n", __LINE__, k, data [k], orig [k]) ; 715 oct_save_short (orig, data, (int) datalen) ; 716 exit (1) ; 717 } ; 718 half_max_abs = LCT_MAX (half_max_abs, abs (data [k] / 2)) ; 719 } ; 720 721 if (half_max_abs < 1.0) 722 { printf ("\n\nLine %d: Signal is all zeros.\n", __LINE__) ; 723 exit (1) ; 724 } ; 725 726 if ((k = (int) sf_readf_short (file, data, datalen)) != sfinfo.frames - datalen) 727 { printf ("\n\nLine %d: Incorrect read length (%" PRId64 " should be %d).\n", __LINE__, 728 channels * sfinfo.frames - datalen, k) ; 729 exit (1) ; 730 } ; 731 732 /* This check is only for block based encoders which must append silence 733 ** to the end of a file so as to fill out a block. 734 */ 735 for (k = 0 ; k < sfinfo.frames - datalen ; k++) 736 if (abs (data [channels * k]) > decay_response (channels * k)) 737 { printf ("\n\nLine %d : Incorrect sample B (#%d : abs (%d) should be < %d).\n", __LINE__, channels * k, data [channels * k], decay_response (channels * k)) ; 738 exit (1) ; 739 } ; 740 741 if (! sfinfo.seekable) 742 { sf_close (file) ; 743 unlink (filename) ; 744 printf ("ok\n") ; 745 return ; 746 } ; 747 748 /* Now test sf_seek function. */ 749 750 if ((k = (int) sf_seek (file, 0, SEEK_SET)) != 0) 751 { printf ("\n\nLine %d: Seek to start of file failed (%d).\n", __LINE__, k) ; 752 exit (1) ; 753 } ; 754 755 for (m = 0 ; m < 3 ; m++) 756 { test_readf_short_or_die (file, m, data, 11, __LINE__) ; 757 758 for (k = 0 ; k < channels * 11 ; k++) 759 if (error_function (1.0 * data [k], 1.0 * orig [k + channels * m * 11], margin)) 760 { printf ("\n\nLine %d: Incorrect sample (m = %d) (#%d : %d => %d).\n", __LINE__, m, k + channels * m * 11, orig [k + channels * m * 11], data [k]) ; 761 for (m = 0 ; m < channels ; m++) 762 printf ("%d ", data [m]) ; 763 printf ("\n") ; 764 exit (1) ; 765 } ; 766 } ; 767 768 seekpos = BUFFER_SIZE / 10 ; 769 770 /* Check seek from start of file. */ 771 if ((k = (int) sf_seek (file, seekpos, SEEK_SET)) != seekpos) 772 { printf ("Seek to start of file + %d failed (%d).\n", seekpos, k) ; 773 exit (1) ; 774 } ; 775 776 test_readf_short_or_die (file, 0, data, 1, __LINE__) ; 777 778 if (error_function (1.0 * data [0], 1.0 * orig [seekpos * channels], margin)) 779 { printf ("\n\nLine %d: sf_seek (SEEK_SET) followed by sf_readf_short failed (%d, %d).\n", __LINE__, orig [1], data [0]) ; 780 exit (1) ; 781 } ; 782 783 if ((k = (int) sf_seek (file, 0, SEEK_CUR)) != seekpos + 1) 784 { printf ("\n\nLine %d: sf_seek (SEEK_CUR) with 0 offset failed (%d should be %d)\n", __LINE__, k, seekpos + 1) ; 785 exit (1) ; 786 } ; 787 788 seekpos = (int) sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ; 789 k = (int) sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ; 790 test_readf_short_or_die (file, 0, data, 1, __LINE__) ; 791 if (error_function (1.0 * data [0], 1.0 * orig [seekpos * channels], margin) || k != seekpos) 792 { printf ("\n\nLine %d: sf_seek (forwards, SEEK_CUR) followed by sf_readf_short failed (%d, %d) (%d, %d).\n", __LINE__, data [0], orig [seekpos * channels], k, seekpos + 1) ; 793 oct_save_short (orig, data, (int) datalen) ; 794 exit (1) ; 795 } ; 796 797 seekpos = (int) sf_seek (file, 0, SEEK_CUR) - 20 ; 798 /* Check seek backward from current position. */ 799 k = (int) sf_seek (file, -20, SEEK_CUR) ; 800 test_readf_short_or_die (file, 0, data, 1, __LINE__) ; 801 if (error_function (1.0 * data [0], 1.0 * orig [seekpos * channels], margin) || k != seekpos) 802 { printf ("\nLine %d: sf_seek (backwards, SEEK_CUR) followed by sf_readf_short failed (%d, %d) (%d, %d).\n", __LINE__, data [0], orig [seekpos * channels], k, seekpos) ; 803 exit (1) ; 804 } ; 805 806 /* Check that read past end of file returns number of items. */ 807 sf_seek (file, sfinfo.frames, SEEK_SET) ; 808 809 if ((k = (int) sf_readf_short (file, data, datalen)) != 0) 810 { printf ("\n\nLine %d: Return value from sf_readf_short past end of file incorrect (%d).\n", __LINE__, k) ; 811 exit (1) ; 812 } ; 813 814 /* Check seek backward from end. */ 815 if ((k = (int) sf_seek (file, 5 - sfinfo.frames, SEEK_END)) != 5) 816 { printf ("\n\nLine %d: sf_seek (SEEK_END) returned %d instead of %d.\n", __LINE__, k, 5) ; 817 exit (1) ; 818 } ; 819 820 test_readf_short_or_die (file, 0, data, 1, __LINE__) ; 821 if (error_function (1.0 * data [0], 1.0 * orig [5 * channels], margin)) 822 { printf ("\nLine %d: sf_seek (SEEK_END) followed by sf_readf_short failed (%d should be %d).\n", __LINE__, data [0], orig [5 * channels]) ; 823 exit (1) ; 824 } ; 825 826 sf_close (file) ; 827 828 unlink (filename) ; 829 printf ("ok\n") ; 830} /* lcomp_test_short */ 831 832/*-------------------------------------------------------------------------------------------- 833*/ 834 835static void 836lcomp_test_int (const char *filename, int filetype, int channels, double margin) 837{ SNDFILE *file ; 838 SF_INFO sfinfo ; 839 int k, m, half_max_abs ; 840 sf_count_t datalen, seekpos ; 841 double scale, max_val ; 842 int *orig, *data ; 843 844 get_unique_test_name (&filename, LCT_TEST_PREFIX) ; 845 print_test_name ("lcomp_test_int", filename) ; 846 847 datalen = BUFFER_SIZE / channels ; 848 849 if (is_lossy (filetype)) 850 { scale = 1.0 * 0x10000 ; 851 max_val = 32000.0 * scale ; 852 } 853 else 854 { scale = 1.0 ; 855 max_val = 0x7fffffff * scale ; 856 } ; 857 858 data = data_buffer.i ; 859 orig = orig_buffer.i ; 860 861 gen_signal_double (orig_buffer.d, max_val, channels, (int) datalen) ; 862 863 for (k = 0 ; k < channels * datalen ; k++) 864 orig [k] = lrint (orig_buffer.d [k]) ; 865 866 sfinfo.samplerate = SAMPLE_RATE ; 867 sfinfo.frames = 123456789 ; /* Ridiculous value. */ 868 sfinfo.channels = channels ; 869 sfinfo.format = filetype ; 870 871 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ; 872 test_writef_int_or_die (file, 0, orig, datalen, __LINE__) ; 873 sf_set_string (file, SF_STR_COMMENT, long_comment) ; 874 sf_close (file) ; 875 876 memset (data, 0, datalen * sizeof (int)) ; 877 878 if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW) 879 memset (&sfinfo, 0, sizeof (sfinfo)) ; 880 881 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ; 882 883 if ((sfinfo.format & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)) != (filetype & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK))) 884 { printf ("\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, filetype, sfinfo.format) ; 885 exit (1) ; 886 } ; 887 888 if (sfinfo.frames < datalen / channels) 889 { printf ("Too few.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", datalen, sfinfo.frames) ; 890 exit (1) ; 891 } ; 892 893 if (sfinfo.frames > (datalen + datalen / 20)) 894 { printf ("Too many.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", datalen, sfinfo.frames) ; 895 exit (1) ; 896 } ; 897 898 if (sfinfo.channels != channels) 899 { printf ("Incorrect number of channels in file.\n") ; 900 exit (1) ; 901 } ; 902 903 check_log_buffer_or_die (file, __LINE__) ; 904 905 check_comment (file, filetype, __LINE__) ; 906 907 test_readf_int_or_die (file, 0, data, datalen, __LINE__) ; 908 909 half_max_abs = 0 ; 910 for (k = 0 ; k < datalen ; k++) 911 { if (error_function (data [k] / scale, orig [k] / scale, margin)) 912 { printf ("\nLine %d: Incorrect sample (#%d : %f should be %f).\n", __LINE__, k, data [k] / scale, orig [k] / scale) ; 913 oct_save_int (orig, data, (int) datalen) ; 914 exit (1) ; 915 } ; 916 half_max_abs = LCT_MAX (half_max_abs, abs (data [k] / 2)) ; 917 } ; 918 919 if (half_max_abs < 1.0) 920 { printf ("\n\nLine %d: Signal is all zeros (%d, 0x%X).\n", __LINE__, half_max_abs, half_max_abs) ; 921 exit (1) ; 922 } ; 923 924 if ((k = (int) sf_readf_int (file, data, datalen)) != sfinfo.frames - datalen) 925 { printf ("\n\nLine %d: Incorrect read length (%" PRId64 " should be %d).\n", __LINE__, 926 channels * sfinfo.frames - datalen, k) ; 927 exit (1) ; 928 } ; 929 930 /* This check is only for block based encoders which must append silence 931 ** to the end of a file so as to fill out a block. 932 */ 933 if ((sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_MS_ADPCM) 934 for (k = 0 ; k < sfinfo.frames - datalen ; k++) 935 if (ABS (data [channels * k] / scale) > decay_response (channels * k)) 936 { printf ("\n\nLine %d : Incorrect sample B (#%d : abs (%d) should be < %d).\n", __LINE__, channels * k, data [channels * k], decay_response (channels * k)) ; 937 exit (1) ; 938 } ; 939 940 if (! sfinfo.seekable) 941 { sf_close (file) ; 942 unlink (filename) ; 943 printf ("ok\n") ; 944 return ; 945 } ; 946 947 /* Now test sf_seek function. */ 948 949 if ((k = (int) sf_seek (file, 0, SEEK_SET)) != 0) 950 { printf ("\n\nLine %d: Seek to start of file failed (%d).\n", __LINE__, k) ; 951 exit (1) ; 952 } ; 953 954 for (m = 0 ; m < 3 ; m++) 955 { test_readf_int_or_die (file, m, data, 11, __LINE__) ; 956 957 for (k = 0 ; k < channels * 11 ; k++) 958 if (error_function (data [k] / scale, orig [k + channels * m * 11] / scale, margin)) 959 { printf ("\nLine %d: Incorrect sample (m = %d) (#%d : %d => %d).\n", __LINE__, m, k + channels * m * 11, orig [k + channels * m * 11], data [k]) ; 960 for (m = 0 ; m < channels ; m++) 961 printf ("%d ", data [m]) ; 962 printf ("\n") ; 963 exit (1) ; 964 } ; 965 } ; 966 967 seekpos = BUFFER_SIZE / 10 ; 968 969 /* Check seek from start of file. */ 970 if ((k = (int) sf_seek (file, seekpos, SEEK_SET)) != seekpos) 971 { printf ("Seek to start of file + %" PRId64 " failed (%d).\n", seekpos, k) ; 972 exit (1) ; 973 } ; 974 975 test_readf_int_or_die (file, 0, data, 1, __LINE__) ; 976 977 if (error_function (1.0 * data [0], 1.0 * orig [seekpos * channels], margin)) 978 { printf ("\nLine %d: sf_seek (SEEK_SET) followed by sf_readf_int failed (%d, %d).\n", __LINE__, orig [1], data [0]) ; 979 exit (1) ; 980 } ; 981 982 if ((k = (int) sf_seek (file, 0, SEEK_CUR)) != seekpos + 1) 983 { printf ("\n\nLine %d: sf_seek (SEEK_CUR) with 0 offset failed (%d should be %" PRId64 ")\n", __LINE__, k, seekpos + 1) ; 984 exit (1) ; 985 } ; 986 987 seekpos = sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ; 988 k = (int) sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ; 989 test_readf_int_or_die (file, 0, data, 1, __LINE__) ; 990 if (error_function (1.0 * data [0], 1.0 * orig [seekpos * channels], margin) || k != seekpos) 991 { printf ("\nLine %d: sf_seek (forwards, SEEK_CUR) followed by sf_readf_int failed (%d, %d) (%d, %" PRId64 ").\n", __LINE__, data [0], orig [seekpos * channels], k, seekpos + 1) ; 992 exit (1) ; 993 } ; 994 995 seekpos = sf_seek (file, 0, SEEK_CUR) - 20 ; 996 /* Check seek backward from current position. */ 997 k = (int) sf_seek (file, -20, SEEK_CUR) ; 998 test_readf_int_or_die (file, 0, data, 1, __LINE__) ; 999 if (error_function (1.0 * data [0], 1.0 * orig [seekpos * channels], margin) || k != seekpos) 1000 { printf ("\nLine %d: sf_seek (backwards, SEEK_CUR) followed by sf_readf_int failed (%d, %d) (%d, %" PRId64 ").\n", __LINE__, data [0], orig [seekpos * channels], k, seekpos) ; 1001 exit (1) ; 1002 } ; 1003 1004 /* Check that read past end of file returns number of items. */ 1005 sf_seek (file, sfinfo.frames, SEEK_SET) ; 1006 1007 if ((k = (int) sf_readf_int (file, data, datalen)) != 0) 1008 { printf ("\n\nLine %d: Return value from sf_readf_int past end of file incorrect (%d).\n", __LINE__, k) ; 1009 exit (1) ; 1010 } ; 1011 1012 /* Check seek backward from end. */ 1013 if ((k = (int) sf_seek (file, 5 - sfinfo.frames, SEEK_END)) != 5) 1014 { printf ("\n\nLine %d: sf_seek (SEEK_END) returned %d instead of %d.\n", __LINE__, k, 5) ; 1015 exit (1) ; 1016 } ; 1017 1018 test_readf_int_or_die (file, 0, data, 1, __LINE__) ; 1019 if (error_function (data [0] / scale, orig [5 * channels] / scale, margin)) 1020 { printf ("\nLine %d: sf_seek (SEEK_END) followed by sf_readf_short failed (%d should be %d).\n", __LINE__, data [0], orig [5]) ; 1021 exit (1) ; 1022 } ; 1023 1024 sf_close (file) ; 1025 1026 unlink (filename) ; 1027 printf ("ok\n") ; 1028} /* lcomp_test_int */ 1029 1030/*-------------------------------------------------------------------------------------------- 1031*/ 1032 1033static void 1034lcomp_test_float (const char *filename, int filetype, int channels, double margin) 1035{ SNDFILE *file ; 1036 SF_INFO sfinfo ; 1037 int k, m, seekpos ; 1038 sf_count_t datalen ; 1039 float *orig, *data ; 1040 double half_max_abs ; 1041 1042 get_unique_test_name (&filename, LCT_TEST_PREFIX) ; 1043 print_test_name ("lcomp_test_float", filename) ; 1044 1045 datalen = BUFFER_SIZE / channels ; 1046 1047 data = data_buffer.f ; 1048 orig = orig_buffer.f ; 1049 1050 gen_signal_double (orig_buffer.d, 32000.0, channels, (int) datalen) ; 1051 for (k = 0 ; k < channels * datalen ; k++) 1052 orig [k] = (float) orig_buffer.d [k] ; 1053 1054 sfinfo.samplerate = SAMPLE_RATE ; 1055 sfinfo.frames = 123456789 ; /* Ridiculous value. */ 1056 sfinfo.channels = channels ; 1057 sfinfo.format = filetype ; 1058 1059 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ; 1060 sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ; 1061 test_writef_float_or_die (file, 0, orig, datalen, __LINE__) ; 1062 sf_set_string (file, SF_STR_COMMENT, long_comment) ; 1063 sf_close (file) ; 1064 1065 memset (data, 0, datalen * sizeof (float)) ; 1066 1067 if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW) 1068 memset (&sfinfo, 0, sizeof (sfinfo)) ; 1069 1070 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ; 1071 1072 if ((sfinfo.format & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)) != (filetype & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK))) 1073 { printf ("\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, filetype, sfinfo.format) ; 1074 exit (1) ; 1075 } ; 1076 1077 if (sfinfo.frames < datalen / channels) 1078 { printf ("Too few.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", datalen, sfinfo.frames) ; 1079 exit (1) ; 1080 } ; 1081 1082 if (sfinfo.frames > (datalen + datalen / 20)) 1083 { printf ("Too many.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", datalen, sfinfo.frames) ; 1084 exit (1) ; 1085 } ; 1086 1087 if (sfinfo.channels != channels) 1088 { printf ("Incorrect number of channels in file.\n") ; 1089 exit (1) ; 1090 } ; 1091 1092 check_comment (file, filetype, __LINE__) ; 1093 1094 sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ; 1095 1096 check_log_buffer_or_die (file, __LINE__) ; 1097 1098 check_comment (file, filetype, __LINE__) ; 1099 1100 sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ; 1101 1102 test_readf_float_or_die (file, 0, data, datalen, __LINE__) ; 1103 1104 half_max_abs = 0.0 ; 1105 for (k = 0 ; k < datalen ; k++) 1106 { if (error_function (data [k], orig [k], margin)) 1107 { printf ("\nLine %d: Incorrect sample A (#%d : %f should be %f).\n", __LINE__, k, data [k], orig [k]) ; 1108 oct_save_float (orig, data, (int) datalen) ; 1109 exit (1) ; 1110 } ; 1111 half_max_abs = LCT_MAX (half_max_abs, fabs (0.5 * data [k])) ; 1112 } ; 1113 1114 if (half_max_abs < 1.0) 1115 { printf ("\n\nLine %d: Signal is all zeros.\n", __LINE__) ; 1116 exit (1) ; 1117 } ; 1118 1119 if ((k = (int) sf_readf_float (file, data, datalen)) != sfinfo.frames - datalen) 1120 { printf ("\n\nLine %d: Incorrect read length (%" PRId64 " should be %d).\n", __LINE__, 1121 channels * sfinfo.frames - datalen, k) ; 1122 exit (1) ; 1123 } ; 1124 1125 /* This check is only for block based encoders which must append silence 1126 ** to the end of a file so as to fill out a block. 1127 */ 1128 if ((sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_MS_ADPCM) 1129 for (k = 0 ; k < sfinfo.frames - datalen ; k++) 1130 if (ABS (data [channels * k]) > decay_response (channels * k)) 1131 { printf ("\n\nLine %d : Incorrect sample B (#%d : abs (%f) should be < %d).\n", __LINE__, channels * k, data [channels * k], decay_response (channels * k)) ; 1132 exit (1) ; 1133 } ; 1134 1135 if (! sfinfo.seekable) 1136 { sf_close (file) ; 1137 unlink (filename) ; 1138 printf ("ok\n") ; 1139 return ; 1140 } ; 1141 1142 /* Now test sf_seek function. */ 1143 1144 if ((k = (int) sf_seek (file, 0, SEEK_SET)) != 0) 1145 { printf ("\n\nLine %d: Seek to start of file failed (%d).\n", __LINE__, k) ; 1146 exit (1) ; 1147 } ; 1148 1149 for (m = 0 ; m < 3 ; m++) 1150 { test_readf_float_or_die (file, 0, data, 11, __LINE__) ; 1151 1152 for (k = 0 ; k < channels * 11 ; k++) 1153 if (error_function (data [k], orig [k + channels * m * 11], margin)) 1154 { printf ("\nLine %d: Incorrect sample (m = %d) (#%d : %f => %f).\n", __LINE__, m, k + channels * m * 11, orig [k + channels * m * 11], data [k]) ; 1155 for (m = 0 ; m < channels ; m++) 1156 printf ("%f ", data [m]) ; 1157 printf ("\n") ; 1158 exit (1) ; 1159 } ; 1160 } ; 1161 1162 seekpos = BUFFER_SIZE / 10 ; 1163 1164 /* Check seek from start of file. */ 1165 if ((k = (int) sf_seek (file, seekpos, SEEK_SET)) != seekpos) 1166 { printf ("Seek to start of file + %d failed (%d).\n", seekpos, k) ; 1167 exit (1) ; 1168 } ; 1169 1170 test_readf_float_or_die (file, 0, data, 1, __LINE__) ; 1171 1172 if (error_function (data [0], orig [seekpos * channels], margin)) 1173 { printf ("\nLine %d: sf_seek (SEEK_SET) followed by sf_readf_float failed (%f, %f).\n", __LINE__, orig [1], data [0]) ; 1174 exit (1) ; 1175 } ; 1176 1177 if ((k = (int) sf_seek (file, 0, SEEK_CUR)) != seekpos + 1) 1178 { printf ("\n\nLine %d: sf_seek (SEEK_CUR) with 0 offset failed (%d should be %d)\n", __LINE__, k, seekpos + 1) ; 1179 exit (1) ; 1180 } ; 1181 1182 seekpos = (int) sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ; 1183 k = (int) sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ; 1184 test_readf_float_or_die (file, 0, data, 1, __LINE__) ; 1185 if (error_function (data [0], orig [seekpos * channels], margin) || k != seekpos) 1186 { printf ("\nLine %d: sf_seek (forwards, SEEK_CUR) followed by sf_readf_float failed (%f, %f) (%d, %d).\n", __LINE__, data [0], orig [seekpos * channels], k, seekpos + 1) ; 1187 exit (1) ; 1188 } ; 1189 1190 seekpos = (int) sf_seek (file, 0, SEEK_CUR) - 20 ; 1191 /* Check seek backward from current position. */ 1192 k = (int) sf_seek (file, -20, SEEK_CUR) ; 1193 test_readf_float_or_die (file, 0, data, 1, __LINE__) ; 1194 if (error_function (data [0], orig [seekpos * channels], margin) || k != seekpos) 1195 { printf ("\nLine %d: sf_seek (backwards, SEEK_CUR) followed by sf_readf_float failed (%f, %f) (%d, %d).\n", __LINE__, data [0], orig [seekpos * channels], k, seekpos) ; 1196 exit (1) ; 1197 } ; 1198 1199 /* Check that read past end of file returns number of items. */ 1200 sf_seek (file, sfinfo.frames, SEEK_SET) ; 1201 1202 if ((k = (int) sf_readf_float (file, data, datalen)) != 0) 1203 { printf ("\n\nLine %d: Return value from sf_readf_float past end of file incorrect (%d).\n", __LINE__, k) ; 1204 exit (1) ; 1205 } ; 1206 1207 /* Check seek backward from end. */ 1208 if ((k = (int) sf_seek (file, 5 - sfinfo.frames, SEEK_END)) != 5) 1209 { printf ("\n\nLine %d: sf_seek (SEEK_END) returned %d instead of %d.\n", __LINE__, k, 5) ; 1210 exit (1) ; 1211 } ; 1212 1213 test_readf_float_or_die (file, 0, data, 1, __LINE__) ; 1214 if (error_function (data [0], orig [5 * channels], margin)) 1215 { printf ("\nLine %d: sf_seek (SEEK_END) followed by sf_readf_short failed (%f should be %f).\n", __LINE__, data [0], orig [5 * channels]) ; 1216 exit (1) ; 1217 } ; 1218 1219 sf_close (file) ; 1220 1221 unlink (filename) ; 1222 printf ("ok\n") ; 1223} /* lcomp_test_float */ 1224 1225/*-------------------------------------------------------------------------------------------- 1226*/ 1227 1228static void 1229lcomp_test_double (const char *filename, int filetype, int channels, double margin) 1230{ SNDFILE *file ; 1231 SF_INFO sfinfo ; 1232 int k, m, seekpos ; 1233 sf_count_t datalen ; 1234 double *orig, *data ; 1235 double half_max_abs ; 1236 1237 get_unique_test_name (&filename, LCT_TEST_PREFIX) ; 1238 print_test_name ("lcomp_test_double", filename) ; 1239 1240 datalen = BUFFER_SIZE / channels ; 1241 1242 data = data_buffer.d ; 1243 orig = orig_buffer.d ; 1244 1245 gen_signal_double (orig_buffer.d, 32000.0, channels, (int) datalen) ; 1246 for (k = 0 ; k < channels * datalen ; k++) 1247 orig [k] = orig_buffer.d [k] ; 1248 1249 sfinfo.samplerate = SAMPLE_RATE ; 1250 sfinfo.frames = 123456789 ; /* Ridiculous value. */ 1251 sfinfo.channels = channels ; 1252 sfinfo.format = filetype ; 1253 1254 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ; 1255 sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ; 1256 test_writef_double_or_die (file, 0, orig, datalen, __LINE__) ; 1257 sf_set_string (file, SF_STR_COMMENT, long_comment) ; 1258 sf_close (file) ; 1259 1260 memset (data, 0, datalen * sizeof (double)) ; 1261 1262 if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW) 1263 memset (&sfinfo, 0, sizeof (sfinfo)) ; 1264 1265 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ; 1266 1267 if ((sfinfo.format & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)) != (filetype & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK))) 1268 { printf ("\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, filetype, sfinfo.format) ; 1269 exit (1) ; 1270 } ; 1271 1272 if (sfinfo.frames < datalen / channels) 1273 { printf ("Too few.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", datalen, sfinfo.frames) ; 1274 exit (1) ; 1275 } ; 1276 1277 if (sfinfo.frames > (datalen + datalen / 20)) 1278 { printf ("Too many.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", datalen, sfinfo.frames) ; 1279 exit (1) ; 1280 } ; 1281 1282 if (sfinfo.channels != channels) 1283 { printf ("Incorrect number of channels in file.\n") ; 1284 exit (1) ; 1285 } ; 1286 1287 check_comment (file, filetype, __LINE__) ; 1288 1289 sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ; 1290 1291 check_log_buffer_or_die (file, __LINE__) ; 1292 1293 check_comment (file, filetype, __LINE__) ; 1294 1295 sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ; 1296 1297 test_readf_double_or_die (file, 0, data, datalen, __LINE__) ; 1298 1299 half_max_abs = 0.0 ; 1300 for (k = 0 ; k < datalen ; k++) 1301 { if (error_function (data [k], orig [k], margin)) 1302 { printf ("\nLine %d: Incorrect sample A (#%d : %f should be %f).\n", __LINE__, k, data [k], orig [k]) ; 1303 oct_save_double (orig, data, (int) datalen) ; 1304 exit (1) ; 1305 } ; 1306 half_max_abs = LCT_MAX (half_max_abs, ABS (0.5 * data [k])) ; 1307 } ; 1308 1309 if (half_max_abs < 1.0) 1310 { printf ("\n\nLine %d: Signal is all zeros.\n", __LINE__) ; 1311 exit (1) ; 1312 } ; 1313 1314 if ((k = (int) sf_readf_double (file, data, datalen)) != sfinfo.frames - datalen) 1315 { printf ("\n\nLine %d: Incorrect read length (%" PRId64 " should be %d).\n", __LINE__, 1316 channels * sfinfo.frames - datalen, k) ; 1317 exit (1) ; 1318 } ; 1319 1320 /* This check is only for block based encoders which must append silence 1321 ** to the end of a file so as to fill out a block. 1322 */ 1323 if ((sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_MS_ADPCM) 1324 for (k = 0 ; k < sfinfo.frames - datalen ; k++) 1325 if (ABS (data [channels * k]) > decay_response (channels * k)) 1326 { printf ("\n\nLine %d : Incorrect sample B (#%d : abs (%f) should be < %d).\n", __LINE__, channels * k, data [channels * k], decay_response (channels * k)) ; 1327 exit (1) ; 1328 } ; 1329 1330 if (! sfinfo.seekable) 1331 { sf_close (file) ; 1332 unlink (filename) ; 1333 printf ("ok\n") ; 1334 return ; 1335 } ; 1336 1337 /* Now test sf_seek function. */ 1338 1339 if ((k = (int) sf_seek (file, 0, SEEK_SET)) != 0) 1340 { printf ("\n\nLine %d: Seek to start of file failed (%d).\n", __LINE__, k) ; 1341 exit (1) ; 1342 } ; 1343 1344 for (m = 0 ; m < 3 ; m++) 1345 { test_readf_double_or_die (file, m, data, 11, __LINE__) ; 1346 1347 for (k = 0 ; k < channels * 11 ; k++) 1348 if (error_function (data [k], orig [k + channels * m * 11], margin)) 1349 { printf ("\nLine %d: Incorrect sample (m = %d) (#%d : %f => %f).\n", __LINE__, m, k + channels * m * 11, orig [k + channels * m * 11], data [k]) ; 1350 for (m = 0 ; m < channels ; m++) 1351 printf ("%f ", data [m]) ; 1352 printf ("\n") ; 1353 exit (1) ; 1354 } ; 1355 } ; 1356 1357 seekpos = BUFFER_SIZE / 10 ; 1358 1359 /* Check seek from start of file. */ 1360 if ((k = (int) sf_seek (file, seekpos, SEEK_SET)) != seekpos) 1361 { printf ("Seek to start of file + %d failed (%d).\n", seekpos, k) ; 1362 exit (1) ; 1363 } ; 1364 1365 test_readf_double_or_die (file, 0, data, 1, __LINE__) ; 1366 1367 if (error_function (data [0], orig [seekpos * channels], margin)) 1368 { printf ("\nLine %d: sf_seek (SEEK_SET) followed by sf_readf_double failed (%f, %f).\n", __LINE__, orig [1], data [0]) ; 1369 exit (1) ; 1370 } ; 1371 1372 if ((k = (int) sf_seek (file, 0, SEEK_CUR)) != seekpos + 1) 1373 { printf ("\n\nLine %d: sf_seek (SEEK_CUR) with 0 offset failed (%d should be %d)\n", __LINE__, k, seekpos + 1) ; 1374 exit (1) ; 1375 } ; 1376 1377 seekpos = (int) sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ; 1378 k = (int) sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ; 1379 test_readf_double_or_die (file, 0, data, 1, __LINE__) ; 1380 if (error_function (data [0], orig [seekpos * channels], margin) || k != seekpos) 1381 { printf ("\nLine %d: sf_seek (forwards, SEEK_CUR) followed by sf_readf_double failed (%f, %f) (%d, %d).\n", __LINE__, data [0], orig [seekpos * channels], k, seekpos + 1) ; 1382 exit (1) ; 1383 } ; 1384 1385 seekpos = (int) sf_seek (file, 0, SEEK_CUR) - 20 ; 1386 /* Check seek backward from current position. */ 1387 k = (int) sf_seek (file, -20, SEEK_CUR) ; 1388 test_readf_double_or_die (file, 0, data, 1, __LINE__) ; 1389 if (error_function (data [0], orig [seekpos * channels], margin) || k != seekpos) 1390 { printf ("\nLine %d: sf_seek (backwards, SEEK_CUR) followed by sf_readf_double failed (%f, %f) (%d, %d).\n", __LINE__, data [0], orig [seekpos * channels], k, seekpos) ; 1391 exit (1) ; 1392 } ; 1393 1394 /* Check that read past end of file returns number of items. */ 1395 sf_seek (file, sfinfo.frames, SEEK_SET) ; 1396 1397 if ((k = (int) sf_readf_double (file, data, datalen)) != 0) 1398 { printf ("\n\nLine %d: Return value from sf_readf_double past end of file incorrect (%d).\n", __LINE__, k) ; 1399 exit (1) ; 1400 } ; 1401 1402 /* Check seek backward from end. */ 1403 if ((k = (int) sf_seek (file, 5 - sfinfo.frames, SEEK_END)) != 5) 1404 { printf ("\n\nLine %d: sf_seek (SEEK_END) returned %d instead of %d.\n", __LINE__, k, 5) ; 1405 exit (1) ; 1406 } ; 1407 1408 test_readf_double_or_die (file, 0, data, 1, __LINE__) ; 1409 if (error_function (data [0], orig [5 * channels], margin)) 1410 { printf ("\nLine %d: sf_seek (SEEK_END) followed by sf_readf_short failed (%f should be %f).\n", __LINE__, data [0], orig [5 * channels]) ; 1411 exit (1) ; 1412 } ; 1413 1414 sf_close (file) ; 1415 1416 unlink (filename) ; 1417 printf ("ok\n") ; 1418} /* lcomp_test_double */ 1419 1420/*======================================================================================== 1421** Smoothed differential loss compression tests. 1422*/ 1423 1424static void 1425sdlcomp_test_short (const char *filename, int filetype, int channels, double margin) 1426{ SNDFILE *file ; 1427 SF_INFO sfinfo ; 1428 int k, m, seekpos, half_max_abs ; 1429 sf_count_t datalen ; 1430 short *orig, *data, *smooth ; 1431 1432channels = 1 ; 1433 1434 get_unique_test_name (&filename, LCT_TEST_PREFIX) ; 1435 print_test_name ("sdlcomp_test_short", filename) ; 1436 1437 datalen = BUFFER_SIZE ; 1438 1439 orig = orig_buffer.s ; 1440 data = data_buffer.s ; 1441 smooth = smooth_buffer.s ; 1442 1443 gen_signal_double (orig_buffer.d, 32000.0, channels, (int) datalen) ; 1444 for (k = 0 ; k < datalen ; k++) 1445 orig [k] = (short) lrint (orig_buffer.d [k]) ; 1446 1447 sfinfo.samplerate = SAMPLE_RATE ; 1448 sfinfo.frames = 123456789 ; /* Ridiculous value. */ 1449 sfinfo.channels = channels ; 1450 sfinfo.format = filetype ; 1451 1452 /* The Vorbis encoder has a bug on PowerPC and X86-64 with sample rates 1453 ** <= 22050. Increasing the sample rate to 32000 avoids triggering it. 1454 ** See https://trac.xiph.org/ticket/1229 1455 ** 1456 ** Opus only supports discrete sample rates. Choose supported 12000. 1457 */ 1458 if ((file = sf_open (filename, SFM_WRITE, &sfinfo)) == NULL) 1459 { const char * errstr ; 1460 1461 errstr = sf_strerror (NULL) ; 1462 if (strstr (errstr, "Sample rate chosen is known to trigger a Vorbis") != NULL) 1463 { printf ("\n Sample rate -> 32kHz ") ; 1464 sfinfo.samplerate = 32000 ; 1465 } 1466 else if (strstr (errstr, "Opus only supports sample rates of") != NULL) 1467 { printf ("\n Sample rate -> 12kHz ") ; 1468 sfinfo.samplerate = 12000 ; 1469 } 1470 else 1471 { printf ("Line %d: sf_open_fd (SFM_WRITE) failed : %s\n", __LINE__, errstr) ; 1472 dump_log_buffer (NULL) ; 1473 exit (1) ; 1474 } ; 1475 1476 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; 1477 } ; 1478 1479 if ((filetype & SF_FORMAT_SUBMASK) == SF_FORMAT_OPUS && !check_opus_version (file)) 1480 { sf_close (file) ; 1481 unlink (filename) ; 1482 return ; 1483 } ; 1484 1485 test_write_short_or_die (file, 0, orig, datalen, __LINE__) ; 1486 sf_set_string (file, SF_STR_COMMENT, long_comment) ; 1487 sf_close (file) ; 1488 1489 memset (data, 0, datalen * sizeof (short)) ; 1490 1491 if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW) 1492 memset (&sfinfo, 0, sizeof (sfinfo)) ; 1493 1494 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ; 1495 1496 if (sfinfo.format != filetype) 1497 { printf ("\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, filetype, sfinfo.format) ; 1498 exit (1) ; 1499 } ; 1500 1501 if (sfinfo.frames < datalen / channels) 1502 { printf ("Too few.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", datalen, sfinfo.frames) ; 1503 exit (1) ; 1504 } ; 1505 1506 if (sfinfo.frames > (datalen + 400)) 1507 { printf ("Too many.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", sfinfo.frames, datalen) ; 1508 exit (1) ; 1509 } ; 1510 1511 if (sfinfo.channels != channels) 1512 { printf ("Incorrect number of channels in file.\n") ; 1513 exit (1) ; 1514 } ; 1515 1516 check_comment (file, filetype, __LINE__) ; 1517 1518 sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ; 1519 1520 check_log_buffer_or_die (file, __LINE__) ; 1521 1522 test_readf_short_or_die (file, 0, data, datalen, __LINE__) ; 1523 1524 memcpy (smooth, orig, datalen * sizeof (short)) ; 1525 smoothed_diff_short (data, (unsigned int) datalen) ; 1526 smoothed_diff_short (smooth, (unsigned int) datalen) ; 1527 1528 half_max_abs = 0 ; 1529 for (k = 0 ; k < datalen ; k++) 1530 { if (error_function (1.0 * data [k], 1.0 * smooth [k], margin)) 1531 { printf ("\nLine %d: Incorrect sample (#%d : %d should be %d).\n", __LINE__, k, data [k], smooth [k]) ; 1532 oct_save_short (orig, smooth, (int) datalen) ; 1533 exit (1) ; 1534 } ; 1535 half_max_abs = (int) (LCT_MAX (half_max_abs, ABS (0.5 * data [k]))) ; 1536 } ; 1537 1538 if (half_max_abs < 1) 1539 { printf ("\n\nLine %d: Signal is all zeros.\n", __LINE__) ; 1540 exit (1) ; 1541 } ; 1542 1543 if ((k = (int) sf_read_short (file, data, datalen)) != sfinfo.frames - datalen) 1544 { printf ("\n\nLine %d: Incorrect read length (%d should be %" PRId64 ").\n", __LINE__, k, sfinfo.frames - datalen) ; 1545 exit (1) ; 1546 } ; 1547 1548 if ((sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_MS_ADPCM && 1549 (sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_GSM610) 1550 for (k = 0 ; k < sfinfo.frames - datalen ; k++) 1551 if (ABS (data [k]) > decay_response (k)) 1552 { printf ("\n\nLine %d: Incorrect sample (#%" PRId64 " : abs (%d) should be < %d).\n", __LINE__, datalen + k, data [k], decay_response (k)) ; 1553 exit (1) ; 1554 } ; 1555 1556 /* Now test sf_seek function. */ 1557 if (sfinfo.seekable) 1558 { if ((k = (int) sf_seek (file, 0, SEEK_SET)) != 0) 1559 { printf ("\n\nLine %d: Seek to start of file failed (%d).\n", __LINE__, k) ; 1560 exit (1) ; 1561 } ; 1562 1563 for (m = 0 ; m < 3 ; m++) 1564 { test_readf_short_or_die (file, m, data, datalen / 7, __LINE__) ; 1565 1566 smoothed_diff_short (data, (unsigned int) (datalen / 7)) ; 1567 memcpy (smooth, orig + m * datalen / 7, datalen / 7 * sizeof (short)) ; 1568 smoothed_diff_short (smooth, (unsigned int) (datalen / 7)) ; 1569 1570 for (k = 0 ; k < datalen / 7 ; k++) 1571 if (error_function (1.0 * data [k], 1.0 * smooth [k], margin)) 1572 { printf ("\nLine %d: Incorrect sample C (#%d (%" PRId64 ") : %d => %d).\n", __LINE__, k, k + m * (datalen / 7), smooth [k], data [k]) ; 1573 for (m = 0 ; m < 10 ; m++) 1574 printf ("%d ", data [k]) ; 1575 printf ("\n") ; 1576 exit (1) ; 1577 } ; 1578 } ; /* for (m = 0 ; m < 3 ; m++) */ 1579 1580 seekpos = BUFFER_SIZE / 10 ; 1581 1582 /* Check seek from start of file. */ 1583 if ((k = (int) sf_seek (file, seekpos, SEEK_SET)) != seekpos) 1584 { printf ("Seek to start of file + %d failed (%d).\n", seekpos, k) ; 1585 exit (1) ; 1586 } ; 1587 test_readf_short_or_die (file, 0, data, 1, __LINE__) ; 1588 1589 if (error_function (1.0 * data [0], 1.0 * orig [seekpos * channels], margin)) 1590 { printf ("\nLine %d: sf_seek (SEEK_SET) followed by sf_read_short failed (%d, %d).\n", __LINE__, orig [1], data [0]) ; 1591 exit (1) ; 1592 } ; 1593 1594 if ((k = (int) sf_seek (file, 0, SEEK_CUR)) != seekpos + 1) 1595 { printf ("\n\nLine %d: sf_seek (SEEK_CUR) with 0 offset failed (%d should be %d)\n", __LINE__, k, seekpos + 1) ; 1596 exit (1) ; 1597 } ; 1598 1599 seekpos = (int) sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ; 1600 k = (int) sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ; 1601 test_readf_short_or_die (file, 0, data, 1, __LINE__) ; 1602 if (error_function (1.0 * data [0], 1.0 * orig [seekpos * channels], margin) || k != seekpos) 1603 { printf ("\nLine %d: sf_seek (forwards, SEEK_CUR) followed by sf_read_short failed (%d, %d) (%d, %d).\n", __LINE__, data [0], orig [seekpos * channels], k, seekpos + 1) ; 1604 exit (1) ; 1605 } ; 1606 1607 seekpos = (int) sf_seek (file, 0, SEEK_CUR) - 20 ; 1608 /* Check seek backward from current position. */ 1609 k = (int) sf_seek (file, -20, SEEK_CUR) ; 1610 test_readf_short_or_die (file, 0, data, 1, __LINE__) ; 1611 if (error_function (1.0 * data [0], 1.0 * orig [seekpos * channels], margin) || k != seekpos) 1612 { printf ("\nLine %d: sf_seek (backwards, SEEK_CUR) followed by sf_read_short failed (%d, %d) (%d, %d).\n", __LINE__, data [0], orig [seekpos * channels], k, seekpos) ; 1613 exit (1) ; 1614 } ; 1615 1616 /* Check that read past end of file returns number of items. */ 1617 sf_seek (file, sfinfo.frames, SEEK_SET) ; 1618 1619 if ((k = (int) sf_read_short (file, data, datalen)) != 0) 1620 { printf ("\n\nLine %d: Return value from sf_read_short past end of file incorrect (%d).\n", __LINE__, k) ; 1621 exit (1) ; 1622 } ; 1623 1624 /* Check seek backward from end. */ 1625 1626 if ((k = (int) sf_seek (file, 5 - sfinfo.frames, SEEK_END)) != 5) 1627 { printf ("\n\nLine %d: sf_seek (SEEK_END) returned %d instead of %d.\n", __LINE__, k, 5) ; 1628 exit (1) ; 1629 } ; 1630 1631 test_read_short_or_die (file, 0, data, channels, __LINE__) ; 1632 if (error_function (1.0 * data [0], 1.0 * orig [5 * channels], margin)) 1633 { printf ("\nLine %d: sf_seek (SEEK_END) followed by sf_read_short failed (%d should be %d).\n", __LINE__, data [0], orig [5 * channels]) ; 1634 exit (1) ; 1635 } ; 1636 } /* if (sfinfo.seekable) */ 1637 1638 sf_close (file) ; 1639 1640 unlink (filename) ; 1641 printf ("ok\n") ; 1642} /* sdlcomp_test_short */ 1643 1644static void 1645sdlcomp_test_int (const char *filename, int filetype, int channels, double margin) 1646{ SNDFILE *file ; 1647 SF_INFO sfinfo ; 1648 int k, m, seekpos, half_max_abs ; 1649 sf_count_t datalen ; 1650 int *orig, *data, *smooth ; 1651 double scale ; 1652 1653channels = 1 ; 1654 1655 get_unique_test_name (&filename, LCT_TEST_PREFIX) ; 1656 print_test_name ("sdlcomp_test_int", filename) ; 1657 1658 datalen = BUFFER_SIZE ; 1659 scale = 1.0 * 0x10000 ; 1660 1661 orig = orig_buffer.i ; 1662 data = data_buffer.i ; 1663 smooth = smooth_buffer.i ; 1664 1665 gen_signal_double (orig_buffer.d, 32000.0 * scale, channels, (int) datalen) ; 1666 for (k = 0 ; k < datalen ; k++) 1667 orig [k] = lrint (orig_buffer.d [k]) ; 1668 1669 sfinfo.samplerate = SAMPLE_RATE ; 1670 sfinfo.frames = 123456789 ; /* Ridiculous value. */ 1671 sfinfo.channels = channels ; 1672 sfinfo.format = filetype ; 1673 1674 /* The Vorbis encoder has a bug on PowerPC and X86-64 with sample rates 1675 ** <= 22050. Increasing the sample rate to 32000 avoids triggering it. 1676 ** See https://trac.xiph.org/ticket/1229 1677 ** 1678 ** Opus only supports discrete sample rates. Choose supported 12000. 1679 */ 1680 if ((file = sf_open (filename, SFM_WRITE, &sfinfo)) == NULL) 1681 { const char * errstr ; 1682 1683 errstr = sf_strerror (NULL) ; 1684 if (strstr (errstr, "Sample rate chosen is known to trigger a Vorbis") != NULL) 1685 { printf ("\n Sample rate -> 32kHz ") ; 1686 sfinfo.samplerate = 32000 ; 1687 } 1688 else if (strstr (errstr, "Opus only supports sample rates of") != NULL) 1689 { printf ("\n Sample rate -> 12kHz ") ; 1690 sfinfo.samplerate = 12000 ; 1691 } 1692 else 1693 { printf ("Line %d: sf_open_fd (SFM_WRITE) failed : %s\n", __LINE__, errstr) ; 1694 dump_log_buffer (NULL) ; 1695 exit (1) ; 1696 } ; 1697 1698 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; 1699 } ; 1700 1701 if ((filetype & SF_FORMAT_SUBMASK) == SF_FORMAT_OPUS && !check_opus_version (file)) 1702 { sf_close (file) ; 1703 unlink (filename) ; 1704 return ; 1705 } ; 1706 1707 test_writef_int_or_die (file, 0, orig, datalen, __LINE__) ; 1708 sf_set_string (file, SF_STR_COMMENT, long_comment) ; 1709 sf_close (file) ; 1710 1711 memset (data, 0, datalen * sizeof (int)) ; 1712 1713 if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW) 1714 memset (&sfinfo, 0, sizeof (sfinfo)) ; 1715 1716 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ; 1717 1718 if (sfinfo.format != filetype) 1719 { printf ("Returned format incorrect (0x%08X => 0x%08X).\n", filetype, sfinfo.format) ; 1720 exit (1) ; 1721 } ; 1722 1723 if (sfinfo.frames < datalen / channels) 1724 { printf ("Too few.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", datalen, sfinfo.frames) ; 1725 exit (1) ; 1726 } ; 1727 1728 if (sfinfo.frames > (datalen + 400)) 1729 { printf ("Too many.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", sfinfo.frames, datalen) ; 1730 exit (1) ; 1731 } ; 1732 1733 if (sfinfo.channels != channels) 1734 { printf ("Incorrect number of channels in file.\n") ; 1735 exit (1) ; 1736 } ; 1737 1738 check_log_buffer_or_die (file, __LINE__) ; 1739 1740 test_readf_int_or_die (file, 0, data, datalen, __LINE__) ; 1741 1742 memcpy (smooth, orig, datalen * sizeof (int)) ; 1743 smoothed_diff_int (data, (unsigned int) datalen) ; 1744 smoothed_diff_int (smooth, (unsigned int) datalen) ; 1745 1746 half_max_abs = abs (data [0] >> 16) ; 1747 for (k = 1 ; k < datalen ; k++) 1748 { if (error_function (data [k] / scale, smooth [k] / scale, margin)) 1749 { printf ("\nLine %d: Incorrect sample (#%d : %d should be %d).\n", __LINE__, k, data [k], smooth [k]) ; 1750 oct_save_int (orig, smooth, (int) datalen) ; 1751 exit (1) ; 1752 } ; 1753 half_max_abs = LCT_MAX (half_max_abs, abs (data [k] / 2)) ; 1754 } ; 1755 1756 if (half_max_abs < 1) 1757 { printf ("\n\nLine %d: Signal is all zeros.\n", __LINE__) ; 1758 exit (1) ; 1759 } ; 1760 1761 if ((k = (int) sf_readf_int (file, data, datalen)) != sfinfo.frames - datalen) 1762 { printf ("\n\nLine %d: Incorrect read length (%d should be %" PRId64 ").\n", __LINE__, k, sfinfo.frames - datalen) ; 1763 exit (1) ; 1764 } ; 1765 1766 if ((sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_IMA_ADPCM && 1767 (sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_MS_ADPCM && 1768 (sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_GSM610 && 1769 (sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_G721_32 && 1770 (sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_G723_24 && 1771 (sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_NMS_ADPCM_16 && 1772 (sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_NMS_ADPCM_24 && 1773 (sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_NMS_ADPCM_32) 1774 for (k = 0 ; k < sfinfo.frames - datalen ; k++) 1775 if (abs (data [k]) > decay_response (k)) 1776 { printf ("\n\nLine %d: Incorrect sample (#%" PRId64 " : abs (%d) should be < %d).\n", __LINE__, datalen + k, data [k], decay_response (k)) ; 1777 exit (1) ; 1778 } ; 1779 1780 /* Now test sf_seek function. */ 1781 if (sfinfo.seekable) 1782 { if ((k = (int) sf_seek (file, 0, SEEK_SET)) != 0) 1783 { printf ("\n\nLine %d: Seek to start of file failed (%d).\n", __LINE__, k) ; 1784 exit (1) ; 1785 } ; 1786 1787 for (m = 0 ; m < 3 ; m++) 1788 { test_readf_int_or_die (file, m, data, datalen / 7, __LINE__) ; 1789 1790 smoothed_diff_int (data, (unsigned int) (datalen / 7)) ; 1791 memcpy (smooth, orig + m * datalen / 7, datalen / 7 * sizeof (int)) ; 1792 smoothed_diff_int (smooth, (unsigned int) (datalen / 7)) ; 1793 1794 for (k = 0 ; k < datalen / 7 ; k++) 1795 if (error_function (data [k] / scale, smooth [k] / scale, margin)) 1796 { printf ("\nLine %d: Incorrect sample (#%d (%" PRId64 ") : %d => %d).\n", __LINE__, k, k + m * (datalen / 7), smooth [k], data [k]) ; 1797 for (m = 0 ; m < 10 ; m++) 1798 printf ("%d ", data [k]) ; 1799 printf ("\n") ; 1800 exit (1) ; 1801 } ; 1802 } ; /* for (m = 0 ; m < 3 ; m++) */ 1803 1804 seekpos = BUFFER_SIZE / 10 ; 1805 1806 /* Check seek from start of file. */ 1807 if ((k = (int) sf_seek (file, seekpos, SEEK_SET)) != seekpos) 1808 { printf ("Seek to start of file + %d failed (%d).\n", seekpos, k) ; 1809 exit (1) ; 1810 } ; 1811 test_readf_int_or_die (file, 0, data, 1, __LINE__) ; 1812 1813 if (error_function (1.0 * data [0], 1.0 * orig [seekpos * channels], margin)) 1814 { printf ("\nLine %d: sf_seek (SEEK_SET) followed by sf_readf_int failed (%d, %d).\n", __LINE__, orig [1], data [0]) ; 1815 exit (1) ; 1816 } ; 1817 1818 if ((k = (int) sf_seek (file, 0, SEEK_CUR)) != seekpos + 1) 1819 { printf ("\n\nLine %d: sf_seek (SEEK_CUR) with 0 offset failed (%d should be %d)\n", __LINE__, k, seekpos + 1) ; 1820 exit (1) ; 1821 } ; 1822 1823 seekpos = (int) sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ; 1824 k = (int) sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ; 1825 test_readf_int_or_die (file, 0, data, 1, __LINE__) ; 1826 if (error_function (1.0 * data [0], 1.0 * orig [seekpos * channels], margin) || k != seekpos) 1827 { printf ("\nLine %d: sf_seek (forwards, SEEK_CUR) followed by sf_readf_int failed (%d, %d) (%d, %d).\n", __LINE__, data [0], orig [seekpos * channels], k, seekpos + 1) ; 1828 exit (1) ; 1829 } ; 1830 1831 seekpos = (int) sf_seek (file, 0, SEEK_CUR) - 20 ; 1832 /* Check seek backward from current position. */ 1833 k = (int) sf_seek (file, -20, SEEK_CUR) ; 1834 test_readf_int_or_die (file, 0, data, 1, __LINE__) ; 1835 if (error_function (1.0 * data [0], 1.0 * orig [seekpos * channels], margin) || k != seekpos) 1836 { printf ("\nLine %d: sf_seek (backwards, SEEK_CUR) followed by sf_readf_int failed (%d, %d) (%d, %d).\n", __LINE__, data [0], orig [seekpos * channels], k, seekpos) ; 1837 exit (1) ; 1838 } ; 1839 1840 /* Check that read past end of file returns number of items. */ 1841 sf_seek (file, sfinfo.frames, SEEK_SET) ; 1842 1843 if ((k = (int) sf_readf_int (file, data, datalen)) != 0) 1844 { printf ("\n\nLine %d: Return value from sf_readf_int past end of file incorrect (%d).\n", __LINE__, k) ; 1845 exit (1) ; 1846 } ; 1847 1848 /* Check seek backward from end. */ 1849 1850 if ((k = (int) sf_seek (file, 5 - sfinfo.frames, SEEK_END)) != 5) 1851 { printf ("\n\nLine %d: sf_seek (SEEK_END) returned %d instead of %d.\n", __LINE__, k, 5) ; 1852 exit (1) ; 1853 } ; 1854 1855 test_readf_int_or_die (file, 0, data, 1, __LINE__) ; 1856 if (error_function (data [0] / scale, orig [5] / scale, margin)) 1857 { printf ("\nLine %d: sf_seek (SEEK_END) followed by sf_readf_int failed (%d should be %d).\n", __LINE__, data [0], orig [5]) ; 1858 exit (1) ; 1859 } ; 1860 } /* if (sfinfo.seekable) */ 1861 1862 sf_close (file) ; 1863 1864 unlink (filename) ; 1865 printf ("ok\n") ; 1866} /* sdlcomp_test_int */ 1867 1868static void 1869sdlcomp_test_float (const char *filename, int filetype, int channels, double margin) 1870{ SNDFILE *file ; 1871 SF_INFO sfinfo ; 1872 int k, m, seekpos ; 1873 sf_count_t datalen ; 1874 float *orig, *data, *smooth ; 1875 double half_max_abs , scale ; 1876 1877channels = 1 ; 1878 1879 get_unique_test_name (&filename, LCT_TEST_PREFIX) ; 1880 print_test_name ("sdlcomp_test_float", filename) ; 1881 1882 switch ((filetype & SF_FORMAT_SUBMASK)) 1883 { case SF_FORMAT_VORBIS : 1884 /* Vorbis starts to loose fidelity with floating point values outside 1885 ** the range of approximately [-2000.0, 2000.0] (Determined 1886 ** experimentally, not know if it is a limitation of Vorbis or 1887 ** libvorbis.) 1888 */ 1889 scale = 16.0 ; /* 32000/16 = 2000 */ 1890 break ; 1891 1892 case SF_FORMAT_OPUS : 1893 /* The Opus spec says that non-normalized floating point value 1894 ** support (extended dynamic range in its terms) is optional and 1895 ** cannot be relied upon. 1896 */ 1897 scale = 32000.0 ; /* 32000/32000 = 1 */ 1898 break ; 1899 1900 default : 1901 scale = 1.0 ; 1902 break ; 1903 } ; 1904 1905 datalen = BUFFER_SIZE ; 1906 1907 orig = orig_buffer.f ; 1908 data = data_buffer.f ; 1909 smooth = smooth_buffer.f ; 1910 1911 gen_signal_double (orig_buffer.d, 32000.0 / scale, channels, (int) datalen) ; 1912 for (k = 0 ; k < datalen ; k++) 1913 orig [k] = (float) orig_buffer.d [k] ; 1914 1915 sfinfo.samplerate = SAMPLE_RATE ; 1916 sfinfo.frames = 123456789 ; /* Ridiculous value. */ 1917 sfinfo.channels = channels ; 1918 sfinfo.format = filetype ; 1919 1920 1921 /* The Vorbis encoder has a bug on PowerPC and X86-64 with sample rates 1922 ** <= 22050. Increasing the sample rate to 32000 avoids triggering it. 1923 ** See https://trac.xiph.org/ticket/1229 1924 ** 1925 ** Opus only supports discrete sample rates. Choose supported 12000. 1926 */ 1927 if ((file = sf_open (filename, SFM_WRITE, &sfinfo)) == NULL) 1928 { const char * errstr ; 1929 1930 errstr = sf_strerror (NULL) ; 1931 if (strstr (errstr, "Sample rate chosen is known to trigger a Vorbis") != NULL) 1932 { printf ("\n Sample rate -> 32kHz ") ; 1933 sfinfo.samplerate = 32000 ; 1934 } 1935 else if (strstr (errstr, "Opus only supports sample rates of") != NULL) 1936 { printf ("\n Sample rate -> 12kHz ") ; 1937 sfinfo.samplerate = 12000 ; 1938 } 1939 else 1940 { printf ("Line %d: sf_open_fd (SFM_WRITE) failed : %s\n", __LINE__, errstr) ; 1941 dump_log_buffer (NULL) ; 1942 exit (1) ; 1943 } ; 1944 1945 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; 1946 } ; 1947 1948 if ((filetype & SF_FORMAT_SUBMASK) == SF_FORMAT_OPUS && !check_opus_version (file)) 1949 { sf_close (file) ; 1950 unlink (filename) ; 1951 return ; 1952 } ; 1953 1954 sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ; 1955 test_write_float_or_die (file, 0, orig, datalen, __LINE__) ; 1956 sf_set_string (file, SF_STR_COMMENT, long_comment) ; 1957 sf_close (file) ; 1958 1959 memset (data, 0, datalen * sizeof (float)) ; 1960 1961 if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW) 1962 memset (&sfinfo, 0, sizeof (sfinfo)) ; 1963 1964 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ; 1965 1966 if ((sfinfo.format & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)) != (filetype & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK))) 1967 { printf ("\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, filetype, sfinfo.format) ; 1968 exit (1) ; 1969 } ; 1970 1971 if (sfinfo.frames < datalen / channels) 1972 { printf ("Too few.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", datalen, sfinfo.frames) ; 1973 exit (1) ; 1974 } ; 1975 1976 if (sfinfo.frames > (datalen + 400)) 1977 { printf ("Too many.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", sfinfo.frames, datalen) ; 1978 exit (1) ; 1979 } ; 1980 1981 if (sfinfo.channels != channels) 1982 { printf ("Incorrect number of channels in file.\n") ; 1983 exit (1) ; 1984 } ; 1985 1986 check_comment (file, filetype, __LINE__) ; 1987 1988 sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ; 1989 1990 check_log_buffer_or_die (file, __LINE__) ; 1991 1992 test_read_float_or_die (file, 0, data, datalen, __LINE__) ; 1993 1994 memcpy (smooth, orig, datalen * sizeof (float)) ; 1995 smoothed_diff_float (data, (unsigned int) datalen) ; 1996 smoothed_diff_float (smooth, (unsigned int) datalen) ; 1997 1998 half_max_abs = fabs (data [0]) ; 1999 for (k = 1 ; k < datalen ; k++) 2000 { if (error_function (data [k] * scale, smooth [k] * scale, margin)) 2001 { printf ("\nLine %d: Incorrect sample (#%d : %d should be %d).\n", __LINE__, k, (int) (data [k] * scale), (int) (smooth [k] * scale)) ; 2002 oct_save_float (orig, smooth, (int) datalen) ; 2003 exit (1) ; 2004 } ; 2005 half_max_abs = LCT_MAX (half_max_abs, ABS (0.5 * data [k] * scale)) ; 2006 } ; 2007 2008 if (half_max_abs <= 0.0) 2009 { printf ("\n\nLine %d: Signal is all zeros.\n", __LINE__) ; 2010 printf ("half_max_abs : % 10.6f\n", half_max_abs) ; 2011 exit (1) ; 2012 } ; 2013 2014 if ((k = (int) sf_read_float (file, data, datalen)) != sfinfo.frames - datalen) 2015 { printf ("\n\nLine %d: Incorrect read length (%d should be %" PRId64 ").\n", __LINE__, k, sfinfo.frames - datalen) ; 2016 exit (1) ; 2017 } ; 2018 2019 if ((sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_MS_ADPCM && 2020 (sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_GSM610) 2021 for (k = 0 ; k < sfinfo.frames - datalen ; k++) 2022 if (ABS (data [k]) > decay_response (k)) 2023 { printf ("\n\nLine %d: Incorrect sample (#%" PRId64 " : abs (%d) should be < %d).\n", __LINE__, datalen + k, (int) data [k], (int) decay_response (k)) ; 2024 exit (1) ; 2025 } ; 2026 2027 /* Now test sf_seek function. */ 2028 if (sfinfo.seekable) 2029 { if ((k = (int) sf_seek (file, 0, SEEK_SET)) != 0) 2030 { printf ("\n\nLine %d: Seek to start of file failed (%d).\n", __LINE__, k) ; 2031 exit (1) ; 2032 } ; 2033 2034 for (m = 0 ; m < 3 ; m++) 2035 { test_read_float_or_die (file, 0, data, datalen / 7, __LINE__) ; 2036 2037 smoothed_diff_float (data, (unsigned int) (datalen / 7)) ; 2038 memcpy (smooth, orig + m * datalen / 7, datalen / 7 * sizeof (float)) ; 2039 smoothed_diff_float (smooth, (unsigned int) (datalen / 7)) ; 2040 2041 for (k = 0 ; k < datalen / 7 ; k++) 2042 if (error_function (data [k] * scale, smooth [k] * scale, margin)) 2043 { printf ("\nLine %d: Incorrect sample C (#%d (%" PRId64 ") : %d => %d).\n", __LINE__, k, k + m * (datalen / 7), (int) (smooth [k] * scale), (int) (data [k] * scale)) ; 2044 for (m = 0 ; m < 10 ; m++) 2045 printf ("%d ", (int) data [k]) ; 2046 printf ("\n") ; 2047 exit (1) ; 2048 } ; 2049 } ; /* for (m = 0 ; m < 3 ; m++) */ 2050 2051 seekpos = BUFFER_SIZE / 10 ; 2052 2053 /* Check seek from start of file. */ 2054 if ((k = (int) sf_seek (file, seekpos, SEEK_SET)) != seekpos) 2055 { printf ("Seek to start of file + %d failed (%d).\n", seekpos, k) ; 2056 exit (1) ; 2057 } ; 2058 test_read_float_or_die (file, 0, data, channels, __LINE__) ; 2059 2060 if (error_function (data [0] * scale, orig [seekpos * channels] * scale, margin)) 2061 { printf ("\nLine %d: sf_seek (SEEK_SET) followed by sf_read_float failed (%d, %d).\n", __LINE__, (int) (orig [1] * scale), (int) (data [0] * scale)) ; 2062 exit (1) ; 2063 } ; 2064 2065 if ((k = (int) sf_seek (file, 0, SEEK_CUR)) != seekpos + 1) 2066 { printf ("\n\nLine %d: sf_seek (SEEK_CUR) with 0 offset failed (%d should be %d)\n", __LINE__, k, seekpos + 1) ; 2067 exit (1) ; 2068 } ; 2069 2070 seekpos = (int) sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ; 2071 k = (int) sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ; 2072 test_read_float_or_die (file, 0, data, channels, __LINE__) ; 2073 if (error_function (data [0] * scale, orig [seekpos * channels] * scale, margin) || k != seekpos) 2074 { printf ("\nLine %d: sf_seek (forwards, SEEK_CUR) followed by sf_read_float failed (%d, %d) (%d, %d).\n", __LINE__, (int) (data [0] * scale), (int) (orig [seekpos * channels] * scale), k, seekpos + 1) ; 2075 exit (1) ; 2076 } ; 2077 2078 seekpos = (int) sf_seek (file, 0, SEEK_CUR) - 20 ; 2079 /* Check seek backward from current position. */ 2080 k = (int) sf_seek (file, -20, SEEK_CUR) ; 2081 test_read_float_or_die (file, 0, data, channels, __LINE__) ; 2082 if (error_function (data [0] * scale, orig [seekpos * channels] * scale, margin) || k != seekpos) 2083 { printf ("\nLine %d: sf_seek (backwards, SEEK_CUR) followed by sf_read_float failed (%d, %d) (%d, %d).\n", __LINE__, (int) (data [0] * scale), (int) (orig [seekpos * channels] * scale), k, seekpos) ; 2084 exit (1) ; 2085 } ; 2086 2087 /* Check that read past end of file returns number of items. */ 2088 sf_seek (file, sfinfo.frames, SEEK_SET) ; 2089 2090 if ((k = (int) sf_read_float (file, data, datalen)) != 0) 2091 { printf ("\n\nLine %d: Return value from sf_read_float past end of file incorrect (%d).\n", __LINE__, k) ; 2092 exit (1) ; 2093 } ; 2094 2095 /* Check seek backward from end. */ 2096 2097 if ((k = (int) sf_seek (file, 5 - sfinfo.frames, SEEK_END)) != 5) 2098 { printf ("\n\nLine %d: sf_seek (SEEK_END) returned %d instead of %d.\n", __LINE__, k, 5) ; 2099 exit (1) ; 2100 } ; 2101 2102 test_read_float_or_die (file, 0, data, channels, __LINE__) ; 2103 if (error_function (data [0] * scale, orig [5 * channels] * scale, margin)) 2104 { printf ("\nLine %d: sf_seek (SEEK_END) followed by sf_read_float failed (%f should be %f).\n", __LINE__, data [0] * scale, orig [5 * channels] * scale) ; 2105 exit (1) ; 2106 } ; 2107 } /* if (sfinfo.seekable) */ 2108 2109 sf_close (file) ; 2110 2111 unlink (filename) ; 2112 printf ("ok\n") ; 2113} /* sdlcomp_test_float */ 2114 2115static void 2116sdlcomp_test_double (const char *filename, int filetype, int channels, double margin) 2117{ SNDFILE *file ; 2118 SF_INFO sfinfo ; 2119 int k, m, seekpos ; 2120 sf_count_t datalen ; 2121 double *orig, *data, *smooth, half_max_abs, scale ; 2122 2123channels = 1 ; 2124 2125 get_unique_test_name (&filename, LCT_TEST_PREFIX) ; 2126 print_test_name ("sdlcomp_test_double", filename) ; 2127 2128 switch ((filetype & SF_FORMAT_SUBMASK)) 2129 { case SF_FORMAT_VORBIS : 2130 /* Vorbis starts to loose fidelity with floating point values outside 2131 ** the range of approximately [-2000.0, 2000.0] (Determined 2132 ** experimentally, not know if it is a limitation of Vorbis or 2133 ** libvorbis.) 2134 */ 2135 scale = 16.0 ; /* 32000/16 = 2000 */ 2136 break ; 2137 2138 case SF_FORMAT_OPUS : 2139 /* The Opus spec says that non-normalized floating point value 2140 ** support (extended dynamic range in its terms) is optional and 2141 ** cannot be relied upon. 2142 */ 2143 scale = 32000.0 ; /* 32000/32000 = 1 */ 2144 break ; 2145 2146 default : 2147 scale = 1.0 ; 2148 break ; 2149 } ; 2150 2151 datalen = BUFFER_SIZE ; 2152 2153 orig = orig_buffer.d ; 2154 data = data_buffer.d ; 2155 smooth = smooth_buffer.d ; 2156 2157 gen_signal_double (orig_buffer.d, 32000.0 / scale, channels, (int) datalen) ; 2158 2159 sfinfo.samplerate = SAMPLE_RATE ; 2160 sfinfo.frames = 123456789 ; /* Ridiculous value. */ 2161 sfinfo.channels = channels ; 2162 sfinfo.format = filetype ; 2163 2164 /* The Vorbis encoder has a bug on PowerPC and X86-64 with sample rates 2165 ** <= 22050. Increasing the sample rate to 32000 avoids triggering it. 2166 ** See https://trac.xiph.org/ticket/1229 2167 ** 2168 ** Opus only supports discrete sample rates. Choose supported 12000. 2169 */ 2170 if ((file = sf_open (filename, SFM_WRITE, &sfinfo)) == NULL) 2171 { const char * errstr ; 2172 2173 errstr = sf_strerror (NULL) ; 2174 if (strstr (errstr, "Sample rate chosen is known to trigger a Vorbis") != NULL) 2175 { printf ("\n Sample rate -> 32kHz ") ; 2176 sfinfo.samplerate = 32000 ; 2177 } 2178 else if (strstr (errstr, "Opus only supports sample rates of") != NULL) 2179 { printf ("\n Sample rate -> 12kHz ") ; 2180 sfinfo.samplerate = 12000 ; 2181 } 2182 else 2183 { printf ("Line %d: sf_open_fd (SFM_WRITE) failed : %s\n", __LINE__, errstr) ; 2184 dump_log_buffer (NULL) ; 2185 exit (1) ; 2186 } ; 2187 2188 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; 2189 } ; 2190 2191 if ((filetype & SF_FORMAT_SUBMASK) == SF_FORMAT_OPUS && !check_opus_version (file)) 2192 { sf_close (file) ; 2193 unlink (filename) ; 2194 return ; 2195 } ; 2196 2197 sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ; 2198 test_write_double_or_die (file, 0, orig, datalen, __LINE__) ; 2199 sf_set_string (file, SF_STR_COMMENT, long_comment) ; 2200 sf_close (file) ; 2201 2202 memset (data, 0, datalen * sizeof (double)) ; 2203 2204 if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW) 2205 memset (&sfinfo, 0, sizeof (sfinfo)) ; 2206 2207 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ; 2208 2209 if (sfinfo.format != filetype) 2210 { printf ("Returned format incorrect (0x%08X => 0x%08X).\n", filetype, sfinfo.format) ; 2211 exit (1) ; 2212 } ; 2213 2214 if (sfinfo.frames < datalen / channels) 2215 { printf ("Too few.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", datalen, sfinfo.frames) ; 2216 exit (1) ; 2217 } ; 2218 2219 if (sfinfo.frames > (datalen + 400)) 2220 { printf ("Too many.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", sfinfo.frames, datalen) ; 2221 exit (1) ; 2222 } ; 2223 2224 if (sfinfo.channels != channels) 2225 { printf ("Incorrect number of channels in file.\n") ; 2226 exit (1) ; 2227 } ; 2228 2229 check_comment (file, filetype, __LINE__) ; 2230 2231 check_comment (file, filetype, __LINE__) ; 2232 2233 sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ; 2234 2235 check_log_buffer_or_die (file, __LINE__) ; 2236 2237 test_read_double_or_die (file, 0, data, datalen, __LINE__) ; 2238 2239 memcpy (smooth, orig, datalen * sizeof (double)) ; 2240 smoothed_diff_double (data, (unsigned int) datalen) ; 2241 smoothed_diff_double (smooth, (unsigned int) datalen) ; 2242 2243 half_max_abs = 0.0 ; 2244 for (k = 0 ; k < datalen ; k++) 2245 { if (error_function (data [k] * scale, smooth [k] * scale, margin)) 2246 { printf ("\n\nLine %d: Incorrect sample (#%d : %d should be %d).\n", __LINE__, k, (int) (data [k] * scale), (int) (smooth [k] * scale)) ; 2247 oct_save_double (orig, smooth, (int) datalen) ; 2248 exit (1) ; 2249 } ; 2250 half_max_abs = LCT_MAX (half_max_abs, 0.5 * fabs (data [k] * scale)) ; 2251 } ; 2252 2253 if (half_max_abs < 1.0) 2254 { printf ("\n\nLine %d: Signal is all zeros.\n", __LINE__) ; 2255 exit (1) ; 2256 } ; 2257 2258 if ((k = (int) sf_read_double (file, data, datalen)) != sfinfo.frames - datalen) 2259 { printf ("\n\nLine %d: Incorrect read length (%d should be %" PRId64 ").\n", __LINE__, k, sfinfo.frames - datalen) ; 2260 exit (1) ; 2261 } ; 2262 2263 if ((sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_MS_ADPCM && 2264 (sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_GSM610) 2265 for (k = 0 ; k < sfinfo.frames - datalen ; k++) 2266 if (ABS (data [k]) > decay_response (k)) 2267 { printf ("\n\nLine %d: Incorrect sample (#%" PRId64 " : abs (%d) should be < %d).\n", __LINE__, datalen + k, (int) data [k], (int) decay_response (k)) ; 2268 exit (1) ; 2269 } ; 2270 2271 /* Now test sf_seek function. */ 2272 if (sfinfo.seekable) 2273 { if ((k = (int) sf_seek (file, 0, SEEK_SET)) != 0) 2274 { printf ("\n\nLine %d: Seek to start of file failed (%d).\n", __LINE__, k) ; 2275 exit (1) ; 2276 } ; 2277 2278 for (m = 0 ; m < 3 ; m++) 2279 { test_read_double_or_die (file, m, data, datalen / 7, __LINE__) ; 2280 2281 smoothed_diff_double (data, (unsigned int) (datalen / 7)) ; 2282 memcpy (smooth, orig + m * datalen / 7, datalen / 7 * sizeof (double)) ; 2283 smoothed_diff_double (smooth, (unsigned int) (datalen / 7)) ; 2284 2285 for (k = 0 ; k < datalen / 7 ; k++) 2286 if (error_function (data [k] * scale, smooth [k] * scale, margin)) 2287 { printf ("\nLine %d: Incorrect sample C (#%d (%" PRId64 ") : %d => %d).\n", __LINE__, k, k + m * (datalen / 7), (int) (smooth [k] * scale), (int) (data [k] * scale)) ; 2288 for (m = 0 ; m < 10 ; m++) 2289 printf ("%d ", (int) data [k]) ; 2290 printf ("\n") ; 2291 exit (1) ; 2292 } ; 2293 } ; /* for (m = 0 ; m < 3 ; m++) */ 2294 2295 seekpos = BUFFER_SIZE / 10 ; 2296 2297 /* Check seek from start of file. */ 2298 if ((k = (int) sf_seek (file, seekpos, SEEK_SET)) != seekpos) 2299 { printf ("Seek to start of file + %d failed (%d).\n", seekpos, k) ; 2300 exit (1) ; 2301 } ; 2302 test_read_double_or_die (file, 0, data, channels, __LINE__) ; 2303 2304 if (error_function (data [0] * scale, orig [seekpos * channels] * scale, margin)) 2305 { printf ("\nLine %d: sf_seek (SEEK_SET) followed by sf_read_double failed (%d, %d).\n", __LINE__, (int) (orig [1] * scale), (int) (data [0] * scale)) ; 2306 exit (1) ; 2307 } ; 2308 2309 if ((k = (int) sf_seek (file, 0, SEEK_CUR)) != seekpos + 1) 2310 { printf ("\n\nLine %d: sf_seek (SEEK_CUR) with 0 offset failed (%d should be %d)\n", __LINE__, k, seekpos + 1) ; 2311 exit (1) ; 2312 } ; 2313 2314 seekpos = (int) sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ; 2315 k = (int) sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ; 2316 test_read_double_or_die (file, 0, data, channels, __LINE__) ; 2317 if (error_function (data [0] * scale, orig [seekpos * channels] * scale, margin) || k != seekpos) 2318 { printf ("\nLine %d: sf_seek (forwards, SEEK_CUR) followed by sf_read_double failed (%d, %d) (%d, %d).\n", __LINE__, (int) (data [0] * scale), (int) (orig [seekpos * channels] * scale), k, seekpos + 1) ; 2319 exit (1) ; 2320 } ; 2321 2322 seekpos = (int) sf_seek (file, 0, SEEK_CUR) - 20 ; 2323 /* Check seek backward from current position. */ 2324 k = (int) sf_seek (file, -20, SEEK_CUR) ; 2325 test_read_double_or_die (file, 0, data, channels, __LINE__) ; 2326 if (error_function (data [0] * scale, orig [seekpos * channels] * scale, margin) || k != seekpos) 2327 { printf ("\nLine %d: sf_seek (backwards, SEEK_CUR) followed by sf_read_double failed (%d, %d) (%d, %d).\n", __LINE__, (int) (data [0] * scale), (int) (orig [seekpos * channels] * scale), k, seekpos) ; 2328 exit (1) ; 2329 } ; 2330 2331 /* Check that read past end of file returns number of items. */ 2332 sf_seek (file, sfinfo.frames, SEEK_SET) ; 2333 2334 if ((k = (int) sf_read_double (file, data, datalen)) != 0) 2335 { printf ("\n\nLine %d: Return value from sf_read_double past end of file incorrect (%d).\n", __LINE__, k) ; 2336 exit (1) ; 2337 } ; 2338 2339 /* Check seek backward from end. */ 2340 2341 if ((k = (int) sf_seek (file, 5 - sfinfo.frames, SEEK_END)) != 5) 2342 { printf ("\n\nLine %d: sf_seek (SEEK_END) returned %d instead of %d.\n", __LINE__, k, 5) ; 2343 exit (1) ; 2344 } ; 2345 2346 test_read_double_or_die (file, 0, data, channels, __LINE__) ; 2347 if (error_function (data [0] * scale, orig [5 * channels] * scale, margin)) 2348 { printf ("\nLine %d: sf_seek (SEEK_END) followed by sf_read_double failed (%f should be %f).\n", __LINE__, data [0] * scale, orig [5 * channels] * scale) ; 2349 exit (1) ; 2350 } ; 2351 } /* if (sfinfo.seekable) */ 2352 2353 sf_close (file) ; 2354 2355 unlink (filename) ; 2356 printf ("ok\n") ; 2357} /* sdlcomp_test_double */ 2358 2359static void 2360read_raw_test (const char *filename, int filetype, int channels) 2361{ SNDFILE *file ; 2362 SF_INFO sfinfo ; 2363 sf_count_t count, datalen ; 2364 short *orig, *data ; 2365 int k ; 2366 2367 get_unique_test_name (&filename, LCT_TEST_PREFIX) ; 2368 print_test_name ("read_raw_test", filename) ; 2369 2370 datalen = ARRAY_LEN (orig_buffer.s) / 2 ; 2371 2372 orig = orig_buffer.s ; 2373 data = data_buffer.s ; 2374 2375 gen_signal_double (orig_buffer.d, 32000.0, channels, (int) datalen) ; 2376 for (k = 0 ; k < datalen ; k++) 2377 orig [k] = (short) lrint (orig_buffer.d [k]) ; 2378 2379 sfinfo.samplerate = SAMPLE_RATE ; 2380 sfinfo.frames = 123456789 ; /* Ridiculous value. */ 2381 sfinfo.channels = channels ; 2382 sfinfo.format = filetype ; 2383 2384 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ; 2385 test_write_short_or_die (file, 0, orig, datalen, __LINE__) ; 2386 sf_set_string (file, SF_STR_COMMENT, long_comment) ; 2387 sf_close (file) ; 2388 2389 memset (data, 0, datalen * sizeof (double)) ; 2390 2391 if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW) 2392 memset (&sfinfo, 0, sizeof (sfinfo)) ; 2393 2394 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ; 2395 2396 if (sfinfo.format != filetype) 2397 { printf ("Returned format incorrect (0x%08X => 0x%08X).\n", filetype, sfinfo.format) ; 2398 exit (1) ; 2399 } ; 2400 2401 if (sfinfo.frames < datalen / channels) 2402 { printf ("Too few.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", datalen, sfinfo.frames) ; 2403 exit (1) ; 2404 } ; 2405 2406 if (sfinfo.frames > (datalen + 400)) 2407 { printf ("Too many.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", sfinfo.frames, datalen) ; 2408 exit (1) ; 2409 } ; 2410 2411 if (sfinfo.channels != channels) 2412 { printf ("Incorrect number of channels in file.\n") ; 2413 exit (1) ; 2414 } ; 2415 2416 check_comment (file, filetype, __LINE__) ; 2417 2418 count = sf_read_raw (file, orig_buffer.c, datalen + 5 * channels) ; 2419 if (count != sfinfo.channels * sfinfo.frames) 2420 { printf ("\nLine %d : sf_read_raw returned %" PRId64 " should be %" PRId64 "\n", __LINE__, count, sfinfo.channels * sfinfo.frames) ; 2421 exit (1) ; 2422 } ; 2423 2424 sf_close (file) ; 2425 2426 unlink (filename) ; 2427 printf ("ok\n") ; 2428} /* read_raw_test */ 2429 2430/*======================================================================================== 2431** Auxiliary functions 2432*/ 2433 2434#define SIGNAL_MAXVAL 30000.0 2435#define DECAY_COUNT 1000 2436 2437static int 2438decay_response (int k) 2439{ if (k < 1) 2440 return (int) (1.2 * SIGNAL_MAXVAL) ; 2441 if (k > DECAY_COUNT) 2442 return 0 ; 2443 return (int) (1.2 * SIGNAL_MAXVAL * (DECAY_COUNT - k) / (1.0 * DECAY_COUNT)) ; 2444} /* decay_response */ 2445 2446static void 2447gen_signal_double (double *data, double scale, int channels, int datalen) 2448{ int k, ramplen ; 2449 double amp = 0.0 ; 2450 2451 ramplen = DECAY_COUNT ; 2452 2453 if (channels == 1) 2454 { for (k = 0 ; k < datalen ; k++) 2455 { if (k <= ramplen) 2456 amp = scale * k / ((double) ramplen) ; 2457 else if (k > datalen - ramplen) 2458 amp = scale * (datalen - k) / ((double) ramplen) ; 2459 2460/*-printf ("%3d : %g\n", k, amp) ;-*/ 2461 2462 data [k] = amp * (0.4 * sin (33.3 * 2.0 * M_PI * ((double) (k+1)) / ((double) SAMPLE_RATE)) 2463 + 0.3 * cos (201.1 * 2.0 * M_PI * ((double) (k+1)) / ((double) SAMPLE_RATE))) ; 2464 } ; 2465 } 2466 else 2467 { for (k = 0 ; k < datalen ; k ++) 2468 { if (k <= ramplen) 2469 amp = scale * k / ((double) ramplen) ; 2470 else if (k > datalen - ramplen) 2471 amp = scale * (datalen - k) / ((double) ramplen) ; 2472 2473 data [2 * k] = amp * (0.4 * sin (33.3 * 2.0 * M_PI * ((double) (k+1)) / ((double) SAMPLE_RATE)) 2474 + 0.3 * cos (201.1 * 2.0 * M_PI * ((double) (k+1)) / ((double) SAMPLE_RATE))) ; 2475 data [2 * k + 1] = amp * (0.4 * sin (55.5 * 2.0 * M_PI * ((double) (k+1)) / ((double) SAMPLE_RATE)) 2476 + 0.3 * cos (201.1 * 2.0 * M_PI * ((double) (k+1)) / ((double) SAMPLE_RATE))) ; 2477 } ; 2478 } ; 2479 2480 return ; 2481} /* gen_signal_double */ 2482 2483static int 2484error_function (double data, double orig, double margin) 2485{ double error ; 2486 2487 if (fabs (orig) <= 500.0) 2488 error = fabs (fabs (data) - fabs (orig)) / 2000.0 ; 2489 else if (fabs (orig) <= 1000.0) 2490 error = fabs (data - orig) / 3000.0 ; 2491 else 2492 error = fabs (data - orig) / fabs (orig) ; 2493 2494 if (error > margin) 2495 { printf ("\n\nerror_function (data = %f, orig = %f, margin = %f) -> %f\n", data, orig, margin, error) ; 2496 return 1 ; 2497 } ; 2498 return 0 ; 2499} /* error_function */ 2500 2501static void 2502smoothed_diff_short (short *data, unsigned int datalen) 2503{ unsigned int k ; 2504 double memory = 0.0 ; 2505 2506 /* Calculate the smoothed sample-to-sample difference. */ 2507 for (k = 0 ; k < datalen - 1 ; k++) 2508 { memory = 0.7 * memory + (1 - 0.7) * (double) (data [k+1] - data [k]) ; 2509 data [k] = (short) memory ; 2510 } ; 2511 data [datalen-1] = data [datalen-2] ; 2512 2513} /* smoothed_diff_short */ 2514 2515static void 2516smoothed_diff_int (int *data, unsigned int datalen) 2517{ unsigned int k ; 2518 double memory = 0.0 ; 2519 2520 /* Calculate the smoothed sample-to-sample difference. */ 2521 for (k = 0 ; k < datalen - 1 ; k++) 2522 { memory = 0.7 * memory + (1 - 0.7) * (double) (data [k+1] - data [k]) ; 2523 data [k] = (int) memory ; 2524 } ; 2525 data [datalen-1] = data [datalen-2] ; 2526 2527} /* smoothed_diff_int */ 2528 2529static void 2530smoothed_diff_float (float *data, unsigned int datalen) 2531{ unsigned int k ; 2532 float memory = 0.0 ; 2533 2534 /* Calculate the smoothed sample-to-sample difference. */ 2535 for (k = 0 ; k < datalen - 1 ; k++) 2536 { memory = (float) (0.7 * memory + (1 - 0.7) * (data [k+1] - data [k])) ; 2537 data [k] = memory ; 2538 } ; 2539 data [datalen-1] = data [datalen-2] ; 2540 2541} /* smoothed_diff_float */ 2542 2543static void 2544smoothed_diff_double (double *data, unsigned int datalen) 2545{ unsigned int k ; 2546 double memory = 0.0 ; 2547 2548 /* Calculate the smoothed sample-to-sample difference. */ 2549 for (k = 0 ; k < datalen - 1 ; k++) 2550 { memory = 0.7 * memory + (1 - 0.7) * (data [k+1] - data [k]) ; 2551 data [k] = memory ; 2552 } ; 2553 data [datalen-1] = data [datalen-2] ; 2554 2555} /* smoothed_diff_double */ 2556 2557static void 2558check_comment (SNDFILE * file, int format, int lineno) 2559{ const char *comment ; 2560 2561 switch (format & SF_FORMAT_TYPEMASK) 2562 { case SF_FORMAT_AIFF : 2563 case SF_FORMAT_WAV : 2564 case SF_FORMAT_WAVEX : 2565 break ; 2566 default : 2567 return ; 2568 } ; 2569 2570 comment = sf_get_string (file, SF_STR_COMMENT) ; 2571 if (comment == NULL) 2572 { printf ("\n\nLine %d : File does not contain a comment string.\n\n", lineno) ; 2573 exit (1) ; 2574 } ; 2575 2576 if (strcmp (comment, long_comment) != 0) 2577 { printf ("\n\nLine %d : File comment does not match comment written.\n\n", lineno) ; 2578 exit (1) ; 2579 } ; 2580 2581 return ; 2582} /* check_comment */ 2583 2584static int 2585is_lossy (int filetype) 2586{ 2587 switch (SF_FORMAT_SUBMASK & filetype) 2588 { case SF_FORMAT_PCM_U8 : 2589 case SF_FORMAT_PCM_S8 : 2590 case SF_FORMAT_PCM_16 : 2591 case SF_FORMAT_PCM_24 : 2592 case SF_FORMAT_PCM_32 : 2593 case SF_FORMAT_FLOAT : 2594 case SF_FORMAT_DOUBLE : 2595 return 0 ; 2596 2597 default : 2598 break ; 2599 } ; 2600 2601 return 1 ; 2602} /* is_lossy */ 2603 2604 2605static int 2606check_opus_version (SNDFILE *file) 2607{ char log_buf [256] ; 2608 char *str, *p ; 2609 const char *str_libopus = "Opus library version: " ; 2610 int ver_major, ver_minor ; 2611 2612 sf_command (file, SFC_GET_LOG_INFO, log_buf, sizeof (log_buf)) ; 2613 str = strstr (log_buf, str_libopus) ; 2614 if (str) 2615 { str += strlen (str_libopus) ; 2616 if ((p = strchr (str, '\n'))) 2617 *p = '\0' ; 2618 if (sscanf (str, "libopus %d.%d", &ver_major, &ver_minor) == 2) 2619 { /* Reject versions prior to 1.3 */ 2620 if (ver_major > 1 || (ver_major == 1 && ver_minor >= 3)) 2621 { /* 2622 ** Make sure that the libopus in use is not fixed-point, as it 2623 ** sacrifices accuracy. libopus API documentation explicitly 2624 ** allows checking for this suffix to determine if it is. 2625 */ 2626 if (!strstr (str, "-fixed")) 2627 return 1 ; 2628 } ; 2629 } ; 2630 } ; 2631 2632 printf ("skipping (%s)\n", str ? str : "unknown libopus version") ; 2633 return 0 ; 2634} /* check_opus_version */ 2635