lossy_comp_test.c 97 KB

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