portsf.c 125 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574
  1. /* Copyright (c) 1999-2009 Richard Dobson
  2. Permission is hereby granted, free of charge, to any person
  3. obtaining a copy of this software and associated documentation
  4. files (the "Software"), to deal in the Software without
  5. restriction, including without limitation the rights to use,
  6. copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. copies of the Software, and to permit persons to whom the
  8. Software is furnished to do so, subject to the following
  9. conditions:
  10. The above copyright notice and this permission notice shall be
  11. included in all copies or substantial portions of the Software.
  12. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  13. EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  14. OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  15. NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  16. HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  17. WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  18. FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  19. OTHER DEALINGS IN THE SOFTWARE.
  20. */
  21. /* Changes Oct 28 2002: support overwrite mode (seek-back->read->wrtite) */
  22. /* fix bug in floats WAVE header reading! */
  23. /* more comprehensive use of assert in _DEBUG mode (still not complete ....) */
  24. /* sundry tidy-ups inspired by Intel compiler messages! */
  25. /* changes Apr 27 2003: fix reversal bug in wave format writing on big-endian platforms */
  26. /* changes Aug 2003: added basic TPDF dither to 16bit output */
  27. /* Nov 2003: fixed aiffsize bug in aiff write func: 8 bytes too big! */
  28. /* Jan 2004 fixed error reading from WAVE_EX file */
  29. /*Oct 19 2006: cleared up some memory leaks on SFFILE (psf_sndOpen etc)*/
  30. /* July 2009: revised to use fget/setpos, 4GB file support, 64bit platforms
  31. Move to 2LSB TPDF dither
  32. */
  33. /* POST BOOK!*/
  34. /* OCT 2009 ADDED MC_CUBE, completed bformat support */
  35. /* fixed bad omission in byteswaaping wavex elements! */
  36. /* added recognition of speaker layouts */
  37. /* corrected absent assignment of chmask on little-endian */
  38. /* Apr 2010 upped MAXFILES to 256! */
  39. /* Aug 2010, and now to 512! */
  40. /* Aug 2012 TODO (?): add running check for 4GB limit to writeFrame funcs */
  41. /* Aug 2012 corrected SPKRS_MONO value (portsf.h) */
  42. /* Nov 2013: added SPKRS_6_1 to list */
  43. /* Mar 2020: fix fault parsing floats amb files! */
  44. #include <stdio.h>
  45. #ifdef unix
  46. #include <unistd.h>
  47. #endif
  48. #include <stdlib.h>
  49. #include <memory.h>
  50. #include <string.h>
  51. #include <math.h>
  52. #include <time.h>
  53. #include "ieee80.h"
  54. #ifdef _DEBUG
  55. #include <assert.h>
  56. #endif
  57. #include <portsf.h>
  58. #ifndef DBGFPRINTF
  59. # ifdef _DEBUG
  60. # define DBGFPRINTF(a) fprintf a
  61. # else
  62. # define DBGFPRINTF(a)
  63. # endif
  64. #endif
  65. #ifndef max
  66. #define max(x,y) ((x) > (y) ? (x) : (y))
  67. #endif
  68. #ifndef min
  69. #define min(x,y) ((x) < (y) ? (x) : (y))
  70. #endif
  71. #ifndef BITS_PER_BYTE
  72. #define BITS_PER_BYTE (8)
  73. #endif
  74. #ifndef WIN32
  75. #include <ctype.h>
  76. int stricmp(const char *a, const char *b);
  77. int strnicmp(const char *a, const char *b, const int length);
  78. #endif
  79. #ifdef linux
  80. #define POS64(x) (x.__pos)
  81. #else
  82. #define POS64(x) (x)
  83. #endif
  84. /* probably no good for 64bit platforms */
  85. #define REVDWBYTES(t) ( (((t)&0xff) << 24) | (((t)&0xff00) << 8) | (((t)&0xff0000) >> 8) | (((t)>>24) & 0xff) )
  86. #define REVWBYTES(t) ( (((t)&0xff) << 8) | (((t)>>8) &0xff) )
  87. #define TAG(a,b,c,d) ( ((a)<<24) | ((b)<<16) | ((c)<<8) | (d) )
  88. /* RW changed 15:10:2002 - one less! */
  89. /* RWD Dec 2009 changed back again for bit-accurate scaling */
  90. #define MAX_16BIT (32768.0)
  91. #define MAX_32BIT (2147483648.0)
  92. #define AIFC_VERSION_1 (0xA2805140)
  93. /*pstring for AIFC - includes the pad byte*/
  94. static const char aifc_floatstring[10] = { 0x08,'F','l','o','a','t',0x20,'3','2',0x00};
  95. static const char aifc_notcompressed[16] = {0x0e,'n','o','t',0x20,'c','o','m','p','r','e','s','s','e','d',0x00};
  96. static float trirand();
  97. static psf_channelformat get_speakerlayout(DWORD chmask,DWORD chans);
  98. static double inv_randmax = 1.0 / RAND_MAX;
  99. static const float dclip16 = (float)(32767.0/32768.0);
  100. static const float dclip24 = (float)(8388607.0/8388608.0);
  101. static const float dclip32 = (float)(2147483647.0/2147483648.0);
  102. /* we need the standard Windows defs, when compiling on other platforms.
  103. <windows.h> defines _INC_WINDOWS
  104. */
  105. #ifndef _INC_WINDOWS
  106. #define WAVE_FORMAT_PCM (0x0001)
  107. typedef union {
  108. int lsamp;
  109. float fsamp;
  110. unsigned char bytes[4];
  111. } SND_SAMP;
  112. typedef struct _GUID
  113. {
  114. unsigned int Data1;
  115. unsigned short Data2;
  116. unsigned short Data3;
  117. unsigned char Data4[8];
  118. } GUID;
  119. typedef struct {
  120. WORD wFormatTag;
  121. WORD nChannels;
  122. DWORD nSamplesPerSec;
  123. DWORD nAvgBytesPerSec;
  124. WORD nBlockAlign;
  125. WORD wBitsPerSample;
  126. } WAVEFORMAT;
  127. typedef struct {
  128. WORD wFormatTag;
  129. WORD nChannels;
  130. DWORD nSamplesPerSec;
  131. DWORD nAvgBytesPerSec;
  132. WORD nBlockAlign;
  133. WORD wBitsPerSample;
  134. WORD cbSize;
  135. } WAVEFORMATEX;
  136. #endif
  137. /* basic support for WAVE_FORMAT_EXTENSIBLE */
  138. typedef struct {
  139. WAVEFORMATEX Format; /* 18 bytes */
  140. union {
  141. WORD wValidBitsPerSample; /* bits of precision */
  142. WORD wSamplesPerBlock; /* valid if wBitsPerSample==0 */
  143. WORD wReserved; /* If neither applies, set to */
  144. /* zero. */
  145. } Samples;
  146. DWORD dwChannelMask; /* which channels are */
  147. /* present in stream */
  148. GUID SubFormat;
  149. } WAVEFORMATEXTENSIBLE;
  150. /* sizeof(WAVEFORMATEXTENSIBLE) gives size plus alignment padding; not good here */
  151. /* size = 18 + 2 + 4 + 16 */
  152. #define sizeof_WFMTEX (40)
  153. /* std WAVE-EX GUIDS from <ksmedia.h> */
  154. static const GUID KSDATAFORMAT_SUBTYPE_PCM = {0x00000001,0x0000,0x0010,
  155. {0x80,
  156. 0x00,
  157. 0x00,
  158. 0xaa,
  159. 0x00,
  160. 0x38,
  161. 0x9b,
  162. 0x71}};
  163. static const GUID KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = {0x00000003,0x0000,0x0010,
  164. {0x80,
  165. 0x00,
  166. 0x00,
  167. 0xaa,
  168. 0x00,
  169. 0x38,
  170. 0x9b,
  171. 0x71}};
  172. static const GUID SUBTYPE_AMBISONIC_B_FORMAT_PCM = { 0x00000001, 0x0721, 0x11d3,
  173. { 0x86,
  174. 0x44,
  175. 0xc8,
  176. 0xc1,
  177. 0xca,
  178. 0x0,
  179. 0x0,
  180. 0x0 } };
  181. static const GUID SUBTYPE_AMBISONIC_B_FORMAT_IEEE_FLOAT = { 0x00000003, 0x0721, 0x11d3,
  182. { 0x86,
  183. 0x44,
  184. 0xc8,
  185. 0xc1,
  186. 0xca,
  187. 0x0,
  188. 0x0,
  189. 0x0 } };
  190. #ifndef WAVE_FORMAT_IEEE_FLOAT
  191. #define WAVE_FORMAT_IEEE_FLOAT (0x0003)
  192. #endif
  193. #ifndef WAVE_FORMAT_EXTENSIBLE
  194. #define WAVE_FORMAT_EXTENSIBLE (0xfffe)
  195. #endif
  196. /*RWD Feb 2010 */
  197. #define WARNSTRING_SIZE (64)
  198. /******** the private structure holding all sfile stuff */
  199. enum lastop {PSF_OP_READ,PSF_OP_WRITE};
  200. typedef struct psffile {
  201. FILE *file;
  202. char *filename;
  203. DWORD curframepos; /* for read operations */
  204. DWORD nFrames; /* multi-channel sample frames */
  205. int isRead; /* how we are using it */
  206. int clip_floats;
  207. int rescale;
  208. float rescale_fac;
  209. psf_format riff_format;
  210. /*int isSeekable;*/ /* any use ? */
  211. int is_little_endian;
  212. psf_stype samptype; /* = nBlockAlign / nChannels */
  213. fpos_t dataoffset; /* = sizeof(header) */
  214. fpos_t fmtoffset;
  215. fpos_t peakoffset;
  216. WAVEFORMATEXTENSIBLE fmt; /* serves all WAVE,AIFF support.*/
  217. psf_channelformat chformat;
  218. PSF_CHPEAK *pPeaks;
  219. time_t peaktime;
  220. fpos_t lastwritepos;
  221. int lastop; /* last op was read or write? */
  222. int dithertype;
  223. /* RWD Feb 2010 ; to warn user of ill-formed files*/
  224. int illformed;
  225. char warnstring[WARNSTRING_SIZE];
  226. } PSFFILE;
  227. static int compare_guids(const GUID *gleft, const GUID *gright)
  228. {
  229. const char *left = (const char *) gleft, *right = (const char *) gright;
  230. return !memcmp(left,right,sizeof(GUID));
  231. }
  232. #define psf_maxfiles (512)
  233. /* could make this dynamically allocated, via psf_init, one day, if it matters. */
  234. static PSFFILE *psf_files[psf_maxfiles];
  235. /* return 0 for success, non-zero for error */
  236. int psf_init(void)
  237. {
  238. int i;
  239. for(i=0;i < psf_maxfiles;i++)
  240. psf_files[i] = NULL;
  241. /* do any other inits we need.... */
  242. return 0;
  243. }
  244. /* return zero for success, non-zero for error*/
  245. static int psf_release_file(PSFFILE *psff)
  246. {
  247. int rc = 0;
  248. #ifdef _DEBUG
  249. assert(psff);
  250. #endif
  251. if(psff->file){
  252. rc = fclose(psff->file);
  253. if(rc)
  254. return rc;
  255. psff->file = NULL;
  256. }
  257. if(psff->filename){
  258. free(psff->filename);
  259. psff->filename = NULL;
  260. }
  261. if(psff->pPeaks) {
  262. free(psff->pPeaks);
  263. psff->pPeaks = NULL;
  264. }
  265. return rc;
  266. }
  267. /* return zero for success, non-zero for error*/
  268. int psf_finish(void)
  269. {
  270. int i,rc = 0;
  271. for(i=0;i < psf_maxfiles;i++) {
  272. if(psf_files[i]!= NULL){
  273. #ifdef _DEBUG
  274. printf("sfile %s not closed: closing.\n",psf_files[i]->filename);
  275. #endif
  276. rc = psf_release_file(psf_files[i]);
  277. /* an alternative is to continue, and write error info to a logfile */
  278. if(rc)
  279. return rc;
  280. }
  281. free(psf_files[i]);
  282. psf_files[i] = NULL;
  283. }
  284. return rc;
  285. }
  286. /* thanks to the SNDAN programmers for this! */
  287. /* return 0 for big-endian machine, 1 for little-endian machine*/
  288. /* probably no good for 16bit swapping though */
  289. static int byte_order()
  290. {
  291. int one = 1;
  292. char* endptr = (char *) &one;
  293. return (*endptr);
  294. }
  295. static void fmtSwapBytes(PSFFILE *sfdat)
  296. {
  297. WAVEFORMATEX *pfmt = (WAVEFORMATEX *) &(sfdat->fmt.Format);
  298. pfmt->wFormatTag = (WORD) REVWBYTES(pfmt->wFormatTag);
  299. pfmt->nChannels = (WORD) REVWBYTES(pfmt->nChannels);
  300. pfmt->nSamplesPerSec = REVDWBYTES(pfmt->nSamplesPerSec);
  301. pfmt->nAvgBytesPerSec = REVDWBYTES(pfmt->nAvgBytesPerSec);
  302. pfmt->nBlockAlign = (WORD) REVWBYTES(pfmt->nBlockAlign);
  303. pfmt->wBitsPerSample = (WORD) REVWBYTES(pfmt->wBitsPerSample);
  304. }
  305. static void fmtExSwapBytes(PSFFILE *sfdat)
  306. {
  307. WAVEFORMATEXTENSIBLE *pfmtEx = &(sfdat->fmt);
  308. WAVEFORMATEX *pfmt = &(pfmtEx->Format);
  309. pfmt->wFormatTag = (WORD) REVWBYTES(pfmt->wFormatTag);
  310. pfmt->nChannels = (WORD) REVWBYTES(pfmt->nChannels);
  311. pfmt->nSamplesPerSec = REVDWBYTES(pfmt->nSamplesPerSec);
  312. pfmt->nAvgBytesPerSec = REVDWBYTES(pfmt->nAvgBytesPerSec);
  313. pfmt->nBlockAlign = (WORD) REVWBYTES(pfmt->nBlockAlign);
  314. pfmt->wBitsPerSample = (WORD) REVWBYTES(pfmt->wBitsPerSample);
  315. pfmt->cbSize = (WORD) REVWBYTES(pfmt->cbSize);
  316. // OCT 09: missing!
  317. pfmtEx->Samples.wValidBitsPerSample = (WORD) REVWBYTES(pfmtEx->Samples.wValidBitsPerSample);
  318. pfmtEx->dwChannelMask = (DWORD) REVDWBYTES(pfmtEx->dwChannelMask);
  319. /* we swap numeric fields of GUID, but not the char string */
  320. pfmtEx->SubFormat.Data1 = REVDWBYTES(pfmtEx->SubFormat.Data1);
  321. pfmtEx->SubFormat.Data2 = (WORD) REVWBYTES(pfmtEx->SubFormat.Data2);
  322. pfmtEx->SubFormat.Data3 = (WORD) REVWBYTES(pfmtEx->SubFormat.Data3);
  323. }
  324. static int check_guid(PSFFILE *sfdat)
  325. {
  326. /* expects a GUID to be loaded already into sfdat.*/
  327. if(sfdat->riff_format != PSF_WAVE_EX)
  328. return 1;
  329. if(compare_guids(&(sfdat->fmt.SubFormat),&(KSDATAFORMAT_SUBTYPE_PCM))){
  330. switch(sfdat->fmt.Format.wBitsPerSample){
  331. case(16):
  332. sfdat->samptype = PSF_SAMP_16;
  333. break;
  334. case(24):
  335. /* only support packed format for now */
  336. if((sfdat->fmt.Format.nBlockAlign / sfdat->fmt.Format.nChannels) != 3){
  337. sfdat->samptype = PSF_SAMP_UNKNOWN;
  338. return 1;
  339. }
  340. sfdat->samptype = PSF_SAMP_24;
  341. break;
  342. case(32):
  343. sfdat->samptype = PSF_SAMP_32;
  344. break;
  345. default:
  346. sfdat->samptype = PSF_SAMP_UNKNOWN;
  347. return 1;
  348. }
  349. return 0;
  350. }
  351. if(compare_guids(&(sfdat->fmt.SubFormat),&(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)))
  352. if(sfdat->fmt.Format.wBitsPerSample == 32) {
  353. sfdat->samptype = PSF_SAMP_IEEE_FLOAT;
  354. return 0;
  355. }
  356. /* add other recognised GUIDs here... */
  357. if(compare_guids(&(sfdat->fmt.SubFormat),&(SUBTYPE_AMBISONIC_B_FORMAT_IEEE_FLOAT)))
  358. if(sfdat->fmt.Format.wBitsPerSample == 32) {
  359. sfdat->samptype = PSF_SAMP_IEEE_FLOAT;
  360. sfdat->chformat = MC_BFMT;
  361. return 0;
  362. }
  363. if(compare_guids(&(sfdat->fmt.SubFormat),&(SUBTYPE_AMBISONIC_B_FORMAT_PCM))) {
  364. switch(sfdat->fmt.Format.wBitsPerSample){
  365. case(16):
  366. sfdat->samptype = PSF_SAMP_16;
  367. break;
  368. case(24):
  369. /* only support packed format for now */
  370. if((sfdat->fmt.Format.nBlockAlign / sfdat->fmt.Format.nChannels) != 3){
  371. sfdat->samptype = PSF_SAMP_UNKNOWN;
  372. return 1;
  373. }
  374. sfdat->samptype = PSF_SAMP_24;
  375. break;
  376. case(32):
  377. sfdat->samptype = PSF_SAMP_32;
  378. break;
  379. default:
  380. sfdat->samptype = PSF_SAMP_UNKNOWN;
  381. return 1;
  382. }
  383. sfdat->chformat = MC_BFMT;
  384. return 0;
  385. }
  386. return 1;
  387. }
  388. /* return actual validbits */
  389. static int psf_bitsize(psf_stype type)
  390. {
  391. int size = 0;
  392. switch(type){
  393. case(PSF_SAMP_16):
  394. size = 16;
  395. break;
  396. case (PSF_SAMP_24):
  397. size = 24;
  398. break;
  399. case(PSF_SAMP_32):
  400. case(PSF_SAMP_IEEE_FLOAT):
  401. size = 32;
  402. break;
  403. default:
  404. break;
  405. }
  406. return size;
  407. }
  408. /* return sample size in bytes */
  409. static int psf_wordsize(psf_stype type)
  410. {
  411. int size = 0;
  412. switch(type){
  413. case(PSF_SAMP_16):
  414. size = 2;
  415. break;
  416. case (PSF_SAMP_24):
  417. size = 3;
  418. break;
  419. case(PSF_SAMP_32):
  420. case(PSF_SAMP_IEEE_FLOAT):
  421. size = 4;
  422. break;
  423. default:
  424. break;
  425. }
  426. return size;
  427. }
  428. #ifdef _MSC_VER
  429. # if(_MSC_VER <= 1200)
  430. /* fast convergent rounding */
  431. __inline int psf_round(double fval)
  432. {
  433. int result;
  434. _asm{
  435. fld fval
  436. fistp result
  437. mov eax,result
  438. }
  439. return result;
  440. }
  441. # else
  442. /* slow convergent rounding ! */
  443. /* TODO: implement IEEE round-to-even */
  444. int psf_round(double val);
  445. # endif
  446. int psf_round(double val)
  447. {
  448. long k;
  449. k = (long)(fabs(val)+0.5);
  450. if(val < 0.0)
  451. k = -k;
  452. return (int) k;
  453. }
  454. #endif
  455. #ifndef WIN32
  456. int stricmp(const char *a, const char *b)
  457. {
  458. while(*a != '\0' && *b != '\0') {
  459. int ca = islower(*a) ? toupper(*a) : *a;
  460. int cb = islower(*b) ? toupper(*b) : *b;
  461. if(ca < cb)
  462. return -1;
  463. if(ca > cb)
  464. return 1;
  465. a++;
  466. b++;
  467. }
  468. if(*a == '\0' && *b == '\0')
  469. return 0;
  470. if(*a != '\0')
  471. return 1;
  472. return -1;
  473. }
  474. int
  475. strnicmp(const char *a, const char *b, const int length)
  476. {
  477. int len = length;
  478. while(*a != '\0' && *b != '\0') {
  479. int ca = islower(*a) ? toupper(*a) : *a;
  480. int cb = islower(*b) ? toupper(*b) : *b;
  481. if(len-- < 1)
  482. return 0;
  483. if(ca < cb)
  484. return -1;
  485. if(ca > cb)
  486. return 1;
  487. a++;
  488. b++;
  489. }
  490. if(*a == '\0' && *b == '\0')
  491. return 0;
  492. if(*a != '\0')
  493. return 1;
  494. return -1;
  495. }
  496. #endif
  497. /* create a new soundfile, from input props, or with default format if props==NULL */
  498. /* current default = sr 44100, ch 1, WAVE, 16bit */
  499. /* could have func to define a new default format...*/
  500. static PSFFILE *psf_newFile(const PSF_PROPS *props)
  501. {
  502. PSFFILE *sfdat;
  503. if(props){
  504. if(props->srate <=0)
  505. return NULL;
  506. if(props->chans <=0)
  507. return NULL;
  508. /* NO support for PSF_SAMP_8 yet...*/
  509. if(props->samptype < PSF_SAMP_16 || props->samptype > PSF_SAMP_IEEE_FLOAT)
  510. return NULL;
  511. if(props->format <= PSF_FMT_UNKNOWN || props->format > PSF_AIFC)
  512. return NULL;
  513. if(props->chformat < STDWAVE || props->chformat > MC_WAVE_EX)
  514. return NULL;
  515. }
  516. sfdat = (PSFFILE *) malloc(sizeof(PSFFILE));
  517. if(sfdat==NULL)
  518. return sfdat;
  519. POS64(sfdat->lastwritepos) = 0;
  520. sfdat->file = NULL;
  521. sfdat->filename = NULL;
  522. sfdat->nFrames = 0;
  523. sfdat->curframepos = 0;
  524. sfdat->isRead = 1; /* OK. who knows? */
  525. /* or use platform default format.... */
  526. sfdat->riff_format = props ? props->format : PSF_STDWAVE; /* almost certainly! */
  527. /*sfdat->isSeekable = 1;*/
  528. sfdat->clip_floats = 1;
  529. sfdat->rescale = 0;
  530. sfdat->rescale_fac = 1.0f;
  531. sfdat->is_little_endian = byte_order();
  532. sfdat->samptype = props ? props->samptype : PSF_SAMP_16; /* reasonable... */
  533. POS64(sfdat->dataoffset) = 0;
  534. POS64(sfdat->fmtoffset) = 0;
  535. POS64(sfdat->peakoffset) = 0;
  536. sfdat->chformat = props ? props->chformat : STDWAVE;
  537. /*setup Format */
  538. if(props)
  539. sfdat->fmt.Format.wFormatTag = (WORD) (props->samptype == PSF_SAMP_IEEE_FLOAT ? WAVE_FORMAT_IEEE_FLOAT : WAVE_FORMAT_PCM);
  540. else
  541. sfdat->fmt.Format.wFormatTag = WAVE_FORMAT_PCM;
  542. sfdat->fmt.Format.nChannels = (WORD) (props ? props->chans : 1);
  543. sfdat->fmt.Format.nSamplesPerSec = props ? props->srate : 44100;
  544. sfdat->fmt.Format.nBlockAlign = (WORD) (props ? sfdat->fmt.Format.nChannels * psf_wordsize(props->samptype) : sfdat->fmt.Format.nChannels * sizeof(short));
  545. sfdat->fmt.Format.wBitsPerSample = (WORD) (props ? psf_bitsize(props->samptype) : sizeof(short) * BITS_PER_BYTE);
  546. sfdat->fmt.Format.nAvgBytesPerSec = sfdat->fmt.Format.nSamplesPerSec
  547. *sfdat->fmt.Format.nChannels
  548. * (sfdat->fmt.Format.wBitsPerSample / BITS_PER_BYTE);
  549. sfdat->pPeaks = NULL;
  550. sfdat->peaktime = 0;
  551. sfdat->fmt.Format.cbSize = 0;
  552. /* set initial defaults for WAVE-EX stuff; may change */
  553. /* but nobody should look at these fields unless we have a real WAVE-EX file anyway... */
  554. sfdat->fmt.dwChannelMask = SPKRS_UNASSIGNED;
  555. sfdat->fmt.Samples.wValidBitsPerSample = sfdat->fmt.Format.wBitsPerSample;
  556. /* 0 should be a guaranteed non-valid GUID! */
  557. memset((char *) &(sfdat->fmt.SubFormat),0,sizeof(GUID));
  558. if(props && (props->format == PSF_WAVE_EX)) {
  559. sfdat->fmt.Format.cbSize = 22;
  560. /* NB we will set the GUID from wFormatTag in waveExWriteHeader() */
  561. /* should really flag an error if user sets this */
  562. if(sfdat->chformat==STDWAVE)
  563. sfdat->chformat = MC_STD;
  564. /* set wavex speaker mask */
  565. /* TODO: support custom speaker masks, wordsizes, etc */
  566. switch(sfdat->chformat){
  567. case MC_MONO:
  568. if(props->chans != 1){
  569. //rsferrstr = "conflicting channel configuration for WAVE-EX file";
  570. free(sfdat);
  571. return NULL;
  572. }
  573. sfdat->fmt.dwChannelMask = SPKRS_MONO;
  574. break;
  575. case MC_STEREO:
  576. if(props->chans != 2){
  577. //rsferrstr = "conflicting channel configuration for WAVE-EX file";
  578. free(sfdat);
  579. return NULL;
  580. }
  581. sfdat->fmt.dwChannelMask = SPKRS_STEREO;
  582. break;
  583. case MC_QUAD:
  584. if(props->chans != 4){
  585. //rsferrstr = "conflicting channel configuration for WAVE-EX file";
  586. free(sfdat);
  587. return NULL;
  588. }
  589. sfdat->fmt.dwChannelMask = SPKRS_GENERIC_QUAD;
  590. break;
  591. case MC_LCRS:
  592. if(props->chans != 4){
  593. free(sfdat);
  594. return NULL;
  595. }
  596. sfdat->fmt.dwChannelMask = SPKRS_SURROUND_LCRS;
  597. break;
  598. case MC_DOLBY_5_1:
  599. if(props->chans != 6){
  600. //rsferrstr = "conflicting channel configuration for WAVE-EX file";
  601. free(sfdat);
  602. return NULL;
  603. }
  604. sfdat->fmt.dwChannelMask = SPKRS_DOLBY5_1;
  605. break;
  606. case MC_SURR_5_0:
  607. if(props->chans != 5){
  608. //rsferrstr = "conflicting channel configuration for WAVE-EX file";
  609. free(sfdat);
  610. return NULL;
  611. }
  612. sfdat->fmt.dwChannelMask = SPKRS_SURR_5_0;
  613. break;
  614. case MC_SURR_6_1:
  615. if(props->chans != 7){
  616. //rsferrstr = "conflicting channel configuration for WAVE-EX file";
  617. free(sfdat);
  618. return NULL;
  619. }
  620. sfdat->fmt.dwChannelMask = SPKRS_6_1;
  621. break;
  622. case MC_SURR_7_1:
  623. if(props->chans != 8){
  624. //rsferrstr = "conflicting channel configuration for WAVE-EX file";
  625. free(sfdat);
  626. return NULL;
  627. }
  628. sfdat->fmt.dwChannelMask = SPKRS_7_1;
  629. break;
  630. case MC_CUBE:
  631. if(props->chans != 8){
  632. //rsferrstr = "conflicting channel configuration for WAVE-EX file";
  633. free(sfdat);
  634. return NULL;
  635. }
  636. sfdat->fmt.dwChannelMask = SPKRS_CUBE;
  637. break;
  638. default:
  639. /*MC_STD, MC_BFMT */
  640. sfdat->fmt.dwChannelMask = SPKRS_UNASSIGNED;
  641. break;
  642. }
  643. }
  644. /* no dither, by default */
  645. sfdat->dithertype = PSF_DITHER_OFF;
  646. sfdat->illformed = 0; /*RWD Feb 2010 */
  647. memset(sfdat->warnstring,0,WARNSTRING_SIZE);
  648. return sfdat;
  649. }
  650. int psf_getWarning(int sfd,const char** warnstring)
  651. {
  652. int retval = 0;
  653. PSFFILE *sfdat;
  654. if(sfd < 0 || sfd > psf_maxfiles)
  655. retval = PSF_E_BADARG;
  656. sfdat = psf_files[sfd];
  657. if(sfdat->illformed==0)
  658. retval = 0;
  659. else{
  660. *warnstring = sfdat->warnstring;
  661. retval = 1;
  662. }
  663. return retval;
  664. }
  665. /* complete header before closing file; return PSF_E_NOERROR[= 0] on success */
  666. static int wavUpdate(PSFFILE *sfdat)
  667. {
  668. DWORD riffsize,datasize;
  669. fpos_t bytepos;
  670. #ifdef _DEBUG
  671. assert(sfdat);
  672. assert(sfdat->file);
  673. assert(POS64(sfdat->dataoffset) != 0);
  674. #endif
  675. POS64(bytepos) = sizeof(int);
  676. if((fsetpos(sfdat->file,&bytepos))==0) {
  677. riffsize = (sfdat->nFrames * sfdat->fmt.Format.nBlockAlign) + (MYLONG) POS64(sfdat->dataoffset);
  678. riffsize -= 2 * sizeof(DWORD);
  679. if(!sfdat->is_little_endian)
  680. riffsize = REVDWBYTES(riffsize);
  681. if(fwrite((char *) &riffsize,sizeof(int),1,sfdat->file) != 1)
  682. return PSF_E_CANT_WRITE;
  683. }
  684. else
  685. return PSF_E_CANT_SEEK;
  686. if(sfdat->pPeaks){
  687. if(POS64(sfdat->peakoffset)==0)
  688. return PSF_E_BADARG;
  689. /*do byterev if necessary...*/
  690. if((fsetpos(sfdat->file,&sfdat->peakoffset))==0){
  691. /*set current time*/
  692. DWORD *pblock;
  693. int i;
  694. time_t now = time(0);
  695. if(!sfdat->is_little_endian){
  696. now = REVDWBYTES(now);
  697. pblock = (DWORD *) (sfdat->pPeaks);
  698. for(i=0;i < sfdat->fmt.Format.nChannels * 2; i++)
  699. pblock[i] = REVDWBYTES(pblock[i]);
  700. }
  701. if((fwrite((char*)&now,sizeof(DWORD),1,sfdat->file)) != 1)
  702. return PSF_E_CANT_WRITE;
  703. if((fwrite((char *) (sfdat->pPeaks),sizeof(PSF_CHPEAK),sfdat->fmt.Format.nChannels,sfdat->file))
  704. != sfdat->fmt.Format.nChannels )
  705. return PSF_E_CANT_WRITE;
  706. }
  707. else
  708. return PSF_E_CANT_SEEK;
  709. }
  710. POS64(bytepos) = POS64(sfdat->dataoffset) - sizeof(int);
  711. if((fsetpos(sfdat->file,&bytepos))==0) {
  712. datasize = sfdat->nFrames * sfdat->fmt.Format.nBlockAlign;
  713. if(!sfdat->is_little_endian)
  714. datasize = REVDWBYTES(datasize);
  715. if(fwrite((char *) & datasize,sizeof(DWORD),1,sfdat->file) != 1)
  716. return PSF_E_CANT_WRITE;
  717. }
  718. if(fseek(sfdat->file,0,SEEK_END)){
  719. /*DBGFPRINTF((stderr,"wavUpdate: error reseeking to end of file\n"));*/
  720. return PSF_E_CANT_SEEK;
  721. }
  722. return PSF_E_NOERROR;
  723. }
  724. /* ditto for AIFF... */
  725. /* NB: the AIFF spec is unclear on type of size field. We decide on unsigned long (DWORD) here;
  726. on the principle that a COMM chunk with an unsigned long nSampleFrames really needs the
  727. chunk size to be unsigned long too!.
  728. */
  729. static int aiffUpdate(PSFFILE *sfdat)
  730. {
  731. DWORD aiffsize,datasize,rev_datasize,frames;
  732. fpos_t bytepos,filesize;
  733. unsigned char pad = 0x00;
  734. if(sfdat==NULL || sfdat->file== NULL)
  735. return PSF_E_BADARG;
  736. if(POS64(sfdat->dataoffset) == 0)
  737. return PSF_E_BADARG;
  738. POS64(bytepos) = sizeof(int);
  739. if((fsetpos(sfdat->file,&bytepos))==0) {
  740. /* RWD 26:10:2002 */
  741. aiffsize = (sfdat->nFrames * sfdat->fmt.Format.nBlockAlign)
  742. + (MYLONG) POS64(sfdat->dataoffset);
  743. // need to count any needed pad byte
  744. aiffsize += (aiffsize % 2);
  745. // deduct 8 bytes for FORM<size>
  746. aiffsize -= 2 * sizeof(DWORD);
  747. if(sfdat->is_little_endian)
  748. aiffsize = REVDWBYTES(aiffsize);
  749. if(fwrite((char *) &aiffsize,sizeof(DWORD),1,sfdat->file) != 1)
  750. return PSF_E_CANT_WRITE;
  751. }
  752. else
  753. return PSF_E_CANT_SEEK;
  754. POS64(bytepos) = POS64(sfdat->fmtoffset) + sizeof(WORD);
  755. if((fsetpos(sfdat->file,&bytepos))==0) {
  756. frames = sfdat->nFrames;
  757. if(sfdat->is_little_endian)
  758. frames = REVDWBYTES(frames);
  759. if(fwrite((char *) &frames,sizeof(DWORD),1,sfdat->file) != 1)
  760. return PSF_E_CANT_WRITE;
  761. }
  762. else
  763. return PSF_E_CANT_SEEK;
  764. if(sfdat->pPeaks){
  765. if(POS64(sfdat->peakoffset)==0)
  766. return PSF_E_BADARG;
  767. /*do byterev if necessary...*/
  768. if((fsetpos(sfdat->file,&sfdat->peakoffset))==0){
  769. /*set current time*/
  770. DWORD *pblock;
  771. int i;
  772. time_t now = time(0);
  773. if(sfdat->is_little_endian){
  774. now = REVDWBYTES(now);
  775. pblock = (DWORD *) (sfdat->pPeaks);
  776. for(i=0;i < sfdat->fmt.Format.nChannels * 2; i++)
  777. pblock[i] = REVDWBYTES(pblock[i]);
  778. }
  779. if((fwrite((char*)&now,sizeof(DWORD),1,sfdat->file)) != 1)
  780. return PSF_E_CANT_WRITE;
  781. if((fwrite((char *) (sfdat->pPeaks),sizeof(PSF_CHPEAK),sfdat->fmt.Format.nChannels,sfdat->file))
  782. != sfdat->fmt.Format.nChannels )
  783. return PSF_E_CANT_WRITE;
  784. }
  785. else
  786. return PSF_E_CANT_SEEK;
  787. }
  788. POS64(bytepos) = POS64(sfdat->dataoffset) - (3 * sizeof(int));
  789. if((fsetpos(sfdat->file,&bytepos))==0) {
  790. datasize = sfdat->nFrames * sfdat->fmt.Format.nBlockAlign;
  791. datasize += 2* sizeof(DWORD); /* add offset and blocksize fields */
  792. rev_datasize = datasize; /* preserve this for the seek later on */
  793. if(sfdat->is_little_endian)
  794. rev_datasize = REVDWBYTES(datasize);
  795. if(fwrite((char *) & rev_datasize,sizeof(DWORD),1,sfdat->file) != 1)
  796. return PSF_E_CANT_WRITE;
  797. }
  798. else
  799. return PSF_E_CANT_SEEK;
  800. /* datachunk needs added pad byte if odd, not included in saved chunksize*/
  801. POS64(bytepos) = POS64(sfdat->dataoffset) + datasize;
  802. if((fsetpos(sfdat->file,&bytepos))){
  803. return PSF_E_CANT_SEEK;
  804. }
  805. if(fgetpos(sfdat->file,&filesize))
  806. return PSF_E_CANT_SEEK;
  807. #ifdef _DEBUG
  808. assert(POS64(filesize) == POS64(bytepos));
  809. #endif
  810. if(POS64(filesize) % 2)
  811. if(fwrite(&pad,sizeof(unsigned char),1,sfdat->file) != 1)
  812. return PSF_E_CANT_WRITE;
  813. return PSF_E_NOERROR;
  814. }
  815. /* internal write func: return 0 for success */
  816. static int wavDoWrite(PSFFILE *sfdat, const void* buf, DWORD nBytes)
  817. {
  818. DWORD written = 0;
  819. if(sfdat==NULL || buf==NULL)
  820. return PSF_E_BADARG;
  821. if(sfdat->file==NULL)
  822. return PSF_E_CANT_WRITE;
  823. if((written = fwrite(buf,sizeof(char),nBytes,sfdat->file)) != nBytes) {
  824. DBGFPRINTF((stderr, "wavDoWrite: wanted %d got %d.\n",
  825. (int) nBytes,(int) written));
  826. return PSF_E_CANT_WRITE;
  827. }
  828. sfdat->lastop = PSF_OP_WRITE;
  829. return PSF_E_NOERROR;
  830. }
  831. static int wavDoRead(PSFFILE *sfdat, void* buf, DWORD nBytes)
  832. {
  833. DWORD got = 0;
  834. if(sfdat==NULL || buf==NULL)
  835. return PSF_E_BADARG;
  836. if(sfdat->file==NULL)
  837. return PSF_E_CANT_READ;
  838. if((got = fread(buf,sizeof(char),nBytes,sfdat->file)) != nBytes) {
  839. DBGFPRINTF((stderr, "wavDoRead: wanted %d got %d.\n",
  840. (int) nBytes,(int) got));
  841. return PSF_E_CANT_READ;
  842. }
  843. sfdat->lastop = PSF_OP_READ;
  844. return PSF_E_NOERROR;
  845. }
  846. /* write PEAK chunk if we have the data */
  847. static int wavWriteHeader(PSFFILE *sfdat)
  848. {
  849. DWORD tag,size;
  850. WORD cbSize = 0;
  851. WAVEFORMATEX *pfmt;
  852. PSF_CHPEAK *peaks;
  853. fpos_t bytepos;
  854. #ifdef _DEBUG
  855. assert(sfdat);
  856. assert(sfdat->file);
  857. assert(sfdat->riff_format == PSF_STDWAVE);
  858. assert(sfdat->nFrames == 0);
  859. assert(!sfdat->isRead);
  860. assert(sfdat->fmt.Format.nChannels != 0);
  861. #endif
  862. /*clear pPeaks array*/
  863. if(sfdat->pPeaks)
  864. memset((char *)sfdat->pPeaks,0,sizeof(PSF_CHPEAK) * sfdat->fmt.Format.nChannels);
  865. tag = TAG('R','I','F','F');
  866. size = 0;
  867. if(!sfdat->is_little_endian)
  868. size = REVDWBYTES(size);
  869. else
  870. tag = REVDWBYTES(tag);
  871. if(wavDoWrite(sfdat,(char *)&tag,sizeof(DWORD))
  872. || wavDoWrite(sfdat,(char *)&size,sizeof(DWORD)))
  873. return PSF_E_CANT_WRITE;
  874. tag = TAG('W','A','V','E');
  875. if(sfdat->is_little_endian)
  876. tag = REVDWBYTES(tag);
  877. if(wavDoWrite(sfdat,(char *)&tag,sizeof(DWORD)))
  878. return PSF_E_CANT_WRITE;
  879. pfmt = &(sfdat->fmt.Format);
  880. tag = TAG('f','m','t',' ');
  881. size = sizeof(WAVEFORMAT);
  882. if(sfdat->samptype==PSF_SAMP_IEEE_FLOAT)
  883. size += sizeof(WORD); /* for cbSize: WAVEOFRMATEX */
  884. if(!sfdat->is_little_endian){
  885. size = REVDWBYTES(size);
  886. fmtSwapBytes(sfdat);
  887. }
  888. else
  889. tag = REVDWBYTES(tag);
  890. if(wavDoWrite(sfdat,(char *)&tag,sizeof(DWORD))
  891. || wavDoWrite(sfdat,(char *)&size,sizeof(DWORD)))
  892. return PSF_E_CANT_WRITE;
  893. if(fgetpos(sfdat->file,&bytepos))
  894. return PSF_E_CANT_SEEK;
  895. sfdat->fmtoffset = bytepos;
  896. if(wavDoWrite(sfdat,(char *)pfmt,sizeof(WAVEFORMAT)))
  897. return PSF_E_CANT_WRITE;
  898. /*add cbSize if floatsams */
  899. if(sfdat->samptype==PSF_SAMP_IEEE_FLOAT)
  900. if(wavDoWrite(sfdat,(char *)&cbSize,sizeof(WORD)))
  901. return PSF_E_CANT_WRITE;
  902. /* reswap it all */
  903. if(!sfdat->is_little_endian){
  904. fmtSwapBytes(sfdat);
  905. }
  906. if(sfdat->pPeaks){
  907. DWORD version = 1, now = 0;
  908. peaks = sfdat->pPeaks;
  909. tag = TAG('P','E','A','K');
  910. size = 2 * sizeof(DWORD) + sizeof(PSF_CHPEAK) * pfmt->nChannels;
  911. if(!sfdat->is_little_endian){
  912. size = REVDWBYTES(size);
  913. version = REVDWBYTES(version);
  914. }
  915. else
  916. tag = REVDWBYTES(tag);
  917. if(wavDoWrite(sfdat,(char *)&tag,sizeof(DWORD))
  918. || wavDoWrite(sfdat,(char *)&size,sizeof(DWORD))
  919. || wavDoWrite(sfdat,(char *)&version,sizeof(DWORD)))
  920. return PSF_E_CANT_WRITE;
  921. if(fgetpos(sfdat->file,&bytepos))
  922. return PSF_E_CANT_SEEK;
  923. sfdat->peakoffset = bytepos; /*we need to update time*/
  924. if(wavDoWrite(sfdat,(char *) &now,sizeof(DWORD))
  925. || wavDoWrite(sfdat,(char *) peaks, sizeof(PSF_CHPEAK) * sfdat->fmt.Format.nChannels))
  926. return PSF_E_CANT_WRITE;
  927. }
  928. tag = TAG('d','a','t','a');
  929. size = 0;
  930. if(sfdat->is_little_endian)
  931. tag = REVDWBYTES(tag);
  932. if(wavDoWrite(sfdat,(char *)&tag,sizeof(DWORD))
  933. || wavDoWrite(sfdat,(char *)&size,sizeof(DWORD)))
  934. return PSF_E_CANT_WRITE;
  935. if(fgetpos(sfdat->file,&bytepos))
  936. return PSF_E_CANT_SEEK;
  937. sfdat->dataoffset = bytepos;
  938. return PSF_E_NOERROR;
  939. }
  940. static int waveExWriteHeader(PSFFILE *sfdat)
  941. {
  942. DWORD tag,size;
  943. WAVEFORMATEXTENSIBLE *pfmt;
  944. PSF_CHPEAK *peaks;
  945. GUID *pGuid = NULL;
  946. fpos_t bytepos;
  947. #ifdef _DEBUG
  948. assert(sfdat);
  949. assert(sfdat->file);
  950. assert(sfdat->chformat > STDWAVE);
  951. assert(sfdat->nFrames==0);
  952. assert(!sfdat->isRead);
  953. assert(sfdat->fmt.Format.nChannels != 0);
  954. #endif
  955. /*clear pPeaks array*/
  956. if(sfdat->pPeaks)
  957. memset((char *)sfdat->pPeaks,0,sizeof(PSF_CHPEAK) * sfdat->fmt.Format.nChannels);
  958. /* complete WAVE-EX format fields: */
  959. if(sfdat->chformat==MC_BFMT){
  960. if(sfdat->samptype== PSF_SAMP_IEEE_FLOAT){
  961. pGuid = (GUID *) &SUBTYPE_AMBISONIC_B_FORMAT_IEEE_FLOAT;
  962. }
  963. else{
  964. pGuid =(GUID *) &SUBTYPE_AMBISONIC_B_FORMAT_PCM;
  965. }
  966. }else {
  967. if(sfdat->fmt.Format.wFormatTag== WAVE_FORMAT_IEEE_FLOAT){
  968. pGuid = (GUID *) &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
  969. }
  970. else{
  971. pGuid =(GUID *) &KSDATAFORMAT_SUBTYPE_PCM;
  972. }
  973. }
  974. sfdat->fmt.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
  975. memcpy((char *) &(sfdat->fmt.SubFormat),(char *)pGuid,sizeof(GUID));
  976. tag = TAG('R','I','F','F');
  977. size = 0;
  978. if(!sfdat->is_little_endian)
  979. size = REVDWBYTES(size);
  980. else
  981. tag = REVDWBYTES(tag);
  982. if(wavDoWrite(sfdat,(char *)&tag,sizeof(DWORD))
  983. || wavDoWrite(sfdat,(char *)&size,sizeof(DWORD)))
  984. return PSF_E_CANT_WRITE;
  985. tag = TAG('W','A','V','E');
  986. if(sfdat->is_little_endian)
  987. tag = REVDWBYTES(tag);
  988. if(wavDoWrite(sfdat,(char *)&tag,sizeof(DWORD)))
  989. return PSF_E_CANT_WRITE;
  990. pfmt = &(sfdat->fmt);
  991. tag = TAG('f','m','t',' ');
  992. size = sizeof_WFMTEX;
  993. if(!sfdat->is_little_endian){
  994. size = REVDWBYTES(size);
  995. fmtExSwapBytes(sfdat);
  996. }
  997. else
  998. tag = REVDWBYTES(tag);
  999. if(wavDoWrite(sfdat,(char *)&tag,sizeof(DWORD))
  1000. || wavDoWrite(sfdat,(char *)&size,sizeof(DWORD)))
  1001. return PSF_E_CANT_WRITE;
  1002. if(fgetpos(sfdat->file,&bytepos))
  1003. return PSF_E_CANT_SEEK;
  1004. sfdat->fmtoffset = bytepos;
  1005. /* write fmt elementwise, to avoid C alignment traps with WORD */
  1006. /* 16byte format...*/
  1007. if(wavDoWrite(sfdat,(char *)pfmt,sizeof(WAVEFORMAT))
  1008. /** cbSize... */
  1009. ||wavDoWrite(sfdat,(char *) &(pfmt->Format.cbSize),sizeof(WORD))
  1010. /* validbits... */
  1011. ||wavDoWrite(sfdat,(char *) &(pfmt->Samples.wValidBitsPerSample),sizeof(WORD))
  1012. /* ChannelMask .... */
  1013. ||wavDoWrite(sfdat,(char *) &(pfmt->dwChannelMask),sizeof(DWORD))
  1014. /* and the GUID */
  1015. ||wavDoWrite(sfdat,(char *) &(pfmt->SubFormat),sizeof(GUID)))
  1016. return PSF_E_CANT_WRITE;
  1017. /* reswap it all */
  1018. if(!sfdat->is_little_endian){
  1019. fmtExSwapBytes(sfdat);
  1020. }
  1021. if(sfdat->pPeaks){
  1022. DWORD version = 1, now = 0;
  1023. peaks = sfdat->pPeaks;
  1024. tag = TAG('P','E','A','K');
  1025. size = 2 * sizeof(DWORD) + sizeof(PSF_CHPEAK) * pfmt->Format.nChannels;
  1026. if(!sfdat->is_little_endian){
  1027. size = REVDWBYTES(size);
  1028. version = REVDWBYTES(version);
  1029. }
  1030. else
  1031. tag = REVDWBYTES(tag);
  1032. if(wavDoWrite(sfdat,(char *)&tag,sizeof(DWORD))
  1033. || wavDoWrite(sfdat,(char *)&size,sizeof(DWORD))
  1034. || wavDoWrite(sfdat,(char *)&version,sizeof(DWORD)))
  1035. return PSF_E_CANT_WRITE;
  1036. if(fgetpos(sfdat->file,&bytepos))
  1037. return PSF_E_CANT_SEEK;
  1038. sfdat->peakoffset = bytepos; /*we need to update time*/
  1039. if(wavDoWrite(sfdat,(char *) &now,sizeof(DWORD))
  1040. || wavDoWrite(sfdat,(char *) peaks, sizeof(PSF_CHPEAK) * sfdat->fmt.Format.nChannels))
  1041. return PSF_E_CANT_WRITE;
  1042. }
  1043. tag = TAG('d','a','t','a');
  1044. size = 0;
  1045. if(sfdat->is_little_endian)
  1046. tag = REVDWBYTES(tag);
  1047. if(wavDoWrite(sfdat,(char *)&tag,sizeof(DWORD))
  1048. || wavDoWrite(sfdat,(char *)&size,sizeof(DWORD)))
  1049. return PSF_E_CANT_WRITE;
  1050. if(fgetpos(sfdat->file,&bytepos))
  1051. return PSF_E_CANT_SEEK;
  1052. sfdat->dataoffset = bytepos;
  1053. return PSF_E_NOERROR;
  1054. }
  1055. static int aiffWriteHeader(PSFFILE *sfdat)
  1056. {
  1057. DWORD tag,size;
  1058. PSF_CHPEAK *peaks;
  1059. DWORD dwData,offset,blocksize;
  1060. unsigned char ieee[10];
  1061. WORD wData;
  1062. fpos_t bytepos;
  1063. #ifdef _DEBUG
  1064. assert(sfdat);
  1065. assert(sfdat->file);
  1066. assert(sfdat->chformat == STDWAVE);
  1067. assert(sfdat->nFrames==0);
  1068. assert(!sfdat->isRead);
  1069. assert(sfdat->riff_format == PSF_AIFF);
  1070. assert(sfdat->fmt.Format.nChannels != 0);
  1071. #endif
  1072. /*clear pPeaks array*/
  1073. if(sfdat->pPeaks)
  1074. memset((char *)sfdat->pPeaks,0,sizeof(PSF_CHPEAK) * sfdat->fmt.Format.nChannels);
  1075. tag = TAG('F','O','R','M');
  1076. size = 0;
  1077. if(sfdat->is_little_endian) {
  1078. size = REVDWBYTES(size);
  1079. tag = REVDWBYTES(tag);
  1080. }
  1081. if(wavDoWrite(sfdat,(char *)&tag,sizeof(DWORD))
  1082. || wavDoWrite(sfdat,(char *)&size,sizeof(DWORD)))
  1083. return PSF_E_CANT_WRITE;
  1084. tag = TAG('A','I','F','F');
  1085. if(sfdat->is_little_endian)
  1086. tag = REVDWBYTES(tag);
  1087. if(wavDoWrite(sfdat,(char *)&tag,sizeof(DWORD)))
  1088. return PSF_E_CANT_WRITE;
  1089. tag = TAG('C','O','M','M');
  1090. size = 18;
  1091. if(sfdat->is_little_endian){
  1092. size = REVDWBYTES(size);
  1093. tag = REVDWBYTES(tag);
  1094. }
  1095. if(wavDoWrite(sfdat,(char *)&tag,sizeof(DWORD))
  1096. || wavDoWrite(sfdat,(char *)&size,sizeof(DWORD)))
  1097. return PSF_E_CANT_WRITE;
  1098. if(fgetpos(sfdat->file,&bytepos))
  1099. return PSF_E_CANT_SEEK;
  1100. sfdat->fmtoffset = bytepos;
  1101. wData = sfdat->fmt.Format.nChannels;
  1102. if(sfdat->is_little_endian)
  1103. wData = (WORD) REVWBYTES(wData);
  1104. if(wavDoWrite(sfdat,(char *)&wData,sizeof(WORD)))
  1105. return PSF_E_CANT_WRITE;
  1106. dwData = 0; /* nFrames */
  1107. if(wavDoWrite(sfdat,(char *)&dwData,sizeof(DWORD)))
  1108. return PSF_E_CANT_WRITE;
  1109. wData = sfdat->fmt.Format.wBitsPerSample;
  1110. if(sfdat->is_little_endian)
  1111. wData = (WORD) REVWBYTES(wData);
  1112. if(wavDoWrite(sfdat,(char *)&wData,sizeof(WORD)))
  1113. return PSF_E_CANT_WRITE;
  1114. double_to_ieee_80((double)sfdat->fmt.Format.nSamplesPerSec,ieee);
  1115. if(wavDoWrite(sfdat,ieee,10))
  1116. return PSF_E_CANT_WRITE;
  1117. if(sfdat->pPeaks){
  1118. DWORD version = 1, now = 0;
  1119. peaks = sfdat->pPeaks;
  1120. tag = TAG('P','E','A','K');
  1121. size = 2 * sizeof(DWORD) + sizeof(PSF_CHPEAK) * sfdat->fmt.Format.nChannels;
  1122. if(sfdat->is_little_endian){
  1123. size = REVDWBYTES(size);
  1124. version = REVDWBYTES(version);
  1125. tag = REVDWBYTES(tag);
  1126. }
  1127. if(wavDoWrite(sfdat,(char *)&tag,sizeof(DWORD))
  1128. || wavDoWrite(sfdat,(char *)&size,sizeof(DWORD))
  1129. || wavDoWrite(sfdat,(char *)&version,sizeof(DWORD)))
  1130. return PSF_E_CANT_WRITE;
  1131. if(fgetpos(sfdat->file,&bytepos))
  1132. return PSF_E_CANT_SEEK;
  1133. sfdat->peakoffset = bytepos; /*we need to update time*/
  1134. if(wavDoWrite(sfdat,(char *) &now,sizeof(DWORD))
  1135. || wavDoWrite(sfdat,(char *) peaks, sizeof(PSF_CHPEAK) * sfdat->fmt.Format.nChannels))
  1136. return PSF_E_CANT_WRITE;
  1137. }
  1138. tag = TAG('S','S','N','D');
  1139. size = offset = blocksize = 0;
  1140. if(sfdat->is_little_endian)
  1141. tag = REVDWBYTES(tag);
  1142. if(wavDoWrite(sfdat,(char *)&tag,sizeof(DWORD))
  1143. || wavDoWrite(sfdat,(char *)&size,sizeof(DWORD))
  1144. || wavDoWrite(sfdat,(char *)&offset,sizeof(DWORD))
  1145. || wavDoWrite(sfdat,(char *)&blocksize,sizeof(DWORD)))
  1146. return PSF_E_CANT_WRITE;
  1147. if(fgetpos(sfdat->file,&bytepos))
  1148. return PSF_E_CANT_SEEK;
  1149. sfdat->dataoffset = bytepos;
  1150. return PSF_E_NOERROR;
  1151. }
  1152. static int aifcWriteHeader(PSFFILE *sfdat)
  1153. {
  1154. DWORD tag,size;
  1155. PSF_CHPEAK *peaks;
  1156. DWORD dwData,offset,blocksize,aifcver = AIFC_VERSION_1,ID_compression;
  1157. /*assume 32bit floats, but we may be asked to use aifc for integer formats too*/
  1158. char *str_compressed = (char *) aifc_floatstring;
  1159. int pstring_size = 10;
  1160. unsigned char ieee[10];
  1161. WORD wData;
  1162. fpos_t bytepos;
  1163. #ifdef _DEBUG
  1164. assert(sfdat);
  1165. assert(sfdat->file);
  1166. assert(sfdat->nFrames==0);
  1167. assert(!sfdat->isRead);
  1168. assert(sfdat->riff_format == PSF_AIFC);
  1169. assert(sfdat->fmt.Format.nChannels != 0);
  1170. #endif
  1171. if(sfdat->samptype==PSF_SAMP_IEEE_FLOAT)
  1172. ID_compression = TAG('f','l','3','2');
  1173. else {
  1174. ID_compression = TAG('N','O','N','E');
  1175. pstring_size = 16;
  1176. str_compressed = (char *) aifc_notcompressed;
  1177. }
  1178. /*clear pPeaks array*/
  1179. if(sfdat->pPeaks)
  1180. memset((char *)sfdat->pPeaks,0,sizeof(PSF_CHPEAK) * sfdat->fmt.Format.nChannels);
  1181. tag = TAG('F','O','R','M');
  1182. size = 0;
  1183. if(sfdat->is_little_endian) {
  1184. size = REVDWBYTES(size);
  1185. tag = REVDWBYTES(tag);
  1186. }
  1187. if(wavDoWrite(sfdat,(char *)&tag,sizeof(DWORD))
  1188. || wavDoWrite(sfdat,(char *)&size,sizeof(DWORD)))
  1189. return PSF_E_CANT_WRITE;
  1190. tag = TAG('A','I','F','C');
  1191. if(sfdat->is_little_endian)
  1192. tag = REVDWBYTES(tag);
  1193. if(wavDoWrite(sfdat,(char *)&tag,sizeof(DWORD)))
  1194. return PSF_E_CANT_WRITE;
  1195. tag = TAG('F','V','E','R');
  1196. size = sizeof(DWORD);
  1197. if(sfdat->is_little_endian){
  1198. size = REVDWBYTES(size);
  1199. tag = REVDWBYTES(tag);
  1200. aifcver = REVDWBYTES(aifcver);
  1201. }
  1202. if(wavDoWrite(sfdat,(char *)&tag,sizeof(DWORD))
  1203. || wavDoWrite(sfdat,(char *)&size,sizeof(DWORD))
  1204. || wavDoWrite(sfdat,(char *)&aifcver,sizeof(DWORD)))
  1205. return PSF_E_CANT_WRITE;
  1206. tag = TAG('C','O','M','M');
  1207. size = 22 + pstring_size;
  1208. if(sfdat->is_little_endian){
  1209. size = REVDWBYTES(size);
  1210. tag = REVDWBYTES(tag);
  1211. }
  1212. if(wavDoWrite(sfdat,(char *)&tag,sizeof(DWORD))
  1213. || wavDoWrite(sfdat,(char *)&size,sizeof(DWORD)))
  1214. return PSF_E_CANT_WRITE;
  1215. if(fgetpos(sfdat->file,&bytepos))
  1216. return PSF_E_CANT_SEEK;
  1217. sfdat->fmtoffset = bytepos;
  1218. wData = sfdat->fmt.Format.nChannels;
  1219. if(sfdat->is_little_endian)
  1220. wData = (WORD) REVWBYTES(wData);
  1221. if(wavDoWrite(sfdat,(char *)&wData,sizeof(WORD)))
  1222. return PSF_E_CANT_WRITE;
  1223. dwData = 0; /* nFrames */
  1224. if(wavDoWrite(sfdat,(char *)&dwData,sizeof(DWORD)))
  1225. return PSF_E_CANT_WRITE;
  1226. wData = sfdat->fmt.Format.wBitsPerSample;
  1227. if(sfdat->is_little_endian)
  1228. wData = (WORD) REVWBYTES(wData);
  1229. if(wavDoWrite(sfdat,(char *)&wData,sizeof(WORD)))
  1230. return PSF_E_CANT_WRITE;
  1231. double_to_ieee_80((double)sfdat->fmt.Format.nSamplesPerSec,ieee);
  1232. if(wavDoWrite(sfdat,ieee,10))
  1233. return PSF_E_CANT_WRITE;
  1234. /*AIFC bits */
  1235. if(sfdat->is_little_endian)
  1236. ID_compression = REVDWBYTES(ID_compression);
  1237. if(wavDoWrite(sfdat,(char *)&ID_compression,sizeof(DWORD)))
  1238. return PSF_E_CANT_WRITE;
  1239. if(wavDoWrite(sfdat,str_compressed,pstring_size))
  1240. return PSF_E_CANT_WRITE;
  1241. if(sfdat->pPeaks){
  1242. DWORD version = 1, now = 0;
  1243. peaks = sfdat->pPeaks;
  1244. tag = TAG('P','E','A','K');
  1245. size = 2 * sizeof(DWORD) + sizeof(PSF_CHPEAK) * sfdat->fmt.Format.nChannels;
  1246. if(sfdat->is_little_endian){
  1247. size = REVDWBYTES(size);
  1248. version = REVDWBYTES(version);
  1249. tag = REVDWBYTES(tag);
  1250. }
  1251. if(wavDoWrite(sfdat,(char *)&tag,sizeof(DWORD))
  1252. || wavDoWrite(sfdat,(char *)&size,sizeof(DWORD))
  1253. || wavDoWrite(sfdat,(char *)&version,sizeof(DWORD)))
  1254. return PSF_E_CANT_WRITE;
  1255. if(fgetpos(sfdat->file,&bytepos))
  1256. return PSF_E_CANT_SEEK;
  1257. sfdat->peakoffset = bytepos; /*we need to update time*/
  1258. if(wavDoWrite(sfdat,(char *) &now,sizeof(DWORD))
  1259. || wavDoWrite(sfdat,(char *) peaks, sizeof(PSF_CHPEAK) * sfdat->fmt.Format.nChannels))
  1260. return PSF_E_CANT_WRITE;
  1261. }
  1262. tag = TAG('S','S','N','D');
  1263. size = offset = blocksize = 0;
  1264. if(sfdat->is_little_endian)
  1265. tag = REVDWBYTES(tag);
  1266. if(wavDoWrite(sfdat,(char *)&tag,sizeof(DWORD))
  1267. || wavDoWrite(sfdat,(char *)&size,sizeof(DWORD))
  1268. || wavDoWrite(sfdat,(char *)&offset,sizeof(DWORD))
  1269. || wavDoWrite(sfdat,(char *)&blocksize,sizeof(DWORD)))
  1270. return PSF_E_CANT_WRITE;
  1271. if(fgetpos(sfdat->file,&bytepos))
  1272. return PSF_E_CANT_SEEK;
  1273. sfdat->dataoffset = bytepos;
  1274. return PSF_E_NOERROR;
  1275. }
  1276. /* create soundfile. return descriptor, or some PSF_error value < 0 */
  1277. /* supported clipping or non-clipping of floats to 0dbFS,
  1278. minimum header (or PEAK), and RDWR or RDONLY (but last not implemented yet!) */
  1279. /* we expect full format info to be set in props */
  1280. /* I want to offer share-read access (easy with WIN32), but can't with ANSI! */
  1281. /* possible TODO: enforce non-destructive by e.g. rejecting create on existing file */
  1282. int psf_sndCreate(const char *path,const PSF_PROPS *props,int clip_floats,int minheader, int mode)
  1283. {
  1284. int i,rc = PSF_E_UNSUPPORTED;
  1285. psf_format fmt;
  1286. PSFFILE *sfdat;
  1287. char *fmtstr = "wb+"; /* default is READ+WRITE */
  1288. /* disallow props = NULL here, until/unless I can offer mechanism to set default props via psf_init() */
  1289. if(path == NULL || props == NULL)
  1290. return PSF_E_BADARG;
  1291. for(i=0; i < psf_maxfiles; i++) {
  1292. if(psf_files[i] == NULL)
  1293. break;
  1294. }
  1295. if(i==psf_maxfiles)
  1296. return PSF_E_TOOMANYFILES;
  1297. sfdat = psf_newFile(props);
  1298. if(sfdat == NULL)
  1299. return PSF_E_NOMEM;
  1300. sfdat->clip_floats = clip_floats;
  1301. fmt = psf_getFormatExt(path);
  1302. if(fmt==PSF_FMT_UNKNOWN)
  1303. return PSF_E_UNSUPPORTED;
  1304. if(sfdat->samptype == PSF_SAMP_UNKNOWN)
  1305. return PSF_E_BADARG;
  1306. sfdat->filename = (char *) malloc(strlen(path)+1);
  1307. if(sfdat->filename==NULL) {
  1308. DBGFPRINTF((stderr, "wavOpenWrite: no memory for filename\n"));
  1309. return PSF_E_NOMEM;
  1310. }
  1311. if(!minheader){
  1312. sfdat->pPeaks = (PSF_CHPEAK *) malloc(sizeof(PSF_CHPEAK) * sfdat->fmt.Format.nChannels);
  1313. if(sfdat->pPeaks==NULL){
  1314. DBGFPRINTF((stderr, "wavOpenWrite: no memory for peak data\n"));
  1315. return PSF_E_NOMEM;
  1316. }
  1317. }
  1318. /*switch (mode).... */
  1319. if(mode==PSF_CREATE_WRONLY)
  1320. fmtstr = "wb";
  1321. /* deal with CREATE_TEMPORARY later on! */
  1322. if((sfdat->file = fopen(path,fmtstr)) == NULL) {
  1323. DBGFPRINTF((stderr, "wavOpenWrite: cannot create '%s'\n", path));
  1324. return PSF_E_CANT_OPEN;
  1325. }
  1326. strcpy(sfdat->filename, path);
  1327. sfdat->isRead = 0;
  1328. sfdat->nFrames = 0;
  1329. /* force aif f/p data to go to aifc format */
  1330. if(sfdat->samptype==PSF_SAMP_IEEE_FLOAT && fmt==PSF_AIFF){
  1331. DBGFPRINTF((stderr, "Warning: writing floating point data in AIFC format\n"));
  1332. fmt= PSF_AIFC;
  1333. }
  1334. /* .wav extension can be either std WAVE or WAVE-EX */
  1335. if(fmt==PSF_STDWAVE){
  1336. if(props->format==PSF_WAVE_EX)
  1337. fmt = PSF_WAVE_EX;
  1338. }
  1339. sfdat->riff_format = fmt;
  1340. switch(fmt){
  1341. case(PSF_STDWAVE):
  1342. rc = wavWriteHeader(sfdat);
  1343. break;
  1344. case(PSF_AIFF):
  1345. rc = aiffWriteHeader(sfdat);
  1346. break;
  1347. case(PSF_AIFC):
  1348. rc = aifcWriteHeader(sfdat);
  1349. break;
  1350. case (PSF_WAVE_EX):
  1351. rc = waveExWriteHeader(sfdat);
  1352. break;
  1353. default:
  1354. sfdat->riff_format = PSF_FMT_UNKNOWN;
  1355. /* RAW? */
  1356. break;
  1357. }
  1358. if(rc < PSF_E_NOERROR)
  1359. return rc;
  1360. psf_files[i] = sfdat;
  1361. return i;
  1362. }
  1363. /* snd close: automatically completes PEAK data when writing */
  1364. /* return 0 for success */
  1365. int psf_sndClose(int sfd)
  1366. {
  1367. int rc = PSF_E_NOERROR;
  1368. PSFFILE *sfdat;
  1369. if(sfd < 0 || sfd > psf_maxfiles)
  1370. return PSF_E_BADARG;
  1371. sfdat = psf_files[sfd];
  1372. #ifdef _DEBUG
  1373. assert(sfdat->file);
  1374. assert(sfdat->filename);
  1375. #endif
  1376. if(sfdat==NULL || sfdat->file==NULL)
  1377. return PSF_E_BADARG;
  1378. if(!sfdat->isRead){
  1379. switch(sfdat->riff_format){
  1380. case(PSF_STDWAVE):
  1381. case(PSF_WAVE_EX):
  1382. rc = wavUpdate(sfdat);
  1383. break;
  1384. case(PSF_AIFF):
  1385. case(PSF_AIFC):
  1386. rc = aiffUpdate(sfdat);
  1387. break;
  1388. default:
  1389. rc = PSF_E_CANT_CLOSE;
  1390. break;
  1391. }
  1392. }
  1393. if(psf_release_file(sfdat))
  1394. rc = PSF_E_CANT_CLOSE;
  1395. else {
  1396. free(sfdat);
  1397. psf_files[sfd]= NULL;
  1398. }
  1399. return rc;
  1400. }
  1401. /* write floats (multi-channel) framebuf to whichever target format. tracks PEAK data.*/
  1402. /* bend over backwards not to modify source data */
  1403. /* returns nFrames, or errval < 0 */
  1404. int psf_sndWriteFloatFrames(int sfd, const float *buf, DWORD nFrames)
  1405. {
  1406. int chans,lsamp;
  1407. DWORD i;
  1408. int j,do_reverse;
  1409. const float *pbuf = buf;
  1410. float fsamp,absfsamp;
  1411. int do_shift = 1;
  1412. PSFFILE *sfdat;
  1413. SND_SAMP s_samp;
  1414. if(sfd < 0 || sfd > psf_maxfiles)
  1415. return PSF_E_BADARG;
  1416. sfdat = psf_files[sfd];
  1417. #ifdef _DEBUG
  1418. assert(sfdat->file);
  1419. assert(sfdat->filename);
  1420. #endif
  1421. if(buf==NULL)
  1422. return PSF_E_BADARG;
  1423. if(nFrames == 0)
  1424. return nFrames;
  1425. if(sfdat->isRead)
  1426. return PSF_E_FILE_READONLY;
  1427. chans = sfdat->fmt.Format.nChannels;
  1428. switch(sfdat->riff_format){
  1429. case(PSF_STDWAVE):
  1430. case(PSF_WAVE_EX):
  1431. do_reverse = (sfdat->is_little_endian ? 0 : 1 );
  1432. do_shift = 1;
  1433. break;
  1434. case(PSF_AIFF):
  1435. case(PSF_AIFC):
  1436. do_reverse = (sfdat->is_little_endian ? 1 : 0 );
  1437. do_shift = 0;
  1438. break;
  1439. default:
  1440. return PSF_E_UNSUPPORTED;
  1441. }
  1442. if(sfdat->lastop == PSF_OP_READ)
  1443. fflush(sfdat->file);
  1444. switch(sfdat->samptype){
  1445. case(PSF_SAMP_IEEE_FLOAT):
  1446. if(do_reverse){
  1447. for(i=0; i < nFrames; i++){
  1448. for(j=0;j < chans; j++) {
  1449. fsamp = *pbuf++;
  1450. if(sfdat->clip_floats){
  1451. fsamp = min(fsamp,1.0f);
  1452. fsamp = max(fsamp,-1.0f);
  1453. }
  1454. absfsamp = (float) fabs((double)fsamp);
  1455. if(sfdat->pPeaks && (sfdat->pPeaks[j].val < absfsamp)){
  1456. sfdat->pPeaks[j].pos = sfdat->nFrames + i;
  1457. sfdat->pPeaks[j].val = absfsamp;
  1458. }
  1459. // lsamp = * (int *) pbuf++;
  1460. s_samp.fsamp = fsamp;
  1461. lsamp = s_samp.lsamp;
  1462. lsamp = REVDWBYTES(lsamp);
  1463. if(wavDoWrite(sfdat,(char *) &lsamp,sizeof(int))){
  1464. DBGFPRINTF((stderr, "wavOpenWrite: write error\n"));
  1465. return PSF_E_CANT_WRITE;
  1466. }
  1467. }
  1468. }
  1469. }
  1470. else {
  1471. for(i=0; i < nFrames; i++, pbuf += chans){
  1472. for(j=0;j < chans; j++) {
  1473. fsamp = pbuf[j];
  1474. if(sfdat->clip_floats){
  1475. fsamp = min(fsamp,1.0f);
  1476. fsamp = max(fsamp,-1.0f);
  1477. }
  1478. absfsamp = (float)fabs((double)fsamp);
  1479. if(sfdat->pPeaks && (sfdat->pPeaks[j].val < absfsamp)){
  1480. sfdat->pPeaks[j].pos = sfdat->nFrames + i;
  1481. sfdat->pPeaks[j].val = absfsamp;
  1482. }
  1483. }
  1484. }
  1485. if(wavDoWrite(sfdat,(char *)buf,nFrames * chans * sizeof(float))){
  1486. DBGFPRINTF((stderr, "wavOpenWrite: write error\n"));
  1487. return PSF_E_CANT_WRITE;
  1488. }
  1489. }
  1490. break;
  1491. case(PSF_SAMP_16):
  1492. /* TODO: optimise all this with func pointers etc */
  1493. if(do_reverse){
  1494. short ssamp;
  1495. for(i=0; i < nFrames; i++){
  1496. for(j=0;j < chans; j++) {
  1497. fsamp = *buf++;
  1498. /* clip now! we may have a flag to rescale first...one day */
  1499. fsamp = min(fsamp,dclip16);
  1500. fsamp = max(fsamp,-dclip16);
  1501. absfsamp = (float) fabs((double)fsamp);
  1502. if(sfdat->pPeaks && (sfdat->pPeaks[j].val < absfsamp)){
  1503. sfdat->pPeaks[j].pos = sfdat->nFrames + i;
  1504. sfdat->pPeaks[j].val = absfsamp;
  1505. }
  1506. if(sfdat->dithertype == PSF_DITHER_TPDF)
  1507. ssamp = (short) psf_round(fsamp * 32766.0 + 2.0 * trirand());
  1508. else
  1509. ssamp = (short) psf_round(fsamp * MAX_16BIT);
  1510. ssamp = (short) REVWBYTES(ssamp);
  1511. if( wavDoWrite(sfdat,(char *) &ssamp,sizeof(short))){
  1512. DBGFPRINTF((stderr, "wavOpenWrite: write error\n"));
  1513. return PSF_E_CANT_WRITE;
  1514. }
  1515. }
  1516. }
  1517. }
  1518. else {
  1519. short ssamp;
  1520. for(i=0; i < nFrames; i++, buf += chans){
  1521. for(j=0;j < chans; j++) {
  1522. fsamp = buf[j];
  1523. /* clip now! we may have a flag to rescale first...one day */
  1524. fsamp = min(fsamp,dclip16);
  1525. fsamp = max(fsamp,-dclip16);
  1526. absfsamp = (float) fabs((double)fsamp);
  1527. if(sfdat->pPeaks && (sfdat->pPeaks[j].val < absfsamp)){
  1528. sfdat->pPeaks[j].pos = sfdat->nFrames + i;
  1529. sfdat->pPeaks[j].val = absfsamp;
  1530. }
  1531. if(sfdat->dithertype == PSF_DITHER_TPDF)
  1532. ssamp = (short) psf_round(fsamp * 32766.0 + 2.0 * trirand());
  1533. else
  1534. ssamp = (short) psf_round(fsamp * MAX_16BIT);
  1535. if(wavDoWrite(sfdat,(char *) &ssamp,sizeof(short))){
  1536. DBGFPRINTF((stderr, "wavOpenWrite: write error\n"));
  1537. return PSF_E_CANT_WRITE;
  1538. }
  1539. }
  1540. }
  1541. }
  1542. break;
  1543. case(PSF_SAMP_24):
  1544. if(do_reverse){
  1545. for(i=0; i < nFrames; i++){
  1546. for(j=0;j < chans; j++) {
  1547. fsamp = *buf++;
  1548. /* clip now! we may have a flag to rescale first...one day */
  1549. fsamp = min(fsamp,dclip24);
  1550. fsamp = max(fsamp,-dclip24);
  1551. absfsamp = (float) fabs((double)fsamp);
  1552. if(sfdat->pPeaks && (sfdat->pPeaks[j].val < absfsamp)){
  1553. sfdat->pPeaks[j].pos = sfdat->nFrames + i;
  1554. sfdat->pPeaks[j].val = absfsamp;
  1555. }
  1556. lsamp = psf_round(fsamp * (MAX_32BIT));
  1557. lsamp = REVDWBYTES(lsamp);
  1558. if(do_shift){
  1559. if(sfdat->is_little_endian)
  1560. lsamp >>= 8;
  1561. else
  1562. lsamp <<= 8;
  1563. }
  1564. if( wavDoWrite(sfdat,(char *) &lsamp,3)){
  1565. DBGFPRINTF((stderr, "wavOpenWrite: write error\n"));
  1566. return PSF_E_CANT_WRITE;
  1567. }
  1568. }
  1569. }
  1570. }
  1571. else {
  1572. for(i=0; i < nFrames; i++, buf += chans){
  1573. for(j=0;j < chans; j++) {
  1574. fsamp = buf[j];
  1575. /* clip now! we may have a flag to rescale first...one day */
  1576. fsamp = min(fsamp,dclip24);
  1577. fsamp = max(fsamp,-dclip24);
  1578. absfsamp = (float) fabs((double)fsamp);
  1579. if(sfdat->pPeaks && (sfdat->pPeaks[j].val < absfsamp)){
  1580. sfdat->pPeaks[j].pos = sfdat->nFrames + i;
  1581. sfdat->pPeaks[j].val = absfsamp;
  1582. }
  1583. lsamp = psf_round(fsamp * (MAX_32BIT));
  1584. if(do_shift){
  1585. if(sfdat->is_little_endian)
  1586. lsamp >>= 8;
  1587. else
  1588. lsamp <<= 8;
  1589. }
  1590. if(wavDoWrite(sfdat,(char *) &lsamp,3)){
  1591. DBGFPRINTF((stderr, "wavOpenWrite: write error\n"));
  1592. return PSF_E_CANT_WRITE;
  1593. }
  1594. }
  1595. }
  1596. }
  1597. break;
  1598. case(PSF_SAMP_32):
  1599. if(do_reverse){
  1600. for(i=0; i < nFrames; i++){
  1601. for(j=0;j < chans; j++) {
  1602. fsamp = *buf++;
  1603. /* clip now! we may have a flag to rescale first...one day */
  1604. fsamp = min(fsamp,dclip32);
  1605. fsamp = max(fsamp,-dclip32);
  1606. absfsamp = (float) fabs((double)fsamp);
  1607. if(sfdat->pPeaks && (sfdat->pPeaks[j].val < absfsamp)){
  1608. sfdat->pPeaks[j].pos = sfdat->nFrames + i;
  1609. sfdat->pPeaks[j].val = absfsamp;
  1610. }
  1611. lsamp = psf_round(fsamp * (MAX_32BIT));
  1612. lsamp = REVDWBYTES(lsamp);
  1613. if( wavDoWrite(sfdat,(char *) &lsamp,sizeof(int))){
  1614. DBGFPRINTF((stderr, "wavOpenWrite: write error\n"));
  1615. return PSF_E_CANT_WRITE;
  1616. }
  1617. }
  1618. }
  1619. }
  1620. else {
  1621. for(i=0; i < nFrames; i++, buf += chans){
  1622. for(j=0;j < chans; j++) {
  1623. fsamp = buf[j];
  1624. /* clip now! we may have a flag to rescale first...one day */
  1625. fsamp = min(fsamp,dclip32);
  1626. fsamp = max(fsamp,-dclip32);
  1627. absfsamp = (float) fabs((double)fsamp);
  1628. if(sfdat->pPeaks && (sfdat->pPeaks[j].val < absfsamp)){
  1629. sfdat->pPeaks[j].pos = sfdat->nFrames + i;
  1630. sfdat->pPeaks[j].val = absfsamp;
  1631. }
  1632. lsamp = psf_round(fsamp * (MAX_32BIT));
  1633. if(wavDoWrite(sfdat,(char *) &lsamp,sizeof(int))){
  1634. DBGFPRINTF((stderr, "wavOpenWrite: write error\n"));
  1635. return PSF_E_CANT_WRITE;
  1636. }
  1637. }
  1638. }
  1639. }
  1640. break;
  1641. default:
  1642. DBGFPRINTF((stderr, "wavOpenWrite: unsupported sample format\n"));
  1643. return PSF_E_UNSUPPORTED;
  1644. }
  1645. POS64(sfdat->lastwritepos) += nFrames;
  1646. sfdat->curframepos = (MYLONG) POS64(sfdat->lastwritepos);
  1647. sfdat->nFrames = max(sfdat->nFrames,(DWORD) POS64(sfdat->lastwritepos));
  1648. /* fflush(sfdat->file); */ /* ? may need this if reading/seeking as well as write, etc */
  1649. return nFrames;
  1650. }
  1651. int psf_sndWriteDoubleFrames(int sfd, const double *buf, DWORD nFrames)
  1652. {
  1653. int chans,lsamp;
  1654. DWORD i;
  1655. int j,do_reverse;
  1656. const double *pbuf = buf;
  1657. float fsamp,absfsamp;
  1658. PSFFILE *sfdat;
  1659. int do_shift = 1;
  1660. SND_SAMP s_samp;
  1661. if(sfd < 0 || sfd > psf_maxfiles)
  1662. return PSF_E_BADARG;
  1663. sfdat = psf_files[sfd];
  1664. #ifdef _DEBUG
  1665. assert(sfdat->file);
  1666. assert(sfdat->filename);
  1667. #endif
  1668. if(buf==NULL)
  1669. return PSF_E_BADARG;
  1670. if(nFrames == 0)
  1671. return nFrames;
  1672. if(sfdat->isRead)
  1673. return PSF_E_FILE_READONLY;
  1674. chans = sfdat->fmt.Format.nChannels;
  1675. switch(sfdat->riff_format){
  1676. case(PSF_STDWAVE):
  1677. case(PSF_WAVE_EX):
  1678. do_reverse = (sfdat->is_little_endian ? 0 : 1 );
  1679. do_shift = 1;
  1680. break;
  1681. case(PSF_AIFF):
  1682. case(PSF_AIFC):
  1683. do_reverse = (sfdat->is_little_endian ? 1 : 0 );
  1684. do_shift = 0;
  1685. break;
  1686. default:
  1687. return PSF_E_UNSUPPORTED;
  1688. }
  1689. if(sfdat->lastop == PSF_OP_READ)
  1690. fflush(sfdat->file);
  1691. switch(sfdat->samptype){
  1692. case(PSF_SAMP_IEEE_FLOAT):
  1693. if(do_reverse){
  1694. for(i=0; i < nFrames; i++){
  1695. for(j=0;j < chans; j++) {
  1696. fsamp = (float) *pbuf++;
  1697. if(sfdat->clip_floats){
  1698. fsamp = min(fsamp,1.0f);
  1699. fsamp = max(fsamp,-1.0f);
  1700. }
  1701. absfsamp = (float) fabs((double)fsamp);
  1702. if(sfdat->pPeaks && (sfdat->pPeaks[j].val < absfsamp)){
  1703. sfdat->pPeaks[j].pos = sfdat->nFrames + i;
  1704. sfdat->pPeaks[j].val = absfsamp;
  1705. }
  1706. s_samp.fsamp = fsamp;
  1707. lsamp = s_samp.lsamp;
  1708. // lsamp = * (int *) &fsamp;
  1709. lsamp = REVDWBYTES(lsamp);
  1710. if(wavDoWrite(sfdat,(char *) &lsamp,sizeof(int))){
  1711. DBGFPRINTF((stderr, "wavOpenWrite: write error\n"));
  1712. return PSF_E_CANT_WRITE;
  1713. }
  1714. }
  1715. }
  1716. }
  1717. else {
  1718. for(i=0; i < nFrames; i++, pbuf += chans){
  1719. for(j=0;j < chans; j++) {
  1720. fsamp = (float) pbuf[j];
  1721. if(sfdat->clip_floats){
  1722. fsamp = min(fsamp,1.0f);
  1723. fsamp = max(fsamp,-1.0f);
  1724. }
  1725. if(wavDoWrite(sfdat,(char*)&fsamp,sizeof(float))){
  1726. DBGFPRINTF((stderr, "wavOpenWrite: write error\n"));
  1727. return PSF_E_CANT_WRITE;
  1728. }
  1729. absfsamp = (float)fabs((double)fsamp);
  1730. if(sfdat->pPeaks && (sfdat->pPeaks[j].val < absfsamp)){
  1731. sfdat->pPeaks[j].pos = sfdat->nFrames + i;
  1732. sfdat->pPeaks[j].val = absfsamp;
  1733. }
  1734. }
  1735. }
  1736. }
  1737. break;
  1738. case(PSF_SAMP_16):
  1739. /* TODO: optimise all this with func pointers etc */
  1740. if(do_reverse){
  1741. short ssamp;
  1742. for(i=0; i < nFrames; i++){
  1743. for(j=0;j < chans; j++) {
  1744. fsamp = (float) *buf++;
  1745. /* clip now! we may have a flag to rescale first...one day */
  1746. fsamp = min(fsamp,dclip16);
  1747. fsamp = max(fsamp,-dclip16);
  1748. absfsamp = (float) fabs((double)fsamp);
  1749. if(sfdat->pPeaks && (sfdat->pPeaks[j].val < absfsamp)){
  1750. sfdat->pPeaks[j].pos = sfdat->nFrames + i;
  1751. sfdat->pPeaks[j].val = absfsamp;
  1752. }
  1753. if(sfdat->dithertype == PSF_DITHER_TPDF)
  1754. ssamp = (short) psf_round(fsamp * 32766.0 + 2.0 * trirand());
  1755. else
  1756. ssamp = (short) psf_round(fsamp * MAX_16BIT);
  1757. ssamp = (short) REVWBYTES(ssamp);
  1758. if( wavDoWrite(sfdat,(char *) &ssamp,sizeof(short))){
  1759. DBGFPRINTF((stderr, "wavOpenWrite: write error\n"));
  1760. return PSF_E_CANT_WRITE;
  1761. }
  1762. }
  1763. }
  1764. }
  1765. else {
  1766. short ssamp;
  1767. for(i=0; i < nFrames; i++, buf += chans){
  1768. for(j=0;j < chans; j++) {
  1769. fsamp = (float) buf[j];
  1770. /* clip now! we may have a flag to rescale first...one day */
  1771. fsamp = min(fsamp,dclip16);
  1772. fsamp = max(fsamp,-dclip16);
  1773. absfsamp = (float) fabs((double)fsamp);
  1774. if(sfdat->pPeaks && (sfdat->pPeaks[j].val < absfsamp)){
  1775. sfdat->pPeaks[j].pos = sfdat->nFrames + i;
  1776. sfdat->pPeaks[j].val = absfsamp;
  1777. }
  1778. if(sfdat->dithertype == PSF_DITHER_TPDF)
  1779. ssamp = (short) psf_round(fsamp * 32766.0 + 2.0 * trirand());
  1780. else
  1781. ssamp = (short) psf_round(fsamp * MAX_16BIT);
  1782. if(wavDoWrite(sfdat,(char *) &ssamp,sizeof(short))){
  1783. DBGFPRINTF((stderr, "wavOpenWrite: write error\n"));
  1784. return PSF_E_CANT_WRITE;
  1785. }
  1786. }
  1787. }
  1788. }
  1789. break;
  1790. case(PSF_SAMP_24):
  1791. if(do_reverse){
  1792. for(i=0; i < nFrames; i++){
  1793. for(j=0;j < chans; j++) {
  1794. fsamp =(float) *buf++;
  1795. /* clip now! we may have a flag to rescale first...one day */
  1796. fsamp = min(fsamp,dclip24);
  1797. fsamp = max(fsamp,-dclip24);
  1798. absfsamp = (float) fabs((double)fsamp);
  1799. if(sfdat->pPeaks && (sfdat->pPeaks[j].val < absfsamp)){
  1800. sfdat->pPeaks[j].pos = sfdat->nFrames + i;
  1801. sfdat->pPeaks[j].val = absfsamp;
  1802. }
  1803. lsamp = psf_round(fsamp * MAX_32BIT);
  1804. lsamp = REVDWBYTES(lsamp);
  1805. if(do_shift){
  1806. if(sfdat->is_little_endian)
  1807. lsamp >>= 8;
  1808. else
  1809. lsamp <<= 8;
  1810. }
  1811. if( wavDoWrite(sfdat,(char *) &lsamp,3)){
  1812. DBGFPRINTF((stderr, "wavOpenWrite: write error\n"));
  1813. return PSF_E_CANT_WRITE;
  1814. }
  1815. }
  1816. }
  1817. }
  1818. else {
  1819. for(i=0; i < nFrames; i++, buf += chans){
  1820. for(j=0;j < chans; j++) {
  1821. fsamp = (float) buf[j];
  1822. /* clip now! we may have a flag to rescale first...one day */
  1823. fsamp = min(fsamp,dclip24);
  1824. fsamp = max(fsamp,-dclip24);
  1825. absfsamp = (float) fabs((double)fsamp);
  1826. if(sfdat->pPeaks && (sfdat->pPeaks[j].val < absfsamp)){
  1827. sfdat->pPeaks[j].pos = sfdat->nFrames + i;
  1828. sfdat->pPeaks[j].val = absfsamp;
  1829. }
  1830. lsamp = psf_round(fsamp * MAX_32BIT);
  1831. if(do_shift){
  1832. if(sfdat->is_little_endian)
  1833. lsamp >>= 8;
  1834. else
  1835. lsamp <<= 8;
  1836. }
  1837. if(wavDoWrite(sfdat,(char *) &lsamp,3)){
  1838. DBGFPRINTF((stderr, "wavOpenWrite: write error\n"));
  1839. return PSF_E_CANT_WRITE;
  1840. }
  1841. }
  1842. }
  1843. }
  1844. break;
  1845. case(PSF_SAMP_32):
  1846. if(do_reverse){
  1847. for(i=0; i < nFrames; i++){
  1848. for(j=0;j < chans; j++) {
  1849. fsamp = (float) *buf++;
  1850. /* clip now! we may have a flag to rescale first...one day */
  1851. fsamp = min(fsamp,dclip32);
  1852. fsamp = max(fsamp,-dclip32);
  1853. absfsamp = (float) fabs((double)fsamp);
  1854. if(sfdat->pPeaks && (sfdat->pPeaks[j].val < absfsamp)){
  1855. sfdat->pPeaks[j].pos = sfdat->nFrames + i;
  1856. sfdat->pPeaks[j].val = absfsamp;
  1857. }
  1858. lsamp = psf_round(fsamp * MAX_32BIT);
  1859. lsamp = REVDWBYTES(lsamp);
  1860. if( wavDoWrite(sfdat,(char *) &lsamp,sizeof(int))){
  1861. DBGFPRINTF((stderr, "wavOpenWrite: write error\n"));
  1862. return PSF_E_CANT_WRITE;
  1863. }
  1864. }
  1865. }
  1866. }
  1867. else {
  1868. for(i=0; i < nFrames; i++, buf += chans){
  1869. for(j=0;j < chans; j++) {
  1870. fsamp = (float) buf[j];
  1871. /* clip now! we may have a flag to rescale first...one day */
  1872. fsamp = min(fsamp,dclip32);
  1873. fsamp = max(fsamp,-dclip32);
  1874. absfsamp = (float) fabs((double)fsamp);
  1875. if(sfdat->pPeaks && (sfdat->pPeaks[j].val < absfsamp)){
  1876. sfdat->pPeaks[j].pos = sfdat->nFrames + i;
  1877. sfdat->pPeaks[j].val = absfsamp;
  1878. }
  1879. lsamp = psf_round(fsamp * MAX_32BIT);
  1880. if(wavDoWrite(sfdat,(char *) &lsamp,sizeof(int))){
  1881. DBGFPRINTF((stderr, "wavOpenWrite: write error\n"));
  1882. return PSF_E_CANT_WRITE;
  1883. }
  1884. }
  1885. }
  1886. }
  1887. break;
  1888. default:
  1889. DBGFPRINTF((stderr, "wavOpenWrite: unsupported sample format\n"));
  1890. return PSF_E_UNSUPPORTED;
  1891. }
  1892. POS64(sfdat->lastwritepos) += nFrames;
  1893. /* keep this as is for now, don't optimize, work in progress, etc */
  1894. sfdat->curframepos = (DWORD) POS64(sfdat->lastwritepos);
  1895. sfdat->nFrames = max(sfdat->nFrames, ((DWORD) POS64(sfdat->lastwritepos)));
  1896. /* fflush(sfdat->file);*/ /* ? need this if reading/seeking as well as write, etc */
  1897. return nFrames;
  1898. }
  1899. /* deprecated! Do not use. */
  1900. int psf_sndWriteShortFrames(int sfd, const short *buf, DWORD nFrames)
  1901. {
  1902. int chans;
  1903. DWORD i;
  1904. int j;
  1905. PSFFILE *sfdat;
  1906. if(sfd < 0 || sfd > psf_maxfiles)
  1907. return PSF_E_BADARG;
  1908. sfdat = psf_files[sfd];
  1909. #ifdef _DEBUG
  1910. assert(sfdat->file);
  1911. assert(sfdat->filename);
  1912. #endif
  1913. if(buf==NULL)
  1914. return PSF_E_BADARG;
  1915. if(nFrames == 0)
  1916. return nFrames;
  1917. if(sfdat->isRead)
  1918. return PSF_E_FILE_READONLY;
  1919. chans = sfdat->fmt.Format.nChannels;
  1920. /* well, it can't be ~less~ efficient than converting twice! */
  1921. if(!sfdat->is_little_endian){
  1922. short ssamp;
  1923. double fval;
  1924. for(i=0; i < nFrames; i++){
  1925. for(j=0;j < chans; j++) {
  1926. ssamp = *buf++;
  1927. fval = ((double) ssamp / MAX_16BIT);
  1928. if(sfdat->pPeaks && (sfdat->pPeaks[j].val < (float)(fabs(fval)))){
  1929. sfdat->pPeaks[j].pos = sfdat->nFrames + i;
  1930. sfdat->pPeaks[j].val = (float)fval;
  1931. }
  1932. ssamp = (short) REVWBYTES(ssamp);
  1933. if(wavDoWrite(sfdat,(char *) &ssamp,sizeof(short))){
  1934. DBGFPRINTF((stderr, "wavOpenWrite: write error\n"));
  1935. return PSF_E_CANT_WRITE;
  1936. }
  1937. }
  1938. }
  1939. }
  1940. else {
  1941. short ssamp;
  1942. double fval;
  1943. for(i=0; i < nFrames; i++){
  1944. for(j=0;j < chans; j++) {
  1945. ssamp = *buf++;
  1946. fval = ((double) ssamp / MAX_16BIT);
  1947. if(sfdat->pPeaks && (sfdat->pPeaks[j].val < (float)(fabs(fval)))){
  1948. sfdat->pPeaks[j].pos = sfdat->nFrames + i;
  1949. sfdat->pPeaks[j].val = (float)fval;
  1950. }
  1951. if(wavDoWrite(sfdat,(char *) &ssamp,sizeof(short))){
  1952. DBGFPRINTF((stderr, "wavOpenWrite: write error\n"));
  1953. return PSF_E_CANT_WRITE;
  1954. }
  1955. }
  1956. }
  1957. }
  1958. POS64(sfdat->lastwritepos) += nFrames;
  1959. sfdat->nFrames = max(sfdat->nFrames, ((DWORD) POS64(sfdat->lastwritepos)));
  1960. fflush(sfdat->file);
  1961. return nFrames;
  1962. }
  1963. /******** READ ***********/
  1964. static int wavReadHeader(PSFFILE *sfdat)
  1965. {
  1966. DWORD tag,version,peaktime;
  1967. DWORD size;
  1968. WORD cbSize;
  1969. fpos_t bytepos;
  1970. if(sfdat==NULL || sfdat->file == NULL)
  1971. return PSF_E_BADARG;
  1972. if(wavDoRead(sfdat,(char *)&tag,sizeof(DWORD))
  1973. || wavDoRead(sfdat,(char *) &size,sizeof(DWORD)))
  1974. return PSF_E_CANT_READ;
  1975. if(!sfdat->is_little_endian)
  1976. size = REVDWBYTES(size);
  1977. else
  1978. tag = REVDWBYTES(tag);
  1979. if(tag != TAG('R','I','F','F'))
  1980. return PSF_E_NOT_WAVE;
  1981. if(size < (sizeof(WAVEFORMAT) + 3 * sizeof(WORD)))
  1982. return PSF_E_BAD_FORMAT;
  1983. if(wavDoRead(sfdat,(char *)&tag,sizeof(DWORD)))
  1984. return PSF_E_CANT_READ;
  1985. if(sfdat->is_little_endian)
  1986. tag = REVDWBYTES(tag);
  1987. if(tag != TAG('W','A','V','E'))
  1988. return PSF_E_NOT_WAVE;
  1989. for(;;){
  1990. if(wavDoRead(sfdat,(char *)&tag,sizeof(DWORD))
  1991. || wavDoRead(sfdat,(char *) &size,sizeof(DWORD)))
  1992. return PSF_E_CANT_READ;
  1993. if(!sfdat->is_little_endian)
  1994. size = REVDWBYTES(size);
  1995. else
  1996. tag = REVDWBYTES(tag);
  1997. switch(tag){
  1998. case(TAG('f','m','t',' ')):
  1999. if( size < sizeof(WAVEFORMAT))
  2000. return PSF_E_BAD_FORMAT;
  2001. if(size > sizeof_WFMTEX)
  2002. return PSF_E_UNSUPPORTED;
  2003. if(fgetpos(sfdat->file,&bytepos))
  2004. return PSF_E_CANT_SEEK;
  2005. sfdat->fmtoffset = bytepos;
  2006. if(wavDoRead(sfdat,(char *)&(sfdat->fmt.Format),sizeof(WAVEFORMAT))){
  2007. return PSF_E_CANT_READ;
  2008. }
  2009. if(!sfdat->is_little_endian)
  2010. fmtSwapBytes(sfdat);
  2011. /* calling function decides if format is supported*/
  2012. if(size > sizeof(WAVEFORMAT)) {
  2013. if(wavDoRead(sfdat,(char*)&cbSize,sizeof(WORD)))
  2014. return PSF_E_CANT_READ;
  2015. if(!sfdat->is_little_endian)
  2016. cbSize = (WORD) REVWBYTES(cbSize);
  2017. if(cbSize != (WORD)0) {
  2018. if(sfdat->fmt.Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE){
  2019. if(cbSize != 22)
  2020. return PSF_E_BAD_FORMAT;
  2021. sfdat->riff_format = PSF_WAVE_EX;
  2022. }
  2023. }
  2024. else {
  2025. int fmtsize = 18;
  2026. /* cbSize = 0: has to be 18-byte WAVEFORMATEX */
  2027. if((sfdat->fmt.Format.wFormatTag == WAVE_FORMAT_PCM
  2028. || sfdat->fmt.Format.wFormatTag == WAVE_FORMAT_IEEE_FLOAT))
  2029. sfdat->riff_format = PSF_STDWAVE;
  2030. else /* some horribly mangled format! */
  2031. return PSF_E_BAD_FORMAT;
  2032. /* Feb 2010: hack to handle bad files with overlarge fmt chunk! */
  2033. while (size > fmtsize){
  2034. char dummy;
  2035. if(wavDoRead(sfdat,(char*)&dummy,sizeof(char)))
  2036. return PSF_E_CANT_READ;
  2037. fmtsize++;
  2038. strcpy(sfdat->warnstring,"fmt chunk too large for format");
  2039. sfdat->illformed = 1;
  2040. }
  2041. }
  2042. sfdat->fmt.Format.cbSize = cbSize;
  2043. /* fill in as if basic Format; may change later from WAVE-EX */
  2044. sfdat->fmt.Samples.wValidBitsPerSample = sfdat->fmt.Format.wBitsPerSample;
  2045. sfdat->fmt.dwChannelMask = 0;
  2046. /* get rest of WAVE-EX, if we have it */
  2047. if(sfdat->fmt.Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE){
  2048. WORD validbits;
  2049. DWORD chmask;
  2050. if(wavDoRead(sfdat,(char *) &validbits,sizeof(WORD)))
  2051. return PSF_E_CANT_READ;
  2052. if(!sfdat->is_little_endian)
  2053. sfdat->fmt.Samples.wValidBitsPerSample = (WORD) REVWBYTES(validbits);
  2054. if(wavDoRead(sfdat,(char *) &chmask,sizeof(DWORD)))
  2055. return PSF_E_CANT_READ;
  2056. sfdat->fmt.dwChannelMask = chmask; /* RWD OCT 2009 ! */
  2057. if(!sfdat->is_little_endian)
  2058. sfdat->fmt.dwChannelMask = REVDWBYTES(chmask);
  2059. /* OCT 2009 identify speaker layout */
  2060. sfdat->chformat = get_speakerlayout(sfdat->fmt.dwChannelMask,sfdat->fmt.Format.nChannels);
  2061. if(wavDoRead(sfdat,(char *) &(sfdat->fmt.SubFormat),sizeof(GUID)))
  2062. return PSF_E_CANT_READ;
  2063. if(!sfdat->is_little_endian){
  2064. sfdat->fmt.SubFormat.Data1 = REVDWBYTES(sfdat->fmt.SubFormat.Data1);
  2065. sfdat->fmt.SubFormat.Data2 = (WORD) REVWBYTES(sfdat->fmt.SubFormat.Data2);
  2066. sfdat->fmt.SubFormat.Data3 = (WORD) REVWBYTES(sfdat->fmt.SubFormat.Data3);
  2067. }
  2068. /* if we get a good GUID, this sets up sfdat with samplesize info */
  2069. if(check_guid(sfdat))
  2070. return PSF_E_UNSUPPORTED;
  2071. }
  2072. }
  2073. break;
  2074. case(TAG('P','E','A','K')):
  2075. /* I SHOULD report an error if this is after data chunk;
  2076. but I suppose innocent users (e.g. of Cubase ) will grumble... */
  2077. if(wavDoRead(sfdat,(char *) &version,sizeof(DWORD)))
  2078. return PSF_E_CANT_READ;
  2079. if(!sfdat->is_little_endian)
  2080. version = REVDWBYTES(version);
  2081. if(version != 1) {
  2082. DBGFPRINTF((stderr, "Unexpected version level for PEAK chunk!\n"));
  2083. return PSF_E_UNSUPPORTED;
  2084. }
  2085. if(size != (2 * sizeof(DWORD) + sizeof(PSF_CHPEAK) * sfdat->fmt.Format.nChannels)) {
  2086. DBGFPRINTF((stderr, "\nBad size for PEAK chunk\n"));
  2087. return PSF_E_BAD_FORMAT;
  2088. }
  2089. if(fgetpos(sfdat->file,&bytepos))
  2090. return PSF_E_CANT_SEEK;
  2091. sfdat->peakoffset = bytepos;
  2092. if(wavDoRead(sfdat,(char *) &peaktime,sizeof(DWORD))){
  2093. DBGFPRINTF((stderr,"Error reading PEAK time\n"));
  2094. return PSF_E_CANT_READ;
  2095. }
  2096. if(!sfdat->is_little_endian)
  2097. peaktime = REVDWBYTES(peaktime);
  2098. sfdat->peaktime = (time_t) peaktime;
  2099. sfdat->pPeaks = (PSF_CHPEAK *) malloc(sizeof(PSF_CHPEAK) * sfdat->fmt.Format.nChannels);
  2100. if(sfdat->pPeaks==NULL){
  2101. DBGFPRINTF((stderr, "wavOpenWrite: no memory for peak data\n"));
  2102. return PSF_E_NOMEM;
  2103. }
  2104. if(wavDoRead(sfdat,(char *) sfdat->pPeaks,sizeof(PSF_CHPEAK) * sfdat->fmt.Format.nChannels)) {
  2105. DBGFPRINTF((stderr,"Error reading PEAK peak data\n"));
  2106. return PSF_E_CANT_READ;
  2107. }
  2108. if(!sfdat->is_little_endian){
  2109. DWORD *pBlock;
  2110. int i;
  2111. pBlock = (DWORD *) (sfdat->pPeaks);
  2112. for(i=0;i < sfdat->fmt.Format.nChannels * 2; i++)
  2113. pBlock[i] = REVDWBYTES(pBlock[i]);
  2114. }
  2115. break;
  2116. case(TAG('d','a','t','a')):
  2117. if(fgetpos(sfdat->file,&bytepos))
  2118. return PSF_E_CANT_SEEK;
  2119. sfdat->dataoffset = bytepos;
  2120. if(POS64(sfdat->fmtoffset)==0)
  2121. return PSF_E_BAD_FORMAT;
  2122. sfdat->nFrames = size / sfdat->fmt.Format.nBlockAlign;
  2123. /* get rescale factor if available */
  2124. /* NB in correct format, val is always >= 0.0 */
  2125. if(sfdat->pPeaks && POS64(sfdat->peakoffset) != 0){
  2126. float fac = 0.0f;
  2127. int i;
  2128. for(i=0;i < sfdat->fmt.Format.nChannels; i++)
  2129. fac = max(fac,sfdat->pPeaks[i].val);
  2130. if(fac > 1.0f)
  2131. sfdat->rescale_fac = 1.0f / fac;
  2132. }
  2133. /* set sampletype */
  2134. switch(sfdat->fmt.Format.wFormatTag){
  2135. case(WAVE_FORMAT_IEEE_FLOAT):
  2136. sfdat->samptype = PSF_SAMP_IEEE_FLOAT;
  2137. if(sfdat->fmt.Format.wBitsPerSample != 32) {
  2138. /*return PSF_E_BAD_FORMAT;*/
  2139. if(sfdat->fmt.Format.wBitsPerSample == sizeof(double))
  2140. return PSF_E_UNSUPPORTED; /*RWD 26:10:2002 allow possibility of doubles! */
  2141. else
  2142. return PSF_E_BAD_FORMAT;
  2143. }
  2144. sfdat->lastop = PSF_OP_READ;
  2145. /* RWD 26:10:2002 IMPORTANT BUGFIX! */
  2146. return PSF_E_NOERROR;
  2147. case(WAVE_FORMAT_PCM):
  2148. case(WAVE_FORMAT_EXTENSIBLE):
  2149. switch(sfdat->fmt.Format.wBitsPerSample){
  2150. case(8):
  2151. sfdat->samptype = PSF_SAMP_8;
  2152. break;
  2153. case(16):
  2154. sfdat->samptype = PSF_SAMP_16;
  2155. break;
  2156. case(24):
  2157. sfdat->samptype = PSF_SAMP_24;
  2158. break;
  2159. case(32):
  2160. sfdat->samptype = PSF_SAMP_32;
  2161. /* RWD 03/20: fix fault parsing floats amb files */
  2162. if(sfdat->chformat == MC_BFMT) {
  2163. if(compare_guids(&(sfdat->fmt.SubFormat),&SUBTYPE_AMBISONIC_B_FORMAT_IEEE_FLOAT)) {
  2164. sfdat->samptype = PSF_SAMP_IEEE_FLOAT;
  2165. }
  2166. else if(!compare_guids(&(sfdat->fmt.SubFormat),&SUBTYPE_AMBISONIC_B_FORMAT_PCM)) {
  2167. sfdat->samptype = PSF_SAMP_UNKNOWN;
  2168. }
  2169. }
  2170. break;
  2171. default:
  2172. sfdat->samptype = PSF_SAMP_UNKNOWN;
  2173. break;
  2174. }
  2175. if(sfdat->samptype == PSF_SAMP_UNKNOWN)
  2176. return PSF_E_UNSUPPORTED;
  2177. sfdat->lastop = PSF_OP_READ;
  2178. return PSF_E_NOERROR;
  2179. }
  2180. default:
  2181. //RWD Apr 2019
  2182. // handle odd chunk sizes
  2183. size = (size+1)&~1;
  2184. /* unknown chunk - skip */
  2185. if(fseek(sfdat->file,size,SEEK_CUR))
  2186. return PSF_E_CANT_READ;
  2187. break;
  2188. }
  2189. }
  2190. }
  2191. static int aiffReadHeader(PSFFILE *sfdat)
  2192. {
  2193. DWORD tag,version,peaktime,remain,offset,blocksize;
  2194. int have_comm =0,have_ssnd =0;
  2195. DWORD dwData,size;
  2196. unsigned char ieee[10];
  2197. WORD wData;
  2198. fpos_t bytepos;
  2199. if(sfdat==NULL || sfdat->file == NULL)
  2200. return PSF_E_BADARG;
  2201. if(wavDoRead(sfdat,(char *)&tag,sizeof(DWORD))
  2202. || wavDoRead(sfdat,(char *) &remain,sizeof(DWORD)))
  2203. return PSF_E_CANT_READ;
  2204. if(sfdat->is_little_endian) {
  2205. remain = REVDWBYTES(remain);
  2206. tag = REVDWBYTES(tag);
  2207. }
  2208. if(tag != TAG('F','O','R','M')){
  2209. DBGFPRINTF((stderr, "file is not AIFF: no PSF chunk\n"));
  2210. return PSF_E_BADARG;
  2211. }
  2212. if(wavDoRead(sfdat,(char *)&tag,sizeof(DWORD)))
  2213. return PSF_E_CANT_READ;
  2214. if(sfdat->is_little_endian)
  2215. tag = REVDWBYTES(tag);
  2216. if(tag != TAG('A','I','F','F')){
  2217. DBGFPRINTF((stderr, "file is not AIFF: no AIFF chunk\n"));
  2218. return PSF_E_BADARG;
  2219. }
  2220. remain -= sizeof(int);
  2221. while(remain > 0){
  2222. if(wavDoRead(sfdat,(char *)&tag,sizeof(DWORD))
  2223. || wavDoRead(sfdat,(char *) &size,sizeof(DWORD)))
  2224. return PSF_E_CANT_READ;
  2225. if(sfdat->is_little_endian) {
  2226. size = REVDWBYTES(size);
  2227. tag = REVDWBYTES(tag);
  2228. }
  2229. remain -=(int)( 2 * sizeof(DWORD));
  2230. switch(tag){
  2231. case(TAG('C','O','M','M')):
  2232. if(size != 18){
  2233. DBGFPRINTF((stderr,"AIFF file has bad size for COMM chunk\n"));
  2234. return PSF_E_BAD_FORMAT;
  2235. }
  2236. if(fgetpos(sfdat->file,&bytepos))
  2237. return PSF_E_CANT_SEEK;
  2238. sfdat->fmtoffset = bytepos;
  2239. if(wavDoRead(sfdat,(char *)&wData,sizeof(WORD)))
  2240. return PSF_E_CANT_READ;
  2241. if(sfdat->is_little_endian)
  2242. wData = (WORD) REVWBYTES(wData);
  2243. sfdat->fmt.Format.nChannels = wData;
  2244. if(wavDoRead(sfdat,(char *)&dwData,sizeof(DWORD)))
  2245. return PSF_E_CANT_READ;
  2246. if(sfdat->is_little_endian)
  2247. dwData = REVDWBYTES(dwData);
  2248. sfdat->nFrames = dwData;
  2249. if(wavDoRead(sfdat,(char *)&wData,sizeof(WORD)))
  2250. return PSF_E_CANT_READ;
  2251. if(sfdat->is_little_endian)
  2252. wData = (WORD) REVWBYTES(wData);
  2253. sfdat->fmt.Format.wBitsPerSample = wData;
  2254. if(wavDoRead(sfdat,ieee,10))
  2255. return PSF_E_CANT_READ;
  2256. sfdat->fmt.Format.nSamplesPerSec = (DWORD)(ieee_80_to_double(ieee));
  2257. /*we have to deduce blockalign, and hence containersize*/
  2258. /* no support (yet) for strange wordsizes such as 20 in 24 */
  2259. switch(sfdat->fmt.Format.wBitsPerSample){
  2260. case(32):
  2261. sfdat->fmt.Format.nBlockAlign = sizeof(int);
  2262. sfdat->samptype = PSF_SAMP_32;
  2263. break;
  2264. case(24):
  2265. sfdat->fmt.Format.nBlockAlign = 3;
  2266. sfdat->samptype = PSF_SAMP_24;
  2267. break;
  2268. case(16):
  2269. sfdat->fmt.Format.nBlockAlign = sizeof(short);
  2270. sfdat->samptype = PSF_SAMP_16;
  2271. break;
  2272. default:
  2273. DBGFPRINTF((stderr, "unsupported sample format for AIFF file\n"));
  2274. return PSF_E_UNSUPPORTED;
  2275. }
  2276. sfdat->fmt.Format.nBlockAlign = (WORD) (sfdat->fmt.Format.nBlockAlign * sfdat->fmt.Format.nChannels);
  2277. remain -= 18;
  2278. have_comm = 1;
  2279. break;
  2280. case (TAG('P','E','A','K')):
  2281. if(!have_comm){
  2282. DBGFPRINTF((stderr, "AIFF file: found PEAK chunk before COMM chunk!\n"));
  2283. return PSF_E_BAD_FORMAT;
  2284. }
  2285. if(size != (2 * sizeof(DWORD) + sizeof(PSF_CHPEAK) * sfdat->fmt.Format.nChannels)){
  2286. DBGFPRINTF((stderr, "AIFF file has bad size for PEAK chunk\n"));
  2287. return PSF_E_BAD_FORMAT;
  2288. }
  2289. if(wavDoRead(sfdat,(char *)&version,sizeof(DWORD))) {
  2290. DBGFPRINTF((stderr,"Error reading PEAK version\n"));
  2291. return PSF_E_CANT_READ;
  2292. }
  2293. if(sfdat->is_little_endian)
  2294. version = REVDWBYTES(version);
  2295. if(version != 1){
  2296. DBGFPRINTF((stderr, "AIFF file has unexpected version level for PEAK chunk!\n"));
  2297. return PSF_E_UNSUPPORTED;
  2298. }
  2299. if(fgetpos(sfdat->file,&bytepos))
  2300. return PSF_E_CANT_SEEK;
  2301. sfdat->peakoffset = bytepos;
  2302. if(wavDoRead(sfdat,(char *) &peaktime,sizeof(DWORD))) {
  2303. DBGFPRINTF((stderr,"Error reading PEAK time\n"));
  2304. return PSF_E_CANT_READ;
  2305. }
  2306. if(sfdat->is_little_endian)
  2307. peaktime = REVDWBYTES(peaktime);
  2308. sfdat->peaktime = (time_t) peaktime;
  2309. sfdat->pPeaks = (PSF_CHPEAK *)malloc(sizeof(PSF_CHPEAK) * sfdat->fmt.Format.nChannels);
  2310. if(sfdat->pPeaks==NULL){
  2311. DBGFPRINTF((stderr, "wavOpenWrite: no memory for peak data\n"));
  2312. return PSF_E_NOMEM;
  2313. }
  2314. if(wavDoRead(sfdat,(char *)(sfdat->pPeaks),sizeof(PSF_CHPEAK) * sfdat->fmt.Format.nChannels)){
  2315. DBGFPRINTF((stderr,"Error reading PEAK peak data\n"));
  2316. return PSF_E_CANT_READ;
  2317. }
  2318. if(sfdat->is_little_endian){
  2319. DWORD *pBlock;
  2320. int i;
  2321. pBlock = (DWORD *) (sfdat->pPeaks);
  2322. for(i=0;i < sfdat->fmt.Format.nChannels * 2; i++)
  2323. pBlock[i] = REVDWBYTES(pBlock[i]);
  2324. }
  2325. remain -= size;
  2326. break;
  2327. case(TAG('S','S','N','D')):
  2328. if(wavDoRead(sfdat,(char *)&offset,sizeof(DWORD))
  2329. || wavDoRead(sfdat,(char *) &blocksize,sizeof(DWORD)))
  2330. return PSF_E_CANT_READ;
  2331. if(sfdat->is_little_endian){
  2332. offset = REVDWBYTES(offset);
  2333. blocksize = REVDWBYTES(blocksize);
  2334. }
  2335. if(fgetpos(sfdat->file,&bytepos))
  2336. return PSF_E_CANT_SEEK;
  2337. sfdat->dataoffset = bytepos;
  2338. POS64(sfdat->dataoffset) += offset;
  2339. sfdat->nFrames = (size - 2* sizeof(DWORD))/ sfdat->fmt.Format.nBlockAlign;
  2340. /* NB for seek: we used up 8 bytes with offset and blocksize */
  2341. /* if we already have COMM, we could finish here! */
  2342. /* TODO! this is still a signed int seek, no good for 4GB */
  2343. if(fseek(sfdat->file,((size - 2* sizeof(DWORD))+1)&~1,SEEK_CUR))
  2344. return PSF_E_CANT_SEEK;
  2345. have_ssnd = 1;
  2346. remain -= (size+1)&~1;
  2347. break;
  2348. /*HARSH! traps linux sox error, for example */
  2349. case(0):
  2350. DBGFPRINTF((stderr, "AIFF file has bad main chunksize\n"));
  2351. return PSF_E_BAD_FORMAT;
  2352. default:
  2353. /* skip all unknown chunks */
  2354. if(fseek(sfdat->file,(size+1)&~1,SEEK_CUR))
  2355. return PSF_E_CANT_SEEK;
  2356. remain -= (size+1)&~1;
  2357. break;
  2358. }
  2359. }
  2360. if(!(have_ssnd && have_comm)){
  2361. DBGFPRINTF((stderr, "AIFF file has missing chunks\n"));
  2362. return PSF_E_BAD_FORMAT;
  2363. }
  2364. /* we have seeked to EOF, so rewind to start of data */
  2365. if(fsetpos(sfdat->file,&sfdat->dataoffset))
  2366. return PSF_E_CANT_SEEK;
  2367. sfdat->curframepos = 0;
  2368. sfdat->riff_format = PSF_AIFF;
  2369. /* get rescale factor if available */
  2370. /* NB in correct format, val is always >= 0.0 */
  2371. if(sfdat->pPeaks && POS64(sfdat->peakoffset) != 0){
  2372. float fac = 0.0f;
  2373. int i;
  2374. for(i=0;i < sfdat->fmt.Format.nChannels; i++)
  2375. fac = max(fac,sfdat->pPeaks[i].val);
  2376. if(fac > 1.0f)
  2377. sfdat->rescale_fac = 1.0f / fac;
  2378. }
  2379. sfdat->lastop = PSF_OP_READ;
  2380. return PSF_E_NOERROR;
  2381. }
  2382. static int aifcReadHeader(PSFFILE *sfdat)
  2383. {
  2384. DWORD tag,version,peaktime,remain,offset,blocksize;
  2385. int have_comm =0,have_ssnd =0,have_fver = 0;
  2386. DWORD dwData,size,aifcver,ID_compression;
  2387. unsigned char ieee[10];
  2388. WORD wData;
  2389. fpos_t bytepos;
  2390. if(sfdat==NULL || sfdat->file == NULL)
  2391. return PSF_E_BADARG;
  2392. if(wavDoRead(sfdat,(char *)&tag,sizeof(DWORD))
  2393. || wavDoRead(sfdat,(char *) &remain,sizeof(DWORD)))
  2394. return PSF_E_CANT_READ;
  2395. if(sfdat->is_little_endian) {
  2396. remain = REVDWBYTES(remain);
  2397. tag = REVDWBYTES(tag);
  2398. }
  2399. if(tag != TAG('F','O','R','M')){
  2400. DBGFPRINTF((stderr, "file is not AIFC: no FORM chunk\n"));
  2401. return PSF_E_BADARG;
  2402. }
  2403. if(wavDoRead(sfdat,(char *)&tag,sizeof(DWORD)))
  2404. return PSF_E_CANT_READ;
  2405. if(sfdat->is_little_endian)
  2406. tag = REVDWBYTES(tag);
  2407. if(tag != TAG('A','I','F','C')){
  2408. DBGFPRINTF((stderr, "file is not AIFC: no AIFC chunk\n"));
  2409. return PSF_E_BADARG;
  2410. }
  2411. remain -= sizeof(DWORD);
  2412. while(remain > 0){
  2413. if(wavDoRead(sfdat,(char *)&tag,sizeof(DWORD))
  2414. || wavDoRead(sfdat,(char *) &size,sizeof(DWORD)))
  2415. return PSF_E_CANT_READ;
  2416. if(sfdat->is_little_endian) {
  2417. size = REVDWBYTES(size);
  2418. tag = REVDWBYTES(tag);
  2419. }
  2420. remain -= 2 * sizeof(DWORD);
  2421. switch(tag){
  2422. case(TAG('F','V','E','R')):
  2423. if(size != sizeof(DWORD)){
  2424. DBGFPRINTF((stderr, "AIFC file has bad size for FVER chunk\n"));
  2425. return PSF_E_BAD_FORMAT;
  2426. }
  2427. if(wavDoRead(sfdat,(char *) &aifcver,sizeof(DWORD)))
  2428. return PSF_E_CANT_READ;
  2429. if(sfdat->is_little_endian)
  2430. aifcver = REVDWBYTES(aifcver);
  2431. remain-= sizeof(DWORD);
  2432. if(aifcver != AIFC_VERSION_1)
  2433. return PSF_E_UNSUPPORTED;
  2434. have_fver = 1;
  2435. break;
  2436. case(TAG('C','O','M','M')):
  2437. if(size < 22) {
  2438. DBGFPRINTF((stderr, "AIFC file has bad size for COMM chunk\n"));
  2439. return PSF_E_BAD_FORMAT;
  2440. }
  2441. if(fgetpos(sfdat->file,&sfdat->fmtoffset))
  2442. return PSF_E_CANT_SEEK;
  2443. if(wavDoRead(sfdat,(char *)&wData,sizeof(WORD)))
  2444. return PSF_E_CANT_READ;
  2445. if(sfdat->is_little_endian)
  2446. wData = (WORD) REVWBYTES(wData);
  2447. sfdat->fmt.Format.nChannels = wData;
  2448. if(wavDoRead(sfdat,(char *)&dwData,sizeof(DWORD)))
  2449. return PSF_E_CANT_READ;
  2450. if(sfdat->is_little_endian)
  2451. dwData = REVDWBYTES(dwData);
  2452. sfdat->nFrames = dwData;
  2453. if(wavDoRead(sfdat,(char *)&wData,sizeof(WORD)))
  2454. return PSF_E_CANT_READ;
  2455. if(sfdat->is_little_endian)
  2456. wData = (WORD) REVWBYTES(wData);
  2457. sfdat->fmt.Format.wBitsPerSample = wData;
  2458. if(wavDoRead(sfdat,ieee,10))
  2459. return PSF_E_CANT_READ;
  2460. sfdat->fmt.Format.nSamplesPerSec = (DWORD)(ieee_80_to_double(ieee));
  2461. /*we have to deduce blockalign, and hence containersize*/
  2462. /* no support for strange wordsizes such as 20 in 24 */
  2463. switch(sfdat->fmt.Format.wBitsPerSample){
  2464. case(32):
  2465. sfdat->fmt.Format.nBlockAlign = sizeof(DWORD);
  2466. sfdat->samptype = PSF_SAMP_32;
  2467. break;
  2468. case(24):
  2469. sfdat->fmt.Format.nBlockAlign = 3;
  2470. sfdat->samptype = PSF_SAMP_24;
  2471. break;
  2472. case(16):
  2473. sfdat->fmt.Format.nBlockAlign = sizeof(short);
  2474. sfdat->samptype = PSF_SAMP_16;
  2475. break;
  2476. default:
  2477. DBGFPRINTF((stderr, "unsupported sample format for AIFC file\n"));
  2478. return PSF_E_UNSUPPORTED;
  2479. }
  2480. sfdat->fmt.Format.nBlockAlign = (WORD) (sfdat->fmt.Format.nBlockAlign * sfdat->fmt.Format.nChannels);
  2481. if(wavDoRead(sfdat,(char *)&ID_compression,sizeof(DWORD))){
  2482. return PSF_E_CANT_READ;
  2483. }
  2484. if(sfdat->is_little_endian)
  2485. ID_compression = REVDWBYTES(ID_compression);
  2486. if(!( (ID_compression == TAG('N','O','N','E'))
  2487. || (ID_compression == TAG('F','L','3','2'))
  2488. || (ID_compression == TAG('f','l','3','2'))
  2489. || (ID_compression == TAG('i','n','2','4')))
  2490. ){
  2491. DBGFPRINTF((stderr, "AIFC file: unsupported compression format\n"));
  2492. return PSF_E_UNSUPPORTED;
  2493. }
  2494. /*set stype info */
  2495. if((ID_compression== TAG('F','L','3','2'))
  2496. || ID_compression == TAG('f','l','3','2')){
  2497. if(sfdat->fmt.Format.wBitsPerSample != 32){
  2498. DBGFPRINTF((stderr, "AIFC file: samples not 32bit in floats file\n"));
  2499. return PSF_E_BAD_FORMAT;
  2500. }
  2501. else {
  2502. sfdat->fmt.Format.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
  2503. sfdat->samptype = PSF_SAMP_IEEE_FLOAT;
  2504. }
  2505. }
  2506. /* yes, lazy! skip past pascal string*/
  2507. if(fseek(sfdat->file,((size-22)+1)&~1,SEEK_CUR)) /*written for documentation, not terseness!*/
  2508. return PSF_E_CANT_SEEK;
  2509. remain -= (size+1)&~1;
  2510. have_comm = 1;
  2511. break;
  2512. case (TAG('P','E','A','K')):
  2513. if(!have_comm){
  2514. DBGFPRINTF((stderr, "\nAIFC file: found PEAK chunk before COMM chunk!\n"));
  2515. return PSF_E_BAD_FORMAT;
  2516. }
  2517. if(size != (2 * sizeof(DWORD) + sizeof(PSF_CHPEAK) * sfdat->fmt.Format.nChannels)){
  2518. DBGFPRINTF((stderr, "\nBad size for PEAK chunk\n"));
  2519. return PSF_E_BAD_FORMAT;
  2520. }
  2521. if(wavDoRead(sfdat,(char *)&version,sizeof(DWORD)))
  2522. return PSF_E_CANT_READ;
  2523. if(sfdat->is_little_endian)
  2524. version = REVDWBYTES(version);
  2525. if(version != 1) {
  2526. DBGFPRINTF((stderr, "Unexpected version level for PEAK chunk!\n"));
  2527. return PSF_E_UNSUPPORTED;
  2528. }
  2529. if(fgetpos(sfdat->file,&bytepos))
  2530. return PSF_E_CANT_SEEK;
  2531. sfdat->peakoffset = bytepos;
  2532. if(wavDoRead(sfdat,(char *) &peaktime,sizeof(DWORD))){
  2533. DBGFPRINTF((stderr,"Error reading PEAK time\n"));
  2534. return PSF_E_CANT_READ;
  2535. }
  2536. if(sfdat->is_little_endian)
  2537. peaktime = REVDWBYTES(peaktime);
  2538. sfdat->peaktime = (time_t) peaktime;
  2539. sfdat->pPeaks = (PSF_CHPEAK *)malloc(sizeof(PSF_CHPEAK) * sfdat->fmt.Format.nChannels);
  2540. if(sfdat->pPeaks==NULL) {
  2541. DBGFPRINTF((stderr, "wavOpenWrite: no memory for peak data\n"));
  2542. return PSF_E_NOMEM;
  2543. }
  2544. if(wavDoRead(sfdat,(char *)(sfdat->pPeaks),sizeof(PSF_CHPEAK) * sfdat->fmt.Format.nChannels)) {
  2545. DBGFPRINTF((stderr,"Error reading PEAK peak data\n"));
  2546. return PSF_E_CANT_READ;
  2547. }
  2548. if(sfdat->is_little_endian){
  2549. DWORD *pBlock;
  2550. int i;
  2551. pBlock = (DWORD *) (sfdat->pPeaks);
  2552. for(i=0;i < sfdat->fmt.Format.nChannels * 2; i++)
  2553. pBlock[i] = REVDWBYTES(pBlock[i]);
  2554. }
  2555. remain -= (size+1)&~1;
  2556. break;
  2557. case(TAG('S','S','N','D')):
  2558. if(wavDoRead(sfdat,(char *)&offset,sizeof(DWORD))
  2559. || wavDoRead(sfdat,(char *) &blocksize,sizeof(DWORD)))
  2560. return PSF_E_CANT_READ;
  2561. if(sfdat->is_little_endian){
  2562. offset = REVDWBYTES(offset);
  2563. blocksize = REVDWBYTES(blocksize);
  2564. }
  2565. if(fgetpos(sfdat->file,&bytepos))
  2566. return PSF_E_CANT_SEEK;
  2567. sfdat->dataoffset = bytepos;
  2568. POS64(sfdat->dataoffset) += offset;
  2569. sfdat->nFrames = (size - 2* sizeof(DWORD))/ sfdat->fmt.Format.nBlockAlign;
  2570. if(fseek(sfdat->file,((size - 2* sizeof(DWORD))+1)&~1,SEEK_CUR))
  2571. return PSF_E_CANT_SEEK;
  2572. have_ssnd = 1;
  2573. remain -= (size+1)&~1;
  2574. break;
  2575. /* HARSH! as above */
  2576. case(0):
  2577. DBGFPRINTF((stderr, "AIFC file has bad main chunksize\n"));
  2578. return PSF_E_BAD_FORMAT;
  2579. default:
  2580. /* skip all unknown chunks */
  2581. if(fseek(sfdat->file,(size+1)&~1,SEEK_CUR))
  2582. return PSF_E_CANT_SEEK;
  2583. remain -= (size+1)&~1;
  2584. break;
  2585. }
  2586. }
  2587. if(!(have_ssnd && have_comm && have_fver)){
  2588. DBGFPRINTF((stderr, "AIFC file has bad format\n"));
  2589. return PSF_E_BAD_FORMAT;
  2590. }
  2591. /* we have seeked (ugh) to EOF, so rewind to start of data */
  2592. if(fsetpos(sfdat->file,&sfdat->dataoffset))
  2593. return PSF_E_CANT_SEEK;
  2594. sfdat->curframepos = 0;
  2595. sfdat->riff_format = PSF_AIFC;
  2596. /* get rescale factor if available */
  2597. /* NB in correct format, val is always >= 0.0 */
  2598. if(sfdat->pPeaks && POS64(sfdat->peakoffset) != 0){
  2599. float fac = 0.0f;
  2600. int i;
  2601. for(i=0;i < sfdat->fmt.Format.nChannels; i++)
  2602. fac = max(fac,sfdat->pPeaks[i].val);
  2603. if(fac > 1.0f)
  2604. sfdat->rescale_fac = 1.0f / fac;
  2605. }
  2606. sfdat->lastop = PSF_OP_READ;
  2607. return PSF_E_NOERROR;
  2608. }
  2609. /* only RDONLY access supported */
  2610. int psf_sndOpen(const char *path,PSF_PROPS *props, int rescale)
  2611. {
  2612. int i,rc = 0;
  2613. PSFFILE *sfdat;
  2614. psf_format fmt;
  2615. /* RWD interesting syntax issue: I need the curlies, or break doesn't work properly */
  2616. for(i=0;i < psf_maxfiles;i++) {
  2617. if(psf_files[i]==NULL)
  2618. break;
  2619. }
  2620. if(i==psf_maxfiles){
  2621. return PSF_E_TOOMANYFILES;
  2622. }
  2623. sfdat = psf_newFile(NULL);
  2624. if(sfdat==NULL){
  2625. return PSF_E_NOMEM;
  2626. }
  2627. sfdat->rescale = rescale;
  2628. sfdat->is_little_endian = byte_order();
  2629. fmt = psf_getFormatExt(path);
  2630. if(!(fmt==PSF_STDWAVE || fmt==PSF_WAVE_EX || fmt==PSF_AIFF || fmt==PSF_AIFC))
  2631. return PSF_E_BADARG;
  2632. if((sfdat->file = fopen(path,"rb")) == NULL) {
  2633. DBGFPRINTF((stderr, "psf_sndOpen: cannot open '%s'\n", path));
  2634. return PSF_E_CANT_OPEN;
  2635. }
  2636. sfdat->filename = (char *) malloc(strlen(path)+1);
  2637. if(sfdat->filename==NULL) {
  2638. return PSF_E_NOMEM;
  2639. }
  2640. strcpy(sfdat->filename, path);
  2641. sfdat->isRead = 1;
  2642. sfdat->nFrames = 0;
  2643. /* no need to calc header sizes */
  2644. switch(fmt){
  2645. case(PSF_STDWAVE):
  2646. case(PSF_WAVE_EX):
  2647. rc = wavReadHeader(sfdat);
  2648. break;
  2649. case(PSF_AIFF):
  2650. /* some .aiff files may actually be aifc - esp if floats! */
  2651. case(PSF_AIFC):
  2652. rc = aiffReadHeader(sfdat);
  2653. /* try AIFC if AIFF fails */
  2654. if(rc < PSF_E_NOERROR) {
  2655. rewind(sfdat->file);
  2656. rc = aifcReadHeader(sfdat);
  2657. }
  2658. break;
  2659. default:
  2660. DBGFPRINTF((stderr, "psf_sndOpen: unsupported file format\n"));
  2661. rc = PSF_E_UNSUPPORTED;
  2662. }
  2663. if(rc < PSF_E_NOERROR)
  2664. return rc;
  2665. /* fill props info*/
  2666. props->srate = sfdat->fmt.Format.nSamplesPerSec;
  2667. props->chans = sfdat->fmt.Format.nChannels;
  2668. props->samptype = sfdat->samptype;
  2669. props->chformat = sfdat->chformat;
  2670. props->format = fmt;
  2671. if(fmt==PSF_STDWAVE && (sfdat->riff_format == PSF_WAVE_EX))
  2672. props->format = PSF_WAVE_EX;
  2673. psf_files[i] = sfdat;
  2674. return i;
  2675. }
  2676. int psf_sndReadFloatFrames(int sfd, float *buf, DWORD nFrames)
  2677. {
  2678. int chans;
  2679. DWORD framesread;
  2680. int blocksize,lsamp;
  2681. int temp;
  2682. int i,do_reverse;
  2683. short ssamp;
  2684. float *pbuf = buf;
  2685. float fsamp;
  2686. PSFFILE *sfdat;
  2687. int do_shift;
  2688. SND_SAMP s_samp;
  2689. #ifdef _DEBUG
  2690. static int debug = 1;
  2691. #endif
  2692. if(sfd < 0 || sfd > psf_maxfiles)
  2693. return PSF_E_BADARG;
  2694. if(buf==NULL)
  2695. return PSF_E_BADARG;
  2696. if(nFrames == 0)
  2697. return nFrames;
  2698. sfdat = psf_files[sfd];
  2699. #ifdef _DEBUG
  2700. assert(sfdat);
  2701. assert(sfdat->file);
  2702. assert(sfdat->filename);
  2703. /* must check our calcs! */
  2704. assert(sfdat->curframepos <= sfdat->nFrames);
  2705. #endif
  2706. /* how much do we have left? return immediately if none! */
  2707. chans = sfdat->fmt.Format.nChannels;
  2708. framesread = min(sfdat->nFrames - sfdat->curframepos,nFrames);
  2709. if(framesread==0)
  2710. return (long) framesread;
  2711. blocksize = framesread * chans;
  2712. switch(sfdat->riff_format){
  2713. case(PSF_STDWAVE):
  2714. case(PSF_WAVE_EX):
  2715. do_reverse = (sfdat->is_little_endian ? 0 : 1 );
  2716. do_shift = 1;
  2717. break;
  2718. case(PSF_AIFF):
  2719. case(PSF_AIFC):
  2720. do_reverse = (sfdat->is_little_endian ? 1 : 0 );
  2721. do_shift = 0;
  2722. break;
  2723. default:
  2724. return PSF_E_UNSUPPORTED;
  2725. }
  2726. if(sfdat->lastop == PSF_OP_WRITE)
  2727. fflush(sfdat->file);
  2728. switch(sfdat->samptype){
  2729. case(PSF_SAMP_IEEE_FLOAT):
  2730. if(do_reverse){
  2731. for(i=0;i < blocksize;i ++){
  2732. if(wavDoRead(sfdat,(char *)&lsamp,sizeof(int)))
  2733. return PSF_E_CANT_READ;
  2734. lsamp = REVDWBYTES(lsamp);
  2735. // fsamp = * (float *)&lsamp;
  2736. s_samp.lsamp = lsamp;
  2737. fsamp = s_samp.fsamp;
  2738. if(sfdat->rescale)
  2739. fsamp *= sfdat->rescale_fac;
  2740. *pbuf++ = fsamp;
  2741. }
  2742. }
  2743. else{
  2744. if(wavDoRead(sfdat,(char *) buf,blocksize * sizeof(float)))
  2745. return PSF_E_CANT_READ;
  2746. if(sfdat->rescale){
  2747. pbuf = buf;
  2748. for(i=0;i < blocksize; i++)
  2749. *pbuf++ *= sfdat->rescale_fac;
  2750. }
  2751. }
  2752. break;
  2753. case(PSF_SAMP_16):
  2754. if(do_reverse){
  2755. for(i = 0; i < blocksize; i++){
  2756. if(wavDoRead(sfdat,(char *)&ssamp,sizeof(short)))
  2757. return PSF_E_CANT_READ;
  2758. ssamp = (short) REVWBYTES(ssamp);
  2759. fsamp = (float)((double) ssamp / MAX_16BIT);
  2760. *pbuf++ = fsamp;
  2761. }
  2762. }
  2763. else{
  2764. for(i = 0; i < blocksize; i++){
  2765. if(wavDoRead(sfdat,(char *)&ssamp,sizeof(short)))
  2766. return PSF_E_CANT_READ;
  2767. fsamp = (float)((double) ssamp / MAX_16BIT);
  2768. *pbuf++ = fsamp;
  2769. }
  2770. }
  2771. break;
  2772. case(PSF_SAMP_24):
  2773. if(do_reverse){
  2774. #ifdef _DEBUG
  2775. if(debug){
  2776. printf("do_reverse: riffformat=%d do_shift = %d little_endian = %d\n",
  2777. sfdat->riff_format,do_shift,sfdat->is_little_endian);
  2778. debug = 0;
  2779. }
  2780. #endif
  2781. for(i=0;i < blocksize;i++){
  2782. temp = 0;
  2783. if(wavDoRead(sfdat,(char *)&temp,3))
  2784. return PSF_E_CANT_READ;
  2785. lsamp = REVDWBYTES(temp);
  2786. if(do_shift)
  2787. lsamp <<= 8;
  2788. fsamp = (float)((double)(lsamp) / MAX_32BIT);
  2789. *pbuf++ = fsamp;
  2790. }
  2791. }
  2792. else{
  2793. for(i=0;i < blocksize;i++){
  2794. lsamp = 0;
  2795. if(wavDoRead(sfdat,(char *)&lsamp,3))
  2796. return PSF_E_CANT_READ;
  2797. if(do_shift)
  2798. lsamp <<= 8;
  2799. fsamp = (float)((double)(lsamp) / MAX_32BIT);
  2800. *pbuf++ = fsamp;
  2801. }
  2802. }
  2803. break;
  2804. case(PSF_SAMP_32):
  2805. if(do_reverse){
  2806. for(i=0;i < blocksize;i++){
  2807. if(wavDoRead(sfdat,(char *)&lsamp,sizeof(int)))
  2808. return PSF_E_CANT_READ;
  2809. lsamp = REVDWBYTES(lsamp);
  2810. fsamp = (float)((double)(lsamp) / MAX_32BIT);
  2811. *pbuf++ = fsamp;
  2812. }
  2813. }
  2814. else{
  2815. for(i=0;i < blocksize;i++){
  2816. lsamp = 0L;
  2817. if(wavDoRead(sfdat,(char *)&lsamp,sizeof(int)))
  2818. return PSF_E_CANT_READ;
  2819. fsamp = (float)((double)(lsamp) / MAX_32BIT);
  2820. *pbuf++ = fsamp;
  2821. }
  2822. }
  2823. break;
  2824. default:
  2825. DBGFPRINTF((stderr, "psf_sndOpen: unsupported sample format\n"));
  2826. return PSF_E_UNSUPPORTED;
  2827. }
  2828. sfdat->curframepos += framesread;
  2829. return framesread;
  2830. }
  2831. /* read doubles version! */
  2832. int psf_sndReadDoubleFrames(int sfd, double *buf, DWORD nFrames)
  2833. {
  2834. int chans;
  2835. DWORD framesread;
  2836. int blocksize,lsamp;
  2837. int i,do_reverse;
  2838. short ssamp;
  2839. double *pbuf = buf;
  2840. float fsamp;
  2841. PSFFILE *sfdat;
  2842. SND_SAMP s_samp;
  2843. int do_shift;
  2844. if(sfd < 0 || sfd > psf_maxfiles)
  2845. return PSF_E_BADARG;
  2846. if(buf==NULL)
  2847. return PSF_E_BADARG;
  2848. if(nFrames == 0)
  2849. return nFrames;
  2850. sfdat = psf_files[sfd];
  2851. #ifdef _DEBUG
  2852. assert(sfdat);
  2853. assert(sfdat->file);
  2854. assert(sfdat->filename);
  2855. /* must check our calcs! */
  2856. assert(sfdat->curframepos <= sfdat->nFrames);
  2857. #endif
  2858. /* how much do we have left? return immediately if none! */
  2859. chans = sfdat->fmt.Format.nChannels;
  2860. framesread = min(sfdat->nFrames - sfdat->curframepos,nFrames);
  2861. if(framesread==0)
  2862. return (long) framesread;
  2863. blocksize = framesread * chans;
  2864. switch(sfdat->riff_format){
  2865. case(PSF_STDWAVE):
  2866. case(PSF_WAVE_EX):
  2867. do_reverse = (sfdat->is_little_endian ? 0 : 1 );
  2868. do_shift = 1;
  2869. break;
  2870. case(PSF_AIFF):
  2871. case(PSF_AIFC):
  2872. do_reverse = (sfdat->is_little_endian ? 1 : 0 );
  2873. do_shift = 0;
  2874. break;
  2875. default:
  2876. return PSF_E_UNSUPPORTED;
  2877. }
  2878. if(sfdat->lastop == PSF_OP_WRITE)
  2879. fflush(sfdat->file);
  2880. switch(sfdat->samptype){
  2881. case(PSF_SAMP_IEEE_FLOAT):
  2882. if(do_reverse){
  2883. for(i=0;i < blocksize;i ++){
  2884. if(wavDoRead(sfdat,(char *)&lsamp,sizeof(int)))
  2885. return PSF_E_CANT_READ;
  2886. lsamp = REVDWBYTES(lsamp);
  2887. // fsamp = * (float *)&lsamp;
  2888. s_samp.lsamp = lsamp;
  2889. fsamp = s_samp.fsamp;
  2890. if(sfdat->rescale)
  2891. fsamp *= sfdat->rescale_fac;
  2892. *pbuf++ = (double) fsamp;
  2893. }
  2894. }
  2895. else{
  2896. for(i=0;i < blocksize;i++){
  2897. if(wavDoRead(sfdat,(char *) &fsamp, sizeof(float)))
  2898. return PSF_E_CANT_READ;
  2899. *pbuf++ = (double) fsamp;
  2900. }
  2901. if(sfdat->rescale){
  2902. pbuf = buf;
  2903. for(i=0;i < blocksize; i++)
  2904. *pbuf++ *= sfdat->rescale_fac;
  2905. }
  2906. }
  2907. break;
  2908. case(PSF_SAMP_16):
  2909. if(do_reverse){
  2910. for(i = 0; i < blocksize; i++){
  2911. if(wavDoRead(sfdat,(char *)&ssamp,sizeof(short)))
  2912. return PSF_E_CANT_READ;
  2913. ssamp = (short) REVWBYTES(ssamp);
  2914. fsamp = (float)((double) ssamp / MAX_16BIT);
  2915. *pbuf++ = (double) fsamp;
  2916. }
  2917. }
  2918. else{
  2919. for(i = 0; i < blocksize; i++){
  2920. if(wavDoRead(sfdat,(char *)&ssamp,sizeof(short)))
  2921. return PSF_E_CANT_READ;
  2922. fsamp = (float)((double) ssamp / MAX_16BIT);
  2923. *pbuf++ = (double) fsamp;
  2924. }
  2925. }
  2926. break;
  2927. case(PSF_SAMP_24):
  2928. if(do_reverse){
  2929. for(i=0;i < blocksize;i++){
  2930. if(wavDoRead(sfdat,(char *)&lsamp,3))
  2931. return PSF_E_CANT_READ;
  2932. lsamp = REVDWBYTES(lsamp);
  2933. if(do_shift)
  2934. lsamp <<= 8;
  2935. fsamp = (float)((double)(lsamp) / MAX_32BIT);
  2936. *pbuf++ = (double) fsamp;
  2937. }
  2938. }
  2939. else{
  2940. for(i=0;i < blocksize;i++){
  2941. lsamp = 0L;
  2942. if(wavDoRead(sfdat,(char *)&lsamp,3))
  2943. return PSF_E_CANT_READ;
  2944. if(do_shift)
  2945. lsamp <<= 8;
  2946. fsamp = (float)((double)(lsamp) / MAX_32BIT);
  2947. *pbuf++ = (double) fsamp;
  2948. }
  2949. }
  2950. break;
  2951. case(PSF_SAMP_32):
  2952. if(do_reverse){
  2953. for(i=0;i < blocksize;i++){
  2954. if(wavDoRead(sfdat,(char *)&lsamp,sizeof(int)))
  2955. return PSF_E_CANT_READ;
  2956. lsamp = REVDWBYTES(lsamp);
  2957. fsamp = (float)((double)(lsamp) / MAX_32BIT);
  2958. *pbuf++ = (double) fsamp;
  2959. }
  2960. }
  2961. else{
  2962. for(i=0;i < blocksize;i++){
  2963. lsamp = 0L;
  2964. if(wavDoRead(sfdat,(char *)&lsamp,sizeof(int)))
  2965. return PSF_E_CANT_READ;
  2966. fsamp = (float)((double)(lsamp) / MAX_32BIT);
  2967. *pbuf++ = (double) fsamp;
  2968. }
  2969. }
  2970. break;
  2971. default:
  2972. DBGFPRINTF((stderr, "psf_sndOpen: unsupported sample format\n"));
  2973. return PSF_E_UNSUPPORTED;
  2974. }
  2975. sfdat->curframepos += framesread;
  2976. return framesread;
  2977. }
  2978. #ifdef _DEBUG
  2979. /* private test func to get raw file size */
  2980. /* verify sfdat->nFrames always <= true EOF position */
  2981. /* NB: size value is wrong if there is junk after data chunk! */
  2982. static fpos_t getsize(FILE* fp){
  2983. fpos_t curpos;
  2984. fpos_t size;
  2985. if(fgetpos(fp,&curpos))
  2986. return -1;
  2987. if(fseek(fp,0,SEEK_END))
  2988. return -1;
  2989. if(fgetpos(fp,&size))
  2990. return -1;
  2991. if(fsetpos(fp,&curpos))
  2992. return -1;
  2993. return size;
  2994. }
  2995. #endif
  2996. /* return size in m/c frames */
  2997. /* signed long because we want error return */
  2998. /* 64 bit: this would have to return a 64bit type (or unsigned 32bit int) IF we want to support 4GB 8bit sfiles! */
  2999. /* (which we don't) */
  3000. int psf_sndSize(int sfd)
  3001. {
  3002. PSFFILE *sfdat;
  3003. #ifdef _DEBUG
  3004. fpos_t size;
  3005. DWORD framesize;
  3006. #endif
  3007. if(sfd < 0 || sfd > psf_maxfiles)
  3008. return PSF_E_BADARG;
  3009. sfdat = psf_files[sfd];
  3010. if(sfdat==NULL)
  3011. return PSF_E_BADARG;
  3012. #ifdef _DEBUG
  3013. assert(sfdat->file);
  3014. assert(sfdat->filename);
  3015. if((size = getsize(sfdat->file)) < 0) {
  3016. DBGFPRINTF((stderr, "getsize() error in psf_sndSize().\n"));
  3017. return -1;
  3018. }
  3019. /* NB deceived if any pad or other junk after data chunk! */
  3020. framesize = (DWORD)((POS64(size) - (MYLONG)(sfdat->dataoffset)) / sfdat->fmt.Format.nBlockAlign);
  3021. assert(framesize >= (DWORD) sfdat->nFrames);
  3022. #endif
  3023. return sfdat->nFrames;
  3024. }
  3025. /* returns multi-channel (frame) position */
  3026. /* 64bit see above! */
  3027. int psf_sndTell(int sfd)
  3028. {
  3029. fpos_t pos;
  3030. PSFFILE *sfdat;
  3031. if(sfd < 0 || sfd > psf_maxfiles)
  3032. return PSF_E_BADARG;
  3033. sfdat = psf_files[sfd];
  3034. if(sfdat==NULL)
  3035. return PSF_E_BADARG;
  3036. #ifdef _DEBUG
  3037. assert(sfdat->file);
  3038. assert(sfdat->filename);
  3039. #endif
  3040. if(fgetpos(sfdat->file,&pos))
  3041. return PSF_E_CANT_SEEK;
  3042. POS64(pos) -= POS64(sfdat->dataoffset);
  3043. POS64(pos) /= sfdat->fmt.Format.nBlockAlign;
  3044. #ifdef _DEBUG
  3045. if(sfdat->lastop == PSF_OP_READ)
  3046. assert(pos== sfdat->curframepos);
  3047. else if(sfdat->lastop == PSF_OP_WRITE)
  3048. /* RWD this will be out (but == curframepos) if lastop was a read . so maybe say >=, or test for lastop ? */
  3049. assert(pos == sfdat->lastwritepos);
  3050. #endif
  3051. return (int) POS64(pos);
  3052. }
  3053. int psf_sndSeek(int sfd,int offset, int mode)
  3054. {
  3055. long byteoffset; /* can be negative - limited to 2GB moves*/
  3056. fpos_t data_end,pos_target,cur_pos;
  3057. PSFFILE *sfdat;
  3058. if(sfd < 0 || sfd > psf_maxfiles)
  3059. return PSF_E_BADARG;
  3060. sfdat = psf_files[sfd];
  3061. if(sfdat==NULL)
  3062. return PSF_E_BADARG;
  3063. #ifdef _DEBUG
  3064. assert(sfdat->file);
  3065. assert(sfdat->filename);
  3066. #endif
  3067. /* RWD NB:dataoffset test only valid for files with headers! */
  3068. if(POS64(sfdat->dataoffset)==0)
  3069. return PSF_E_BADARG;
  3070. /* or, it indicates a RAW file.... */
  3071. byteoffset = offset * sfdat->fmt.Format.nBlockAlign;
  3072. POS64(data_end) = POS64(sfdat->dataoffset) + (sfdat->nFrames * sfdat->fmt.Format.nBlockAlign);
  3073. switch(mode){
  3074. case PSF_SEEK_SET:
  3075. POS64(pos_target) = POS64(sfdat->dataoffset) + byteoffset;
  3076. if(fsetpos(sfdat->file,&pos_target))
  3077. return PSF_E_CANT_SEEK;
  3078. break;
  3079. case PSF_SEEK_END:
  3080. /* NB can't just seek to end of file as there may be junk after data chunk! */
  3081. POS64(pos_target) = POS64(data_end) + byteoffset;
  3082. if(fsetpos(sfdat->file,&pos_target))
  3083. return PSF_E_CANT_SEEK;
  3084. break;
  3085. case PSF_SEEK_CUR:
  3086. /* should be safe using fseek for SEEK_END */
  3087. /* Currently UNDECIDED whether to allow seeks beyond end of file! */
  3088. if(fseek(sfdat->file,byteoffset,SEEK_CUR))
  3089. return PSF_E_CANT_SEEK;
  3090. break;
  3091. }
  3092. if(fgetpos(sfdat->file,&cur_pos))
  3093. return PSF_E_CANT_SEEK;
  3094. if(POS64(cur_pos) >= POS64(sfdat->dataoffset)){
  3095. sfdat->curframepos = (DWORD)(POS64(cur_pos) - POS64(sfdat->dataoffset)) / sfdat->fmt.Format.nBlockAlign;
  3096. if(!sfdat->isRead) { /*RWD NEW*/
  3097. /* we are rewinding a file open for writing */
  3098. POS64(sfdat->lastwritepos) = sfdat->curframepos;
  3099. }
  3100. return PSF_E_NOERROR;
  3101. }
  3102. else
  3103. return PSF_E_CANT_SEEK;
  3104. }
  3105. /* decide sfile format from the filename extension */
  3106. /* TODO: add func to get format from file header */
  3107. psf_format psf_getFormatExt(const char *path)
  3108. {
  3109. char *lastdot;
  3110. if(path==NULL || (strlen(path) < 4))
  3111. return PSF_FMT_UNKNOWN; /* TODO: support RAW data... */
  3112. lastdot = strrchr(path,'.');
  3113. if(lastdot==NULL)
  3114. return PSF_FMT_UNKNOWN;
  3115. if(stricmp(lastdot,".wav")==0)
  3116. return PSF_STDWAVE;
  3117. else if((stricmp(lastdot,".aif")==0) || stricmp(lastdot,".aiff")==0)
  3118. return PSF_AIFF;
  3119. else if((stricmp(lastdot,".afc")==0) || stricmp(lastdot,".aifc")==0)
  3120. return PSF_AIFC;
  3121. /* Ambisonic b-format files */
  3122. else if(stricmp(lastdot,".wxyz")==0)
  3123. return PSF_STDWAVE;
  3124. else if(stricmp(lastdot,".amb")==0)
  3125. return PSF_WAVE_EX;
  3126. else
  3127. return PSF_FMT_UNKNOWN;
  3128. }
  3129. /* return 0 for no PEAK data, 1 for success */
  3130. /* NB: we read PEAK data from sfdat, so we can read peaks while writing the file, before closing */
  3131. int psf_sndReadPeaks(int sfd,PSF_CHPEAK peakdata[],MYLONG *peaktime)
  3132. {
  3133. int i,nchans;
  3134. PSFFILE *sfdat;
  3135. if(sfd < 0 || sfd > psf_maxfiles)
  3136. return PSF_E_BADARG;
  3137. sfdat = psf_files[sfd];
  3138. if(sfdat==NULL)
  3139. return PSF_E_BADARG;
  3140. #ifdef _DEBUG
  3141. assert(sfdat->file);
  3142. assert(sfdat->filename);
  3143. #endif
  3144. /* TODO: we may want to have this, for RAW files, even though we won't write it */
  3145. if(sfdat->pPeaks==NULL){ /*NOT an error: just don't have the chunk*/
  3146. if(peaktime!= NULL)
  3147. *peaktime = 0;
  3148. return 0;
  3149. }
  3150. if(peaktime != NULL)
  3151. *peaktime = (int) sfdat->peaktime;
  3152. nchans = sfdat->fmt.Format.nChannels;
  3153. for(i=0;i < nchans;i++){
  3154. peakdata[i].val = sfdat->pPeaks[i].val;
  3155. peakdata[i].pos = sfdat->pPeaks[i].pos;
  3156. }
  3157. return 1;
  3158. }
  3159. static float trirand(void)
  3160. {
  3161. double r1,r2;
  3162. r1 = (double) rand() * inv_randmax;
  3163. r2 = (double) rand() * inv_randmax;
  3164. return (float)((r1 + r2) - 1.0);
  3165. }
  3166. int psf_sndSetDither(int sfd,unsigned int dtype)
  3167. {
  3168. PSFFILE *sfdat;;
  3169. if(sfd < 0 || sfd > psf_maxfiles)
  3170. return PSF_E_BADARG;
  3171. sfdat = psf_files[sfd];
  3172. if(sfdat==NULL)
  3173. return PSF_E_BADARG;
  3174. #ifdef _DEBUG
  3175. assert(sfdat->file);
  3176. assert(sfdat->filename);
  3177. #endif
  3178. if(dtype < PSF_DITHER_OFF || dtype > PSF_DITHER_TPDF || sfdat->isRead)
  3179. return PSF_E_BADARG;
  3180. sfdat->dithertype = dtype;
  3181. return PSF_E_NOERROR;
  3182. }
  3183. /* get current dither setting */
  3184. int psf_sndGetDither(int sfd)
  3185. {
  3186. PSFFILE *sfdat;
  3187. if(sfd < 0 || sfd > psf_maxfiles)
  3188. return PSF_E_BADARG;
  3189. sfdat = psf_files[sfd];
  3190. if(sfdat==NULL)
  3191. return PSF_E_BADARG;
  3192. #ifdef _DEBUG
  3193. assert(sfdat->file);
  3194. assert(sfdat->filename);
  3195. #endif
  3196. return sfdat->dithertype;
  3197. }
  3198. /* OCT 2009 */
  3199. psf_channelformat get_speakerlayout(DWORD chmask,DWORD chans)
  3200. {
  3201. psf_channelformat chformat = MC_WAVE_EX; // default is some weird format!
  3202. /* accept chancount > numbits set in speakermask */
  3203. switch(chmask){
  3204. /*check all cross-platform formats first...*/
  3205. case(SPKRS_UNASSIGNED):
  3206. chformat = MC_STD;
  3207. break;
  3208. case(SPKRS_MONO):
  3209. if(chans==1)
  3210. chformat = MC_MONO;
  3211. break;
  3212. case(SPKRS_STEREO):
  3213. if(chans==2)
  3214. chformat = MC_STEREO;
  3215. break;
  3216. case(SPKRS_GENERIC_QUAD):
  3217. if(chans==4)
  3218. chformat = MC_QUAD;
  3219. break;
  3220. case(SPKRS_SURROUND_LCRS):
  3221. if(chans==4)
  3222. chformat = MC_LCRS;
  3223. break;
  3224. case(SPKRS_DOLBY5_1):
  3225. if(chans==6)
  3226. chformat = MC_DOLBY_5_1;
  3227. break;
  3228. case(SPKRS_SURR_5_0): /* March 2008 */
  3229. if(chans==5)
  3230. chformat = MC_SURR_5_0;
  3231. break;
  3232. case(SPKRS_6_1):
  3233. if(chans==7)
  3234. chformat = MC_SURR_6_1;
  3235. break;
  3236. case(SPKRS_7_1):
  3237. if(chans==8)
  3238. chformat = MC_SURR_7_1;
  3239. break;
  3240. case SPKRS_CUBE:
  3241. if(chans==8)
  3242. chformat = MC_CUBE;
  3243. break;
  3244. default:
  3245. break;
  3246. }
  3247. return chformat;
  3248. }
  3249. /* NOV 2009 get raw speaker mask */
  3250. int psf_speakermask(int sfd)
  3251. {
  3252. PSFFILE *sfdat;
  3253. if(sfd < 0 || sfd > psf_maxfiles)
  3254. return PSF_E_BADARG;
  3255. sfdat = psf_files[sfd];
  3256. if(sfdat==NULL)
  3257. return PSF_E_BADARG;
  3258. return (int) sfdat->fmt.dwChannelMask;
  3259. }
  3260. /* September 2010 to check output file sizes */
  3261. #define PSF_SIZE_SAFETY (512)
  3262. int is_legalsize(unsigned long nFrames, const PSF_PROPS *props)
  3263. {
  3264. int samplesize = 0;
  3265. int result = 0;
  3266. int blocksize;
  3267. unsigned long long bytesize;
  3268. switch(props->samptype){
  3269. case PSF_SAMP_8:
  3270. samplesize = 1;
  3271. break;
  3272. case PSF_SAMP_16:
  3273. samplesize = 2;
  3274. break;
  3275. case PSF_SAMP_24:
  3276. samplesize = 3;
  3277. break;
  3278. case PSF_SAMP_32:
  3279. case PSF_SAMP_IEEE_FLOAT:
  3280. samplesize = 4;
  3281. break;
  3282. default:
  3283. return result;
  3284. }
  3285. blocksize = props->chans * samplesize;
  3286. bytesize = nFrames * blocksize;
  3287. if( bytesize <= 0xffffffffLL - PSF_SIZE_SAFETY)
  3288. result = 1;
  3289. return result;
  3290. }
  3291. /* TODO: define a psf_writePeak function; probably to a single nominated channel.
  3292. This would be needed as soon as write is performed with random over-write activity.
  3293. This is probably something to discourage, however!
  3294. */