utils.c 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162
  1. /*
  2. ** Copyright (C) 2002-2011 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. ** Utility functions to make writing the test suite easier.
  20. **
  21. ** The .c and .h files were generated automagically with Autogen from
  22. ** the files utils.def and utils.tpl.
  23. */
  24. #include "sfconfig.h"
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <inttypes.h>
  28. #if HAVE_UNISTD_H
  29. #include <unistd.h>
  30. #endif
  31. #if (HAVE_DECL_S_IRGRP == 0)
  32. #include <sf_unistd.h>
  33. #endif
  34. #include <errno.h>
  35. #include <string.h>
  36. #include <ctype.h>
  37. #include <math.h>
  38. #include <fcntl.h>
  39. #include <sys/stat.h>
  40. #include <sndfile.h>
  41. #include "utils.h"
  42. #ifndef M_PI
  43. #define M_PI 3.14159265358979323846264338
  44. #endif
  45. #define LOG_BUFFER_SIZE 2048
  46. /*
  47. ** Neat solution to the Win32/OS2 binary file flage requirement.
  48. ** If O_BINARY isn't already defined by the inclusion of the system
  49. ** headers, set it to zero.
  50. */
  51. #ifndef O_BINARY
  52. #define O_BINARY 0
  53. #endif
  54. void
  55. gen_windowed_sine_float (float *data, int len, double maximum)
  56. { int k ;
  57. memset (data, 0, len * sizeof (float)) ;
  58. /*
  59. ** Choose a frequency of 1/32 so that it aligns perfectly with a DFT
  60. ** bucket to minimise spreading of energy over more than one bucket.
  61. ** Also do not want to make the frequency too high as some of the
  62. ** codecs (ie gsm610) have a quite severe high frequency roll off.
  63. */
  64. len /= 2 ;
  65. for (k = 0 ; k < len ; k++)
  66. { data [k] = sin (2.0 * k * M_PI * 1.0 / 32.0 + 0.4) ;
  67. /* Apply Hanning Window. */
  68. data [k] *= maximum * (0.5 - 0.5 * cos (2.0 * M_PI * k / ((len) - 1))) ;
  69. }
  70. return ;
  71. } /* gen_windowed_sine_float */
  72. void
  73. gen_windowed_sine_double (double *data, int len, double maximum)
  74. { int k ;
  75. memset (data, 0, len * sizeof (double)) ;
  76. /*
  77. ** Choose a frequency of 1/32 so that it aligns perfectly with a DFT
  78. ** bucket to minimise spreading of energy over more than one bucket.
  79. ** Also do not want to make the frequency too high as some of the
  80. ** codecs (ie gsm610) have a quite severe high frequency roll off.
  81. */
  82. len /= 2 ;
  83. for (k = 0 ; k < len ; k++)
  84. { data [k] = sin (2.0 * k * M_PI * 1.0 / 32.0 + 0.4) ;
  85. /* Apply Hanning Window. */
  86. data [k] *= maximum * (0.5 - 0.5 * cos (2.0 * M_PI * k / ((len) - 1))) ;
  87. }
  88. return ;
  89. } /* gen_windowed_sine_double */
  90. void
  91. create_short_sndfile (const char *filename, int format, int channels)
  92. { short data [2 * 3 * 4 * 5 * 6 * 7] = { 0, } ;
  93. SNDFILE *file ;
  94. SF_INFO sfinfo ;
  95. sfinfo.samplerate = 44100 ;
  96. sfinfo.channels = channels ;
  97. sfinfo.format = format ;
  98. if ((file = sf_open (filename, SFM_WRITE, &sfinfo)) == NULL)
  99. { printf ("Error (%s, %d) : sf_open failed : %s\n", __FILE__, __LINE__, sf_strerror (file)) ;
  100. exit (1) ;
  101. } ;
  102. sf_write_short (file, data, ARRAY_LEN (data)) ;
  103. sf_close (file) ;
  104. } /* create_short_sndfile */
  105. void
  106. check_file_hash_or_die (const char *filename, uint64_t target_hash, int line_num)
  107. { static unsigned char buf [4096] ;
  108. uint64_t cksum ;
  109. FILE *file ;
  110. int k, read_count ;
  111. memset (buf, 0, sizeof (buf)) ;
  112. /* The 'b' in the mode string means binary for Win32. */
  113. if ((file = fopen (filename, "rb")) == NULL)
  114. { printf ("\n\nLine %d: could not open file '%s'\n\n", line_num, filename) ;
  115. exit (1) ;
  116. } ;
  117. cksum = 0 ;
  118. while ((read_count = fread (buf, 1, sizeof (buf), file)))
  119. for (k = 0 ; k < read_count ; k++)
  120. cksum = cksum * 511 + buf [k] ;
  121. fclose (file) ;
  122. if (target_hash == 0)
  123. { printf (" 0x%016" PRIx64 "\n", cksum) ;
  124. return ;
  125. } ;
  126. if (cksum != target_hash)
  127. { printf ("\n\nLine %d: incorrect hash value 0x%016" PRIx64 " should be 0x%016" PRIx64 ".\n\n", line_num, cksum, target_hash) ;
  128. exit (1) ;
  129. } ;
  130. return ;
  131. } /* check_file_hash_or_die */
  132. void
  133. print_test_name (const char *test, const char *filename)
  134. { int count ;
  135. if (test == NULL)
  136. { printf (__FILE__ ": bad test of filename parameter.\n") ;
  137. exit (1) ;
  138. } ;
  139. if (filename == NULL || strlen (filename) == 0)
  140. { printf (" %-30s : ", test) ;
  141. count = 25 ;
  142. }
  143. else
  144. { printf (" %-30s : %s ", test, filename) ;
  145. count = 24 - strlen (filename) ;
  146. } ;
  147. while (count -- > 0)
  148. putchar ('.') ;
  149. putchar (' ') ;
  150. fflush (stdout) ;
  151. } /* print_test_name */
  152. void
  153. dump_data_to_file (const char *filename, const void *data, unsigned int datalen)
  154. { FILE *file ;
  155. if ((file = fopen (filename, "wb")) == NULL)
  156. { printf ("\n\nLine %d : could not open file : %s\n\n", __LINE__, filename) ;
  157. exit (1) ;
  158. } ;
  159. if (fwrite (data, 1, datalen, file) != datalen)
  160. { printf ("\n\nLine %d : fwrite failed.\n\n", __LINE__) ;
  161. exit (1) ;
  162. } ;
  163. fclose (file) ;
  164. } /* dump_data_to_file */
  165. /*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  166. */
  167. static char octfilename [] = "error.dat" ;
  168. int
  169. oct_save_short (const short *a, const short *b, int len)
  170. { FILE *file ;
  171. int k ;
  172. if (! (file = fopen (octfilename, "w")))
  173. return 1 ;
  174. fprintf (file, "# Not created by Octave\n") ;
  175. fprintf (file, "# name: a\n") ;
  176. fprintf (file, "# type: matrix\n") ;
  177. fprintf (file, "# rows: %d\n", len) ;
  178. fprintf (file, "# columns: 1\n") ;
  179. for (k = 0 ; k < len ; k++)
  180. fprintf (file, "% d" "\n", a [k]) ;
  181. fprintf (file, "# name: b\n") ;
  182. fprintf (file, "# type: matrix\n") ;
  183. fprintf (file, "# rows: %d\n", len) ;
  184. fprintf (file, "# columns: 1\n") ;
  185. for (k = 0 ; k < len ; k++)
  186. fprintf (file, "% d" "\n", b [k]) ;
  187. fclose (file) ;
  188. return 0 ;
  189. } /* oct_save_short */
  190. int
  191. oct_save_int (const int *a, const int *b, int len)
  192. { FILE *file ;
  193. int k ;
  194. if (! (file = fopen (octfilename, "w")))
  195. return 1 ;
  196. fprintf (file, "# Not created by Octave\n") ;
  197. fprintf (file, "# name: a\n") ;
  198. fprintf (file, "# type: matrix\n") ;
  199. fprintf (file, "# rows: %d\n", len) ;
  200. fprintf (file, "# columns: 1\n") ;
  201. for (k = 0 ; k < len ; k++)
  202. fprintf (file, "% d" "\n", a [k]) ;
  203. fprintf (file, "# name: b\n") ;
  204. fprintf (file, "# type: matrix\n") ;
  205. fprintf (file, "# rows: %d\n", len) ;
  206. fprintf (file, "# columns: 1\n") ;
  207. for (k = 0 ; k < len ; k++)
  208. fprintf (file, "% d" "\n", b [k]) ;
  209. fclose (file) ;
  210. return 0 ;
  211. } /* oct_save_int */
  212. int
  213. oct_save_float (const float *a, const float *b, int len)
  214. { FILE *file ;
  215. int k ;
  216. if (! (file = fopen (octfilename, "w")))
  217. return 1 ;
  218. fprintf (file, "# Not created by Octave\n") ;
  219. fprintf (file, "# name: a\n") ;
  220. fprintf (file, "# type: matrix\n") ;
  221. fprintf (file, "# rows: %d\n", len) ;
  222. fprintf (file, "# columns: 1\n") ;
  223. for (k = 0 ; k < len ; k++)
  224. fprintf (file, "% g" "\n", a [k]) ;
  225. fprintf (file, "# name: b\n") ;
  226. fprintf (file, "# type: matrix\n") ;
  227. fprintf (file, "# rows: %d\n", len) ;
  228. fprintf (file, "# columns: 1\n") ;
  229. for (k = 0 ; k < len ; k++)
  230. fprintf (file, "% g" "\n", b [k]) ;
  231. fclose (file) ;
  232. return 0 ;
  233. } /* oct_save_float */
  234. int
  235. oct_save_double (const double *a, const double *b, int len)
  236. { FILE *file ;
  237. int k ;
  238. if (! (file = fopen (octfilename, "w")))
  239. return 1 ;
  240. fprintf (file, "# Not created by Octave\n") ;
  241. fprintf (file, "# name: a\n") ;
  242. fprintf (file, "# type: matrix\n") ;
  243. fprintf (file, "# rows: %d\n", len) ;
  244. fprintf (file, "# columns: 1\n") ;
  245. for (k = 0 ; k < len ; k++)
  246. fprintf (file, "% g" "\n", a [k]) ;
  247. fprintf (file, "# name: b\n") ;
  248. fprintf (file, "# type: matrix\n") ;
  249. fprintf (file, "# rows: %d\n", len) ;
  250. fprintf (file, "# columns: 1\n") ;
  251. for (k = 0 ; k < len ; k++)
  252. fprintf (file, "% g" "\n", b [k]) ;
  253. fclose (file) ;
  254. return 0 ;
  255. } /* oct_save_double */
  256. void
  257. check_log_buffer_or_die (SNDFILE *file, int line_num)
  258. { static char buffer [LOG_BUFFER_SIZE] ;
  259. int count ;
  260. memset (buffer, 0, sizeof (buffer)) ;
  261. /* Get the log buffer data. */
  262. count = sf_command (file, SFC_GET_LOG_INFO, buffer, LOG_BUFFER_SIZE) ;
  263. if (LOG_BUFFER_SIZE - count < 2)
  264. { printf ("\n\nLine %d : Possible long log buffer.\n", line_num) ;
  265. exit (1) ;
  266. }
  267. /* Look for "Should" */
  268. if (strstr (buffer, "ould"))
  269. { printf ("\n\nLine %d : Log buffer contains `ould'. Dumping.\n", line_num) ;
  270. puts (buffer) ;
  271. exit (1) ;
  272. } ;
  273. /* Look for "**" */
  274. if (strstr (buffer, "*"))
  275. { printf ("\n\nLine %d : Log buffer contains `*'. Dumping.\n", line_num) ;
  276. puts (buffer) ;
  277. exit (1) ;
  278. } ;
  279. /* Look for "Should" */
  280. if (strstr (buffer, "nknown marker"))
  281. { printf ("\n\nLine %d : Log buffer contains `nknown marker'. Dumping.\n", line_num) ;
  282. puts (buffer) ;
  283. exit (1) ;
  284. } ;
  285. return ;
  286. } /* check_log_buffer_or_die */
  287. int
  288. string_in_log_buffer (SNDFILE *file, const char *s)
  289. { static char buffer [LOG_BUFFER_SIZE] ;
  290. int count ;
  291. memset (buffer, 0, sizeof (buffer)) ;
  292. /* Get the log buffer data. */
  293. count = sf_command (file, SFC_GET_LOG_INFO, buffer, LOG_BUFFER_SIZE) ;
  294. if (LOG_BUFFER_SIZE - count < 2)
  295. { printf ("Possible long log buffer.\n") ;
  296. exit (1) ;
  297. }
  298. /* Look for string */
  299. return strstr (buffer, s) ? SF_TRUE : SF_FALSE ;
  300. } /* string_in_log_buffer */
  301. void
  302. hexdump_file (const char * filename, sf_count_t offset, sf_count_t length)
  303. {
  304. FILE * file ;
  305. char buffer [16] ;
  306. int k, m, ch, readcount ;
  307. if (length > 1000000)
  308. { printf ("\n\nError : length (%ld) too long.\n\n", SF_COUNT_TO_LONG (offset)) ;
  309. exit (1) ;
  310. } ;
  311. if ((file = fopen (filename, "r")) == NULL)
  312. { printf ("\n\nError : hexdump_file (%s) could not open file for read.\n\n", filename) ;
  313. exit (1) ;
  314. } ;
  315. if (fseek (file, offset, SEEK_SET) != 0)
  316. { printf ("\n\nError : fseek(file, %ld, SEEK_SET) failed : %s\n\n", SF_COUNT_TO_LONG (offset), strerror (errno)) ;
  317. exit (1) ;
  318. } ;
  319. puts ("\n\n") ;
  320. for (k = 0 ; k < length ; k+= sizeof (buffer))
  321. { readcount = fread (buffer, 1, sizeof (buffer), file) ;
  322. printf ("%08lx : ", SF_COUNT_TO_LONG (offset + k)) ;
  323. for (m = 0 ; m < readcount ; m++)
  324. printf ("%02x ", buffer [m] & 0xFF) ;
  325. for (m = readcount ; m < SIGNED_SIZEOF (buffer) ; m++)
  326. printf (" ") ;
  327. printf (" ") ;
  328. for (m = 0 ; m < readcount ; m++)
  329. { ch = isprint (buffer [m]) ? buffer [m] : '.' ;
  330. putchar (ch) ;
  331. } ;
  332. if (readcount < SIGNED_SIZEOF (buffer))
  333. break ;
  334. putchar ('\n') ;
  335. } ;
  336. puts ("\n") ;
  337. fclose (file) ;
  338. } /* hexdump_file */
  339. void
  340. dump_log_buffer (SNDFILE *file)
  341. { static char buffer [LOG_BUFFER_SIZE] ;
  342. memset (buffer, 0, sizeof (buffer)) ;
  343. /* Get the log buffer data. */
  344. sf_command (file, SFC_GET_LOG_INFO, buffer, LOG_BUFFER_SIZE) ;
  345. if (strlen (buffer) < 1)
  346. puts ("Log buffer empty.\n") ;
  347. else
  348. puts (buffer) ;
  349. return ;
  350. } /* dump_log_buffer */
  351. SNDFILE *
  352. test_open_file_or_die (const char *filename, int mode, SF_INFO *sfinfo, int allow_fd, int line_num)
  353. { static int count = 0 ;
  354. SNDFILE *file ;
  355. const char *modestr, *func_name ;
  356. int oflags = 0, omode = 0, err ;
  357. /*
  358. ** Need to test both sf_open() and sf_open_fd().
  359. ** Do so alternately.
  360. */
  361. switch (mode)
  362. { case SFM_READ :
  363. modestr = "SFM_READ" ;
  364. oflags = O_RDONLY | O_BINARY ;
  365. omode = 0 ;
  366. break ;
  367. case SFM_WRITE :
  368. modestr = "SFM_WRITE" ;
  369. oflags = O_WRONLY | O_CREAT | O_TRUNC | O_BINARY ;
  370. omode = S_IRUSR | S_IWUSR | S_IRGRP ;
  371. break ;
  372. case SFM_RDWR :
  373. modestr = "SFM_RDWR" ;
  374. oflags = O_RDWR | O_CREAT | O_BINARY ;
  375. omode = S_IRUSR | S_IWUSR | S_IRGRP ;
  376. break ;
  377. default :
  378. printf ("\n\nLine %d: Bad mode.\n", line_num) ;
  379. fflush (stdout) ;
  380. exit (1) ;
  381. } ;
  382. if (OS_IS_WIN32)
  383. { /* Windows does not understand and ignores the S_IRGRP flag, but Wine
  384. ** gives a run time warning message, so just clear it.
  385. */
  386. omode &= ~S_IRGRP ;
  387. } ;
  388. if (allow_fd && ((++count) & 1) == 1)
  389. { int fd ;
  390. /* Only use the three argument open() function if omode != 0. */
  391. fd = (omode == 0) ? open (filename, oflags) : open (filename, oflags, omode) ;
  392. if (fd < 0)
  393. { printf ("\n\n%s : open failed : %s\n", __func__, strerror (errno)) ;
  394. exit (1) ;
  395. } ;
  396. func_name = "sf_open_fd" ;
  397. file = sf_open_fd (fd, mode, sfinfo, SF_TRUE) ;
  398. }
  399. else
  400. { func_name = "sf_open" ;
  401. file = sf_open (filename, mode, sfinfo) ;
  402. } ;
  403. if (file == NULL)
  404. { printf ("\n\nLine %d: %s (%s) failed : %s\n\n", line_num, func_name, modestr, sf_strerror (NULL)) ;
  405. dump_log_buffer (file) ;
  406. exit (1) ;
  407. } ;
  408. err = sf_error (file) ;
  409. if (err != SF_ERR_NO_ERROR)
  410. { printf ("\n\nLine %d : sf_error : %s\n\n", line_num, sf_error_number (err)) ;
  411. dump_log_buffer (file) ;
  412. exit (1) ;
  413. } ;
  414. return file ;
  415. } /* test_open_file_or_die */
  416. void
  417. test_read_write_position_or_die (SNDFILE *file, int line_num, int pass, sf_count_t read_pos, sf_count_t write_pos)
  418. { sf_count_t pos ;
  419. /* Check the current read position. */
  420. if (read_pos >= 0 && (pos = sf_seek (file, 0, SEEK_CUR | SFM_READ)) != read_pos)
  421. { printf ("\n\nLine %d ", line_num) ;
  422. if (pass > 0)
  423. printf ("(pass %d): ", pass) ;
  424. printf ("Read position (%ld) should be %ld.\n", SF_COUNT_TO_LONG (pos), SF_COUNT_TO_LONG (read_pos)) ;
  425. exit (1) ;
  426. } ;
  427. /* Check the current write position. */
  428. if (write_pos >= 0 && (pos = sf_seek (file, 0, SEEK_CUR | SFM_WRITE)) != write_pos)
  429. { printf ("\n\nLine %d", line_num) ;
  430. if (pass > 0)
  431. printf (" (pass %d)", pass) ;
  432. printf (" : Write position (%ld) should be %ld.\n",
  433. SF_COUNT_TO_LONG (pos), SF_COUNT_TO_LONG (write_pos)) ;
  434. exit (1) ;
  435. } ;
  436. return ;
  437. } /* test_read_write_position */
  438. void
  439. test_seek_or_die (SNDFILE *file, sf_count_t offset, int whence, sf_count_t new_pos, int channels, int line_num)
  440. { sf_count_t position ;
  441. const char *channel_name, *whence_name ;
  442. switch (whence)
  443. { case SEEK_SET :
  444. whence_name = "SEEK_SET" ;
  445. break ;
  446. case SEEK_CUR :
  447. whence_name = "SEEK_CUR" ;
  448. break ;
  449. case SEEK_END :
  450. whence_name = "SEEK_END" ;
  451. break ;
  452. /* SFM_READ */
  453. case SEEK_SET | SFM_READ :
  454. whence_name = "SFM_READ | SEEK_SET" ;
  455. break ;
  456. case SEEK_CUR | SFM_READ :
  457. whence_name = "SFM_READ | SEEK_CUR" ;
  458. break ;
  459. case SEEK_END | SFM_READ :
  460. whence_name = "SFM_READ | SEEK_END" ;
  461. break ;
  462. /* SFM_WRITE */
  463. case SEEK_SET | SFM_WRITE :
  464. whence_name = "SFM_WRITE | SEEK_SET" ;
  465. break ;
  466. case SEEK_CUR | SFM_WRITE :
  467. whence_name = "SFM_WRITE | SEEK_CUR" ;
  468. break ;
  469. case SEEK_END | SFM_WRITE :
  470. whence_name = "SFM_WRITE | SEEK_END" ;
  471. break ;
  472. default :
  473. printf ("\n\nLine %d: bad whence parameter.\n", line_num) ;
  474. exit (1) ;
  475. } ;
  476. channel_name = (channels == 1) ? "Mono" : "Stereo" ;
  477. if ((position = sf_seek (file, offset, whence)) != new_pos)
  478. { printf ("\n\nLine %d : %s : sf_seek (file, %ld, %s) returned %ld (should be %ld).\n\n",
  479. line_num, channel_name, SF_COUNT_TO_LONG (offset), whence_name,
  480. SF_COUNT_TO_LONG (position), SF_COUNT_TO_LONG (new_pos)) ;
  481. exit (1) ;
  482. } ;
  483. } /* test_seek_or_die */
  484. void
  485. test_read_short_or_die (SNDFILE *file, int pass, short *test, sf_count_t items, int line_num)
  486. { sf_count_t count ;
  487. if ((count = sf_read_short (file, test, items)) != items)
  488. { printf ("\n\nLine %d", line_num) ;
  489. if (pass > 0)
  490. printf (" (pass %d)", pass) ;
  491. printf (" : sf_read_short failed with short read (%ld => %ld).\n",
  492. SF_COUNT_TO_LONG (items), SF_COUNT_TO_LONG (count)) ;
  493. fflush (stdout) ;
  494. puts (sf_strerror (file)) ;
  495. exit (1) ;
  496. } ;
  497. return ;
  498. } /* test_read_short_or_die */
  499. void
  500. test_read_int_or_die (SNDFILE *file, int pass, int *test, sf_count_t items, int line_num)
  501. { sf_count_t count ;
  502. if ((count = sf_read_int (file, test, items)) != items)
  503. { printf ("\n\nLine %d", line_num) ;
  504. if (pass > 0)
  505. printf (" (pass %d)", pass) ;
  506. printf (" : sf_read_int failed with short read (%ld => %ld).\n",
  507. SF_COUNT_TO_LONG (items), SF_COUNT_TO_LONG (count)) ;
  508. fflush (stdout) ;
  509. puts (sf_strerror (file)) ;
  510. exit (1) ;
  511. } ;
  512. return ;
  513. } /* test_read_int_or_die */
  514. void
  515. test_read_float_or_die (SNDFILE *file, int pass, float *test, sf_count_t items, int line_num)
  516. { sf_count_t count ;
  517. if ((count = sf_read_float (file, test, items)) != items)
  518. { printf ("\n\nLine %d", line_num) ;
  519. if (pass > 0)
  520. printf (" (pass %d)", pass) ;
  521. printf (" : sf_read_float failed with short read (%ld => %ld).\n",
  522. SF_COUNT_TO_LONG (items), SF_COUNT_TO_LONG (count)) ;
  523. fflush (stdout) ;
  524. puts (sf_strerror (file)) ;
  525. exit (1) ;
  526. } ;
  527. return ;
  528. } /* test_read_float_or_die */
  529. void
  530. test_read_double_or_die (SNDFILE *file, int pass, double *test, sf_count_t items, int line_num)
  531. { sf_count_t count ;
  532. if ((count = sf_read_double (file, test, items)) != items)
  533. { printf ("\n\nLine %d", line_num) ;
  534. if (pass > 0)
  535. printf (" (pass %d)", pass) ;
  536. printf (" : sf_read_double failed with short read (%ld => %ld).\n",
  537. SF_COUNT_TO_LONG (items), SF_COUNT_TO_LONG (count)) ;
  538. fflush (stdout) ;
  539. puts (sf_strerror (file)) ;
  540. exit (1) ;
  541. } ;
  542. return ;
  543. } /* test_read_double_or_die */
  544. void
  545. test_readf_short_or_die (SNDFILE *file, int pass, short *test, sf_count_t frames, int line_num)
  546. { sf_count_t count ;
  547. if ((count = sf_readf_short (file, test, frames)) != frames)
  548. { printf ("\n\nLine %d", line_num) ;
  549. if (pass > 0)
  550. printf (" (pass %d)", pass) ;
  551. printf (" : sf_readf_short failed with short readf (%ld => %ld).\n",
  552. SF_COUNT_TO_LONG (frames), SF_COUNT_TO_LONG (count)) ;
  553. fflush (stdout) ;
  554. puts (sf_strerror (file)) ;
  555. exit (1) ;
  556. } ;
  557. return ;
  558. } /* test_readf_short_or_die */
  559. void
  560. test_readf_int_or_die (SNDFILE *file, int pass, int *test, sf_count_t frames, int line_num)
  561. { sf_count_t count ;
  562. if ((count = sf_readf_int (file, test, frames)) != frames)
  563. { printf ("\n\nLine %d", line_num) ;
  564. if (pass > 0)
  565. printf (" (pass %d)", pass) ;
  566. printf (" : sf_readf_int failed with short readf (%ld => %ld).\n",
  567. SF_COUNT_TO_LONG (frames), SF_COUNT_TO_LONG (count)) ;
  568. fflush (stdout) ;
  569. puts (sf_strerror (file)) ;
  570. exit (1) ;
  571. } ;
  572. return ;
  573. } /* test_readf_int_or_die */
  574. void
  575. test_readf_float_or_die (SNDFILE *file, int pass, float *test, sf_count_t frames, int line_num)
  576. { sf_count_t count ;
  577. if ((count = sf_readf_float (file, test, frames)) != frames)
  578. { printf ("\n\nLine %d", line_num) ;
  579. if (pass > 0)
  580. printf (" (pass %d)", pass) ;
  581. printf (" : sf_readf_float failed with short readf (%ld => %ld).\n",
  582. SF_COUNT_TO_LONG (frames), SF_COUNT_TO_LONG (count)) ;
  583. fflush (stdout) ;
  584. puts (sf_strerror (file)) ;
  585. exit (1) ;
  586. } ;
  587. return ;
  588. } /* test_readf_float_or_die */
  589. void
  590. test_readf_double_or_die (SNDFILE *file, int pass, double *test, sf_count_t frames, int line_num)
  591. { sf_count_t count ;
  592. if ((count = sf_readf_double (file, test, frames)) != frames)
  593. { printf ("\n\nLine %d", line_num) ;
  594. if (pass > 0)
  595. printf (" (pass %d)", pass) ;
  596. printf (" : sf_readf_double failed with short readf (%ld => %ld).\n",
  597. SF_COUNT_TO_LONG (frames), SF_COUNT_TO_LONG (count)) ;
  598. fflush (stdout) ;
  599. puts (sf_strerror (file)) ;
  600. exit (1) ;
  601. } ;
  602. return ;
  603. } /* test_readf_double_or_die */
  604. void
  605. test_read_raw_or_die (SNDFILE *file, int pass, void *test, sf_count_t items, int line_num)
  606. { sf_count_t count ;
  607. if ((count = sf_read_raw (file, test, items)) != items)
  608. { printf ("\n\nLine %d", line_num) ;
  609. if (pass > 0)
  610. printf (" (pass %d)", pass) ;
  611. printf (" : sf_read_raw failed with short read (%ld => %ld).\n",
  612. SF_COUNT_TO_LONG (items), SF_COUNT_TO_LONG (count)) ;
  613. fflush (stdout) ;
  614. puts (sf_strerror (file)) ;
  615. exit (1) ;
  616. } ;
  617. return ;
  618. } /* test_read_raw_or_die */
  619. void
  620. test_write_short_or_die (SNDFILE *file, int pass, const short *test, sf_count_t items, int line_num)
  621. { sf_count_t count ;
  622. if ((count = sf_write_short (file, test, items)) != items)
  623. { printf ("\n\nLine %d", line_num) ;
  624. if (pass > 0)
  625. printf (" (pass %d)", pass) ;
  626. printf (" : sf_write_short failed with short write (%ld => %ld).\n",
  627. SF_COUNT_TO_LONG (items), SF_COUNT_TO_LONG (count)) ;
  628. fflush (stdout) ;
  629. puts (sf_strerror (file)) ;
  630. exit (1) ;
  631. } ;
  632. return ;
  633. } /* test_write_short_or_die */
  634. void
  635. test_write_int_or_die (SNDFILE *file, int pass, const int *test, sf_count_t items, int line_num)
  636. { sf_count_t count ;
  637. if ((count = sf_write_int (file, test, items)) != items)
  638. { printf ("\n\nLine %d", line_num) ;
  639. if (pass > 0)
  640. printf (" (pass %d)", pass) ;
  641. printf (" : sf_write_int failed with short write (%ld => %ld).\n",
  642. SF_COUNT_TO_LONG (items), SF_COUNT_TO_LONG (count)) ;
  643. fflush (stdout) ;
  644. puts (sf_strerror (file)) ;
  645. exit (1) ;
  646. } ;
  647. return ;
  648. } /* test_write_int_or_die */
  649. void
  650. test_write_float_or_die (SNDFILE *file, int pass, const float *test, sf_count_t items, int line_num)
  651. { sf_count_t count ;
  652. if ((count = sf_write_float (file, test, items)) != items)
  653. { printf ("\n\nLine %d", line_num) ;
  654. if (pass > 0)
  655. printf (" (pass %d)", pass) ;
  656. printf (" : sf_write_float failed with short write (%ld => %ld).\n",
  657. SF_COUNT_TO_LONG (items), SF_COUNT_TO_LONG (count)) ;
  658. fflush (stdout) ;
  659. puts (sf_strerror (file)) ;
  660. exit (1) ;
  661. } ;
  662. return ;
  663. } /* test_write_float_or_die */
  664. void
  665. test_write_double_or_die (SNDFILE *file, int pass, const double *test, sf_count_t items, int line_num)
  666. { sf_count_t count ;
  667. if ((count = sf_write_double (file, test, items)) != items)
  668. { printf ("\n\nLine %d", line_num) ;
  669. if (pass > 0)
  670. printf (" (pass %d)", pass) ;
  671. printf (" : sf_write_double failed with short write (%ld => %ld).\n",
  672. SF_COUNT_TO_LONG (items), SF_COUNT_TO_LONG (count)) ;
  673. fflush (stdout) ;
  674. puts (sf_strerror (file)) ;
  675. exit (1) ;
  676. } ;
  677. return ;
  678. } /* test_write_double_or_die */
  679. void
  680. test_writef_short_or_die (SNDFILE *file, int pass, const short *test, sf_count_t frames, int line_num)
  681. { sf_count_t count ;
  682. if ((count = sf_writef_short (file, test, frames)) != frames)
  683. { printf ("\n\nLine %d", line_num) ;
  684. if (pass > 0)
  685. printf (" (pass %d)", pass) ;
  686. printf (" : sf_writef_short failed with short writef (%ld => %ld).\n",
  687. SF_COUNT_TO_LONG (frames), SF_COUNT_TO_LONG (count)) ;
  688. fflush (stdout) ;
  689. puts (sf_strerror (file)) ;
  690. exit (1) ;
  691. } ;
  692. return ;
  693. } /* test_writef_short_or_die */
  694. void
  695. test_writef_int_or_die (SNDFILE *file, int pass, const int *test, sf_count_t frames, int line_num)
  696. { sf_count_t count ;
  697. if ((count = sf_writef_int (file, test, frames)) != frames)
  698. { printf ("\n\nLine %d", line_num) ;
  699. if (pass > 0)
  700. printf (" (pass %d)", pass) ;
  701. printf (" : sf_writef_int failed with short writef (%ld => %ld).\n",
  702. SF_COUNT_TO_LONG (frames), SF_COUNT_TO_LONG (count)) ;
  703. fflush (stdout) ;
  704. puts (sf_strerror (file)) ;
  705. exit (1) ;
  706. } ;
  707. return ;
  708. } /* test_writef_int_or_die */
  709. void
  710. test_writef_float_or_die (SNDFILE *file, int pass, const float *test, sf_count_t frames, int line_num)
  711. { sf_count_t count ;
  712. if ((count = sf_writef_float (file, test, frames)) != frames)
  713. { printf ("\n\nLine %d", line_num) ;
  714. if (pass > 0)
  715. printf (" (pass %d)", pass) ;
  716. printf (" : sf_writef_float failed with short writef (%ld => %ld).\n",
  717. SF_COUNT_TO_LONG (frames), SF_COUNT_TO_LONG (count)) ;
  718. fflush (stdout) ;
  719. puts (sf_strerror (file)) ;
  720. exit (1) ;
  721. } ;
  722. return ;
  723. } /* test_writef_float_or_die */
  724. void
  725. test_writef_double_or_die (SNDFILE *file, int pass, const double *test, sf_count_t frames, int line_num)
  726. { sf_count_t count ;
  727. if ((count = sf_writef_double (file, test, frames)) != frames)
  728. { printf ("\n\nLine %d", line_num) ;
  729. if (pass > 0)
  730. printf (" (pass %d)", pass) ;
  731. printf (" : sf_writef_double failed with short writef (%ld => %ld).\n",
  732. SF_COUNT_TO_LONG (frames), SF_COUNT_TO_LONG (count)) ;
  733. fflush (stdout) ;
  734. puts (sf_strerror (file)) ;
  735. exit (1) ;
  736. } ;
  737. return ;
  738. } /* test_writef_double_or_die */
  739. void
  740. test_write_raw_or_die (SNDFILE *file, int pass, const void *test, sf_count_t items, int line_num)
  741. { sf_count_t count ;
  742. if ((count = sf_write_raw (file, test, items)) != items)
  743. { printf ("\n\nLine %d", line_num) ;
  744. if (pass > 0)
  745. printf (" (pass %d)", pass) ;
  746. printf (" : sf_write_raw failed with short write (%ld => %ld).\n",
  747. SF_COUNT_TO_LONG (items), SF_COUNT_TO_LONG (count)) ;
  748. fflush (stdout) ;
  749. puts (sf_strerror (file)) ;
  750. exit (1) ;
  751. } ;
  752. return ;
  753. } /* test_write_raw_or_die */
  754. void
  755. compare_short_or_die (const short *left, const short *right, unsigned count, int line_num)
  756. {
  757. unsigned k ;
  758. for (k = 0 ; k < count ;k++)
  759. if (left [k] != right [k])
  760. { printf ("\n\nLine %d : Error at index %d, " "% d" " should be " "% d" ".\n\n", line_num, k, left [k], right [k]) ;
  761. exit (1) ;
  762. } ;
  763. return ;
  764. } /* compare_short_or_die */
  765. void
  766. compare_int_or_die (const int *left, const int *right, unsigned count, int line_num)
  767. {
  768. unsigned k ;
  769. for (k = 0 ; k < count ;k++)
  770. if (left [k] != right [k])
  771. { printf ("\n\nLine %d : Error at index %d, " "% d" " should be " "% d" ".\n\n", line_num, k, left [k], right [k]) ;
  772. exit (1) ;
  773. } ;
  774. return ;
  775. } /* compare_int_or_die */
  776. void
  777. compare_float_or_die (const float *left, const float *right, unsigned count, int line_num)
  778. {
  779. unsigned k ;
  780. for (k = 0 ; k < count ;k++)
  781. if (left [k] != right [k])
  782. { printf ("\n\nLine %d : Error at index %d, " "% g" " should be " "% g" ".\n\n", line_num, k, left [k], right [k]) ;
  783. exit (1) ;
  784. } ;
  785. return ;
  786. } /* compare_float_or_die */
  787. void
  788. compare_double_or_die (const double *left, const double *right, unsigned count, int line_num)
  789. {
  790. unsigned k ;
  791. for (k = 0 ; k < count ;k++)
  792. if (left [k] != right [k])
  793. { printf ("\n\nLine %d : Error at index %d, " "% g" " should be " "% g" ".\n\n", line_num, k, left [k], right [k]) ;
  794. exit (1) ;
  795. } ;
  796. return ;
  797. } /* compare_double_or_die */
  798. void
  799. delete_file (int format, const char *filename)
  800. { char rsrc_name [512], *fname ;
  801. unlink (filename) ;
  802. if ((format & SF_FORMAT_TYPEMASK) != SF_FORMAT_SD2)
  803. return ;
  804. /*
  805. ** Now try for a resource fork stored as a separate file.
  806. ** Grab the un-adulterated filename again.
  807. */
  808. snprintf (rsrc_name, sizeof (rsrc_name), "%s", filename) ;
  809. if ((fname = strrchr (rsrc_name, '/')) != NULL)
  810. fname ++ ;
  811. else if ((fname = strrchr (rsrc_name, '\\')) != NULL)
  812. fname ++ ;
  813. else
  814. fname = rsrc_name ;
  815. memmove (fname + 2, fname, strlen (fname) + 1) ;
  816. fname [0] = '.' ;
  817. fname [1] = '_' ;
  818. unlink (rsrc_name) ;
  819. } /* delete_file */
  820. static int allowed_open_files = -1 ;
  821. void
  822. count_open_files (void)
  823. {
  824. #if OS_IS_WIN32
  825. return ;
  826. #else
  827. int k, count = 0 ;
  828. struct stat statbuf ;
  829. if (allowed_open_files > 0)
  830. return ;
  831. for (k = 0 ; k < 1024 ; k++)
  832. if (fstat (k, &statbuf) == 0)
  833. count ++ ;
  834. allowed_open_files = count ;
  835. #endif
  836. } /* count_open_files */
  837. void
  838. increment_open_file_count (void)
  839. { allowed_open_files ++ ;
  840. } /* increment_open_file_count */
  841. void
  842. check_open_file_count_or_die (int lineno)
  843. {
  844. #if OS_IS_WIN32
  845. lineno = 0 ;
  846. return ;
  847. #else
  848. int k, count = 0 ;
  849. struct stat statbuf ;
  850. if (allowed_open_files < 0)
  851. count_open_files () ;
  852. for (k = 0 ; k < 1024 ; k++)
  853. if (fstat (k, &statbuf) == 0)
  854. count ++ ;
  855. if (count > allowed_open_files)
  856. { printf ("\nLine %d : number of open files (%d) > allowed (%d).\n\n", lineno, count, allowed_open_files) ;
  857. exit (1) ;
  858. } ;
  859. #endif
  860. } /* check_open_file_count_or_die */
  861. void
  862. write_mono_file (const char * filename, int format, int srate, float * output, int len)
  863. { SNDFILE * file ;
  864. SF_INFO sfinfo ;
  865. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  866. sfinfo.samplerate = srate ;
  867. sfinfo.channels = 1 ;
  868. sfinfo.format = format ;
  869. if ((file = sf_open (filename, SFM_WRITE, &sfinfo)) == NULL)
  870. { printf ("sf_open (%s) : %s\n", filename, sf_strerror (NULL)) ;
  871. exit (1) ;
  872. } ;
  873. sf_write_float (file, output, len) ;
  874. sf_close (file) ;
  875. } /* write_mono_file */
  876. void
  877. gen_lowpass_noise_float (float *data, int len)
  878. { int32_t value = 0x1243456 ;
  879. double sample, last_val = 0.0 ;
  880. int k ;
  881. for (k = 0 ; k < len ; k++)
  882. { /* Not a crypto quality RNG. */
  883. value = 11117 * value + 211231 ;
  884. value = 11117 * value + 211231 ;
  885. value = 11117 * value + 211231 ;
  886. sample = value / (0x7fffffff * 1.000001) ;
  887. sample = 0.2 * sample - 0.9 * last_val ;
  888. data [k] = last_val = sample ;
  889. } ;
  890. } /* gen_lowpass_noise_float */
  891. /*
  892. ** Windows is fucked.
  893. ** If a file is opened R/W and data is written to it, then fstat will return
  894. ** the correct file length, but stat will return zero.
  895. */
  896. sf_count_t
  897. file_length (const char * fname)
  898. { struct stat data ;
  899. if (stat (fname, &data) != 0)
  900. return 0 ;
  901. return (sf_count_t) data.st_size ;
  902. } /* file_length */
  903. sf_count_t
  904. file_length_fd (int fd)
  905. { struct stat data ;
  906. memset (&data, 0, sizeof (data)) ;
  907. if (fstat (fd, &data) != 0)
  908. return 0 ;
  909. return (sf_count_t) data.st_size ;
  910. } /* file_length_fd */