1/* 2** Copyright (C) 2015-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#if HAVE_UNISTD_H 28#include <unistd.h> 29#else 30#include "sf_unistd.h" 31#endif 32 33#include <sndfile.h> 34 35#include "dft_cmp.h" 36#include "utils.h" 37 38#define BUFFER_LENGTH 10000 39#define SAMPLE_RATE 44010 40 41static void short_lrw_test (const char *filename, int filetype, const short * output, int out_len) ; 42static void int_lrw_test (const char *filename, int filetype, const int * output, int out_len) ; 43static void float_lrw_test (const char *filename, int filetype, const float * output, int out_len) ; 44static void double_lrw_test (const char *filename, int filetype, const double * output, int out_len) ; 45 46 47static short short_data [BUFFER_LENGTH] ; 48static int int_data [BUFFER_LENGTH] ; 49static float float_data [BUFFER_LENGTH] ; 50static double double_data [BUFFER_LENGTH] ; 51 52int 53main (int argc, char *argv []) 54{ int do_all ; 55 size_t k ; 56 57 if (argc != 2) 58 { printf ("Usage : %s <test>\n", argv [0]) ; 59 printf (" Where <test> is one of the following:\n") ; 60 printf (" alac - test CAF/ALAC file functions\n") ; 61 printf (" all - perform all tests\n") ; 62 exit (1) ; 63 } ; 64 65 for (k = 0 ; k < ARRAY_LEN (short_data) ; k++) 66 { int value = k / 32 ; 67 int_data [k] = (value & 1 ? -1 : 1) * value ; 68 short_data [k] = int_data [k] ; 69 float_data [k] = int_data [k] / 32000.0f ; 70 double_data [k] = int_data [k] / 32000.0 ; 71 } 72 73 do_all = ! strcmp (argv [1], "all") ; 74 75 if (do_all || strcmp (argv [1], "alac") == 0) 76 { short_lrw_test ("alac.caf", SF_FORMAT_CAF | SF_FORMAT_ALAC_16, short_data, ARRAY_LEN (short_data)) ; 77 int_lrw_test ("alac.caf", SF_FORMAT_CAF | SF_FORMAT_ALAC_32, int_data, ARRAY_LEN (int_data)) ; 78 float_lrw_test ("alac.caf", SF_FORMAT_CAF | SF_FORMAT_ALAC_32, float_data, ARRAY_LEN (float_data)) ; 79 double_lrw_test ("alac.caf", SF_FORMAT_CAF | SF_FORMAT_ALAC_32, double_data, ARRAY_LEN (double_data)) ; 80 } ; 81 82 return 0 ; 83} /* main */ 84 85/*============================================================================================ 86 * Here are the test functions. 87 */ 88 89static void 90short_lrw_test (const char *filename, int filetype, const short * output, int out_len) 91{ SNDFILE *file ; 92 SF_INFO sfinfo ; 93 int k ; 94 short input [BUFFER_LENGTH] ; 95 96 print_test_name ("short_lrw_test", filename) ; 97 98 exit_if_true (BUFFER_LENGTH > out_len, "\n\nLine %d: Bad array length.\n", __LINE__) ; 99 100 sfinfo.samplerate = SAMPLE_RATE ; 101 sfinfo.frames = out_len ; 102 sfinfo.channels = 1 ; 103 sfinfo.format = filetype ; 104 105 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; 106 107 test_write_short_or_die (file, 0, output, out_len, __LINE__) ; 108 109 sf_close (file) ; 110 111 memset (input, 0, sizeof (input)) ; 112 113 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; 114 115 exit_if_true (sfinfo.format != filetype, "\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, filetype, sfinfo.format) ; 116 exit_if_true (sfinfo.frames < out_len, "\n\nLine %d: Incorrect number of frames in file (too short). (%" PRId64 " should be %d)\n", __LINE__, sfinfo.frames, DFT_DATA_LENGTH) ; 117 exit_if_true (sfinfo.channels != 1, "\n\nLine %d: Incorrect number of channels in file.\n", __LINE__) ; 118 119 check_log_buffer_or_die (file, __LINE__) ; 120 121 test_read_short_or_die (file, 0, input, out_len, __LINE__) ; 122 123 sf_close (file) ; 124 125 for (k = 0 ; k < out_len ; k++) 126 exit_if_true (input [k] != output [k], 127 "\n\nLine: %d: Error on input %d, expected %d, got %d\n", __LINE__, k, output [k], input [k]) ; 128 129 puts ("ok") ; 130 unlink (filename) ; 131 132 return ; 133} /* short_lrw_test */ 134 135static void 136int_lrw_test (const char *filename, int filetype, const int * output, int out_len) 137{ SNDFILE *file ; 138 SF_INFO sfinfo ; 139 int k ; 140 int input [BUFFER_LENGTH] ; 141 142 print_test_name ("int_lrw_test", filename) ; 143 144 exit_if_true (BUFFER_LENGTH > out_len, "\n\nLine %d: Bad array length.\n", __LINE__) ; 145 146 sfinfo.samplerate = SAMPLE_RATE ; 147 sfinfo.frames = out_len ; 148 sfinfo.channels = 1 ; 149 sfinfo.format = filetype ; 150 151 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; 152 153 test_write_int_or_die (file, 0, output, out_len, __LINE__) ; 154 155 sf_close (file) ; 156 157 memset (input, 0, sizeof (input)) ; 158 159 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; 160 161 exit_if_true (sfinfo.format != filetype, "\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, filetype, sfinfo.format) ; 162 exit_if_true (sfinfo.frames < out_len, "\n\nLine %d: Incorrect number of frames in file (too int). (%" PRId64 " should be %d)\n", __LINE__, sfinfo.frames, DFT_DATA_LENGTH) ; 163 exit_if_true (sfinfo.channels != 1, "\n\nLine %d: Incorrect number of channels in file.\n", __LINE__) ; 164 165 check_log_buffer_or_die (file, __LINE__) ; 166 167 test_read_int_or_die (file, 0, input, out_len, __LINE__) ; 168 169 sf_close (file) ; 170 171 for (k = 0 ; k < out_len ; k++) 172 exit_if_true (input [k] != output [k], 173 "\n\nLine: %d: Error on input %d, expected %d, got %d\n", __LINE__, k, output [k], input [k]) ; 174 175 puts ("ok") ; 176 unlink (filename) ; 177 178 return ; 179} /* int_lrw_test */ 180 181static void 182float_lrw_test (const char *filename, int filetype, const float * output, int out_len) 183{ SNDFILE *file ; 184 SF_INFO sfinfo ; 185 int k ; 186 float input [BUFFER_LENGTH] ; 187 188 print_test_name ("float_lrw_test", filename) ; 189 190 exit_if_true (BUFFER_LENGTH > out_len, "\n\nLine %d: Bad array length.\n", __LINE__) ; 191 192 sfinfo.samplerate = SAMPLE_RATE ; 193 sfinfo.frames = out_len ; 194 sfinfo.channels = 1 ; 195 sfinfo.format = filetype ; 196 197 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; 198 199 test_write_float_or_die (file, 0, output, out_len, __LINE__) ; 200 201 sf_close (file) ; 202 203 memset (input, 0, sizeof (input)) ; 204 205 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; 206 207 exit_if_true (sfinfo.format != filetype, "\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, filetype, sfinfo.format) ; 208 exit_if_true (sfinfo.frames < out_len, "\n\nLine %d: Incorrect number of frames in file (too float). (%" PRId64 " should be %d)\n", __LINE__, sfinfo.frames, DFT_DATA_LENGTH) ; 209 exit_if_true (sfinfo.channels != 1, "\n\nLine %d: Incorrect number of channels in file.\n", __LINE__) ; 210 211 check_log_buffer_or_die (file, __LINE__) ; 212 213 test_read_float_or_die (file, 0, input, out_len, __LINE__) ; 214 215 sf_close (file) ; 216 217 for (k = 0 ; k < out_len ; k++) 218 exit_if_true (fabs (input [k] - output [k]) > 0.00001, 219 "\n\nLine: %d: Error on input %d, expected %f, got %f\n", __LINE__, k, output [k], input [k]) ; 220 221 puts ("ok") ; 222 unlink (filename) ; 223 224 return ; 225} /* float_lrw_test */ 226 227static void 228double_lrw_test (const char *filename, int filetype, const double * output, int out_len) 229{ SNDFILE *file ; 230 SF_INFO sfinfo ; 231 int k ; 232 double input [BUFFER_LENGTH] ; 233 234 print_test_name ("double_lrw_test", filename) ; 235 236 exit_if_true (BUFFER_LENGTH > out_len, "\n\nLine %d: Bad array length.\n", __LINE__) ; 237 238 sfinfo.samplerate = SAMPLE_RATE ; 239 sfinfo.frames = out_len ; 240 sfinfo.channels = 1 ; 241 sfinfo.format = filetype ; 242 243 file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; 244 245 test_write_double_or_die (file, 0, output, out_len, __LINE__) ; 246 247 sf_close (file) ; 248 249 memset (input, 0, sizeof (input)) ; 250 251 file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; 252 253 exit_if_true (sfinfo.format != filetype, "\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, filetype, sfinfo.format) ; 254 exit_if_true (sfinfo.frames < out_len, "\n\nLine %d: Incorrect number of frames in file (too double). (%" PRId64 " should be %d)\n", __LINE__, sfinfo.frames, DFT_DATA_LENGTH) ; 255 exit_if_true (sfinfo.channels != 1, "\n\nLine %d: Incorrect number of channels in file.\n", __LINE__) ; 256 257 check_log_buffer_or_die (file, __LINE__) ; 258 259 test_read_double_or_die (file, 0, input, out_len, __LINE__) ; 260 261 sf_close (file) ; 262 263 for (k = 0 ; k < out_len ; k++) 264 exit_if_true (fabs (input [k] - output [k]) > 0.00001, 265 "\n\nLine: %d: Error on input %d, expected %f, got %f\n", __LINE__, k, output [k], input [k]) ; 266 267 puts ("ok") ; 268 unlink (filename) ; 269 270 return ; 271} /* double_lrw_test */ 272 273