lossy_comp_test.c 85 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372
  1. /*
  2. ** Copyright (C) 1999-2012 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. #include "sfconfig.h"
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <math.h>
  23. #include <inttypes.h>
  24. #if HAVE_UNISTD_H
  25. #include <unistd.h>
  26. #endif
  27. #include <sndfile.h>
  28. #include "utils.h"
  29. #define BUFFER_SIZE (1 << 14)
  30. #define SAMPLE_RATE 11025
  31. #ifndef M_PI
  32. #define M_PI 3.14159265358979323846264338
  33. #endif
  34. #define LCT_MAX(x, y) ((x) > (y) ? (x) : (y))
  35. static void lcomp_test_short (const char *filename, int filetype, int chan, double margin) ;
  36. static void lcomp_test_int (const char *filename, int filetype, int chan, double margin) ;
  37. static void lcomp_test_float (const char *filename, int filetype, int chan, double margin) ;
  38. static void lcomp_test_double (const char *filename, int filetype, int chan, double margin) ;
  39. static void sdlcomp_test_short (const char *filename, int filetype, int chan, double margin) ;
  40. static void sdlcomp_test_int (const char *filename, int filetype, int chan, double margin) ;
  41. static void sdlcomp_test_float (const char *filename, int filetype, int chan, double margin) ;
  42. static void sdlcomp_test_double (const char *filename, int filetype, int chan, double margin) ;
  43. static void read_raw_test (const char *filename, int filetype, int chan) ;
  44. static int error_function (double data, double orig, double margin) ;
  45. static int decay_response (int k) ;
  46. static void gen_signal_double (double *data, double scale, int channels, int datalen) ;
  47. static void smoothed_diff_short (short *data, unsigned int datalen) ;
  48. static void smoothed_diff_int (int *data, unsigned int datalen) ;
  49. static void smoothed_diff_float (float *data, unsigned int datalen) ;
  50. static void smoothed_diff_double (double *data, unsigned int datalen) ;
  51. static void check_comment (SNDFILE * file, int format, int lineno) ;
  52. static int is_lossy (int filetype) ;
  53. /*
  54. ** Force the start of these buffers to be double aligned. Sparc-solaris will
  55. ** choke if they are not.
  56. */
  57. typedef union
  58. { double d [BUFFER_SIZE + 1] ;
  59. float f [BUFFER_SIZE + 1] ;
  60. int i [BUFFER_SIZE + 1] ;
  61. short s [BUFFER_SIZE + 1] ;
  62. char c [BUFFER_SIZE + 1] ;
  63. } BUFFER ;
  64. static BUFFER data_buffer ;
  65. static BUFFER orig_buffer ;
  66. static BUFFER smooth_buffer ;
  67. static const char *long_comment =
  68. "This is really quite a long comment. It is designed to be long enough "
  69. "to screw up the encoders and decoders if the file container format does "
  70. "not handle things correctly. If everything is working correctly, the "
  71. "decoder will only decode the actual audio data, and not this string at "
  72. "the end of the file." ;
  73. int
  74. main (int argc, char *argv [])
  75. { int do_all = 0 ;
  76. int test_count = 0 ;
  77. if (argc != 2)
  78. { printf ("Usage : %s <test>\n", argv [0]) ;
  79. printf (" Where <test> is one of the following:\n") ;
  80. printf (" wav_ima - test IMA ADPCM WAV file functions\n") ;
  81. printf (" wav_msadpcm - test MS ADPCM WAV file functions\n") ;
  82. printf (" wav_gsm610 - test GSM 6.10 WAV file functions\n") ;
  83. printf (" wav_ulaw - test u-law WAV file functions\n") ;
  84. printf (" wav_alaw - test A-law WAV file functions\n") ;
  85. printf (" wve - test Psion WVE file functions\n") ;
  86. printf (" all - perform all tests\n") ;
  87. exit (1) ;
  88. } ;
  89. do_all = ! strcmp (argv [1], "all") ;
  90. if (do_all || strcmp (argv [1], "wav_pcm") == 0)
  91. { /* This is just a sanity test for PCM encoding. */
  92. lcomp_test_short ("pcm.wav", SF_FORMAT_WAV | SF_FORMAT_PCM_16, 2, 1e-50) ;
  93. lcomp_test_int ("pcm.wav", SF_FORMAT_WAV | SF_FORMAT_PCM_32, 2, 1e-50) ;
  94. lcomp_test_short ("pcm.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_PCM_16, 2, 1e-50) ;
  95. lcomp_test_int ("pcm.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_PCM_32, 2, 1e-50) ;
  96. /* Lite remove start */
  97. lcomp_test_float ("pcm.wav", SF_FORMAT_WAV | SF_FORMAT_FLOAT, 2, 1e-50) ;
  98. lcomp_test_double ("pcm.wav", SF_FORMAT_WAV | SF_FORMAT_DOUBLE, 2, 1e-50) ;
  99. /* Lite remove end */
  100. read_raw_test ("pcm.wav", SF_FORMAT_WAV | SF_FORMAT_PCM_U8, 2) ;
  101. test_count++ ;
  102. } ;
  103. /* For all the rest, if the file format supports more than 1 channel, use stereo. */
  104. /* Lite remove start */
  105. if (do_all || strcmp (argv [1], "wav_ima") == 0)
  106. { lcomp_test_short ("ima.wav", SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM, 2, 0.18) ;
  107. lcomp_test_int ("ima.wav", SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM, 2, 0.65) ;
  108. lcomp_test_float ("ima.wav", SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM, 2, 0.18) ;
  109. lcomp_test_double ("ima.wav", SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM, 2, 0.18) ;
  110. lcomp_test_short ("ima.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM, 2, 0.18) ;
  111. lcomp_test_int ("ima.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM, 2, 0.18) ;
  112. lcomp_test_float ("ima.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM, 2, 0.18) ;
  113. lcomp_test_double ("ima.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM, 2, 0.18) ;
  114. sdlcomp_test_short ("ima.wav", SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM, 2, 0.18) ;
  115. sdlcomp_test_int ("ima.wav", SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM, 2, 0.18) ;
  116. sdlcomp_test_float ("ima.wav", SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM, 2, 0.18) ;
  117. sdlcomp_test_double ("ima.wav", SF_FORMAT_WAV | SF_FORMAT_IMA_ADPCM, 2, 0.18) ;
  118. test_count++ ;
  119. } ;
  120. if (do_all || strcmp (argv [1], "wav_msadpcm") == 0)
  121. { lcomp_test_short ("msadpcm.wav", SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM, 2, 0.36) ;
  122. lcomp_test_int ("msadpcm.wav", SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM, 2, 0.36) ;
  123. lcomp_test_float ("msadpcm.wav", SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM, 2, 0.36) ;
  124. lcomp_test_double ("msadpcm.wav", SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM, 2, 0.36) ;
  125. lcomp_test_short ("msadpcm.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM, 2, 0.36) ;
  126. lcomp_test_int ("msadpcm.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM, 2, 0.36) ;
  127. lcomp_test_float ("msadpcm.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM, 2, 0.36) ;
  128. lcomp_test_double ("msadpcm.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM, 2, 0.36) ;
  129. sdlcomp_test_short ("msadpcm.wav", SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM, 2, 0.36) ;
  130. sdlcomp_test_int ("msadpcm.wav", SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM, 2, 0.36) ;
  131. sdlcomp_test_float ("msadpcm.wav", SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM, 2, 0.36) ;
  132. sdlcomp_test_double ("msadpcm.wav", SF_FORMAT_WAV | SF_FORMAT_MS_ADPCM, 2, 0.36) ;
  133. test_count++ ;
  134. } ;
  135. if (do_all || strcmp (argv [1], "wav_g721") == 0)
  136. { printf ("**** Fix this later : error bound should be 0.06 ****\n") ;
  137. lcomp_test_short ("g721.wav", SF_FORMAT_WAV | SF_FORMAT_G721_32, 1, 0.7) ;
  138. lcomp_test_int ("g721.wav", SF_FORMAT_WAV | SF_FORMAT_G721_32, 1, 0.7) ;
  139. lcomp_test_short ("g721.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_G721_32, 1, 0.7) ;
  140. lcomp_test_int ("g721.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_G721_32, 1, 0.7) ;
  141. test_count++ ;
  142. } ;
  143. /* Lite remove end */
  144. if (do_all || strcmp (argv [1], "wav_ulaw") == 0)
  145. { lcomp_test_short ("ulaw.wav", SF_FORMAT_WAV | SF_FORMAT_ULAW, 2, 0.04) ;
  146. lcomp_test_int ("ulaw.wav", SF_FORMAT_WAV | SF_FORMAT_ULAW, 2, 0.04) ;
  147. lcomp_test_short ("ulaw.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_ULAW, 2, 0.04) ;
  148. lcomp_test_int ("ulaw.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_ULAW, 2, 0.04) ;
  149. /* Lite remove start */
  150. lcomp_test_float ("ulaw.wav", SF_FORMAT_WAV | SF_FORMAT_ULAW, 2, 0.04) ;
  151. lcomp_test_double ("ulaw.wav", SF_FORMAT_WAV | SF_FORMAT_ULAW, 2, 0.04) ;
  152. /* Lite remove end */
  153. read_raw_test ("ulaw.wav", SF_FORMAT_WAV | SF_FORMAT_ULAW, 2) ;
  154. test_count++ ;
  155. } ;
  156. if (do_all || strcmp (argv [1], "wav_alaw") == 0)
  157. { lcomp_test_short ("alaw.wav", SF_FORMAT_WAV | SF_FORMAT_ALAW, 2, 0.04) ;
  158. lcomp_test_int ("alaw.wav", SF_FORMAT_WAV | SF_FORMAT_ALAW, 2, 0.04) ;
  159. /* Lite remove start */
  160. lcomp_test_float ("alaw.wav", SF_FORMAT_WAV | SF_FORMAT_ALAW, 2, 0.04) ;
  161. lcomp_test_double ("alaw.wav", SF_FORMAT_WAV | SF_FORMAT_ALAW, 2, 0.04) ;
  162. /* Lite remove end */
  163. read_raw_test ("alaw.wav", SF_FORMAT_WAV | SF_FORMAT_ALAW, 2) ;
  164. test_count++ ;
  165. } ;
  166. if (do_all || strcmp (argv [1], "wav_gsm610") == 0)
  167. { /* Don't do lcomp_test_XXX as the errors are too big. */
  168. sdlcomp_test_short ("gsm610.wav", SF_FORMAT_WAV | SF_FORMAT_GSM610, 1, 0.24) ;
  169. sdlcomp_test_int ("gsm610.wav", SF_FORMAT_WAV | SF_FORMAT_GSM610, 1, 0.24) ;
  170. sdlcomp_test_short ("gsm610.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_GSM610, 1, 0.24) ;
  171. sdlcomp_test_int ("gsm610.rifx", SF_ENDIAN_BIG | SF_FORMAT_WAV | SF_FORMAT_GSM610, 1, 0.24) ;
  172. /* Lite remove start */
  173. sdlcomp_test_float ("gsm610.wav", SF_FORMAT_WAV | SF_FORMAT_GSM610, 1, 0.24) ;
  174. sdlcomp_test_double ("gsm610.wav", SF_FORMAT_WAV | SF_FORMAT_GSM610, 1, 0.24) ;
  175. /* Lite remove end */
  176. test_count++ ;
  177. } ;
  178. if (do_all || strcmp (argv [1], "aiff_ulaw") == 0)
  179. { lcomp_test_short ("ulaw.aiff", SF_FORMAT_AIFF | SF_FORMAT_ULAW, 2, 0.04) ;
  180. lcomp_test_int ("ulaw.aiff", SF_FORMAT_AIFF | SF_FORMAT_ULAW, 2, 0.04) ;
  181. /* Lite remove start */
  182. lcomp_test_float ("ulaw.aiff", SF_FORMAT_AIFF | SF_FORMAT_ULAW, 2, 0.04) ;
  183. lcomp_test_double ("ulaw.aiff", SF_FORMAT_AIFF | SF_FORMAT_ULAW, 2, 0.04) ;
  184. /* Lite remove end */
  185. read_raw_test ("ulaw.aiff", SF_FORMAT_AIFF | SF_FORMAT_ULAW, 2) ;
  186. test_count++ ;
  187. } ;
  188. if (do_all || strcmp (argv [1], "aiff_alaw") == 0)
  189. { lcomp_test_short ("alaw.aiff", SF_FORMAT_AIFF | SF_FORMAT_ALAW, 2, 0.04) ;
  190. lcomp_test_int ("alaw.aiff", SF_FORMAT_AIFF | SF_FORMAT_ALAW, 2, 0.04) ;
  191. /* Lite remove start */
  192. lcomp_test_float ("alaw.aiff", SF_FORMAT_AIFF | SF_FORMAT_ALAW, 2, 0.04) ;
  193. lcomp_test_double ("alaw.aiff", SF_FORMAT_AIFF | SF_FORMAT_ALAW, 2, 0.04) ;
  194. /* Lite remove end */
  195. read_raw_test ("alaw.aiff", SF_FORMAT_AIFF | SF_FORMAT_ALAW, 2) ;
  196. test_count++ ;
  197. } ;
  198. if (do_all || strcmp (argv [1], "aiff_gsm610") == 0)
  199. { /* Don't do lcomp_test_XXX as the errors are too big. */
  200. sdlcomp_test_short ("gsm610.aiff", SF_FORMAT_AIFF | SF_FORMAT_GSM610, 1, 0.24) ;
  201. sdlcomp_test_int ("gsm610.aiff", SF_FORMAT_AIFF | SF_FORMAT_GSM610, 1, 0.24) ;
  202. /* Lite remove start */
  203. sdlcomp_test_float ("gsm610.aiff", SF_FORMAT_AIFF | SF_FORMAT_GSM610, 1, 0.24) ;
  204. sdlcomp_test_double ("gsm610.aiff", SF_FORMAT_AIFF | SF_FORMAT_GSM610, 1, 0.24) ;
  205. /* Lite remove end */
  206. test_count++ ;
  207. } ;
  208. if (strcmp (argv [1], "aiff_ima") == 0)
  209. { lcomp_test_short ("ima.aiff", SF_FORMAT_AIFF | SF_FORMAT_IMA_ADPCM, 2, 0.18) ;
  210. lcomp_test_int ("ima.aiff", SF_FORMAT_AIFF | SF_FORMAT_IMA_ADPCM, 2, 0.18) ;
  211. /* Lite remove start */
  212. lcomp_test_float ("ima.aiff", SF_FORMAT_AIFF | SF_FORMAT_IMA_ADPCM, 2, 0.18) ;
  213. lcomp_test_double ("ima.aiff", SF_FORMAT_AIFF | SF_FORMAT_IMA_ADPCM, 2, 0.18) ;
  214. /* Lite remove end */
  215. } ;
  216. if (do_all || strcmp (argv [1], "au_ulaw") == 0)
  217. { lcomp_test_short ("ulaw.au", SF_ENDIAN_BIG | SF_FORMAT_AU | SF_FORMAT_ULAW, 2, 0.04) ;
  218. lcomp_test_int ("ulaw.au", SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_ULAW, 2, 0.04) ;
  219. /* Lite remove start */
  220. lcomp_test_float ("ulaw.au", SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_ULAW, 2, 0.04) ;
  221. lcomp_test_double ("ulaw.au", SF_ENDIAN_BIG | SF_FORMAT_AU | SF_FORMAT_ULAW, 2, 0.04) ;
  222. /* Lite remove end */
  223. test_count++ ;
  224. } ;
  225. if (do_all || strcmp (argv [1], "au_alaw") == 0)
  226. { lcomp_test_short ("alaw.au", SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_ALAW, 2, 0.04) ;
  227. lcomp_test_int ("alaw.au", SF_ENDIAN_BIG | SF_FORMAT_AU | SF_FORMAT_ALAW, 2, 0.04) ;
  228. /* Lite remove start */
  229. lcomp_test_float ("alaw.au", SF_ENDIAN_BIG | SF_FORMAT_AU | SF_FORMAT_ALAW, 2, 0.04) ;
  230. lcomp_test_double ("alaw.au", SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_ALAW, 2, 0.04) ;
  231. /* Lite remove end */
  232. test_count++ ;
  233. } ;
  234. /* Lite remove start */
  235. if (do_all || strcmp (argv [1], "au_g721") == 0)
  236. { printf ("**** Fix this later : error bound should be 0.06 ****\n") ;
  237. lcomp_test_short ("g721.au", SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_G721_32, 1, 0.7) ;
  238. lcomp_test_int ("g721.au", SF_ENDIAN_BIG | SF_FORMAT_AU | SF_FORMAT_G721_32, 1, 0.7) ;
  239. lcomp_test_float ("g721.au", SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_G721_32, 1, 0.7) ;
  240. lcomp_test_double ("g721.au", SF_ENDIAN_BIG | SF_FORMAT_AU | SF_FORMAT_G721_32, 1, 0.7) ;
  241. /*- sdlcomp_test_short ("g721.au", SF_ENDIAN_BIG | SF_FORMAT_AU | SF_FORMAT_G721_32, 1, 0.07) ;
  242. sdlcomp_test_int ("g721.au", SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_G721_32, 1, 0.07) ;
  243. sdlcomp_test_float ("g721.au", SF_ENDIAN_BIG | SF_FORMAT_AU | SF_FORMAT_G721_32, 1, 0.07) ;
  244. sdlcomp_test_double ("g721.au", SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_G721_32, 1, 0.12) ;
  245. -*/
  246. test_count++ ;
  247. } ;
  248. if (do_all || strcmp (argv [1], "au_g723") == 0)
  249. { printf ("**** Fix this later : error bound should be 0.16 ****\n") ;
  250. lcomp_test_short ("g723_24.au", SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_G723_24, 1, 0.7) ;
  251. lcomp_test_int ("g723_24.au", SF_ENDIAN_BIG | SF_FORMAT_AU | SF_FORMAT_G723_24, 1, 0.7) ;
  252. lcomp_test_float ("g723_24.au", SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_G723_24, 1, 0.7) ;
  253. lcomp_test_double ("g723_24.au", SF_ENDIAN_BIG | SF_FORMAT_AU | SF_FORMAT_G723_24, 1, 0.7) ;
  254. lcomp_test_short ("g723_40.au", SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_G723_40, 1, 0.85) ;
  255. lcomp_test_int ("g723_40.au", SF_ENDIAN_BIG | SF_FORMAT_AU | SF_FORMAT_G723_40, 1, 0.84) ;
  256. lcomp_test_float ("g723_40.au", SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_G723_40, 1, 0.86) ;
  257. lcomp_test_double ("g723_40.au", SF_ENDIAN_BIG | SF_FORMAT_AU | SF_FORMAT_G723_40, 1, 0.86) ;
  258. /*- sdlcomp_test_short ("g723.au", SF_ENDIAN_BIG | SF_FORMAT_AU | SF_FORMAT_G723_24, 1, 0.15) ;
  259. sdlcomp_test_int ("g723.au", SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_G723_24, 1, 0.15) ;
  260. sdlcomp_test_float ("g723.au", SF_ENDIAN_BIG | SF_FORMAT_AU | SF_FORMAT_G723_24, 1, 0.15) ;
  261. sdlcomp_test_double ("g723.au", SF_ENDIAN_LITTLE | SF_FORMAT_AU | SF_FORMAT_G723_24, 1, 0.15) ;
  262. -*/
  263. test_count++ ;
  264. } ;
  265. /* Lite remove end */
  266. if (do_all || strcmp (argv [1], "caf_ulaw") == 0)
  267. { lcomp_test_short ("ulaw.caf", SF_FORMAT_CAF | SF_FORMAT_ULAW, 2, 0.04) ;
  268. lcomp_test_int ("ulaw.caf", SF_FORMAT_CAF | SF_FORMAT_ULAW, 2, 0.04) ;
  269. /* Lite remove start */
  270. lcomp_test_float ("ulaw.caf", SF_FORMAT_CAF | SF_FORMAT_ULAW, 2, 0.04) ;
  271. lcomp_test_double ("ulaw.caf", SF_FORMAT_CAF | SF_FORMAT_ULAW, 2, 0.04) ;
  272. /* Lite remove end */
  273. read_raw_test ("ulaw.caf", SF_FORMAT_CAF | SF_FORMAT_ULAW, 2) ;
  274. test_count++ ;
  275. } ;
  276. if (do_all || strcmp (argv [1], "caf_alaw") == 0)
  277. { lcomp_test_short ("alaw.caf", SF_FORMAT_CAF | SF_FORMAT_ALAW, 2, 0.04) ;
  278. lcomp_test_int ("alaw.caf", SF_FORMAT_CAF | SF_FORMAT_ALAW, 2, 0.04) ;
  279. /* Lite remove start */
  280. lcomp_test_float ("alaw.caf", SF_FORMAT_CAF | SF_FORMAT_ALAW, 2, 0.04) ;
  281. lcomp_test_double ("alaw.caf", SF_FORMAT_CAF | SF_FORMAT_ALAW, 2, 0.04) ;
  282. /* Lite remove end */
  283. read_raw_test ("alaw.caf", SF_FORMAT_CAF | SF_FORMAT_ALAW, 2) ;
  284. test_count++ ;
  285. } ;
  286. if (do_all || strcmp (argv [1], "raw_ulaw") == 0)
  287. { lcomp_test_short ("ulaw.raw", SF_ENDIAN_LITTLE | SF_FORMAT_RAW | SF_FORMAT_ULAW, 2, 0.04) ;
  288. lcomp_test_int ("ulaw.raw", SF_ENDIAN_BIG | SF_FORMAT_RAW | SF_FORMAT_ULAW, 2, 0.04) ;
  289. /* Lite remove start */
  290. lcomp_test_float ("ulaw.raw", SF_ENDIAN_LITTLE | SF_FORMAT_RAW | SF_FORMAT_ULAW, 2, 0.04) ;
  291. lcomp_test_double ("ulaw.raw", SF_ENDIAN_BIG | SF_FORMAT_RAW | SF_FORMAT_ULAW, 2, 0.04) ;
  292. /* Lite remove end */
  293. test_count++ ;
  294. } ;
  295. if (do_all || strcmp (argv [1], "raw_alaw") == 0)
  296. { lcomp_test_short ("alaw.raw", SF_ENDIAN_LITTLE | SF_FORMAT_RAW | SF_FORMAT_ALAW, 2, 0.04) ;
  297. lcomp_test_int ("alaw.raw", SF_ENDIAN_BIG | SF_FORMAT_RAW | SF_FORMAT_ALAW, 2, 0.04) ;
  298. /* Lite remove start */
  299. lcomp_test_float ("alaw.raw", SF_ENDIAN_LITTLE | SF_FORMAT_RAW | SF_FORMAT_ALAW, 2, 0.04) ;
  300. lcomp_test_double ("alaw.raw", SF_ENDIAN_BIG | SF_FORMAT_RAW | SF_FORMAT_ALAW, 2, 0.04) ;
  301. /* Lite remove end */
  302. test_count++ ;
  303. } ;
  304. if (do_all || strcmp (argv [1], "raw_gsm610") == 0)
  305. { /* Don't do lcomp_test_XXX as the errors are too big. */
  306. sdlcomp_test_short ("raw.gsm", SF_FORMAT_RAW | SF_FORMAT_GSM610, 1, 0.24) ;
  307. sdlcomp_test_int ("raw.gsm", SF_FORMAT_RAW | SF_FORMAT_GSM610, 1, 0.24) ;
  308. sdlcomp_test_float ("raw.gsm", SF_FORMAT_RAW | SF_FORMAT_GSM610, 1, 0.24) ;
  309. sdlcomp_test_double ("raw.gsm", SF_FORMAT_RAW | SF_FORMAT_GSM610, 1, 0.24) ;
  310. test_count++ ;
  311. } ;
  312. if (do_all || strcmp (argv [1], "ogg_vorbis") == 0)
  313. { if (HAVE_EXTERNAL_LIBS)
  314. { /* Don't do lcomp_test_XXX as the errors are too big. */
  315. sdlcomp_test_short ("vorbis.oga", SF_FORMAT_OGG | SF_FORMAT_VORBIS, 1, 0.30) ;
  316. sdlcomp_test_int ("vorbis.oga", SF_FORMAT_OGG | SF_FORMAT_VORBIS, 1, 0.30) ;
  317. sdlcomp_test_float ("vorbis.oga", SF_FORMAT_OGG | SF_FORMAT_VORBIS, 1, 0.30) ;
  318. sdlcomp_test_double ("vorbis.oga", SF_FORMAT_OGG | SF_FORMAT_VORBIS, 1, 0.30) ;
  319. }
  320. else
  321. puts (" No Ogg/Vorbis tests because Ogg/Vorbis support was not compiled in.") ;
  322. test_count++ ;
  323. } ;
  324. /* Lite remove start */
  325. if (do_all || strcmp (argv [1], "ircam_ulaw") == 0)
  326. { lcomp_test_short ("ulaw.ircam", SF_ENDIAN_LITTLE | SF_FORMAT_IRCAM | SF_FORMAT_ULAW, 2, 0.04) ;
  327. lcomp_test_int ("ulaw.ircam", SF_ENDIAN_BIG | SF_FORMAT_IRCAM | SF_FORMAT_ULAW, 2, 0.04) ;
  328. lcomp_test_float ("ulaw.ircam", SF_ENDIAN_LITTLE | SF_FORMAT_IRCAM | SF_FORMAT_ULAW, 2, 0.04) ;
  329. lcomp_test_double ("ulaw.ircam", SF_ENDIAN_BIG | SF_FORMAT_IRCAM | SF_FORMAT_ULAW, 2, 0.04) ;
  330. test_count++ ;
  331. } ;
  332. if (do_all || strcmp (argv [1], "ircam_alaw") == 0)
  333. { lcomp_test_short ("alaw.ircam", SF_ENDIAN_LITTLE | SF_FORMAT_IRCAM | SF_FORMAT_ALAW, 2, 0.04) ;
  334. lcomp_test_int ("alaw.ircam", SF_ENDIAN_BIG | SF_FORMAT_IRCAM | SF_FORMAT_ALAW, 2, 0.04) ;
  335. lcomp_test_float ("alaw.ircam", SF_ENDIAN_LITTLE | SF_FORMAT_IRCAM | SF_FORMAT_ALAW, 2, 0.04) ;
  336. lcomp_test_double ("alaw.ircam", SF_ENDIAN_BIG | SF_FORMAT_IRCAM | SF_FORMAT_ALAW, 2, 0.04) ;
  337. test_count++ ;
  338. } ;
  339. if (do_all || strcmp (argv [1], "nist_ulaw") == 0)
  340. { lcomp_test_short ("ulaw.nist", SF_ENDIAN_LITTLE | SF_FORMAT_NIST | SF_FORMAT_ULAW, 2, 0.04) ;
  341. lcomp_test_int ("ulaw.nist", SF_ENDIAN_BIG | SF_FORMAT_NIST | SF_FORMAT_ULAW, 2, 0.04) ;
  342. lcomp_test_float ("ulaw.nist", SF_ENDIAN_LITTLE | SF_FORMAT_NIST | SF_FORMAT_ULAW, 2, 0.04) ;
  343. lcomp_test_double ("ulaw.nist", SF_ENDIAN_BIG | SF_FORMAT_NIST | SF_FORMAT_ULAW, 2, 0.04) ;
  344. test_count++ ;
  345. } ;
  346. if (do_all || strcmp (argv [1], "nist_alaw") == 0)
  347. { lcomp_test_short ("alaw.nist", SF_ENDIAN_LITTLE | SF_FORMAT_NIST | SF_FORMAT_ALAW, 2, 0.04) ;
  348. lcomp_test_int ("alaw.nist", SF_ENDIAN_BIG | SF_FORMAT_NIST | SF_FORMAT_ALAW, 2, 0.04) ;
  349. lcomp_test_float ("alaw.nist", SF_ENDIAN_LITTLE | SF_FORMAT_NIST | SF_FORMAT_ALAW, 2, 0.04) ;
  350. lcomp_test_double ("alaw.nist", SF_ENDIAN_BIG | SF_FORMAT_NIST | SF_FORMAT_ALAW, 2, 0.04) ;
  351. test_count++ ;
  352. } ;
  353. if (do_all || strcmp (argv [1], "voc_ulaw") == 0)
  354. { lcomp_test_short ("ulaw.voc", SF_FORMAT_VOC | SF_FORMAT_ULAW, 2, 0.04) ;
  355. lcomp_test_int ("ulaw.voc", SF_FORMAT_VOC | SF_FORMAT_ULAW, 2, 0.04) ;
  356. lcomp_test_float ("ulaw.voc", SF_FORMAT_VOC | SF_FORMAT_ULAW, 2, 0.04) ;
  357. lcomp_test_double ("ulaw.voc", SF_FORMAT_VOC | SF_FORMAT_ULAW, 2, 0.04) ;
  358. test_count++ ;
  359. } ;
  360. if (do_all || strcmp (argv [1], "voc_alaw") == 0)
  361. { lcomp_test_short ("alaw.voc", SF_FORMAT_VOC | SF_FORMAT_ALAW, 2, 0.04) ;
  362. lcomp_test_int ("alaw.voc", SF_FORMAT_VOC | SF_FORMAT_ALAW, 2, 0.04) ;
  363. lcomp_test_float ("alaw.voc", SF_FORMAT_VOC | SF_FORMAT_ALAW, 2, 0.04) ;
  364. lcomp_test_double ("alaw.voc", SF_FORMAT_VOC | SF_FORMAT_ALAW, 2, 0.04) ;
  365. test_count++ ;
  366. } ;
  367. /* Lite remove end */
  368. if (do_all || strcmp (argv [1], "w64_ulaw") == 0)
  369. { lcomp_test_short ("ulaw.w64", SF_FORMAT_W64 | SF_FORMAT_ULAW, 2, 0.04) ;
  370. lcomp_test_int ("ulaw.w64", SF_FORMAT_W64 | SF_FORMAT_ULAW, 2, 0.04) ;
  371. /* Lite remove start */
  372. lcomp_test_float ("ulaw.w64", SF_FORMAT_W64 | SF_FORMAT_ULAW, 2, 0.04) ;
  373. lcomp_test_double ("ulaw.w64", SF_FORMAT_W64 | SF_FORMAT_ULAW, 2, 0.04) ;
  374. /* Lite remove end */
  375. read_raw_test ("ulaw.w64", SF_FORMAT_W64 | SF_FORMAT_ULAW, 2) ;
  376. test_count++ ;
  377. } ;
  378. if (do_all || strcmp (argv [1], "w64_alaw") == 0)
  379. { lcomp_test_short ("alaw.w64", SF_FORMAT_W64 | SF_FORMAT_ALAW, 2, 0.04) ;
  380. lcomp_test_int ("alaw.w64", SF_FORMAT_W64 | SF_FORMAT_ALAW, 2, 0.04) ;
  381. /* Lite remove start */
  382. lcomp_test_float ("alaw.w64", SF_FORMAT_W64 | SF_FORMAT_ALAW, 2, 0.04) ;
  383. lcomp_test_double ("alaw.w64", SF_FORMAT_W64 | SF_FORMAT_ALAW, 2, 0.04) ;
  384. /* Lite remove end */
  385. read_raw_test ("alaw.w64", SF_FORMAT_W64 | SF_FORMAT_ALAW, 2) ;
  386. test_count++ ;
  387. } ;
  388. /* Lite remove start */
  389. if (do_all || strcmp (argv [1], "w64_ima") == 0)
  390. { lcomp_test_short ("ima.w64", SF_FORMAT_W64 | SF_FORMAT_IMA_ADPCM, 2, 0.18) ;
  391. lcomp_test_int ("ima.w64", SF_FORMAT_W64 | SF_FORMAT_IMA_ADPCM, 2, 0.18) ;
  392. lcomp_test_float ("ima.w64", SF_FORMAT_W64 | SF_FORMAT_IMA_ADPCM, 2, 0.18) ;
  393. lcomp_test_double ("ima.w64", SF_FORMAT_W64 | SF_FORMAT_IMA_ADPCM, 2, 0.18) ;
  394. sdlcomp_test_short ("ima.w64", SF_FORMAT_W64 | SF_FORMAT_IMA_ADPCM, 2, 0.18) ;
  395. sdlcomp_test_int ("ima.w64", SF_FORMAT_W64 | SF_FORMAT_IMA_ADPCM, 2, 0.18) ;
  396. sdlcomp_test_float ("ima.w64", SF_FORMAT_W64 | SF_FORMAT_IMA_ADPCM, 2, 0.18) ;
  397. sdlcomp_test_double ("ima.w64", SF_FORMAT_W64 | SF_FORMAT_IMA_ADPCM, 2, 0.18) ;
  398. test_count++ ;
  399. } ;
  400. if (do_all || strcmp (argv [1], "w64_msadpcm") == 0)
  401. { lcomp_test_short ("msadpcm.w64", SF_FORMAT_W64 | SF_FORMAT_MS_ADPCM, 2, 0.36) ;
  402. lcomp_test_int ("msadpcm.w64", SF_FORMAT_W64 | SF_FORMAT_MS_ADPCM, 2, 0.36) ;
  403. lcomp_test_float ("msadpcm.w64", SF_FORMAT_W64 | SF_FORMAT_MS_ADPCM, 2, 0.36) ;
  404. lcomp_test_double ("msadpcm.w64", SF_FORMAT_W64 | SF_FORMAT_MS_ADPCM, 2, 0.36) ;
  405. sdlcomp_test_short ("msadpcm.w64", SF_FORMAT_W64 | SF_FORMAT_MS_ADPCM, 2, 0.36) ;
  406. sdlcomp_test_int ("msadpcm.w64", SF_FORMAT_W64 | SF_FORMAT_MS_ADPCM, 2, 0.36) ;
  407. sdlcomp_test_float ("msadpcm.w64", SF_FORMAT_W64 | SF_FORMAT_MS_ADPCM, 2, 0.36) ;
  408. sdlcomp_test_double ("msadpcm.w64", SF_FORMAT_W64 | SF_FORMAT_MS_ADPCM, 2, 0.36) ;
  409. test_count++ ;
  410. } ;
  411. if (do_all || strcmp (argv [1], "wve") == 0)
  412. { lcomp_test_short ("psion.wve", SF_FORMAT_WVE | SF_FORMAT_ALAW, 1, 0.04) ;
  413. lcomp_test_int ("psion.wve", SF_FORMAT_WVE | SF_FORMAT_ALAW, 1, 0.04) ;
  414. /* Lite remove start */
  415. lcomp_test_float ("psion.wve", SF_FORMAT_WVE | SF_FORMAT_ALAW, 1, 0.04) ;
  416. lcomp_test_double ("psion.wve", SF_FORMAT_WVE | SF_FORMAT_ALAW, 1, 0.04) ;
  417. /* Lite remove end */
  418. test_count++ ;
  419. } ;
  420. /* Lite remove end */
  421. if (do_all || strcmp (argv [1], "w64_gsm610") == 0)
  422. { /* Don't do lcomp_test_XXX as the errors are too big. */
  423. sdlcomp_test_short ("gsm610.w64", SF_FORMAT_W64 | SF_FORMAT_GSM610, 1, 0.2) ;
  424. sdlcomp_test_int ("gsm610.w64", SF_FORMAT_W64 | SF_FORMAT_GSM610, 1, 0.2) ;
  425. /* Lite remove start */
  426. sdlcomp_test_float ("gsm610.w64", SF_FORMAT_W64 | SF_FORMAT_GSM610, 1, 0.2) ;
  427. sdlcomp_test_double ("gsm610.w64", SF_FORMAT_W64 | SF_FORMAT_GSM610, 1, 0.2) ;
  428. /* Lite remove end */
  429. test_count++ ;
  430. } ;
  431. /* Lite remove start */
  432. if (do_all || strcmp (argv [1], "vox_adpcm") == 0)
  433. { lcomp_test_short ("adpcm.vox", SF_FORMAT_RAW | SF_FORMAT_VOX_ADPCM, 1, 0.17) ;
  434. lcomp_test_int ("adpcm.vox", SF_FORMAT_RAW | SF_FORMAT_VOX_ADPCM, 1, 0.17) ;
  435. lcomp_test_float ("adpcm.vox", SF_FORMAT_RAW | SF_FORMAT_VOX_ADPCM, 1, 0.17) ;
  436. lcomp_test_double ("adpcm.vox", SF_FORMAT_RAW | SF_FORMAT_VOX_ADPCM, 1, 0.17) ;
  437. sdlcomp_test_short ("adpcm.vox", SF_FORMAT_RAW | SF_FORMAT_VOX_ADPCM, 1, 0.072) ;
  438. sdlcomp_test_int ("adpcm.vox", SF_FORMAT_RAW | SF_FORMAT_VOX_ADPCM, 1, 0.072) ;
  439. sdlcomp_test_float ("adpcm.vox", SF_FORMAT_RAW | SF_FORMAT_VOX_ADPCM, 1, 0.072) ;
  440. sdlcomp_test_double ("adpcm.vox", SF_FORMAT_RAW | SF_FORMAT_VOX_ADPCM, 1, 0.072) ;
  441. test_count++ ;
  442. } ;
  443. if (do_all || strcmp (argv [1], "xi_dpcm") == 0)
  444. { lcomp_test_short ("8bit.xi", SF_FORMAT_XI | SF_FORMAT_DPCM_8, 1, 0.25) ;
  445. lcomp_test_int ("8bit.xi", SF_FORMAT_XI | SF_FORMAT_DPCM_8, 1, 0.25) ;
  446. lcomp_test_short ("16bit.xi", SF_FORMAT_XI | SF_FORMAT_DPCM_16, 1, 0.002) ;
  447. lcomp_test_int ("16bit.xi", SF_FORMAT_XI | SF_FORMAT_DPCM_16, 1, 0.002) ;
  448. lcomp_test_float ("16bit.xi", SF_FORMAT_XI | SF_FORMAT_DPCM_16, 1, 0.002) ;
  449. lcomp_test_double ("16bit.xi", SF_FORMAT_XI | SF_FORMAT_DPCM_16, 1, 0.002) ;
  450. test_count++ ;
  451. } ;
  452. /* Lite remove end */
  453. if (test_count == 0)
  454. { printf ("************************************\n") ;
  455. printf ("* No '%s' test defined.\n", argv [1]) ;
  456. printf ("************************************\n") ;
  457. return 1 ;
  458. } ;
  459. return 0 ;
  460. } /* main */
  461. /*============================================================================================
  462. ** Here are the test functions.
  463. */
  464. static void
  465. lcomp_test_short (const char *filename, int filetype, int channels, double margin)
  466. { SNDFILE *file ;
  467. SF_INFO sfinfo ;
  468. int k, m, seekpos, half_max_abs ;
  469. sf_count_t datalen ;
  470. short *orig, *data ;
  471. print_test_name ("lcomp_test_short", filename) ;
  472. datalen = BUFFER_SIZE / channels ;
  473. data = data_buffer.s ;
  474. orig = orig_buffer.s ;
  475. gen_signal_double (orig_buffer.d, 32000.0, channels, datalen) ;
  476. for (k = 0 ; k < channels * datalen ; k++)
  477. orig [k] = (short) (orig_buffer.d [k]) ;
  478. sfinfo.samplerate = SAMPLE_RATE ;
  479. sfinfo.frames = 123456789 ; /* Ridiculous value. */
  480. sfinfo.channels = channels ;
  481. sfinfo.format = filetype ;
  482. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ;
  483. test_writef_short_or_die (file, 0, orig, datalen, __LINE__) ;
  484. sf_set_string (file, SF_STR_COMMENT, long_comment) ;
  485. sf_close (file) ;
  486. memset (data, 0, datalen * sizeof (short)) ;
  487. if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
  488. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  489. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
  490. if ((sfinfo.format & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)) != (filetype & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)))
  491. { printf ("\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, filetype, sfinfo.format) ;
  492. exit (1) ;
  493. } ;
  494. if (sfinfo.frames < datalen / channels)
  495. { printf ("Too few frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", sfinfo.frames, datalen) ;
  496. exit (1) ;
  497. } ;
  498. if (sfinfo.frames > (datalen + datalen / 20))
  499. { printf ("Too many frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", sfinfo.frames, datalen) ;
  500. exit (1) ;
  501. } ;
  502. if (sfinfo.channels != channels)
  503. { printf ("Incorrect number of channels in file.\n") ;
  504. exit (1) ;
  505. } ;
  506. check_log_buffer_or_die (file, __LINE__) ;
  507. check_comment (file, filetype, __LINE__) ;
  508. test_readf_short_or_die (file, 0, data, datalen, __LINE__) ;
  509. half_max_abs = 0 ;
  510. for (k = 0 ; k < datalen ; k++)
  511. { if (error_function (data [k], orig [k], margin))
  512. { printf ("\n\nLine %d: Incorrect sample A (#%d : %d should be %d).\n", __LINE__, k, data [k], orig [k]) ;
  513. oct_save_short (orig, data, datalen) ;
  514. exit (1) ;
  515. } ;
  516. half_max_abs = LCT_MAX (half_max_abs, abs (data [k] / 2)) ;
  517. } ;
  518. if (half_max_abs < 1.0)
  519. { printf ("\n\nLine %d: Signal is all zeros.\n", __LINE__) ;
  520. exit (1) ;
  521. } ;
  522. if ((k = sf_readf_short (file, data, datalen)) != sfinfo.frames - datalen)
  523. { printf ("\n\nLine %d: Incorrect read length (%" PRId64 " should be %d).\n", __LINE__,
  524. channels * sfinfo.frames - datalen, k) ;
  525. exit (1) ;
  526. } ;
  527. /* This check is only for block based encoders which must append silence
  528. ** to the end of a file so as to fill out a block.
  529. */
  530. for (k = 0 ; k < sfinfo.frames - datalen ; k++)
  531. if (abs (data [channels * k]) > decay_response (channels * k))
  532. { printf ("\n\nLine %d : Incorrect sample B (#%d : abs (%d) should be < %d).\n", __LINE__, channels * k, data [channels * k], decay_response (channels * k)) ;
  533. exit (1) ;
  534. } ;
  535. if (! sfinfo.seekable)
  536. { sf_close (file) ;
  537. unlink (filename) ;
  538. printf ("ok\n") ;
  539. return ;
  540. } ;
  541. /* Now test sf_seek function. */
  542. if ((k = sf_seek (file, 0, SEEK_SET)) != 0)
  543. { printf ("\n\nLine %d: Seek to start of file failed (%d).\n", __LINE__, k) ;
  544. exit (1) ;
  545. } ;
  546. for (m = 0 ; m < 3 ; m++)
  547. { test_readf_short_or_die (file, m, data, 11, __LINE__) ;
  548. for (k = 0 ; k < channels * 11 ; k++)
  549. if (error_function (1.0 * data [k], 1.0 * orig [k + channels * m * 11], margin))
  550. { 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]) ;
  551. for (m = 0 ; m < channels ; m++)
  552. printf ("%d ", data [m]) ;
  553. printf ("\n") ;
  554. exit (1) ;
  555. } ;
  556. } ;
  557. seekpos = BUFFER_SIZE / 10 ;
  558. /* Check seek from start of file. */
  559. if ((k = sf_seek (file, seekpos, SEEK_SET)) != seekpos)
  560. { printf ("Seek to start of file + %d failed (%d).\n", seekpos, k) ;
  561. exit (1) ;
  562. } ;
  563. test_readf_short_or_die (file, 0, data, 1, __LINE__) ;
  564. if (error_function (1.0 * data [0], 1.0 * orig [seekpos * channels], margin))
  565. { printf ("\n\nLine %d: sf_seek (SEEK_SET) followed by sf_readf_short failed (%d, %d).\n", __LINE__, orig [1], data [0]) ;
  566. exit (1) ;
  567. } ;
  568. if ((k = sf_seek (file, 0, SEEK_CUR)) != seekpos + 1)
  569. { printf ("\n\nLine %d: sf_seek (SEEK_CUR) with 0 offset failed (%d should be %d)\n", __LINE__, k, seekpos + 1) ;
  570. exit (1) ;
  571. } ;
  572. seekpos = sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ;
  573. k = sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ;
  574. test_readf_short_or_die (file, 0, data, 1, __LINE__) ;
  575. if (error_function (1.0 * data [0], 1.0 * orig [seekpos * channels], margin) || k != seekpos)
  576. { 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) ;
  577. oct_save_short (orig, data, datalen) ;
  578. exit (1) ;
  579. } ;
  580. seekpos = sf_seek (file, 0, SEEK_CUR) - 20 ;
  581. /* Check seek backward from current position. */
  582. k = sf_seek (file, -20, SEEK_CUR) ;
  583. test_readf_short_or_die (file, 0, data, 1, __LINE__) ;
  584. if (error_function (1.0 * data [0], 1.0 * orig [seekpos * channels], margin) || k != seekpos)
  585. { 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) ;
  586. exit (1) ;
  587. } ;
  588. /* Check that read past end of file returns number of items. */
  589. sf_seek (file, sfinfo.frames, SEEK_SET) ;
  590. if ((k = sf_readf_short (file, data, datalen)) != 0)
  591. { printf ("\n\nLine %d: Return value from sf_readf_short past end of file incorrect (%d).\n", __LINE__, k) ;
  592. exit (1) ;
  593. } ;
  594. /* Check seek backward from end. */
  595. if ((k = sf_seek (file, 5 - sfinfo.frames, SEEK_END)) != 5)
  596. { printf ("\n\nLine %d: sf_seek (SEEK_END) returned %d instead of %d.\n", __LINE__, k, 5) ;
  597. exit (1) ;
  598. } ;
  599. test_readf_short_or_die (file, 0, data, 1, __LINE__) ;
  600. if (error_function (1.0 * data [0], 1.0 * orig [5 * channels], margin))
  601. { printf ("\nLine %d: sf_seek (SEEK_END) followed by sf_readf_short failed (%d should be %d).\n", __LINE__, data [0], orig [5 * channels]) ;
  602. exit (1) ;
  603. } ;
  604. sf_close (file) ;
  605. unlink (filename) ;
  606. printf ("ok\n") ;
  607. } /* lcomp_test_short */
  608. /*--------------------------------------------------------------------------------------------
  609. */
  610. static void
  611. lcomp_test_int (const char *filename, int filetype, int channels, double margin)
  612. { SNDFILE *file ;
  613. SF_INFO sfinfo ;
  614. int k, m, half_max_abs ;
  615. sf_count_t datalen, seekpos ;
  616. double scale, max_val ;
  617. int *orig, *data ;
  618. print_test_name ("lcomp_test_int", filename) ;
  619. datalen = BUFFER_SIZE / channels ;
  620. if (is_lossy (filetype))
  621. { scale = 1.0 * 0x10000 ;
  622. max_val = 32000.0 * scale ;
  623. }
  624. else
  625. { scale = 1.0 ;
  626. max_val = 0x7fffffff * scale ;
  627. } ;
  628. data = data_buffer.i ;
  629. orig = orig_buffer.i ;
  630. gen_signal_double (orig_buffer.d, max_val, channels, datalen) ;
  631. for (k = 0 ; k < channels * datalen ; k++)
  632. orig [k] = lrint (orig_buffer.d [k]) ;
  633. sfinfo.samplerate = SAMPLE_RATE ;
  634. sfinfo.frames = 123456789 ; /* Ridiculous value. */
  635. sfinfo.channels = channels ;
  636. sfinfo.format = filetype ;
  637. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ;
  638. test_writef_int_or_die (file, 0, orig, datalen, __LINE__) ;
  639. sf_set_string (file, SF_STR_COMMENT, long_comment) ;
  640. sf_close (file) ;
  641. memset (data, 0, datalen * sizeof (int)) ;
  642. if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
  643. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  644. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
  645. if ((sfinfo.format & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)) != (filetype & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)))
  646. { printf ("\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, filetype, sfinfo.format) ;
  647. exit (1) ;
  648. } ;
  649. if (sfinfo.frames < datalen / channels)
  650. { printf ("Too few.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", datalen, sfinfo.frames) ;
  651. exit (1) ;
  652. } ;
  653. if (sfinfo.frames > (datalen + datalen / 20))
  654. { printf ("Too many.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", datalen, sfinfo.frames) ;
  655. exit (1) ;
  656. } ;
  657. if (sfinfo.channels != channels)
  658. { printf ("Incorrect number of channels in file.\n") ;
  659. exit (1) ;
  660. } ;
  661. check_log_buffer_or_die (file, __LINE__) ;
  662. check_comment (file, filetype, __LINE__) ;
  663. test_readf_int_or_die (file, 0, data, datalen, __LINE__) ;
  664. half_max_abs = 0 ;
  665. for (k = 0 ; k < datalen ; k++)
  666. { if (error_function (data [k] / scale, orig [k] / scale, margin))
  667. { printf ("\nLine %d: Incorrect sample (#%d : %f should be %f).\n", __LINE__, k, data [k] / scale, orig [k] / scale) ;
  668. oct_save_int (orig, data, datalen) ;
  669. exit (1) ;
  670. } ;
  671. half_max_abs = LCT_MAX (half_max_abs, abs (data [k] / 2)) ;
  672. } ;
  673. if (half_max_abs < 1.0)
  674. { printf ("\n\nLine %d: Signal is all zeros (%d, 0x%X).\n", __LINE__, half_max_abs, half_max_abs) ;
  675. exit (1) ;
  676. } ;
  677. if ((k = sf_readf_int (file, data, datalen)) != sfinfo.frames - datalen)
  678. { printf ("\n\nLine %d: Incorrect read length (%" PRId64 " should be %d).\n", __LINE__,
  679. channels * sfinfo.frames - datalen, k) ;
  680. exit (1) ;
  681. } ;
  682. /* This check is only for block based encoders which must append silence
  683. ** to the end of a file so as to fill out a block.
  684. */
  685. if ((sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_MS_ADPCM)
  686. for (k = 0 ; k < sfinfo.frames - datalen ; k++)
  687. if (abs (data [channels * k] / scale) > decay_response (channels * k))
  688. { printf ("\n\nLine %d : Incorrect sample B (#%d : abs (%d) should be < %d).\n", __LINE__, channels * k, data [channels * k], decay_response (channels * k)) ;
  689. exit (1) ;
  690. } ;
  691. if (! sfinfo.seekable)
  692. { sf_close (file) ;
  693. unlink (filename) ;
  694. printf ("ok\n") ;
  695. return ;
  696. } ;
  697. /* Now test sf_seek function. */
  698. if ((k = sf_seek (file, 0, SEEK_SET)) != 0)
  699. { printf ("\n\nLine %d: Seek to start of file failed (%d).\n", __LINE__, k) ;
  700. exit (1) ;
  701. } ;
  702. for (m = 0 ; m < 3 ; m++)
  703. { test_readf_int_or_die (file, m, data, 11, __LINE__) ;
  704. for (k = 0 ; k < channels * 11 ; k++)
  705. if (error_function (data [k] / scale, orig [k + channels * m * 11] / scale, margin))
  706. { printf ("\nLine %d: Incorrect sample (m = %d) (#%d : %d => %d).\n", __LINE__, m, k + channels * m * 11, orig [k + channels * m * 11], data [k]) ;
  707. for (m = 0 ; m < channels ; m++)
  708. printf ("%d ", data [m]) ;
  709. printf ("\n") ;
  710. exit (1) ;
  711. } ;
  712. } ;
  713. seekpos = BUFFER_SIZE / 10 ;
  714. /* Check seek from start of file. */
  715. if ((k = sf_seek (file, seekpos, SEEK_SET)) != seekpos)
  716. { printf ("Seek to start of file + %" PRId64 " failed (%d).\n", seekpos, k) ;
  717. exit (1) ;
  718. } ;
  719. test_readf_int_or_die (file, 0, data, 1, __LINE__) ;
  720. if (error_function (1.0 * data [0], 1.0 * orig [seekpos * channels], margin))
  721. { printf ("\nLine %d: sf_seek (SEEK_SET) followed by sf_readf_int failed (%d, %d).\n", __LINE__, orig [1], data [0]) ;
  722. exit (1) ;
  723. } ;
  724. if ((k = sf_seek (file, 0, SEEK_CUR)) != seekpos + 1)
  725. { printf ("\n\nLine %d: sf_seek (SEEK_CUR) with 0 offset failed (%d should be %" PRId64 ")\n", __LINE__, k, seekpos + 1) ;
  726. exit (1) ;
  727. } ;
  728. seekpos = sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ;
  729. k = sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ;
  730. test_readf_int_or_die (file, 0, data, 1, __LINE__) ;
  731. if (error_function (1.0 * data [0], 1.0 * orig [seekpos * channels], margin) || k != seekpos)
  732. { 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) ;
  733. exit (1) ;
  734. } ;
  735. seekpos = sf_seek (file, 0, SEEK_CUR) - 20 ;
  736. /* Check seek backward from current position. */
  737. k = sf_seek (file, -20, SEEK_CUR) ;
  738. test_readf_int_or_die (file, 0, data, 1, __LINE__) ;
  739. if (error_function (1.0 * data [0], 1.0 * orig [seekpos * channels], margin) || k != seekpos)
  740. { 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) ;
  741. exit (1) ;
  742. } ;
  743. /* Check that read past end of file returns number of items. */
  744. sf_seek (file, sfinfo.frames, SEEK_SET) ;
  745. if ((k = sf_readf_int (file, data, datalen)) != 0)
  746. { printf ("\n\nLine %d: Return value from sf_readf_int past end of file incorrect (%d).\n", __LINE__, k) ;
  747. exit (1) ;
  748. } ;
  749. /* Check seek backward from end. */
  750. if ((k = sf_seek (file, 5 - sfinfo.frames, SEEK_END)) != 5)
  751. { printf ("\n\nLine %d: sf_seek (SEEK_END) returned %d instead of %d.\n", __LINE__, k, 5) ;
  752. exit (1) ;
  753. } ;
  754. test_readf_int_or_die (file, 0, data, 1, __LINE__) ;
  755. if (error_function (data [0] / scale, orig [5 * channels] / scale, margin))
  756. { printf ("\nLine %d: sf_seek (SEEK_END) followed by sf_readf_short failed (%d should be %d).\n", __LINE__, data [0], orig [5]) ;
  757. exit (1) ;
  758. } ;
  759. sf_close (file) ;
  760. unlink (filename) ;
  761. printf ("ok\n") ;
  762. } /* lcomp_test_int */
  763. /*--------------------------------------------------------------------------------------------
  764. */
  765. static void
  766. lcomp_test_float (const char *filename, int filetype, int channels, double margin)
  767. { SNDFILE *file ;
  768. SF_INFO sfinfo ;
  769. int k, m, seekpos ;
  770. sf_count_t datalen ;
  771. float *orig, *data ;
  772. double half_max_abs ;
  773. print_test_name ("lcomp_test_float", filename) ;
  774. datalen = BUFFER_SIZE / channels ;
  775. data = data_buffer.f ;
  776. orig = orig_buffer.f ;
  777. gen_signal_double (orig_buffer.d, 32000.0, channels, datalen) ;
  778. for (k = 0 ; k < channels * datalen ; k++)
  779. orig [k] = orig_buffer.d [k] ;
  780. sfinfo.samplerate = SAMPLE_RATE ;
  781. sfinfo.frames = 123456789 ; /* Ridiculous value. */
  782. sfinfo.channels = channels ;
  783. sfinfo.format = filetype ;
  784. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ;
  785. sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ;
  786. test_writef_float_or_die (file, 0, orig, datalen, __LINE__) ;
  787. sf_set_string (file, SF_STR_COMMENT, long_comment) ;
  788. sf_close (file) ;
  789. memset (data, 0, datalen * sizeof (float)) ;
  790. if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
  791. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  792. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
  793. if ((sfinfo.format & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)) != (filetype & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)))
  794. { printf ("\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, filetype, sfinfo.format) ;
  795. exit (1) ;
  796. } ;
  797. if (sfinfo.frames < datalen / channels)
  798. { printf ("Too few.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", datalen, sfinfo.frames) ;
  799. exit (1) ;
  800. } ;
  801. if (sfinfo.frames > (datalen + datalen / 20))
  802. { printf ("Too many.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", datalen, sfinfo.frames) ;
  803. exit (1) ;
  804. } ;
  805. if (sfinfo.channels != channels)
  806. { printf ("Incorrect number of channels in file.\n") ;
  807. exit (1) ;
  808. } ;
  809. check_comment (file, filetype, __LINE__) ;
  810. sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ;
  811. check_log_buffer_or_die (file, __LINE__) ;
  812. check_comment (file, filetype, __LINE__) ;
  813. sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ;
  814. test_readf_float_or_die (file, 0, data, datalen, __LINE__) ;
  815. half_max_abs = 0.0 ;
  816. for (k = 0 ; k < datalen ; k++)
  817. { if (error_function (data [k], orig [k], margin))
  818. { printf ("\nLine %d: Incorrect sample A (#%d : %f should be %f).\n", __LINE__, k, data [k], orig [k]) ;
  819. oct_save_float (orig, data, datalen) ;
  820. exit (1) ;
  821. } ;
  822. half_max_abs = LCT_MAX (half_max_abs, fabs (0.5 * data [k])) ;
  823. } ;
  824. if (half_max_abs < 1.0)
  825. { printf ("\n\nLine %d: Signal is all zeros.\n", __LINE__) ;
  826. exit (1) ;
  827. } ;
  828. if ((k = sf_readf_float (file, data, datalen)) != sfinfo.frames - datalen)
  829. { printf ("\n\nLine %d: Incorrect read length (%" PRId64 " should be %d).\n", __LINE__,
  830. channels * sfinfo.frames - datalen, k) ;
  831. exit (1) ;
  832. } ;
  833. /* This check is only for block based encoders which must append silence
  834. ** to the end of a file so as to fill out a block.
  835. */
  836. if ((sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_MS_ADPCM)
  837. for (k = 0 ; k < sfinfo.frames - datalen ; k++)
  838. if (abs (data [channels * k]) > decay_response (channels * k))
  839. { printf ("\n\nLine %d : Incorrect sample B (#%d : abs (%f) should be < %d).\n", __LINE__, channels * k, data [channels * k], decay_response (channels * k)) ;
  840. exit (1) ;
  841. } ;
  842. if (! sfinfo.seekable)
  843. { sf_close (file) ;
  844. unlink (filename) ;
  845. printf ("ok\n") ;
  846. return ;
  847. } ;
  848. /* Now test sf_seek function. */
  849. if ((k = sf_seek (file, 0, SEEK_SET)) != 0)
  850. { printf ("\n\nLine %d: Seek to start of file failed (%d).\n", __LINE__, k) ;
  851. exit (1) ;
  852. } ;
  853. for (m = 0 ; m < 3 ; m++)
  854. { test_readf_float_or_die (file, 0, data, 11, __LINE__) ;
  855. for (k = 0 ; k < channels * 11 ; k++)
  856. if (error_function (data [k], orig [k + channels * m * 11], margin))
  857. { printf ("\nLine %d: Incorrect sample (m = %d) (#%d : %f => %f).\n", __LINE__, m, k + channels * m * 11, orig [k + channels * m * 11], data [k]) ;
  858. for (m = 0 ; m < channels ; m++)
  859. printf ("%f ", data [m]) ;
  860. printf ("\n") ;
  861. exit (1) ;
  862. } ;
  863. } ;
  864. seekpos = BUFFER_SIZE / 10 ;
  865. /* Check seek from start of file. */
  866. if ((k = sf_seek (file, seekpos, SEEK_SET)) != seekpos)
  867. { printf ("Seek to start of file + %d failed (%d).\n", seekpos, k) ;
  868. exit (1) ;
  869. } ;
  870. test_readf_float_or_die (file, 0, data, 1, __LINE__) ;
  871. if (error_function (data [0], orig [seekpos * channels], margin))
  872. { printf ("\nLine %d: sf_seek (SEEK_SET) followed by sf_readf_float failed (%f, %f).\n", __LINE__, orig [1], data [0]) ;
  873. exit (1) ;
  874. } ;
  875. if ((k = sf_seek (file, 0, SEEK_CUR)) != seekpos + 1)
  876. { printf ("\n\nLine %d: sf_seek (SEEK_CUR) with 0 offset failed (%d should be %d)\n", __LINE__, k, seekpos + 1) ;
  877. exit (1) ;
  878. } ;
  879. seekpos = sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ;
  880. k = sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ;
  881. test_readf_float_or_die (file, 0, data, 1, __LINE__) ;
  882. if (error_function (data [0], orig [seekpos * channels], margin) || k != seekpos)
  883. { 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) ;
  884. exit (1) ;
  885. } ;
  886. seekpos = sf_seek (file, 0, SEEK_CUR) - 20 ;
  887. /* Check seek backward from current position. */
  888. k = sf_seek (file, -20, SEEK_CUR) ;
  889. test_readf_float_or_die (file, 0, data, 1, __LINE__) ;
  890. if (error_function (data [0], orig [seekpos * channels], margin) || k != seekpos)
  891. { 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) ;
  892. exit (1) ;
  893. } ;
  894. /* Check that read past end of file returns number of items. */
  895. sf_seek (file, sfinfo.frames, SEEK_SET) ;
  896. if ((k = sf_readf_float (file, data, datalen)) != 0)
  897. { printf ("\n\nLine %d: Return value from sf_readf_float past end of file incorrect (%d).\n", __LINE__, k) ;
  898. exit (1) ;
  899. } ;
  900. /* Check seek backward from end. */
  901. if ((k = sf_seek (file, 5 - sfinfo.frames, SEEK_END)) != 5)
  902. { printf ("\n\nLine %d: sf_seek (SEEK_END) returned %d instead of %d.\n", __LINE__, k, 5) ;
  903. exit (1) ;
  904. } ;
  905. test_readf_float_or_die (file, 0, data, 1, __LINE__) ;
  906. if (error_function (data [0], orig [5 * channels], margin))
  907. { printf ("\nLine %d: sf_seek (SEEK_END) followed by sf_readf_short failed (%f should be %f).\n", __LINE__, data [0], orig [5 * channels]) ;
  908. exit (1) ;
  909. } ;
  910. sf_close (file) ;
  911. unlink (filename) ;
  912. printf ("ok\n") ;
  913. } /* lcomp_test_float */
  914. /*--------------------------------------------------------------------------------------------
  915. */
  916. static void
  917. lcomp_test_double (const char *filename, int filetype, int channels, double margin)
  918. { SNDFILE *file ;
  919. SF_INFO sfinfo ;
  920. int k, m, seekpos ;
  921. sf_count_t datalen ;
  922. double *orig, *data ;
  923. double half_max_abs ;
  924. print_test_name ("lcomp_test_double", filename) ;
  925. datalen = BUFFER_SIZE / channels ;
  926. data = data_buffer.d ;
  927. orig = orig_buffer.d ;
  928. gen_signal_double (orig_buffer.d, 32000.0, channels, datalen) ;
  929. for (k = 0 ; k < channels * datalen ; k++)
  930. orig [k] = orig_buffer.d [k] ;
  931. sfinfo.samplerate = SAMPLE_RATE ;
  932. sfinfo.frames = 123456789 ; /* Ridiculous value. */
  933. sfinfo.channels = channels ;
  934. sfinfo.format = filetype ;
  935. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ;
  936. sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ;
  937. test_writef_double_or_die (file, 0, orig, datalen, __LINE__) ;
  938. sf_set_string (file, SF_STR_COMMENT, long_comment) ;
  939. sf_close (file) ;
  940. memset (data, 0, datalen * sizeof (double)) ;
  941. if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
  942. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  943. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
  944. if ((sfinfo.format & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)) != (filetype & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)))
  945. { printf ("\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, filetype, sfinfo.format) ;
  946. exit (1) ;
  947. } ;
  948. if (sfinfo.frames < datalen / channels)
  949. { printf ("Too few.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", datalen, sfinfo.frames) ;
  950. exit (1) ;
  951. } ;
  952. if (sfinfo.frames > (datalen + datalen / 20))
  953. { printf ("Too many.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", datalen, sfinfo.frames) ;
  954. exit (1) ;
  955. } ;
  956. if (sfinfo.channels != channels)
  957. { printf ("Incorrect number of channels in file.\n") ;
  958. exit (1) ;
  959. } ;
  960. check_comment (file, filetype, __LINE__) ;
  961. sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ;
  962. check_log_buffer_or_die (file, __LINE__) ;
  963. check_comment (file, filetype, __LINE__) ;
  964. sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ;
  965. test_readf_double_or_die (file, 0, data, datalen, __LINE__) ;
  966. half_max_abs = 0.0 ;
  967. for (k = 0 ; k < datalen ; k++)
  968. { if (error_function (data [k], orig [k], margin))
  969. { printf ("\nLine %d: Incorrect sample A (#%d : %f should be %f).\n", __LINE__, k, data [k], orig [k]) ;
  970. oct_save_double (orig, data, datalen) ;
  971. exit (1) ;
  972. } ;
  973. half_max_abs = LCT_MAX (half_max_abs, abs (0.5 * data [k])) ;
  974. } ;
  975. if (half_max_abs < 1.0)
  976. { printf ("\n\nLine %d: Signal is all zeros.\n", __LINE__) ;
  977. exit (1) ;
  978. } ;
  979. if ((k = sf_readf_double (file, data, datalen)) != sfinfo.frames - datalen)
  980. { printf ("\n\nLine %d: Incorrect read length (%" PRId64 " should be %d).\n", __LINE__,
  981. channels * sfinfo.frames - datalen, k) ;
  982. exit (1) ;
  983. } ;
  984. /* This check is only for block based encoders which must append silence
  985. ** to the end of a file so as to fill out a block.
  986. */
  987. if ((sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_MS_ADPCM)
  988. for (k = 0 ; k < sfinfo.frames - datalen ; k++)
  989. if (abs (data [channels * k]) > decay_response (channels * k))
  990. { printf ("\n\nLine %d : Incorrect sample B (#%d : abs (%f) should be < %d).\n", __LINE__, channels * k, data [channels * k], decay_response (channels * k)) ;
  991. exit (1) ;
  992. } ;
  993. if (! sfinfo.seekable)
  994. { sf_close (file) ;
  995. unlink (filename) ;
  996. printf ("ok\n") ;
  997. return ;
  998. } ;
  999. /* Now test sf_seek function. */
  1000. if ((k = sf_seek (file, 0, SEEK_SET)) != 0)
  1001. { printf ("\n\nLine %d: Seek to start of file failed (%d).\n", __LINE__, k) ;
  1002. exit (1) ;
  1003. } ;
  1004. for (m = 0 ; m < 3 ; m++)
  1005. { test_readf_double_or_die (file, m, data, 11, __LINE__) ;
  1006. for (k = 0 ; k < channels * 11 ; k++)
  1007. if (error_function (data [k], orig [k + channels * m * 11], margin))
  1008. { printf ("\nLine %d: Incorrect sample (m = %d) (#%d : %f => %f).\n", __LINE__, m, k + channels * m * 11, orig [k + channels * m * 11], data [k]) ;
  1009. for (m = 0 ; m < channels ; m++)
  1010. printf ("%f ", data [m]) ;
  1011. printf ("\n") ;
  1012. exit (1) ;
  1013. } ;
  1014. } ;
  1015. seekpos = BUFFER_SIZE / 10 ;
  1016. /* Check seek from start of file. */
  1017. if ((k = sf_seek (file, seekpos, SEEK_SET)) != seekpos)
  1018. { printf ("Seek to start of file + %d failed (%d).\n", seekpos, k) ;
  1019. exit (1) ;
  1020. } ;
  1021. test_readf_double_or_die (file, 0, data, 1, __LINE__) ;
  1022. if (error_function (data [0], orig [seekpos * channels], margin))
  1023. { printf ("\nLine %d: sf_seek (SEEK_SET) followed by sf_readf_double failed (%f, %f).\n", __LINE__, orig [1], data [0]) ;
  1024. exit (1) ;
  1025. } ;
  1026. if ((k = sf_seek (file, 0, SEEK_CUR)) != seekpos + 1)
  1027. { printf ("\n\nLine %d: sf_seek (SEEK_CUR) with 0 offset failed (%d should be %d)\n", __LINE__, k, seekpos + 1) ;
  1028. exit (1) ;
  1029. } ;
  1030. seekpos = sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ;
  1031. k = sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ;
  1032. test_readf_double_or_die (file, 0, data, 1, __LINE__) ;
  1033. if (error_function (data [0], orig [seekpos * channels], margin) || k != seekpos)
  1034. { 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) ;
  1035. exit (1) ;
  1036. } ;
  1037. seekpos = sf_seek (file, 0, SEEK_CUR) - 20 ;
  1038. /* Check seek backward from current position. */
  1039. k = sf_seek (file, -20, SEEK_CUR) ;
  1040. test_readf_double_or_die (file, 0, data, 1, __LINE__) ;
  1041. if (error_function (data [0], orig [seekpos * channels], margin) || k != seekpos)
  1042. { 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) ;
  1043. exit (1) ;
  1044. } ;
  1045. /* Check that read past end of file returns number of items. */
  1046. sf_seek (file, sfinfo.frames, SEEK_SET) ;
  1047. if ((k = sf_readf_double (file, data, datalen)) != 0)
  1048. { printf ("\n\nLine %d: Return value from sf_readf_double past end of file incorrect (%d).\n", __LINE__, k) ;
  1049. exit (1) ;
  1050. } ;
  1051. /* Check seek backward from end. */
  1052. if ((k = sf_seek (file, 5 - sfinfo.frames, SEEK_END)) != 5)
  1053. { printf ("\n\nLine %d: sf_seek (SEEK_END) returned %d instead of %d.\n", __LINE__, k, 5) ;
  1054. exit (1) ;
  1055. } ;
  1056. test_readf_double_or_die (file, 0, data, 1, __LINE__) ;
  1057. if (error_function (data [0], orig [5 * channels], margin))
  1058. { printf ("\nLine %d: sf_seek (SEEK_END) followed by sf_readf_short failed (%f should be %f).\n", __LINE__, data [0], orig [5 * channels]) ;
  1059. exit (1) ;
  1060. } ;
  1061. sf_close (file) ;
  1062. unlink (filename) ;
  1063. printf ("ok\n") ;
  1064. } /* lcomp_test_double */
  1065. /*========================================================================================
  1066. ** Smoothed differential loss compression tests.
  1067. */
  1068. static void
  1069. sdlcomp_test_short (const char *filename, int filetype, int channels, double margin)
  1070. { SNDFILE *file ;
  1071. SF_INFO sfinfo ;
  1072. int k, m, seekpos, half_max_abs ;
  1073. sf_count_t datalen ;
  1074. short *orig, *data, *smooth ;
  1075. channels = 1 ;
  1076. print_test_name ("sdlcomp_test_short", filename) ;
  1077. datalen = BUFFER_SIZE ;
  1078. orig = orig_buffer.s ;
  1079. data = data_buffer.s ;
  1080. smooth = smooth_buffer.s ;
  1081. gen_signal_double (orig_buffer.d, 32000.0, channels, datalen) ;
  1082. for (k = 0 ; k < datalen ; k++)
  1083. orig [k] = lrint (orig_buffer.d [k]) ;
  1084. sfinfo.samplerate = SAMPLE_RATE ;
  1085. sfinfo.frames = 123456789 ; /* Ridiculous value. */
  1086. sfinfo.channels = channels ;
  1087. sfinfo.format = filetype ;
  1088. /* The Vorbis encoder has a bug on PowerPC and X86-64 with sample rates
  1089. ** <= 22050. Increasing the sample rate to 32000 avoids triggering it.
  1090. ** See https://trac.xiph.org/ticket/1229
  1091. */
  1092. if ((file = sf_open (filename, SFM_WRITE, &sfinfo)) == NULL)
  1093. { const char * errstr ;
  1094. errstr = sf_strerror (NULL) ;
  1095. if (strstr (errstr, "Sample rate chosen is known to trigger a Vorbis") == NULL)
  1096. { printf ("Line %d: sf_open_fd (SFM_WRITE) failed : %s\n", __LINE__, errstr) ;
  1097. dump_log_buffer (NULL) ;
  1098. exit (1) ;
  1099. } ;
  1100. printf ("\n Sample rate -> 32kHz ") ;
  1101. sfinfo.samplerate = 32000 ;
  1102. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
  1103. } ;
  1104. test_write_short_or_die (file, 0, orig, datalen, __LINE__) ;
  1105. sf_set_string (file, SF_STR_COMMENT, long_comment) ;
  1106. sf_close (file) ;
  1107. memset (data, 0, datalen * sizeof (short)) ;
  1108. if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
  1109. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  1110. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
  1111. if (sfinfo.format != filetype)
  1112. { printf ("\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, filetype, sfinfo.format) ;
  1113. exit (1) ;
  1114. } ;
  1115. if (sfinfo.frames < datalen / channels)
  1116. { printf ("Too few.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", datalen, sfinfo.frames) ;
  1117. exit (1) ;
  1118. } ;
  1119. if (sfinfo.frames > (datalen + 400))
  1120. { printf ("Too many.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", sfinfo.frames, datalen) ;
  1121. exit (1) ;
  1122. } ;
  1123. if (sfinfo.channels != channels)
  1124. { printf ("Incorrect number of channels in file.\n") ;
  1125. exit (1) ;
  1126. } ;
  1127. check_comment (file, filetype, __LINE__) ;
  1128. sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ;
  1129. check_log_buffer_or_die (file, __LINE__) ;
  1130. test_readf_short_or_die (file, 0, data, datalen, __LINE__) ;
  1131. memcpy (smooth, orig, datalen * sizeof (short)) ;
  1132. smoothed_diff_short (data, datalen) ;
  1133. smoothed_diff_short (smooth, datalen) ;
  1134. half_max_abs = 0.0 ;
  1135. for (k = 0 ; k < datalen ; k++)
  1136. { if (error_function (1.0 * data [k], 1.0 * smooth [k], margin))
  1137. { printf ("\nLine %d: Incorrect sample (#%d : %d should be %d).\n", __LINE__, k, data [k], smooth [k]) ;
  1138. oct_save_short (orig, smooth, datalen) ;
  1139. exit (1) ;
  1140. } ;
  1141. half_max_abs = LCT_MAX (half_max_abs, abs (0.5 * data [k])) ;
  1142. } ;
  1143. if (half_max_abs < 1)
  1144. { printf ("\n\nLine %d: Signal is all zeros.\n", __LINE__) ;
  1145. exit (1) ;
  1146. } ;
  1147. if ((k = sf_read_short (file, data, datalen)) != sfinfo.frames - datalen)
  1148. { printf ("\n\nLine %d: Incorrect read length (%d should be %" PRId64 ").\n", __LINE__, k, sfinfo.frames - datalen) ;
  1149. exit (1) ;
  1150. } ;
  1151. if ((sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_MS_ADPCM &&
  1152. (sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_GSM610)
  1153. for (k = 0 ; k < sfinfo.frames - datalen ; k++)
  1154. if (abs (data [k]) > decay_response (k))
  1155. { printf ("\n\nLine %d: Incorrect sample (#%" PRId64 " : abs (%d) should be < %d).\n", __LINE__, datalen + k, data [k], decay_response (k)) ;
  1156. exit (1) ;
  1157. } ;
  1158. /* Now test sf_seek function. */
  1159. if (sfinfo.seekable)
  1160. { if ((k = sf_seek (file, 0, SEEK_SET)) != 0)
  1161. { printf ("\n\nLine %d: Seek to start of file failed (%d).\n", __LINE__, k) ;
  1162. exit (1) ;
  1163. } ;
  1164. for (m = 0 ; m < 3 ; m++)
  1165. { test_readf_short_or_die (file, m, data, datalen / 7, __LINE__) ;
  1166. smoothed_diff_short (data, datalen / 7) ;
  1167. memcpy (smooth, orig + m * datalen / 7, datalen / 7 * sizeof (short)) ;
  1168. smoothed_diff_short (smooth, datalen / 7) ;
  1169. for (k = 0 ; k < datalen / 7 ; k++)
  1170. if (error_function (1.0 * data [k], 1.0 * smooth [k], margin))
  1171. { printf ("\nLine %d: Incorrect sample C (#%d (%" PRId64 ") : %d => %d).\n", __LINE__, k, k + m * (datalen / 7), smooth [k], data [k]) ;
  1172. for (m = 0 ; m < 10 ; m++)
  1173. printf ("%d ", data [k]) ;
  1174. printf ("\n") ;
  1175. exit (1) ;
  1176. } ;
  1177. } ; /* for (m = 0 ; m < 3 ; m++) */
  1178. seekpos = BUFFER_SIZE / 10 ;
  1179. /* Check seek from start of file. */
  1180. if ((k = sf_seek (file, seekpos, SEEK_SET)) != seekpos)
  1181. { printf ("Seek to start of file + %d failed (%d).\n", seekpos, k) ;
  1182. exit (1) ;
  1183. } ;
  1184. test_readf_short_or_die (file, 0, data, 1, __LINE__) ;
  1185. if (error_function (1.0 * data [0], 1.0 * orig [seekpos * channels], margin))
  1186. { printf ("\nLine %d: sf_seek (SEEK_SET) followed by sf_read_short failed (%d, %d).\n", __LINE__, orig [1], data [0]) ;
  1187. exit (1) ;
  1188. } ;
  1189. if ((k = sf_seek (file, 0, SEEK_CUR)) != seekpos + 1)
  1190. { printf ("\n\nLine %d: sf_seek (SEEK_CUR) with 0 offset failed (%d should be %d)\n", __LINE__, k, seekpos + 1) ;
  1191. exit (1) ;
  1192. } ;
  1193. seekpos = sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ;
  1194. k = sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ;
  1195. test_readf_short_or_die (file, 0, data, 1, __LINE__) ;
  1196. if (error_function (1.0 * data [0], 1.0 * orig [seekpos * channels], margin) || k != seekpos)
  1197. { 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) ;
  1198. exit (1) ;
  1199. } ;
  1200. seekpos = sf_seek (file, 0, SEEK_CUR) - 20 ;
  1201. /* Check seek backward from current position. */
  1202. k = sf_seek (file, -20, SEEK_CUR) ;
  1203. test_readf_short_or_die (file, 0, data, 1, __LINE__) ;
  1204. if (error_function (1.0 * data [0], 1.0 * orig [seekpos * channels], margin) || k != seekpos)
  1205. { 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) ;
  1206. exit (1) ;
  1207. } ;
  1208. /* Check that read past end of file returns number of items. */
  1209. sf_seek (file, sfinfo.frames, SEEK_SET) ;
  1210. if ((k = sf_read_short (file, data, datalen)) != 0)
  1211. { printf ("\n\nLine %d: Return value from sf_read_short past end of file incorrect (%d).\n", __LINE__, k) ;
  1212. exit (1) ;
  1213. } ;
  1214. /* Check seek backward from end. */
  1215. if ((k = sf_seek (file, 5 - sfinfo.frames, SEEK_END)) != 5)
  1216. { printf ("\n\nLine %d: sf_seek (SEEK_END) returned %d instead of %d.\n", __LINE__, k, 5) ;
  1217. exit (1) ;
  1218. } ;
  1219. test_read_short_or_die (file, 0, data, channels, __LINE__) ;
  1220. if (error_function (1.0 * data [0], 1.0 * orig [5 * channels], margin))
  1221. { printf ("\nLine %d: sf_seek (SEEK_END) followed by sf_read_short failed (%d should be %d).\n", __LINE__, data [0], orig [5 * channels]) ;
  1222. exit (1) ;
  1223. } ;
  1224. } /* if (sfinfo.seekable) */
  1225. sf_close (file) ;
  1226. unlink (filename) ;
  1227. printf ("ok\n") ;
  1228. } /* sdlcomp_test_short */
  1229. static void
  1230. sdlcomp_test_int (const char *filename, int filetype, int channels, double margin)
  1231. { SNDFILE *file ;
  1232. SF_INFO sfinfo ;
  1233. int k, m, seekpos, half_max_abs ;
  1234. sf_count_t datalen ;
  1235. int *orig, *data, *smooth ;
  1236. double scale ;
  1237. channels = 1 ;
  1238. print_test_name ("sdlcomp_test_int", filename) ;
  1239. datalen = BUFFER_SIZE ;
  1240. scale = 1.0 * 0x10000 ;
  1241. orig = orig_buffer.i ;
  1242. data = data_buffer.i ;
  1243. smooth = smooth_buffer.i ;
  1244. gen_signal_double (orig_buffer.d, 32000.0 * scale, channels, datalen) ;
  1245. for (k = 0 ; k < datalen ; k++)
  1246. orig [k] = lrint (orig_buffer.d [k]) ;
  1247. sfinfo.samplerate = SAMPLE_RATE ;
  1248. sfinfo.frames = 123456789 ; /* Ridiculous value. */
  1249. sfinfo.channels = channels ;
  1250. sfinfo.format = filetype ;
  1251. /* The Vorbis encoder has a bug on PowerPC and X86-64 with sample rates
  1252. ** <= 22050. Increasing the sample rate to 32000 avoids triggering it.
  1253. ** See https://trac.xiph.org/ticket/1229
  1254. */
  1255. if ((file = sf_open (filename, SFM_WRITE, &sfinfo)) == NULL)
  1256. { const char * errstr ;
  1257. errstr = sf_strerror (NULL) ;
  1258. if (strstr (errstr, "Sample rate chosen is known to trigger a Vorbis") == NULL)
  1259. { printf ("Line %d: sf_open_fd (SFM_WRITE) failed : %s\n", __LINE__, errstr) ;
  1260. dump_log_buffer (NULL) ;
  1261. exit (1) ;
  1262. } ;
  1263. printf ("\n Sample rate -> 32kHz ") ;
  1264. sfinfo.samplerate = 32000 ;
  1265. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_TRUE, __LINE__) ;
  1266. } ;
  1267. test_writef_int_or_die (file, 0, orig, datalen, __LINE__) ;
  1268. sf_set_string (file, SF_STR_COMMENT, long_comment) ;
  1269. sf_close (file) ;
  1270. memset (data, 0, datalen * sizeof (int)) ;
  1271. if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
  1272. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  1273. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
  1274. if (sfinfo.format != filetype)
  1275. { printf ("Returned format incorrect (0x%08X => 0x%08X).\n", filetype, sfinfo.format) ;
  1276. exit (1) ;
  1277. } ;
  1278. if (sfinfo.frames < datalen / channels)
  1279. { printf ("Too few.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", datalen, sfinfo.frames) ;
  1280. exit (1) ;
  1281. } ;
  1282. if (sfinfo.frames > (datalen + 400))
  1283. { printf ("Too many.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", sfinfo.frames, datalen) ;
  1284. exit (1) ;
  1285. } ;
  1286. if (sfinfo.channels != channels)
  1287. { printf ("Incorrect number of channels in file.\n") ;
  1288. exit (1) ;
  1289. } ;
  1290. check_log_buffer_or_die (file, __LINE__) ;
  1291. test_readf_int_or_die (file, 0, data, datalen, __LINE__) ;
  1292. memcpy (smooth, orig, datalen * sizeof (int)) ;
  1293. smoothed_diff_int (data, datalen) ;
  1294. smoothed_diff_int (smooth, datalen) ;
  1295. half_max_abs = abs (data [0] >> 16) ;
  1296. for (k = 1 ; k < datalen ; k++)
  1297. { if (error_function (data [k] / scale, smooth [k] / scale, margin))
  1298. { printf ("\nLine %d: Incorrect sample (#%d : %d should be %d).\n", __LINE__, k, data [k], smooth [k]) ;
  1299. oct_save_int (orig, smooth, datalen) ;
  1300. exit (1) ;
  1301. } ;
  1302. half_max_abs = LCT_MAX (half_max_abs, abs (data [k] / 2)) ;
  1303. } ;
  1304. if (half_max_abs < 1)
  1305. { printf ("\n\nLine %d: Signal is all zeros.\n", __LINE__) ;
  1306. exit (1) ;
  1307. } ;
  1308. if ((k = sf_readf_int (file, data, datalen)) != sfinfo.frames - datalen)
  1309. { printf ("\n\nLine %d: Incorrect read length (%d should be %" PRId64 ").\n", __LINE__, k, sfinfo.frames - datalen) ;
  1310. exit (1) ;
  1311. } ;
  1312. if ((sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_IMA_ADPCM &&
  1313. (sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_MS_ADPCM &&
  1314. (sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_GSM610 &&
  1315. (sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_G721_32 &&
  1316. (sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_G723_24)
  1317. for (k = 0 ; k < sfinfo.frames - datalen ; k++)
  1318. if (abs (data [k]) > decay_response (k))
  1319. { printf ("\n\nLine %d: Incorrect sample (#%" PRId64 " : abs (%d) should be < %d).\n", __LINE__, datalen + k, data [k], decay_response (k)) ;
  1320. exit (1) ;
  1321. } ;
  1322. /* Now test sf_seek function. */
  1323. if (sfinfo.seekable)
  1324. { if ((k = sf_seek (file, 0, SEEK_SET)) != 0)
  1325. { printf ("\n\nLine %d: Seek to start of file failed (%d).\n", __LINE__, k) ;
  1326. exit (1) ;
  1327. } ;
  1328. for (m = 0 ; m < 3 ; m++)
  1329. { test_readf_int_or_die (file, m, data, datalen / 7, __LINE__) ;
  1330. smoothed_diff_int (data, datalen / 7) ;
  1331. memcpy (smooth, orig + m * datalen / 7, datalen / 7 * sizeof (int)) ;
  1332. smoothed_diff_int (smooth, datalen / 7) ;
  1333. for (k = 0 ; k < datalen / 7 ; k++)
  1334. if (error_function (data [k] / scale, smooth [k] / scale, margin))
  1335. { printf ("\nLine %d: Incorrect sample (#%d (%" PRId64 ") : %d => %d).\n", __LINE__, k, k + m * (datalen / 7), smooth [k], data [k]) ;
  1336. for (m = 0 ; m < 10 ; m++)
  1337. printf ("%d ", data [k]) ;
  1338. printf ("\n") ;
  1339. exit (1) ;
  1340. } ;
  1341. } ; /* for (m = 0 ; m < 3 ; m++) */
  1342. seekpos = BUFFER_SIZE / 10 ;
  1343. /* Check seek from start of file. */
  1344. if ((k = sf_seek (file, seekpos, SEEK_SET)) != seekpos)
  1345. { printf ("Seek to start of file + %d failed (%d).\n", seekpos, k) ;
  1346. exit (1) ;
  1347. } ;
  1348. test_readf_int_or_die (file, 0, data, 1, __LINE__) ;
  1349. if (error_function (1.0 * data [0], 1.0 * orig [seekpos * channels], margin))
  1350. { printf ("\nLine %d: sf_seek (SEEK_SET) followed by sf_readf_int failed (%d, %d).\n", __LINE__, orig [1], data [0]) ;
  1351. exit (1) ;
  1352. } ;
  1353. if ((k = sf_seek (file, 0, SEEK_CUR)) != seekpos + 1)
  1354. { printf ("\n\nLine %d: sf_seek (SEEK_CUR) with 0 offset failed (%d should be %d)\n", __LINE__, k, seekpos + 1) ;
  1355. exit (1) ;
  1356. } ;
  1357. seekpos = sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ;
  1358. k = sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ;
  1359. test_readf_int_or_die (file, 0, data, 1, __LINE__) ;
  1360. if (error_function (1.0 * data [0], 1.0 * orig [seekpos * channels], margin) || k != seekpos)
  1361. { 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) ;
  1362. exit (1) ;
  1363. } ;
  1364. seekpos = sf_seek (file, 0, SEEK_CUR) - 20 ;
  1365. /* Check seek backward from current position. */
  1366. k = sf_seek (file, -20, SEEK_CUR) ;
  1367. test_readf_int_or_die (file, 0, data, 1, __LINE__) ;
  1368. if (error_function (1.0 * data [0], 1.0 * orig [seekpos * channels], margin) || k != seekpos)
  1369. { 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) ;
  1370. exit (1) ;
  1371. } ;
  1372. /* Check that read past end of file returns number of items. */
  1373. sf_seek (file, sfinfo.frames, SEEK_SET) ;
  1374. if ((k = sf_readf_int (file, data, datalen)) != 0)
  1375. { printf ("\n\nLine %d: Return value from sf_readf_int past end of file incorrect (%d).\n", __LINE__, k) ;
  1376. exit (1) ;
  1377. } ;
  1378. /* Check seek backward from end. */
  1379. if ((k = sf_seek (file, 5 - sfinfo.frames, SEEK_END)) != 5)
  1380. { printf ("\n\nLine %d: sf_seek (SEEK_END) returned %d instead of %d.\n", __LINE__, k, 5) ;
  1381. exit (1) ;
  1382. } ;
  1383. test_readf_int_or_die (file, 0, data, 1, __LINE__) ;
  1384. if (error_function (data [0] / scale, orig [5] / scale, margin))
  1385. { printf ("\nLine %d: sf_seek (SEEK_END) followed by sf_readf_int failed (%d should be %d).\n", __LINE__, data [0], orig [5]) ;
  1386. exit (1) ;
  1387. } ;
  1388. } /* if (sfinfo.seekable) */
  1389. sf_close (file) ;
  1390. unlink (filename) ;
  1391. printf ("ok\n") ;
  1392. } /* sdlcomp_test_int */
  1393. static void
  1394. sdlcomp_test_float (const char *filename, int filetype, int channels, double margin)
  1395. { SNDFILE *file ;
  1396. SF_INFO sfinfo ;
  1397. int k, m, seekpos ;
  1398. sf_count_t datalen ;
  1399. float *orig, *data, *smooth ;
  1400. double half_max_abs ;
  1401. channels = 1 ;
  1402. print_test_name ("sdlcomp_test_float", filename) ;
  1403. if ((filetype & SF_FORMAT_SUBMASK) == SF_FORMAT_VORBIS)
  1404. { puts ("Not working for this format.") ;
  1405. return ;
  1406. } ;
  1407. printf ("** fix this ** ") ;
  1408. datalen = BUFFER_SIZE ;
  1409. orig = orig_buffer.f ;
  1410. data = data_buffer.f ;
  1411. smooth = smooth_buffer.f ;
  1412. gen_signal_double (orig_buffer.d, 32000.0, channels, datalen) ;
  1413. for (k = 0 ; k < datalen ; k++)
  1414. orig [k] = lrint (orig_buffer.d [k]) ;
  1415. sfinfo.samplerate = SAMPLE_RATE ;
  1416. sfinfo.frames = 123456789 ; /* Ridiculous value. */
  1417. sfinfo.channels = channels ;
  1418. sfinfo.format = filetype ;
  1419. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ;
  1420. sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ;
  1421. test_write_float_or_die (file, 0, orig, datalen, __LINE__) ;
  1422. sf_set_string (file, SF_STR_COMMENT, long_comment) ;
  1423. sf_close (file) ;
  1424. memset (data, 0, datalen * sizeof (float)) ;
  1425. if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
  1426. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  1427. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
  1428. if ((sfinfo.format & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)) != (filetype & (SF_FORMAT_TYPEMASK | SF_FORMAT_SUBMASK)))
  1429. { printf ("\n\nLine %d: Returned format incorrect (0x%08X => 0x%08X).\n", __LINE__, filetype, sfinfo.format) ;
  1430. exit (1) ;
  1431. } ;
  1432. if (sfinfo.frames < datalen / channels)
  1433. { printf ("Too few.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", datalen, sfinfo.frames) ;
  1434. exit (1) ;
  1435. } ;
  1436. if (sfinfo.frames > (datalen + 400))
  1437. { printf ("Too many.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", sfinfo.frames, datalen) ;
  1438. exit (1) ;
  1439. } ;
  1440. if (sfinfo.channels != channels)
  1441. { printf ("Incorrect number of channels in file.\n") ;
  1442. exit (1) ;
  1443. } ;
  1444. check_comment (file, filetype, __LINE__) ;
  1445. sf_command (file, SFC_SET_NORM_FLOAT, NULL, SF_FALSE) ;
  1446. check_log_buffer_or_die (file, __LINE__) ;
  1447. test_read_float_or_die (file, 0, data, datalen, __LINE__) ;
  1448. memcpy (smooth, orig, datalen * sizeof (float)) ;
  1449. smoothed_diff_float (data, datalen) ;
  1450. smoothed_diff_float (smooth, datalen) ;
  1451. half_max_abs = fabs (data [0]) ;
  1452. for (k = 1 ; k < datalen ; k++)
  1453. { if (error_function (data [k], smooth [k], margin))
  1454. { printf ("\nLine %d: Incorrect sample (#%d : %d should be %d).\n", __LINE__, k, (int) data [k], (int) smooth [k]) ;
  1455. oct_save_float (orig, smooth, datalen) ;
  1456. exit (1) ;
  1457. } ;
  1458. half_max_abs = LCT_MAX (half_max_abs, abs (0.5 * data [k])) ;
  1459. } ;
  1460. if (half_max_abs <= 0.0)
  1461. { printf ("\n\nLine %d: Signal is all zeros.\n", __LINE__) ;
  1462. printf ("half_max_abs : % 10.6f\n", half_max_abs) ;
  1463. exit (1) ;
  1464. } ;
  1465. if ((k = sf_read_float (file, data, datalen)) != sfinfo.frames - datalen)
  1466. { printf ("\n\nLine %d: Incorrect read length (%d should be %" PRId64 ").\n", __LINE__, k, sfinfo.frames - datalen) ;
  1467. exit (1) ;
  1468. } ;
  1469. if ((sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_MS_ADPCM &&
  1470. (sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_GSM610)
  1471. for (k = 0 ; k < sfinfo.frames - datalen ; k++)
  1472. if (abs (data [k]) > decay_response (k))
  1473. { printf ("\n\nLine %d: Incorrect sample (#%" PRId64 " : abs (%d) should be < %d).\n", __LINE__, datalen + k, (int) data [k], (int) decay_response (k)) ;
  1474. exit (1) ;
  1475. } ;
  1476. /* Now test sf_seek function. */
  1477. if (sfinfo.seekable)
  1478. { if ((k = sf_seek (file, 0, SEEK_SET)) != 0)
  1479. { printf ("\n\nLine %d: Seek to start of file failed (%d).\n", __LINE__, k) ;
  1480. exit (1) ;
  1481. } ;
  1482. for (m = 0 ; m < 3 ; m++)
  1483. { test_read_float_or_die (file, 0, data, datalen / 7, __LINE__) ;
  1484. smoothed_diff_float (data, datalen / 7) ;
  1485. memcpy (smooth, orig + m * datalen / 7, datalen / 7 * sizeof (float)) ;
  1486. smoothed_diff_float (smooth, datalen / 7) ;
  1487. for (k = 0 ; k < datalen / 7 ; k++)
  1488. if (error_function (data [k], smooth [k], margin))
  1489. { printf ("\nLine %d: Incorrect sample C (#%d (%" PRId64 ") : %d => %d).\n", __LINE__, k, k + m * (datalen / 7), (int) smooth [k], (int) data [k]) ;
  1490. for (m = 0 ; m < 10 ; m++)
  1491. printf ("%d ", (int) data [k]) ;
  1492. printf ("\n") ;
  1493. exit (1) ;
  1494. } ;
  1495. } ; /* for (m = 0 ; m < 3 ; m++) */
  1496. seekpos = BUFFER_SIZE / 10 ;
  1497. /* Check seek from start of file. */
  1498. if ((k = sf_seek (file, seekpos, SEEK_SET)) != seekpos)
  1499. { printf ("Seek to start of file + %d failed (%d).\n", seekpos, k) ;
  1500. exit (1) ;
  1501. } ;
  1502. test_read_float_or_die (file, 0, data, channels, __LINE__) ;
  1503. if (error_function (data [0], orig [seekpos * channels], margin))
  1504. { printf ("\nLine %d: sf_seek (SEEK_SET) followed by sf_read_float failed (%d, %d).\n", __LINE__, (int) orig [1], (int) data [0]) ;
  1505. exit (1) ;
  1506. } ;
  1507. if ((k = sf_seek (file, 0, SEEK_CUR)) != seekpos + 1)
  1508. { printf ("\n\nLine %d: sf_seek (SEEK_CUR) with 0 offset failed (%d should be %d)\n", __LINE__, k, seekpos + 1) ;
  1509. exit (1) ;
  1510. } ;
  1511. seekpos = sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ;
  1512. k = sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ;
  1513. test_read_float_or_die (file, 0, data, channels, __LINE__) ;
  1514. if (error_function (data [0], orig [seekpos * channels], margin) || k != seekpos)
  1515. { printf ("\nLine %d: sf_seek (forwards, SEEK_CUR) followed by sf_read_float failed (%d, %d) (%d, %d).\n", __LINE__, (int) data [0], (int) orig [seekpos * channels], k, seekpos + 1) ;
  1516. exit (1) ;
  1517. } ;
  1518. seekpos = sf_seek (file, 0, SEEK_CUR) - 20 ;
  1519. /* Check seek backward from current position. */
  1520. k = sf_seek (file, -20, SEEK_CUR) ;
  1521. test_read_float_or_die (file, 0, data, channels, __LINE__) ;
  1522. if (error_function (data [0], orig [seekpos * channels], margin) || k != seekpos)
  1523. { printf ("\nLine %d: sf_seek (backwards, SEEK_CUR) followed by sf_read_float failed (%d, %d) (%d, %d).\n", __LINE__, (int) data [0], (int) orig [seekpos * channels], k, seekpos) ;
  1524. exit (1) ;
  1525. } ;
  1526. /* Check that read past end of file returns number of items. */
  1527. sf_seek (file, sfinfo.frames, SEEK_SET) ;
  1528. if ((k = sf_read_float (file, data, datalen)) != 0)
  1529. { printf ("\n\nLine %d: Return value from sf_read_float past end of file incorrect (%d).\n", __LINE__, k) ;
  1530. exit (1) ;
  1531. } ;
  1532. /* Check seek backward from end. */
  1533. if ((k = sf_seek (file, 5 - sfinfo.frames, SEEK_END)) != 5)
  1534. { printf ("\n\nLine %d: sf_seek (SEEK_END) returned %d instead of %d.\n", __LINE__, k, 5) ;
  1535. exit (1) ;
  1536. } ;
  1537. test_read_float_or_die (file, 0, data, channels, __LINE__) ;
  1538. if (error_function (data [0], orig [5 * channels], margin))
  1539. { printf ("\nLine %d: sf_seek (SEEK_END) followed by sf_read_float failed (%f should be %f).\n", __LINE__, data [0], orig [5 * channels]) ;
  1540. exit (1) ;
  1541. } ;
  1542. } /* if (sfinfo.seekable) */
  1543. sf_close (file) ;
  1544. unlink (filename) ;
  1545. printf ("ok\n") ;
  1546. } /* sdlcomp_test_float */
  1547. static void
  1548. sdlcomp_test_double (const char *filename, int filetype, int channels, double margin)
  1549. { SNDFILE *file ;
  1550. SF_INFO sfinfo ;
  1551. int k, m, seekpos ;
  1552. sf_count_t datalen ;
  1553. double *orig, *data, *smooth, half_max_abs ;
  1554. channels = 1 ;
  1555. print_test_name ("sdlcomp_test_double", filename) ;
  1556. if ((filetype & SF_FORMAT_SUBMASK) == SF_FORMAT_VORBIS)
  1557. { puts ("Not working for this format.") ;
  1558. return ;
  1559. } ;
  1560. datalen = BUFFER_SIZE ;
  1561. orig = orig_buffer.d ;
  1562. data = data_buffer.d ;
  1563. smooth = smooth_buffer.d ;
  1564. gen_signal_double (orig_buffer.d, 32000.0, channels, datalen) ;
  1565. sfinfo.samplerate = SAMPLE_RATE ;
  1566. sfinfo.frames = 123456789 ; /* Ridiculous value. */
  1567. sfinfo.channels = channels ;
  1568. sfinfo.format = filetype ;
  1569. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ;
  1570. sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ;
  1571. test_write_double_or_die (file, 0, orig, datalen, __LINE__) ;
  1572. sf_set_string (file, SF_STR_COMMENT, long_comment) ;
  1573. sf_close (file) ;
  1574. memset (data, 0, datalen * sizeof (double)) ;
  1575. if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
  1576. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  1577. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
  1578. if (sfinfo.format != filetype)
  1579. { printf ("Returned format incorrect (0x%08X => 0x%08X).\n", filetype, sfinfo.format) ;
  1580. exit (1) ;
  1581. } ;
  1582. if (sfinfo.frames < datalen / channels)
  1583. { printf ("Too few.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", datalen, sfinfo.frames) ;
  1584. exit (1) ;
  1585. } ;
  1586. if (sfinfo.frames > (datalen + 400))
  1587. { printf ("Too many.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", sfinfo.frames, datalen) ;
  1588. exit (1) ;
  1589. } ;
  1590. if (sfinfo.channels != channels)
  1591. { printf ("Incorrect number of channels in file.\n") ;
  1592. exit (1) ;
  1593. } ;
  1594. check_comment (file, filetype, __LINE__) ;
  1595. check_comment (file, filetype, __LINE__) ;
  1596. sf_command (file, SFC_SET_NORM_DOUBLE, NULL, SF_FALSE) ;
  1597. check_log_buffer_or_die (file, __LINE__) ;
  1598. test_read_double_or_die (file, 0, data, datalen, __LINE__) ;
  1599. memcpy (smooth, orig, datalen * sizeof (double)) ;
  1600. smoothed_diff_double (data, datalen) ;
  1601. smoothed_diff_double (smooth, datalen) ;
  1602. half_max_abs = 0.0 ;
  1603. for (k = 0 ; k < datalen ; k++)
  1604. { if (error_function (data [k], smooth [k], margin))
  1605. { printf ("\n\nLine %d: Incorrect sample (#%d : %d should be %d).\n", __LINE__, k, (int) data [k], (int) smooth [k]) ;
  1606. oct_save_double (orig, smooth, datalen) ;
  1607. exit (1) ;
  1608. } ;
  1609. half_max_abs = LCT_MAX (half_max_abs, 0.5 * fabs (data [k])) ;
  1610. } ;
  1611. if (half_max_abs < 1.0)
  1612. { printf ("\n\nLine %d: Signal is all zeros.\n", __LINE__) ;
  1613. exit (1) ;
  1614. } ;
  1615. if ((k = sf_read_double (file, data, datalen)) != sfinfo.frames - datalen)
  1616. { printf ("\n\nLine %d: Incorrect read length (%d should be %" PRId64 ").\n", __LINE__, k, sfinfo.frames - datalen) ;
  1617. exit (1) ;
  1618. } ;
  1619. if ((sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_MS_ADPCM &&
  1620. (sfinfo.format & SF_FORMAT_SUBMASK) != SF_FORMAT_GSM610)
  1621. for (k = 0 ; k < sfinfo.frames - datalen ; k++)
  1622. if (abs (data [k]) > decay_response (k))
  1623. { printf ("\n\nLine %d: Incorrect sample (#%" PRId64 " : abs (%d) should be < %d).\n", __LINE__, datalen + k, (int) data [k], (int) decay_response (k)) ;
  1624. exit (1) ;
  1625. } ;
  1626. /* Now test sf_seek function. */
  1627. if (sfinfo.seekable)
  1628. { if ((k = sf_seek (file, 0, SEEK_SET)) != 0)
  1629. { printf ("\n\nLine %d: Seek to start of file failed (%d).\n", __LINE__, k) ;
  1630. exit (1) ;
  1631. } ;
  1632. for (m = 0 ; m < 3 ; m++)
  1633. { test_read_double_or_die (file, m, data, datalen / 7, __LINE__) ;
  1634. smoothed_diff_double (data, datalen / 7) ;
  1635. memcpy (smooth, orig + m * datalen / 7, datalen / 7 * sizeof (double)) ;
  1636. smoothed_diff_double (smooth, datalen / 7) ;
  1637. for (k = 0 ; k < datalen / 7 ; k++)
  1638. if (error_function (data [k], smooth [k], margin))
  1639. { printf ("\nLine %d: Incorrect sample C (#%d (%" PRId64 ") : %d => %d).\n", __LINE__, k, k + m * (datalen / 7), (int) smooth [k], (int) data [k]) ;
  1640. for (m = 0 ; m < 10 ; m++)
  1641. printf ("%d ", (int) data [k]) ;
  1642. printf ("\n") ;
  1643. exit (1) ;
  1644. } ;
  1645. } ; /* for (m = 0 ; m < 3 ; m++) */
  1646. seekpos = BUFFER_SIZE / 10 ;
  1647. /* Check seek from start of file. */
  1648. if ((k = sf_seek (file, seekpos, SEEK_SET)) != seekpos)
  1649. { printf ("Seek to start of file + %d failed (%d).\n", seekpos, k) ;
  1650. exit (1) ;
  1651. } ;
  1652. test_read_double_or_die (file, 0, data, channels, __LINE__) ;
  1653. if (error_function (data [0], orig [seekpos * channels], margin))
  1654. { printf ("\nLine %d: sf_seek (SEEK_SET) followed by sf_read_double failed (%d, %d).\n", __LINE__, (int) orig [1], (int) data [0]) ;
  1655. exit (1) ;
  1656. } ;
  1657. if ((k = sf_seek (file, 0, SEEK_CUR)) != seekpos + 1)
  1658. { printf ("\n\nLine %d: sf_seek (SEEK_CUR) with 0 offset failed (%d should be %d)\n", __LINE__, k, seekpos + 1) ;
  1659. exit (1) ;
  1660. } ;
  1661. seekpos = sf_seek (file, 0, SEEK_CUR) + BUFFER_SIZE / 5 ;
  1662. k = sf_seek (file, BUFFER_SIZE / 5, SEEK_CUR) ;
  1663. test_read_double_or_die (file, 0, data, channels, __LINE__) ;
  1664. if (error_function (data [0], orig [seekpos * channels], margin) || k != seekpos)
  1665. { printf ("\nLine %d: sf_seek (forwards, SEEK_CUR) followed by sf_read_double failed (%d, %d) (%d, %d).\n", __LINE__, (int) data [0], (int) orig [seekpos * channels], k, seekpos + 1) ;
  1666. exit (1) ;
  1667. } ;
  1668. seekpos = sf_seek (file, 0, SEEK_CUR) - 20 ;
  1669. /* Check seek backward from current position. */
  1670. k = sf_seek (file, -20, SEEK_CUR) ;
  1671. test_read_double_or_die (file, 0, data, channels, __LINE__) ;
  1672. if (error_function (data [0], orig [seekpos * channels], margin) || k != seekpos)
  1673. { printf ("\nLine %d: sf_seek (backwards, SEEK_CUR) followed by sf_read_double failed (%d, %d) (%d, %d).\n", __LINE__, (int) data [0], (int) orig [seekpos * channels], k, seekpos) ;
  1674. exit (1) ;
  1675. } ;
  1676. /* Check that read past end of file returns number of items. */
  1677. sf_seek (file, sfinfo.frames, SEEK_SET) ;
  1678. if ((k = sf_read_double (file, data, datalen)) != 0)
  1679. { printf ("\n\nLine %d: Return value from sf_read_double past end of file incorrect (%d).\n", __LINE__, k) ;
  1680. exit (1) ;
  1681. } ;
  1682. /* Check seek backward from end. */
  1683. if ((k = sf_seek (file, 5 - sfinfo.frames, SEEK_END)) != 5)
  1684. { printf ("\n\nLine %d: sf_seek (SEEK_END) returned %d instead of %d.\n", __LINE__, k, 5) ;
  1685. exit (1) ;
  1686. } ;
  1687. test_read_double_or_die (file, 0, data, channels, __LINE__) ;
  1688. if (error_function (data [0], orig [5 * channels], margin))
  1689. { printf ("\nLine %d: sf_seek (SEEK_END) followed by sf_read_double failed (%f should be %f).\n", __LINE__, data [0], orig [5 * channels]) ;
  1690. exit (1) ;
  1691. } ;
  1692. } /* if (sfinfo.seekable) */
  1693. sf_close (file) ;
  1694. unlink (filename) ;
  1695. printf ("ok\n") ;
  1696. } /* sdlcomp_test_double */
  1697. static void
  1698. read_raw_test (const char *filename, int filetype, int channels)
  1699. { SNDFILE *file ;
  1700. SF_INFO sfinfo ;
  1701. sf_count_t count, datalen ;
  1702. short *orig, *data ;
  1703. int k ;
  1704. print_test_name ("read_raw_test", filename) ;
  1705. datalen = ARRAY_LEN (orig_buffer.s) / 2 ;
  1706. orig = orig_buffer.s ;
  1707. data = data_buffer.s ;
  1708. gen_signal_double (orig_buffer.d, 32000.0, channels, datalen) ;
  1709. for (k = 0 ; k < datalen ; k++)
  1710. orig [k] = lrint (orig_buffer.d [k]) ;
  1711. sfinfo.samplerate = SAMPLE_RATE ;
  1712. sfinfo.frames = 123456789 ; /* Ridiculous value. */
  1713. sfinfo.channels = channels ;
  1714. sfinfo.format = filetype ;
  1715. file = test_open_file_or_die (filename, SFM_WRITE, &sfinfo, SF_FALSE, __LINE__) ;
  1716. test_write_short_or_die (file, 0, orig, datalen, __LINE__) ;
  1717. sf_set_string (file, SF_STR_COMMENT, long_comment) ;
  1718. sf_close (file) ;
  1719. memset (data, 0, datalen * sizeof (double)) ;
  1720. if ((filetype & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
  1721. memset (&sfinfo, 0, sizeof (sfinfo)) ;
  1722. file = test_open_file_or_die (filename, SFM_READ, &sfinfo, SF_FALSE, __LINE__) ;
  1723. if (sfinfo.format != filetype)
  1724. { printf ("Returned format incorrect (0x%08X => 0x%08X).\n", filetype, sfinfo.format) ;
  1725. exit (1) ;
  1726. } ;
  1727. if (sfinfo.frames < datalen / channels)
  1728. { printf ("Too few.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", datalen, sfinfo.frames) ;
  1729. exit (1) ;
  1730. } ;
  1731. if (sfinfo.frames > (datalen + 400))
  1732. { printf ("Too many.frames in file. (%" PRId64 " should be a little more than %" PRId64 ")\n", sfinfo.frames, datalen) ;
  1733. exit (1) ;
  1734. } ;
  1735. if (sfinfo.channels != channels)
  1736. { printf ("Incorrect number of channels in file.\n") ;
  1737. exit (1) ;
  1738. } ;
  1739. check_comment (file, filetype, __LINE__) ;
  1740. count = sf_read_raw (file, orig_buffer.c, datalen + 5 * channels) ;
  1741. if (count != sfinfo.channels * sfinfo.frames)
  1742. { printf ("\nLine %d : sf_read_raw returned %" PRId64 " should be %" PRId64 "\n", __LINE__, count, sfinfo.channels * sfinfo.frames) ;
  1743. exit (1) ;
  1744. } ;
  1745. sf_close (file) ;
  1746. unlink (filename) ;
  1747. printf ("ok\n") ;
  1748. } /* read_raw_test */
  1749. /*========================================================================================
  1750. ** Auxiliary functions
  1751. */
  1752. #define SIGNAL_MAXVAL 30000.0
  1753. #define DECAY_COUNT 1000
  1754. static int
  1755. decay_response (int k)
  1756. { if (k < 1)
  1757. return (int) (1.2 * SIGNAL_MAXVAL) ;
  1758. if (k > DECAY_COUNT)
  1759. return 0 ;
  1760. return (int) (1.2 * SIGNAL_MAXVAL * (DECAY_COUNT - k) / (1.0 * DECAY_COUNT)) ;
  1761. } /* decay_response */
  1762. static void
  1763. gen_signal_double (double *data, double scale, int channels, int datalen)
  1764. { int k, ramplen ;
  1765. double amp = 0.0 ;
  1766. ramplen = DECAY_COUNT ;
  1767. if (channels == 1)
  1768. { for (k = 0 ; k < datalen ; k++)
  1769. { if (k <= ramplen)
  1770. amp = scale * k / ((double) ramplen) ;
  1771. else if (k > datalen - ramplen)
  1772. amp = scale * (datalen - k) / ((double) ramplen) ;
  1773. /*-printf ("%3d : %g\n", k, amp) ;-*/
  1774. data [k] = amp * (0.4 * sin (33.3 * 2.0 * M_PI * ((double) (k+1)) / ((double) SAMPLE_RATE))
  1775. + 0.3 * cos (201.1 * 2.0 * M_PI * ((double) (k+1)) / ((double) SAMPLE_RATE))) ;
  1776. } ;
  1777. }
  1778. else
  1779. { for (k = 0 ; k < datalen ; k ++)
  1780. { if (k <= ramplen)
  1781. amp = scale * k / ((double) ramplen) ;
  1782. else if (k > datalen - ramplen)
  1783. amp = scale * (datalen - k) / ((double) ramplen) ;
  1784. data [2 * k] = amp * (0.4 * sin (33.3 * 2.0 * M_PI * ((double) (k+1)) / ((double) SAMPLE_RATE))
  1785. + 0.3 * cos (201.1 * 2.0 * M_PI * ((double) (k+1)) / ((double) SAMPLE_RATE))) ;
  1786. data [2 * k + 1] = amp * (0.4 * sin (55.5 * 2.0 * M_PI * ((double) (k+1)) / ((double) SAMPLE_RATE))
  1787. + 0.3 * cos (201.1 * 2.0 * M_PI * ((double) (k+1)) / ((double) SAMPLE_RATE))) ;
  1788. } ;
  1789. } ;
  1790. return ;
  1791. } /* gen_signal_double */
  1792. static int
  1793. error_function (double data, double orig, double margin)
  1794. { double error ;
  1795. if (fabs (orig) <= 500.0)
  1796. error = fabs (fabs (data) - fabs (orig)) / 2000.0 ;
  1797. else if (fabs (orig) <= 1000.0)
  1798. error = fabs (data - orig) / 3000.0 ;
  1799. else
  1800. error = fabs (data - orig) / fabs (orig) ;
  1801. if (error > margin)
  1802. { printf ("\n\nerror_function (data = %f, orig = %f, margin = %f) -> %f\n", data, orig, margin, error) ;
  1803. return 1 ;
  1804. } ;
  1805. return 0 ;
  1806. } /* error_function */
  1807. static void
  1808. smoothed_diff_short (short *data, unsigned int datalen)
  1809. { unsigned int k ;
  1810. double memory = 0.0 ;
  1811. /* Calculate the smoothed sample-to-sample difference. */
  1812. for (k = 0 ; k < datalen - 1 ; k++)
  1813. { memory = 0.7 * memory + (1 - 0.7) * (double) (data [k+1] - data [k]) ;
  1814. data [k] = (short) memory ;
  1815. } ;
  1816. data [datalen-1] = data [datalen-2] ;
  1817. } /* smoothed_diff_short */
  1818. static void
  1819. smoothed_diff_int (int *data, unsigned int datalen)
  1820. { unsigned int k ;
  1821. double memory = 0.0 ;
  1822. /* Calculate the smoothed sample-to-sample difference. */
  1823. for (k = 0 ; k < datalen - 1 ; k++)
  1824. { memory = 0.7 * memory + (1 - 0.7) * (double) (data [k+1] - data [k]) ;
  1825. data [k] = (int) memory ;
  1826. } ;
  1827. data [datalen-1] = data [datalen-2] ;
  1828. } /* smoothed_diff_int */
  1829. static void
  1830. smoothed_diff_float (float *data, unsigned int datalen)
  1831. { unsigned int k ;
  1832. float memory = 0.0 ;
  1833. /* Calculate the smoothed sample-to-sample difference. */
  1834. for (k = 0 ; k < datalen - 1 ; k++)
  1835. { memory = 0.7 * memory + (1 - 0.7) * (data [k+1] - data [k]) ;
  1836. data [k] = memory ;
  1837. } ;
  1838. data [datalen-1] = data [datalen-2] ;
  1839. } /* smoothed_diff_float */
  1840. static void
  1841. smoothed_diff_double (double *data, unsigned int datalen)
  1842. { unsigned int k ;
  1843. double memory = 0.0 ;
  1844. /* Calculate the smoothed sample-to-sample difference. */
  1845. for (k = 0 ; k < datalen - 1 ; k++)
  1846. { memory = 0.7 * memory + (1 - 0.7) * (data [k+1] - data [k]) ;
  1847. data [k] = memory ;
  1848. } ;
  1849. data [datalen-1] = data [datalen-2] ;
  1850. } /* smoothed_diff_double */
  1851. static void
  1852. check_comment (SNDFILE * file, int format, int lineno)
  1853. { const char *comment ;
  1854. switch (format & SF_FORMAT_TYPEMASK)
  1855. { case SF_FORMAT_AIFF :
  1856. case SF_FORMAT_WAV :
  1857. case SF_FORMAT_WAVEX :
  1858. break ;
  1859. default :
  1860. return ;
  1861. } ;
  1862. comment = sf_get_string (file, SF_STR_COMMENT) ;
  1863. if (comment == NULL)
  1864. { printf ("\n\nLine %d : File does not contain a comment string.\n\n", lineno) ;
  1865. exit (1) ;
  1866. } ;
  1867. if (strcmp (comment, long_comment) != 0)
  1868. { printf ("\n\nLine %d : File comment does not match comment written.\n\n", lineno) ;
  1869. exit (1) ;
  1870. } ;
  1871. return ;
  1872. } /* check_comment */
  1873. static int
  1874. is_lossy (int filetype)
  1875. {
  1876. switch (SF_FORMAT_SUBMASK & filetype)
  1877. { case SF_FORMAT_PCM_U8 :
  1878. case SF_FORMAT_PCM_S8 :
  1879. case SF_FORMAT_PCM_16 :
  1880. case SF_FORMAT_PCM_24 :
  1881. case SF_FORMAT_PCM_32 :
  1882. case SF_FORMAT_FLOAT :
  1883. case SF_FORMAT_DOUBLE :
  1884. return 0 ;
  1885. default :
  1886. break ;
  1887. } ;
  1888. return 1 ;
  1889. } /* is_lossy */