1b815c7f3Sopenharmony_ci[+ AutoGen5 template c +] 2b815c7f3Sopenharmony_ci/* 3b815c7f3Sopenharmony_ci** Copyright (C) 1999-2012 Erik de Castro Lopo <erikd@mega-nerd.com> 4b815c7f3Sopenharmony_ci** 5b815c7f3Sopenharmony_ci** This program is free software; you can redistribute it and/or modify 6b815c7f3Sopenharmony_ci** it under the terms of the GNU General Public License as published by 7b815c7f3Sopenharmony_ci** the Free Software Foundation; either version 2 of the License, or 8b815c7f3Sopenharmony_ci** (at your option) any later version. 9b815c7f3Sopenharmony_ci** 10b815c7f3Sopenharmony_ci** This program is distributed in the hope that it will be useful, 11b815c7f3Sopenharmony_ci** but WITHOUT ANY WARRANTY; without even the implied warranty of 12b815c7f3Sopenharmony_ci** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13b815c7f3Sopenharmony_ci** GNU General Public License for more details. 14b815c7f3Sopenharmony_ci** 15b815c7f3Sopenharmony_ci** You should have received a copy of the GNU General Public License 16b815c7f3Sopenharmony_ci** along with this program; if not, write to the Free Software 17b815c7f3Sopenharmony_ci** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18b815c7f3Sopenharmony_ci*/ 19b815c7f3Sopenharmony_ci 20b815c7f3Sopenharmony_ci#include "sfconfig.h" 21b815c7f3Sopenharmony_ci 22b815c7f3Sopenharmony_ci#include <stdio.h> 23b815c7f3Sopenharmony_ci#include <stdlib.h> 24b815c7f3Sopenharmony_ci#include <string.h> 25b815c7f3Sopenharmony_ci#include <math.h> 26b815c7f3Sopenharmony_ci#include <inttypes.h> 27b815c7f3Sopenharmony_ci 28b815c7f3Sopenharmony_ci#if HAVE_UNISTD_H 29b815c7f3Sopenharmony_ci#include <unistd.h> 30b815c7f3Sopenharmony_ci#else 31b815c7f3Sopenharmony_ci#include "sf_unistd.h" 32b815c7f3Sopenharmony_ci#endif 33b815c7f3Sopenharmony_ci 34b815c7f3Sopenharmony_ci#include <sndfile.h> 35b815c7f3Sopenharmony_ci 36b815c7f3Sopenharmony_ci#include "utils.h" 37b815c7f3Sopenharmony_ci 38b815c7f3Sopenharmony_ci#ifndef M_PI 39b815c7f3Sopenharmony_ci#define M_PI 3.14159265358979323846264338 40b815c7f3Sopenharmony_ci#endif 41b815c7f3Sopenharmony_ci 42b815c7f3Sopenharmony_ci#define HALF_BUFFER_SIZE (1 << 12) 43b815c7f3Sopenharmony_ci#define BUFFER_SIZE (2 * HALF_BUFFER_SIZE) 44b815c7f3Sopenharmony_ci 45b815c7f3Sopenharmony_ci#define SINE_AMP 1.1 46b815c7f3Sopenharmony_ci#define MAX_ERROR 0.0202 47b815c7f3Sopenharmony_ci 48b815c7f3Sopenharmony_ci[+ FOR float_type +] 49b815c7f3Sopenharmony_ci[+ FOR data_type 50b815c7f3Sopenharmony_ci+]static void [+ (get "float_short_name") +]_scale_clip_test_[+ (get "name") +] (const char *filename, int filetype, float maxval) ; 51b815c7f3Sopenharmony_ci[+ ENDFOR data_type 52b815c7f3Sopenharmony_ci+][+ ENDFOR float_type +] 53b815c7f3Sopenharmony_ci 54b815c7f3Sopenharmony_ci[+ FOR float_type +] 55b815c7f3Sopenharmony_ci[+ FOR int_type 56b815c7f3Sopenharmony_ci+]static void [+ (get "float_short_name") +]_[+ (get "int_type_name") +]_clip_read_test (const char *filename, int filetype) ; 57b815c7f3Sopenharmony_ci[+ ENDFOR int_type 58b815c7f3Sopenharmony_ci+][+ ENDFOR float_type +] 59b815c7f3Sopenharmony_ci 60b815c7f3Sopenharmony_ci[+ FOR int_type +] 61b815c7f3Sopenharmony_ci[+ FOR float_type 62b815c7f3Sopenharmony_ci+]static void [+ (get "int_type_name") +]_[+ (get "float_short_name") +]_scale_write_test (const char *filename, int filetype) ; 63b815c7f3Sopenharmony_ci[+ ENDFOR float_type 64b815c7f3Sopenharmony_ci+][+ ENDFOR int_type +] 65b815c7f3Sopenharmony_ci 66b815c7f3Sopenharmony_citypedef union 67b815c7f3Sopenharmony_ci{ double dbl [BUFFER_SIZE] ; 68b815c7f3Sopenharmony_ci float flt [BUFFER_SIZE] ; 69b815c7f3Sopenharmony_ci int i [BUFFER_SIZE] ; 70b815c7f3Sopenharmony_ci short s [BUFFER_SIZE] ; 71b815c7f3Sopenharmony_ci} BUFFER ; 72b815c7f3Sopenharmony_ci 73b815c7f3Sopenharmony_ci/* Data buffer. */ 74b815c7f3Sopenharmony_cistatic BUFFER buffer_out ; 75b815c7f3Sopenharmony_cistatic BUFFER buffer_in ; 76b815c7f3Sopenharmony_ci 77b815c7f3Sopenharmony_ciint 78b815c7f3Sopenharmony_cimain (void) 79b815c7f3Sopenharmony_ci{ 80b815c7f3Sopenharmony_ci flt_scale_clip_test_08 ("scale_clip_s8.au", SF_FORMAT_AU | SF_FORMAT_PCM_S8, 1.0 * 0x80) ; 81b815c7f3Sopenharmony_ci flt_scale_clip_test_08 ("scale_clip_u8.wav", SF_FORMAT_WAV | SF_FORMAT_PCM_U8, 1.0 * 0x80) ; 82b815c7f3Sopenharmony_ci 83b815c7f3Sopenharmony_ci dbl_scale_clip_test_08 ("scale_clip_s8.au", SF_FORMAT_AU | SF_FORMAT_PCM_S8, 1.0 * 0x80) ; 84b815c7f3Sopenharmony_ci dbl_scale_clip_test_08 ("scale_clip_u8.wav", SF_FORMAT_WAV | SF_FORMAT_PCM_U8, 1.0 * 0x80) ; 85b815c7f3Sopenharmony_ci 86b815c7f3Sopenharmony_ci /* 87b815c7f3Sopenharmony_ci ** Now use SF_FORMAT_AU where possible because it allows both 88b815c7f3Sopenharmony_ci ** big and little endian files. 89b815c7f3Sopenharmony_ci */ 90b815c7f3Sopenharmony_ci 91b815c7f3Sopenharmony_ci flt_scale_clip_test_16 ("scale_clip_be16.au", SF_ENDIAN_BIG | SF_FORMAT_AU | SF_FORMAT_PCM_16, 1.0 * 0x8000) ; 92b815c7f3Sopenharmony_ci flt_scale_clip_test_16 ("scale_clip_le16.au", SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_PCM_16, 1.0 * 0x8000) ; 93b815c7f3Sopenharmony_ci flt_scale_clip_test_24 ("scale_clip_be24.au", SF_ENDIAN_BIG | SF_FORMAT_AU | SF_FORMAT_PCM_24, 1.0 * 0x800000) ; 94b815c7f3Sopenharmony_ci flt_scale_clip_test_24 ("scale_clip_le24.au", SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_PCM_24, 1.0 * 0x800000) ; 95b815c7f3Sopenharmony_ci flt_scale_clip_test_32 ("scale_clip_be32.au", SF_ENDIAN_BIG | SF_FORMAT_AU | SF_FORMAT_PCM_32, 1.0 * 0x80000000) ; 96b815c7f3Sopenharmony_ci flt_scale_clip_test_32 ("scale_clip_le32.au", SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_PCM_32, 1.0 * 0x80000000) ; 97b815c7f3Sopenharmony_ci 98b815c7f3Sopenharmony_ci dbl_scale_clip_test_16 ("scale_clip_be16.au", SF_ENDIAN_BIG | SF_FORMAT_AU | SF_FORMAT_PCM_16, 1.0 * 0x8000) ; 99b815c7f3Sopenharmony_ci dbl_scale_clip_test_16 ("scale_clip_le16.au", SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_PCM_16, 1.0 * 0x8000) ; 100b815c7f3Sopenharmony_ci dbl_scale_clip_test_24 ("scale_clip_be24.au", SF_ENDIAN_BIG | SF_FORMAT_AU | SF_FORMAT_PCM_24, 1.0 * 0x800000) ; 101b815c7f3Sopenharmony_ci dbl_scale_clip_test_24 ("scale_clip_le24.au", SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_PCM_24, 1.0 * 0x800000) ; 102b815c7f3Sopenharmony_ci dbl_scale_clip_test_32 ("scale_clip_be32.au", SF_ENDIAN_BIG | SF_FORMAT_AU | SF_FORMAT_PCM_32, 1.0 * 0x80000000) ; 103b815c7f3Sopenharmony_ci dbl_scale_clip_test_32 ("scale_clip_le32.au", SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_PCM_32, 1.0 * 0x80000000) ; 104b815c7f3Sopenharmony_ci 105b815c7f3Sopenharmony_ci flt_short_clip_read_test ("flt_short.au" , SF_ENDIAN_BIG | SF_FORMAT_AU | SF_FORMAT_FLOAT) ; 106b815c7f3Sopenharmony_ci flt_int_clip_read_test ("flt_int.au" , SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_FLOAT) ; 107b815c7f3Sopenharmony_ci dbl_short_clip_read_test ("dbl_short.au" , SF_ENDIAN_BIG | SF_FORMAT_AU | SF_FORMAT_DOUBLE) ; 108b815c7f3Sopenharmony_ci dbl_int_clip_read_test ("dbl_int.au" , SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_DOUBLE) ; 109b815c7f3Sopenharmony_ci 110b815c7f3Sopenharmony_ci short_flt_scale_write_test ("short_flt.au" , SF_ENDIAN_BIG | SF_FORMAT_AU | SF_FORMAT_FLOAT) ; 111b815c7f3Sopenharmony_ci int_flt_scale_write_test ("int_flt.au" , SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_FLOAT) ; 112b815c7f3Sopenharmony_ci short_dbl_scale_write_test ("short_dbl.au" , SF_ENDIAN_BIG | SF_FORMAT_AU | SF_FORMAT_DOUBLE) ; 113b815c7f3Sopenharmony_ci int_dbl_scale_write_test ("int_dbl.au" , SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_DOUBLE) ; 114b815c7f3Sopenharmony_ci 115b815c7f3Sopenharmony_ci return 0 ; 116b815c7f3Sopenharmony_ci} /* main */ 117b815c7f3Sopenharmony_ci 118b815c7f3Sopenharmony_ci/*============================================================================================ 119b815c7f3Sopenharmony_ci** Here are the test functions. 120b815c7f3Sopenharmony_ci*/ 121b815c7f3Sopenharmony_ci 122b815c7f3Sopenharmony_ci[+ FOR float_type +] 123b815c7f3Sopenharmony_ci[+ FOR data_type 124b815c7f3Sopenharmony_ci+]static void 125b815c7f3Sopenharmony_ci[+ (get "float_short_name") +]_scale_clip_test_[+ (get "name") +] (const char *filename, int filetype, float maxval) 126b815c7f3Sopenharmony_ci{ SNDFILE *file ; 127b815c7f3Sopenharmony_ci SF_INFO sfinfo ; 128b815c7f3Sopenharmony_ci int k ; 129b815c7f3Sopenharmony_ci [+ (get "float_type_name") +] *data_out, *data_in ; 130b815c7f3Sopenharmony_ci double diff, clip_max_diff ; 131b815c7f3Sopenharmony_ci 132b815c7f3Sopenharmony_ci print_test_name ("[+ (get "float_short_name") +]_scale_clip_test_[+ (get "name") +]", filename) ; 133b815c7f3Sopenharmony_ci 134b815c7f3Sopenharmony_ci data_out = buffer_out.[+ (get "float_short_name") +] ; 135b815c7f3Sopenharmony_ci data_in = buffer_in.[+ (get "float_short_name") +] ; 136b815c7f3Sopenharmony_ci 137b815c7f3Sopenharmony_ci for (k = 0 ; k < HALF_BUFFER_SIZE ; k++) 138b815c7f3Sopenharmony_ci { data_out [k] = 1.2 * sin (2 * M_PI * k / HALF_BUFFER_SIZE) ; 139b815c7f3Sopenharmony_ci data_out [k + HALF_BUFFER_SIZE] = data_out [k] * maxval ; 140b815c7f3Sopenharmony_ci } ; 141b815c7f3Sopenharmony_ci 142b815c7f3Sopenharmony_ci sfinfo.samplerate = 44100 ; 143b815c7f3Sopenharmony_ci sfinfo.frames = 123456789 ; /* Wrong length. Library should correct this on sf_close. */ 144b815c7f3Sopenharmony_ci sfinfo.channels = 1 ; 145b815c7f3Sopenharmony_ci sfinfo.format = filetype ; 146b815c7f3Sopenharmony_ci 147b815c7f3Sopenharmony_ci /* 148b815c7f3Sopenharmony_ci ** Write two versions of the data: 149b815c7f3Sopenharmony_ci ** normalized and clipped 150b815c7f3Sopenharmony_ci ** un-normalized and clipped. 151b815c7f3Sopenharmony_ci */ 152b815c7f3Sopenharmony_ci 153b815c7f3Sopenharmony_ci file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; 154b815c7f3Sopenharmony_ci sf_command (file, SFC_SET_CLIPPING, NULL, SF_TRUE) ; 155b815c7f3Sopenharmony_ci test_write_[+ (get "float_type_name") +]_or_die (file, 0, data_out, HALF_BUFFER_SIZE, __LINE__) ; 156b815c7f3Sopenharmony_ci sf_command (file, SFC_SET_NORM_[+ (get "float_upper_name") +], NULL, SF_FALSE) ; 157b815c7f3Sopenharmony_ci test_write_[+ (get "float_type_name") +]_or_die (file, 0, data_out + HALF_BUFFER_SIZE, HALF_BUFFER_SIZE, __LINE__) ; 158b815c7f3Sopenharmony_ci sf_close (file) ; 159b815c7f3Sopenharmony_ci 160b815c7f3Sopenharmony_ci memset (&buffer_in, 0, sizeof (buffer_in)) ; 161b815c7f3Sopenharmony_ci 162b815c7f3Sopenharmony_ci file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; 163b815c7f3Sopenharmony_ci 164b815c7f3Sopenharmony_ci sfinfo.format &= (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK) ; 165b815c7f3Sopenharmony_ci 166b815c7f3Sopenharmony_ci if (sfinfo.format != (filetype & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK))) 167b815c7f3Sopenharmony_ci { printf ("\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n\n", __LINE__, filetype, sfinfo.format) ; 168b815c7f3Sopenharmony_ci exit (1) ; 169b815c7f3Sopenharmony_ci } ; 170b815c7f3Sopenharmony_ci 171b815c7f3Sopenharmony_ci if (sfinfo.frames != BUFFER_SIZE) 172b815c7f3Sopenharmony_ci { printf ("\n\nLine %d: Incorrect number of frames in file (%d => %" PRId64 ").\n\n", __LINE__, BUFFER_SIZE, sfinfo.frames) ; 173b815c7f3Sopenharmony_ci exit (1) ; 174b815c7f3Sopenharmony_ci } ; 175b815c7f3Sopenharmony_ci 176b815c7f3Sopenharmony_ci if (sfinfo.channels != 1) 177b815c7f3Sopenharmony_ci { printf ("\n\nLine %d: Incorrect number of channels in file.\n\n", __LINE__) ; 178b815c7f3Sopenharmony_ci exit (1) ; 179b815c7f3Sopenharmony_ci } ; 180b815c7f3Sopenharmony_ci 181b815c7f3Sopenharmony_ci check_log_buffer_or_die (file, __LINE__) ; 182b815c7f3Sopenharmony_ci 183b815c7f3Sopenharmony_ci test_read_[+ (get "float_type_name") +]_or_die (file, 0, data_in, HALF_BUFFER_SIZE, __LINE__) ; 184b815c7f3Sopenharmony_ci sf_command (file, SFC_SET_NORM_[+ (get "float_upper_name") +], NULL, SF_FALSE) ; 185b815c7f3Sopenharmony_ci test_read_[+ (get "float_type_name") +]_or_die (file, 0, data_in + HALF_BUFFER_SIZE, HALF_BUFFER_SIZE, __LINE__) ; 186b815c7f3Sopenharmony_ci sf_close (file) ; 187b815c7f3Sopenharmony_ci 188b815c7f3Sopenharmony_ci /* Check normalized version. */ 189b815c7f3Sopenharmony_ci clip_max_diff = 0.0 ; 190b815c7f3Sopenharmony_ci for (k = 0 ; k < HALF_BUFFER_SIZE ; k++) 191b815c7f3Sopenharmony_ci { if (fabs (data_in [k]) > 1.0) 192b815c7f3Sopenharmony_ci { printf ("\n\nLine %d: Input sample %d/%d (%f) has not been clipped.\n\n", __LINE__, k, BUFFER_SIZE, data_in [k]) ; 193b815c7f3Sopenharmony_ci exit (1) ; 194b815c7f3Sopenharmony_ci } ; 195b815c7f3Sopenharmony_ci 196b815c7f3Sopenharmony_ci if (data_out [k] * data_in [k] < 0.0) 197b815c7f3Sopenharmony_ci { printf ("\n\nLine %d: Data wrap around at index %d/%d.\n\n", __LINE__, k, BUFFER_SIZE) ; 198b815c7f3Sopenharmony_ci exit (1) ; 199b815c7f3Sopenharmony_ci } ; 200b815c7f3Sopenharmony_ci 201b815c7f3Sopenharmony_ci if (fabs (data_out [k]) > 1.0) 202b815c7f3Sopenharmony_ci continue ; 203b815c7f3Sopenharmony_ci 204b815c7f3Sopenharmony_ci diff = fabs (data_out [k] - data_in [k]) ; 205b815c7f3Sopenharmony_ci if (diff > clip_max_diff) 206b815c7f3Sopenharmony_ci clip_max_diff = diff ; 207b815c7f3Sopenharmony_ci } ; 208b815c7f3Sopenharmony_ci 209b815c7f3Sopenharmony_ci if (clip_max_diff < 1e-20) 210b815c7f3Sopenharmony_ci { printf ("\n\nLine %d: Clipping difference (%e) too small (normalized).\n\n", __LINE__, clip_max_diff) ; 211b815c7f3Sopenharmony_ci exit (1) ; 212b815c7f3Sopenharmony_ci } ; 213b815c7f3Sopenharmony_ci 214b815c7f3Sopenharmony_ci if (clip_max_diff > [+ (get "error_val") +]) 215b815c7f3Sopenharmony_ci { printf ("\n\nLine %d: Clipping difference (%e) too large (normalized).\n\n", __LINE__, clip_max_diff) ; 216b815c7f3Sopenharmony_ci exit (1) ; 217b815c7f3Sopenharmony_ci } ; 218b815c7f3Sopenharmony_ci 219b815c7f3Sopenharmony_ci /* Check the un-normalized data. */ 220b815c7f3Sopenharmony_ci clip_max_diff = 0.0 ; 221b815c7f3Sopenharmony_ci for (k = HALF_BUFFER_SIZE ; k < BUFFER_SIZE ; k++) 222b815c7f3Sopenharmony_ci { if (fabs (data_in [k]) > maxval) 223b815c7f3Sopenharmony_ci { printf ("\n\nLine %d: Input sample %d/%d (%f) has not been clipped.\n\n", __LINE__, k, BUFFER_SIZE, data_in [k]) ; 224b815c7f3Sopenharmony_ci exit (1) ; 225b815c7f3Sopenharmony_ci } ; 226b815c7f3Sopenharmony_ci 227b815c7f3Sopenharmony_ci if (data_out [k] * data_in [k] < 0.0) 228b815c7f3Sopenharmony_ci { printf ("\n\nLine %d: Data wrap around at index %d/%d.\n\n", __LINE__, k, BUFFER_SIZE) ; 229b815c7f3Sopenharmony_ci exit (1) ; 230b815c7f3Sopenharmony_ci } ; 231b815c7f3Sopenharmony_ci 232b815c7f3Sopenharmony_ci if (fabs (data_out [k]) > maxval) 233b815c7f3Sopenharmony_ci continue ; 234b815c7f3Sopenharmony_ci 235b815c7f3Sopenharmony_ci diff = fabs (data_out [k] - data_in [k]) ; 236b815c7f3Sopenharmony_ci if (diff > clip_max_diff) 237b815c7f3Sopenharmony_ci clip_max_diff = diff ; 238b815c7f3Sopenharmony_ci } ; 239b815c7f3Sopenharmony_ci 240b815c7f3Sopenharmony_ci if (clip_max_diff < 1e-20) 241b815c7f3Sopenharmony_ci { printf ("\n\nLine %d: Clipping difference (%e) too small (un-normalized).\n\n", __LINE__, clip_max_diff) ; 242b815c7f3Sopenharmony_ci exit (1) ; 243b815c7f3Sopenharmony_ci } ; 244b815c7f3Sopenharmony_ci 245b815c7f3Sopenharmony_ci if (clip_max_diff > 1.0) 246b815c7f3Sopenharmony_ci { printf ("\n\nLine %d: Clipping difference (%e) too large (un-normalised).\n\n", __LINE__, clip_max_diff) ; 247b815c7f3Sopenharmony_ci exit (1) ; 248b815c7f3Sopenharmony_ci } ; 249b815c7f3Sopenharmony_ci 250b815c7f3Sopenharmony_ci printf ("ok\n") ; 251b815c7f3Sopenharmony_ci unlink (filename) ; 252b815c7f3Sopenharmony_ci} /* [+ (get "float_short_name") +]_scale_clip_test_[+ (get "name") +] */ 253b815c7f3Sopenharmony_ci 254b815c7f3Sopenharmony_ci[+ ENDFOR data_type 255b815c7f3Sopenharmony_ci+] 256b815c7f3Sopenharmony_ci[+ ENDFOR float_type +] 257b815c7f3Sopenharmony_ci 258b815c7f3Sopenharmony_ci/*============================================================================== 259b815c7f3Sopenharmony_ci*/ 260b815c7f3Sopenharmony_ci 261b815c7f3Sopenharmony_ci[+ FOR float_type +] 262b815c7f3Sopenharmony_ci[+ FOR int_type 263b815c7f3Sopenharmony_ci+]static void [+ (get "float_short_name") +]_[+ (get "int_type_name") +]_clip_read_test (const char *filename, int filetype) 264b815c7f3Sopenharmony_ci{ SNDFILE *file ; 265b815c7f3Sopenharmony_ci SF_INFO sfinfo ; 266b815c7f3Sopenharmony_ci [+ (get "float_type_name") +] *data_out ; 267b815c7f3Sopenharmony_ci [+ (get "int_type_name") +] *data_in, max_value ; 268b815c7f3Sopenharmony_ci int k ; 269b815c7f3Sopenharmony_ci 270b815c7f3Sopenharmony_ci print_test_name ("[+ (get "float_short_name") +]_[+ (get "int_type_name") +]_clip_read_test", filename) ; 271b815c7f3Sopenharmony_ci 272b815c7f3Sopenharmony_ci data_out = buffer_out.[+ (get "float_short_name") +] ; 273b815c7f3Sopenharmony_ci data_in = buffer_in.[+ (get "int_short_name") +] ; 274b815c7f3Sopenharmony_ci 275b815c7f3Sopenharmony_ci for (k = 0 ; k < BUFFER_SIZE ; k++) 276b815c7f3Sopenharmony_ci data_out [k] = 0.995 * sin (4 * M_PI * k / BUFFER_SIZE) ; 277b815c7f3Sopenharmony_ci data_out [BUFFER_SIZE / 8] = 1.0 ; 278b815c7f3Sopenharmony_ci data_out [3 * BUFFER_SIZE / 8] = -1.000000001 ; 279b815c7f3Sopenharmony_ci data_out [5 * BUFFER_SIZE / 8] = 1.0 ; 280b815c7f3Sopenharmony_ci data_out [7 * BUFFER_SIZE / 8] = -1.000000001 ; 281b815c7f3Sopenharmony_ci 282b815c7f3Sopenharmony_ci memset (&sfinfo, 0, sizeof (sfinfo)) ; 283b815c7f3Sopenharmony_ci sfinfo.samplerate = 44100 ; 284b815c7f3Sopenharmony_ci sfinfo.frames = 123456789 ; /* Wrong length. Library should correct this on sf_close. */ 285b815c7f3Sopenharmony_ci sfinfo.channels = 1 ; 286b815c7f3Sopenharmony_ci sfinfo.format = filetype ; 287b815c7f3Sopenharmony_ci 288b815c7f3Sopenharmony_ci /* Save unclipped data to the file. */ 289b815c7f3Sopenharmony_ci file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; 290b815c7f3Sopenharmony_ci test_write_[+ (get "float_type_name") +]_or_die (file, 0, data_out, BUFFER_SIZE, __LINE__) ; 291b815c7f3Sopenharmony_ci sf_close (file) ; 292b815c7f3Sopenharmony_ci 293b815c7f3Sopenharmony_ci memset (&sfinfo, 0, sizeof (sfinfo)) ; 294b815c7f3Sopenharmony_ci 295b815c7f3Sopenharmony_ci file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; 296b815c7f3Sopenharmony_ci sf_command (file, SFC_SET_SCALE_FLOAT_INT_READ, NULL, SF_TRUE) ; 297b815c7f3Sopenharmony_ci 298b815c7f3Sopenharmony_ci sfinfo.format &= (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK) ; 299b815c7f3Sopenharmony_ci 300b815c7f3Sopenharmony_ci if (sfinfo.format != (filetype & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK))) 301b815c7f3Sopenharmony_ci { printf ("\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n\n", __LINE__, filetype, sfinfo.format) ; 302b815c7f3Sopenharmony_ci exit (1) ; 303b815c7f3Sopenharmony_ci } ; 304b815c7f3Sopenharmony_ci 305b815c7f3Sopenharmony_ci if (sfinfo.frames != BUFFER_SIZE) 306b815c7f3Sopenharmony_ci { printf ("\n\nLine %d: Incorrect number of frames in file (%d => %" PRId64 ").\n\n", __LINE__, BUFFER_SIZE, sfinfo.frames) ; 307b815c7f3Sopenharmony_ci exit (1) ; 308b815c7f3Sopenharmony_ci } ; 309b815c7f3Sopenharmony_ci 310b815c7f3Sopenharmony_ci if (sfinfo.channels != 1) 311b815c7f3Sopenharmony_ci { printf ("\n\nLine %d: Incorrect number of channels in file.\n\n", __LINE__) ; 312b815c7f3Sopenharmony_ci exit (1) ; 313b815c7f3Sopenharmony_ci } ; 314b815c7f3Sopenharmony_ci 315b815c7f3Sopenharmony_ci check_log_buffer_or_die (file, __LINE__) ; 316b815c7f3Sopenharmony_ci 317b815c7f3Sopenharmony_ci sf_command (file, SFC_SET_CLIPPING, NULL, SF_TRUE) ; 318b815c7f3Sopenharmony_ci test_read_[+ (get "int_type_name") +]_or_die (file, 0, data_in, BUFFER_SIZE, __LINE__) ; 319b815c7f3Sopenharmony_ci /*-sf_command (file, SFC_SET_NORM_[+ (get "float_upper_name") +], NULL, SF_FALSE) ;-*/ 320b815c7f3Sopenharmony_ci sf_close (file) ; 321b815c7f3Sopenharmony_ci 322b815c7f3Sopenharmony_ci /* Check the first half. */ 323b815c7f3Sopenharmony_ci max_value = 0 ; 324b815c7f3Sopenharmony_ci for (k = 0 ; k < sfinfo.frames ; k++) 325b815c7f3Sopenharmony_ci { /* Check if data_out has different sign from data_in. */ 326b815c7f3Sopenharmony_ci if ((data_out [k] < 0.0 && data_in [k] > 0) || (data_out [k] > 0.0 && data_in [k] < 0)) 327b815c7f3Sopenharmony_ci { printf ("\n\nLine %d: Data wrap around at index %d/%d (%f -> %d).\n\n", __LINE__, k, BUFFER_SIZE, data_out [k], data_in [k]) ; 328b815c7f3Sopenharmony_ci exit (1) ; 329b815c7f3Sopenharmony_ci } ; 330b815c7f3Sopenharmony_ci max_value = (max_value > abs (data_in [k])) ? max_value : abs (data_in [k]) ; 331b815c7f3Sopenharmony_ci } ; 332b815c7f3Sopenharmony_ci 333b815c7f3Sopenharmony_ci unlink (filename) ; 334b815c7f3Sopenharmony_ci puts ("ok") ; 335b815c7f3Sopenharmony_ci} /* [+ (get "float_short_name") +]_[+ (get "int_type_name") +]_clip_read_test */ 336b815c7f3Sopenharmony_ci[+ ENDFOR int_type 337b815c7f3Sopenharmony_ci+][+ ENDFOR float_type +] 338b815c7f3Sopenharmony_ci 339b815c7f3Sopenharmony_ci/*============================================================================== 340b815c7f3Sopenharmony_ci*/ 341b815c7f3Sopenharmony_ci 342b815c7f3Sopenharmony_ci[+ FOR int_type +] 343b815c7f3Sopenharmony_ci[+ FOR float_type 344b815c7f3Sopenharmony_ci+]static void [+ (get "int_type_name") +]_[+ (get "float_short_name") +]_scale_write_test (const char *filename, int filetype) 345b815c7f3Sopenharmony_ci{ SNDFILE *file ; 346b815c7f3Sopenharmony_ci SF_INFO sfinfo ; 347b815c7f3Sopenharmony_ci [+ (get "int_type_name") +] *data_out ; 348b815c7f3Sopenharmony_ci [+ (get "float_type_name") +] *data_in, max_value ; 349b815c7f3Sopenharmony_ci int k ; 350b815c7f3Sopenharmony_ci 351b815c7f3Sopenharmony_ci print_test_name ("[+ (get "int_type_name") +]_[+ (get "float_short_name") +]_clip_write_test", filename) ; 352b815c7f3Sopenharmony_ci 353b815c7f3Sopenharmony_ci data_out = buffer_out.[+ (get "int_short_name") +] ; 354b815c7f3Sopenharmony_ci data_in = buffer_in.[+ (get "float_short_name") +] ; 355b815c7f3Sopenharmony_ci 356b815c7f3Sopenharmony_ci for (k = 0 ; k < BUFFER_SIZE ; k++) 357b815c7f3Sopenharmony_ci data_out [k] = [+ (get "float_to_int") +] ([+ (get "int_max_value") +] * 0.995 * sin (4 * M_PI * k / BUFFER_SIZE)) ; 358b815c7f3Sopenharmony_ci 359b815c7f3Sopenharmony_ci memset (&sfinfo, 0, sizeof (sfinfo)) ; 360b815c7f3Sopenharmony_ci sfinfo.samplerate = 44100 ; 361b815c7f3Sopenharmony_ci sfinfo.frames = 123456789 ; /* Wrong length. Library should correct this on sf_close. */ 362b815c7f3Sopenharmony_ci sfinfo.channels = 1 ; 363b815c7f3Sopenharmony_ci sfinfo.format = filetype ; 364b815c7f3Sopenharmony_ci 365b815c7f3Sopenharmony_ci file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ; 366b815c7f3Sopenharmony_ci test_write_[+ (get "int_type_name") +]_or_die (file, 0, data_out, BUFFER_SIZE, __LINE__) ; 367b815c7f3Sopenharmony_ci sf_command (file, SFC_SET_SCALE_INT_FLOAT_WRITE, NULL, SF_TRUE) ; 368b815c7f3Sopenharmony_ci test_write_[+ (get "int_type_name") +]_or_die (file, 0, data_out, BUFFER_SIZE, __LINE__) ; 369b815c7f3Sopenharmony_ci sf_command (file, SFC_SET_SCALE_INT_FLOAT_WRITE, NULL, SF_FALSE) ; 370b815c7f3Sopenharmony_ci test_write_[+ (get "int_type_name") +]_or_die (file, 0, data_out, BUFFER_SIZE, __LINE__) ; 371b815c7f3Sopenharmony_ci sf_close (file) ; 372b815c7f3Sopenharmony_ci 373b815c7f3Sopenharmony_ci memset (&sfinfo, 0, sizeof (sfinfo)) ; 374b815c7f3Sopenharmony_ci 375b815c7f3Sopenharmony_ci file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_TRUE, __LINE__) ; 376b815c7f3Sopenharmony_ci 377b815c7f3Sopenharmony_ci sfinfo.format &= (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK) ; 378b815c7f3Sopenharmony_ci 379b815c7f3Sopenharmony_ci if (sfinfo.format != (filetype & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK))) 380b815c7f3Sopenharmony_ci { printf ("\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n\n", __LINE__, filetype, sfinfo.format) ; 381b815c7f3Sopenharmony_ci exit (1) ; 382b815c7f3Sopenharmony_ci } ; 383b815c7f3Sopenharmony_ci 384b815c7f3Sopenharmony_ci if (sfinfo.frames != 3 * BUFFER_SIZE) 385b815c7f3Sopenharmony_ci { printf ("\n\nLine %d: Incorrect number of frames in file (%d => %" PRId64 ").\n\n", __LINE__, 3 * BUFFER_SIZE, sfinfo.frames) ; 386b815c7f3Sopenharmony_ci exit (1) ; 387b815c7f3Sopenharmony_ci } ; 388b815c7f3Sopenharmony_ci 389b815c7f3Sopenharmony_ci if (sfinfo.channels != 1) 390b815c7f3Sopenharmony_ci { printf ("\n\nLine %d: Incorrect number of channels in file.\n\n", __LINE__) ; 391b815c7f3Sopenharmony_ci exit (1) ; 392b815c7f3Sopenharmony_ci } ; 393b815c7f3Sopenharmony_ci 394b815c7f3Sopenharmony_ci check_log_buffer_or_die (file, __LINE__) ; 395b815c7f3Sopenharmony_ci 396b815c7f3Sopenharmony_ci /* Check the first section. */ 397b815c7f3Sopenharmony_ci test_read_[+ (get "float_type_name") +]_or_die (file, 0, data_in, BUFFER_SIZE, __LINE__) ; 398b815c7f3Sopenharmony_ci 399b815c7f3Sopenharmony_ci max_value = 0.0 ; 400b815c7f3Sopenharmony_ci for (k = 0 ; k < BUFFER_SIZE ; k++) 401b815c7f3Sopenharmony_ci max_value = (max_value > fabs (data_in [k])) ? max_value : fabs (data_in [k]) ; 402b815c7f3Sopenharmony_ci 403b815c7f3Sopenharmony_ci if (max_value < 1000.0) 404b815c7f3Sopenharmony_ci { printf ("\n\nLine %d: Max value (%f) < 1000.0.\n\n", __LINE__, max_value) ; 405b815c7f3Sopenharmony_ci exit (1) ; 406b815c7f3Sopenharmony_ci } ; 407b815c7f3Sopenharmony_ci 408b815c7f3Sopenharmony_ci /* Check the second section. */ 409b815c7f3Sopenharmony_ci test_read_[+ (get "float_type_name") +]_or_die (file, 0, data_in, BUFFER_SIZE, __LINE__) ; 410b815c7f3Sopenharmony_ci 411b815c7f3Sopenharmony_ci max_value = 0.0 ; 412b815c7f3Sopenharmony_ci for (k = 0 ; k < BUFFER_SIZE ; k++) 413b815c7f3Sopenharmony_ci max_value = (max_value > fabs (data_in [k])) ? max_value : fabs (data_in [k]) ; 414b815c7f3Sopenharmony_ci 415b815c7f3Sopenharmony_ci if (max_value > 1.0) 416b815c7f3Sopenharmony_ci { printf ("\n\nLine %d: Max value (%f) > 1.0.\n\n", __LINE__, max_value) ; 417b815c7f3Sopenharmony_ci exit (1) ; 418b815c7f3Sopenharmony_ci } ; 419b815c7f3Sopenharmony_ci 420b815c7f3Sopenharmony_ci /* Check the third section. */ 421b815c7f3Sopenharmony_ci test_read_[+ (get "float_type_name") +]_or_die (file, 0, data_in, BUFFER_SIZE, __LINE__) ; 422b815c7f3Sopenharmony_ci 423b815c7f3Sopenharmony_ci max_value = 0.0 ; 424b815c7f3Sopenharmony_ci for (k = 0 ; k < BUFFER_SIZE ; k++) 425b815c7f3Sopenharmony_ci max_value = (max_value > fabs (data_in [k])) ? max_value : fabs (data_in [k]) ; 426b815c7f3Sopenharmony_ci 427b815c7f3Sopenharmony_ci if (max_value < 1000.0) 428b815c7f3Sopenharmony_ci { printf ("\n\nLine %d: Max value (%f) < 1000.0.\n\n", __LINE__, max_value) ; 429b815c7f3Sopenharmony_ci exit (1) ; 430b815c7f3Sopenharmony_ci } ; 431b815c7f3Sopenharmony_ci 432b815c7f3Sopenharmony_ci sf_close (file) ; 433b815c7f3Sopenharmony_ci 434b815c7f3Sopenharmony_ci unlink (filename) ; 435b815c7f3Sopenharmony_ci puts ("ok") ; 436b815c7f3Sopenharmony_ci} /* [+ (get "int_type_name") +]_[+ (get "float_short_name") +]_scale_write_test */ 437b815c7f3Sopenharmony_ci[+ ENDFOR float_type 438b815c7f3Sopenharmony_ci+][+ ENDFOR int_type +] 439b815c7f3Sopenharmony_ci 440b815c7f3Sopenharmony_ci 441