snd.c 55 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920
  1. /*
  2. * Copyright (c) 1983-2013 Martin Atkins, Richard Dobson and Composers Desktop Project Ltd
  3. * http://people.bath.ac.uk/masrwd
  4. * http://www.composersdesktop.com
  5. *
  6. This file is part of the CDP System.
  7. The CDP System is free software; you can redistribute it
  8. and/or modify it under the terms of the GNU Lesser General Public
  9. License as published by the Free Software Foundation; either
  10. version 2.1 of the License, or (at your option) any later version.
  11. The CDP System is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. GNU Lesser General Public License for more details.
  15. You should have received a copy of the GNU Lesser General Public
  16. License along with the CDP System; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  18. 02111-1307 USA
  19. *
  20. */
  21. /*
  22. * Sound Filing System - Buffered sound system, open/close, etc.
  23. *
  24. * Portable version
  25. *
  26. * Copyright M. C. Atkins, 1986, 1987, 1993; RWD 2007,2014
  27. * All Rights Reserved.
  28. */
  29. /* RWD: old sfsys functions DEPRECATED and emptied */
  30. /* RWD Dec 2019 fixed SndCloseEx for int64 comps */
  31. #ifdef _DEBUG
  32. #include <stdio.h>
  33. #endif
  34. #include <stdlib.h>
  35. #include <string.h>
  36. #include <math.h>
  37. #include <sfsys.h>
  38. #include "sffuncs.h"
  39. #ifdef _WIN32
  40. #ifdef _MSC_VER
  41. static __inline int cdp_round(double fval)
  42. {
  43. int result;
  44. _asm{
  45. fld fval
  46. fistp result
  47. mov eax,result /* RWD: need this line? */
  48. }
  49. return result;
  50. }
  51. #else
  52. # ifndef __GNUWIN32__
  53. static int cdp_round(double val)
  54. {
  55. int k;
  56. k = (int)(fabs(val)+0.5);
  57. if(val < 0.0)
  58. k = -k;
  59. return k;
  60. }
  61. # endif
  62. #endif
  63. #endif
  64. /*
  65. * This is the main structure describing a procom file
  66. */
  67. struct sndfile {
  68. int flags; /* various flags */
  69. int fd; /* SFfile/gemfile file descripter */
  70. char *buffer; /* pointer to the buffer */
  71. char *next; /* next entry in buffer to access */
  72. int bufsiz; /* the size of the buffer (in sectors) */
  73. int remain; /* number of samples remaining in buffer */
  74. char *endbuf; /* end of buffer (for short bufs at eof) */
  75. int samptype; /* the type of samples in the file */
  76. int lastread; /* number of bytes obtained from last read */
  77. /* CDP97*/
  78. int true_bufsize; /*for 24bit alignment, etc: adjust buffer downwards*/
  79. int scale_floats;
  80. double fscalefac;
  81. };
  82. typedef union {
  83. int lsamp;
  84. /*float fsamp; //any use for this? */
  85. unsigned char bytes[4];
  86. } SND_SAMP;
  87. /*
  88. * values for sndfile.flags
  89. */
  90. #define SNDFLG_WRITTEN (1) /* the buffer must be flushed back to disk */
  91. #define SNDFLG_LASTWR (4) /* last i/o was a write (for sndtell) */
  92. #define SNDFLG_TRUNC (8) /* truncate when closed */
  93. #define SNDFLG_USERBUF (32) /* the buffer was supplied by the user */
  94. #define SNDFLG_ATEND (64) /* the last i/o went over the end of the file */
  95. /*
  96. * Various constants/global data
  97. */
  98. #define SNDFDBASE (4000) /* sndfd's allocated from here */
  99. #define SNDBUFSIZE (64)
  100. /*
  101. * global storage
  102. */
  103. /*
  104. * The array of open sndfiles
  105. */
  106. static struct sndfile *sndfiles[MAXSNDFILES];
  107. /*
  108. * mapping table from sample type, to size
  109. */
  110. /* the possible sample types are now:
  111. SAMP_SHORT (0) * 16-bit short integers *
  112. SAMP_FLOAT (1) * 32-bit (IEEE) floating point *
  113. SAMP_BYTE (2) //recognize 8bit soundfiles?
  114. SAMP_LONG (3) // four most likely formats
  115. SAMP_2424 (4)
  116. SAMP_2432 (5)
  117. SAMP_2024 (6)
  118. SAMP_MASKED (7) //some weird WAVE_EX format!
  119. */
  120. /*RWD.6.99 set this as container-size
  121. *private, but sfsys.c needs to have it
  122. */
  123. int sampsize[] = {
  124. /* SAMP_SHORT */ sizeof(short),
  125. /* SAMP_FLOAT */ sizeof(float),
  126. /* SAMP_BYTE */ sizeof(unsigned char),
  127. /* SAMP_LONG */ sizeof(int),
  128. /* SAMP_2424 */ 3 * sizeof(unsigned char),
  129. /* SAMP_2432 */ sizeof(int),
  130. /* SAMP_2024 */ 3 * sizeof(unsigned char),
  131. /* dummy */ 0 /*for masked formats, have to calc from 1st principles...*/
  132. };
  133. /*
  134. * Utility routines
  135. */
  136. #define getmem(type) ((type *)malloc(sizeof(type)))
  137. extern int _rsf_getmaxpeak(int sfd,float *peak);
  138. extern int _rsf_getbitmask(int sfd);
  139. /*
  140. * initialisation/termination routines
  141. */
  142. static void
  143. rsndallclose(void)
  144. {
  145. int fd;
  146. for(fd = 0; fd < MAXSFNAME; fd++)
  147. if(sndfiles[fd] != 0)
  148. sndclose(fd + SNDFDBASE);
  149. }
  150. static void
  151. rsndinit()
  152. {
  153. register int fd;
  154. static int inited = 0;
  155. if(inited != 0)
  156. return;
  157. inited++;
  158. for(fd = 0; fd < MAXSFNAME; fd++)
  159. sndfiles[fd] = 0;
  160. atexit(rsndallclose);
  161. }
  162. /*
  163. * map a sndfd onto a sndfiles index,
  164. * return 0 on failure
  165. */
  166. /*RWD I want a public version of this, for use in ASSERT etc*/
  167. static int
  168. mapsndfd(int *sfdp)
  169. {
  170. *sfdp -= SNDFDBASE;
  171. if(*sfdp < 0 || *sfdp >= MAXSNDFILES) {
  172. rsferrno = ESFBADADDR;
  173. rsferrstr = "sfd is not in valid range";
  174. return 0;
  175. }
  176. if(sndfiles[*sfdp] == 0) {
  177. rsferrno = ESFNOTOPEN;
  178. rsferrstr = "sndfile is not open (bad sndfd)";
  179. return 0;
  180. }
  181. return 1;
  182. }
  183. /*
  184. * do the underlying seek
  185. * NOTE
  186. * seeks to the end of an sffile are rounded down!!
  187. */
  188. static long
  189. doseek(struct sndfile *sf, long dist, int whence)
  190. {
  191. return sfseek(sf->fd, dist, whence);
  192. }
  193. #ifdef FILE64_WIN
  194. static __int64
  195. doseekEx(struct sndfile *sf, __int64 dist, int whence)
  196. {
  197. return sfseek_buffered(sf->fd, dist, whence);
  198. }
  199. #else
  200. /*RWD Feb 2010 ??? */
  201. //static long
  202. //doseekEx(struct sndfile *sf, long dist, int whence)
  203. //{
  204. // return sfseek_buffered(sf->fd, dist, whence);
  205. //}
  206. static __int64 doseekEx(struct sndfile *sf, __int64 dist, int whence)
  207. {
  208. return sfseek_buffered(sf->fd, dist, whence);
  209. }
  210. #endif
  211. /*
  212. * sndfilbuf - fill a buffer, for reading
  213. * return true, if an error occurs
  214. */
  215. static int
  216. sndfilbuf(struct sndfile *sfd)
  217. {
  218. long want /* = SECSIZE * sfd->bufsiz*/ ; /*RWD: almost a const!*/
  219. long got;
  220. int rc = 0;
  221. if(sfd->flags & SNDFLG_ATEND)
  222. return 0;
  223. #ifdef SFSYS_UNBUFFERED
  224. want = SECSIZE * sfd->bufsiz;
  225. got = sfread(sfd->fd, sfd->buffer, want); /*NB: does conversion of 8bit data*/
  226. #else
  227. want = sfd->true_bufsize;
  228. /*only difference - supports other sample sizes*/
  229. got = sfread_buffered(sfd->fd, sfd->buffer, want);
  230. #endif
  231. if(got < 0) {
  232. rc = 1;
  233. got = 0;
  234. }
  235. if(got < want)
  236. sfd->flags |= SNDFLG_ATEND;
  237. sfd->lastread = got; /*bytes of <size>samps*/
  238. sfd->flags &= ~(SNDFLG_WRITTEN|SNDFLG_LASTWR);
  239. sfd->endbuf = &sfd->buffer[got];
  240. /*RWD NB all snd funcs think in SAMPLES, of 2 types: SHORTS or FLOATS; all 8bit stuff hidden in sf_calls*/
  241. sfd->remain = got / sampsize[sfd->samptype]; /*RWD : adjust for 8bit files...*/
  242. sfd->next = sfd->buffer;
  243. return rc;
  244. }
  245. /*
  246. * sndflsbuf - flush a buffer, after writing
  247. * return true, if an error occurs
  248. */
  249. static int
  250. sndflsbuf(struct sndfile *sfd)
  251. {
  252. int toput = sfd->endbuf - sfd->buffer;
  253. int put;
  254. if(sfd->next == sfd->buffer)
  255. return 0;
  256. if(sfd->flags & SNDFLG_ATEND)
  257. return 0;
  258. sfd->next = sfd->buffer;
  259. sfd->flags &= ~SNDFLG_WRITTEN;
  260. sfd->endbuf = sfd->buffer;
  261. if(!(sfd->flags&SNDFLG_LASTWR) ) {
  262. if(doseek(sfd, -sfd->lastread, 1) < 0) {
  263. sfd->flags |= SNDFLG_LASTWR;
  264. sfd->remain = (sfd->bufsiz<<LOGSECSIZE) / sampsize[sfd->samptype];
  265. return 1;
  266. }
  267. }
  268. sfd->flags |= SNDFLG_LASTWR;
  269. sfd->remain = (sfd->bufsiz<<LOGSECSIZE) / sampsize[sfd->samptype];
  270. toput = (toput+SECSIZE-1)&~(SECSIZE-1);
  271. if((put = sfwrite(sfd->fd, sfd->buffer, toput)) < 0)
  272. return 1;
  273. if(put < toput) {
  274. sfd->flags |= SNDFLG_ATEND;
  275. sfd->remain = 0;
  276. }
  277. return 0;
  278. }
  279. static int
  280. sndflsbufEx(struct sndfile *sfd)
  281. {
  282. int toput = sfd->endbuf - sfd->buffer;
  283. int put;
  284. if(sfd->next == sfd->buffer)
  285. return 0;
  286. if(sfd->flags & SNDFLG_ATEND)
  287. return 0;
  288. sfd->next = sfd->buffer;
  289. sfd->flags &= ~SNDFLG_WRITTEN;
  290. sfd->endbuf = sfd->buffer;
  291. if(!(sfd->flags&SNDFLG_LASTWR) ) {
  292. if(doseekEx(sfd,(__int64) -sfd->lastread, 1) < 0) {
  293. sfd->flags |= SNDFLG_LASTWR;
  294. #ifdef SFSYS_UNBUFFERED
  295. sfd->remain = (sfd->bufsiz<<LOGSECSIZE) / sampsize[sfd->samptype];
  296. #else
  297. sfd->remain = sfd->true_bufsize / sampsize[sfd->samptype];
  298. #endif
  299. return 1;
  300. }
  301. }
  302. sfd->flags |= SNDFLG_LASTWR;
  303. #ifdef SFSYS_UNBUFFERED
  304. sfd->remain = (sfd->bufsiz<<LOGSECSIZE) / sampsize[sfd->samptype];
  305. toput = (toput+SECSIZE-1)&~(SECSIZE-1);
  306. if((put = sfwrite(sfd->fd, sfd->buffer, toput)) < 0)
  307. return 1;
  308. #else
  309. sfd->remain = sfd->true_bufsize / sampsize[sfd->samptype];
  310. if((put = sfwrite_buffered(sfd->fd, sfd->buffer, toput)) < 0)
  311. return 1;
  312. #endif
  313. if(put < toput) {
  314. sfd->flags |= SNDFLG_ATEND;
  315. sfd->remain = 0;
  316. }
  317. return 0;
  318. }
  319. /*
  320. * free the sample buffer, if it wasn't supplied by a sndsetbuf
  321. */
  322. static void
  323. freesndbuf(int fd)
  324. {
  325. if(sndfiles[fd]->flags & SNDFLG_USERBUF)
  326. return;
  327. free(sndfiles[fd]->buffer);
  328. }
  329. /*
  330. * free the memory for an open SFfile
  331. * used on last close, and failure of creat
  332. */
  333. static void
  334. freesndfd(int fd)
  335. {
  336. freesndbuf(fd);
  337. free((char *)sndfiles[fd]);
  338. sndfiles[fd] = 0;
  339. return;
  340. }
  341. /*
  342. * Try to find a snd file descripter
  343. * returns -1, if there aren't any
  344. */
  345. static int
  346. findsndfd()
  347. {
  348. register int fd = 0;
  349. while(sndfiles[fd] != 0)
  350. if(++fd >= MAXSNDFILES) {
  351. rsferrno = ESFNOSFD;
  352. rsferrstr = "Too many sndfiles are already open";
  353. return -1;
  354. }
  355. rsferrstr = "no memory to open sndfile";
  356. rsferrno = ESFNOMEM;
  357. if((sndfiles[fd] = getmem(struct sndfile)) == 0)
  358. return -1;
  359. if((sndfiles[fd]->buffer = (char*) malloc(SNDBUFSIZE*SECSIZE)) == 0) {
  360. free((char *)sndfiles[fd]);
  361. sndfiles[fd] = 0;
  362. return -1;
  363. }
  364. sndfiles[fd]->flags = 0;
  365. sndfiles[fd]->bufsiz = SNDBUFSIZE;
  366. sndfiles[fd]->lastread = 0;
  367. sndfiles[fd]->endbuf = sndfiles[fd]->next = sndfiles[fd]->buffer;
  368. sndfiles[fd]->true_bufsize = SNDBUFSIZE * SECSIZE; /*may get rounded down for 24bit formats*/
  369. return fd;
  370. }
  371. /*
  372. * The user-accessable routines
  373. */
  374. /*
  375. * open a sndfile
  376. */
  377. int
  378. sndopen(const char *fn)
  379. {
  380. register struct sndfile *sf;
  381. int fd;
  382. rsndinit();
  383. if((fd = findsndfd()) < 0)
  384. return -1;
  385. sf = sndfiles[fd];
  386. if((sf->fd = sfopen(fn)) < 0) {
  387. freesndfd(fd);
  388. return -1;
  389. }
  390. sf->remain = 0;
  391. if(sfgetprop(sf->fd, "sample type",
  392. (char *)&sf->samptype, sizeof(int)) != sizeof(int)) {
  393. rsferrno = ESFNOSTYPE;
  394. rsferrstr = "no sample type defined";
  395. freesndfd(fd);
  396. return -1;
  397. }
  398. #ifdef CDP97
  399. /*RWD only used to rescale floatsams when read into shorts (eg for playback)*/
  400. sf->scale_floats = 0;
  401. sf->fscalefac = 1.0;
  402. #endif
  403. #ifdef NOTDEF
  404. if(sndfilbuf(sf))
  405. sf->remain = -1;
  406. #endif
  407. return fd+SNDFDBASE;
  408. }
  409. int
  410. sndopenEx(const char *fn,int auto_scale, int access)
  411. {
  412. register struct sndfile *sf;
  413. int fd;
  414. rsndinit();
  415. if((fd = findsndfd()) < 0)
  416. return -1;
  417. sf = sndfiles[fd];
  418. if((sf->fd = sfopenEx(fn,access)) < 0) {
  419. freesndfd(fd);
  420. return -1;
  421. }
  422. sf->remain = 0;
  423. if(sfgetprop(sf->fd, "sample type",
  424. (char *)&sf->samptype, sizeof(int)) != sizeof(int)) {
  425. rsferrno = ESFNOSTYPE;
  426. rsferrstr = "no sample type defined";
  427. freesndfd(fd);
  428. return -1;
  429. }
  430. #ifdef SFSYS_UNBUFFERED
  431. if(!(sf->samptype==SAMP_SHORT ||sf->samptype==SAMP_FLOAT)){
  432. rsferrno = ESFBADFORMAT;
  433. rsferrstr = "unsupported sample format";
  434. freesndfd(fd);
  435. return -1;
  436. }
  437. #else
  438. /*RWD only used to rescale floatsams when read into shorts (eg for playback)*/
  439. sf->scale_floats = 0;
  440. sf->fscalefac = 1.0;
  441. if(auto_scale && (sf->samptype==SAMP_FLOAT)){
  442. float fac = 0.0f;
  443. /* RWD 4:2002: I would prefer to rely on PEAK only for this now... */
  444. if(sfgetprop(sf->fd,"maxamp",(char *)&fac,sizeof(float)) == sizeof(float)){
  445. if(fac > sf->fscalefac){
  446. sf->scale_floats = 1;
  447. sf->fscalefac = 0.99995 / (double) fac;
  448. }
  449. }
  450. /*get it from PEAK data if available*/
  451. else if (_rsf_getmaxpeak(sf->fd,&fac) > 0){
  452. if(fac > sf->fscalefac){
  453. sf->scale_floats = 1;
  454. sf->fscalefac = 0.99995 / (double) fac;
  455. }
  456. }
  457. /*Could also provide a set_autoscale() func, legal only before first read (like sndsetbuf)*/
  458. }
  459. /*adjust internal buffer if reading 24bit formats*/
  460. if(sf->samptype==SAMP_2424 || sf->samptype == SAMP_2024)
  461. sf->true_bufsize = (sf->true_bufsize / sampsize[sf->samptype]) * sampsize[sf->samptype];
  462. #endif
  463. #ifdef NOTDEF
  464. if(sndfilbuf(sf))
  465. sf->remain = -1;
  466. #endif
  467. /* need superfluous seek to overcome daft OS problems reopening just-closed file */
  468. if(sndseekEx(fd+SNDFDBASE,0,0) != 0)
  469. return -1;
  470. return fd+SNDFDBASE;
  471. }
  472. #ifdef NOTDEF
  473. /*
  474. * user-called routine for sndcreat
  475. */
  476. int
  477. sndcreat(const char *fn, long size, int stype)
  478. {
  479. register struct sndfile *sf;
  480. int fd;
  481. rsndinit();
  482. if(stype != SAMP_SHORT && stype != SAMP_FLOAT) {
  483. rsferrno = ESFBADPARAM;
  484. rsferrstr = "not a valid sample type";
  485. return -1;
  486. }
  487. if((fd = findsndfd()) < 0)
  488. return -1;
  489. sf = sndfiles[fd];
  490. sf->flags |= SNDFLG_TRUNC;
  491. sf->samptype = stype;
  492. if((sf->fd = sfcreat(fn, size*sampsize[stype], (int *)0)) < 0) {
  493. freesndfd(fd);
  494. return -1;
  495. }
  496. if(sfputprop(sf->fd, "sample type",
  497. (char *)&sf->samptype, sizeof(int)) < 0) {
  498. sfunlink(sf->fd);
  499. sfclose(sf->fd);
  500. freesndfd(fd);
  501. rsferrstr = "can't set sample type";
  502. return -1;
  503. }
  504. sf->remain = (SECSIZE*sf->bufsiz)/sampsize[stype];
  505. #ifdef NOTDEF
  506. if(sndfilbuf(sf))
  507. sf->remain = -1;
  508. #endif
  509. return fd+SNDFDBASE;
  510. }
  511. #endif
  512. int
  513. sndcreat_formatted(const char *fn, int size, int stype,int channels,
  514. int srate,cdp_create_mode mode)
  515. {
  516. register struct sndfile *sf;
  517. int fd;
  518. rsndinit();
  519. if((fd = findsndfd()) < 0)
  520. return -1;
  521. sf = sndfiles[fd];
  522. sf->flags |= SNDFLG_TRUNC;
  523. sf->samptype = stype;
  524. /*RWD NB sampsize[] - no slot for 24bit size yet*/
  525. if((sf->fd = sfcreat_formatted(fn, size*sampsize[stype], (__int64 *)0,channels,srate,
  526. stype,mode)) < 0) {
  527. freesndfd(fd);
  528. return -1;
  529. }
  530. #ifdef SFSYS_UNBUFFERED
  531. /*for 24bit alignment*/
  532. sf->remain = (SECSIZE*sf->bufsiz)/sampsize[stype]
  533. #else
  534. sf->remain = sf->true_bufsize / sampsize[stype];
  535. #endif
  536. #ifdef NOTDEF
  537. if(sndfilbuf(sf))
  538. sf->remain = -1;
  539. #endif
  540. return fd+SNDFDBASE;
  541. }
  542. /*TODO: TEST THIS WITH SOMETHING....*/
  543. int
  544. sndcreat_ex(const char *name, int size,SFPROPS *props,int min_header,cdp_create_mode mode)
  545. {
  546. register struct sndfile *sf;
  547. int fd;
  548. int smpsize;
  549. rsndinit();
  550. if((fd = findsndfd()) < 0)
  551. return -1;
  552. sf = sndfiles[fd];
  553. sf->flags |= SNDFLG_TRUNC;
  554. /* RWD.6.99 write 24bit formats, etc */
  555. switch(props->samptype){
  556. case(FLOAT32):
  557. sf->samptype = SAMP_FLOAT;
  558. break;
  559. case(SHORT16):
  560. sf->samptype = SAMP_SHORT;
  561. break;
  562. case(INT_32):
  563. #ifdef SFSYS_UNBUFFERED
  564. error! /*but this is easy,,,,now we have floats set in header*/
  565. #endif
  566. sf->samptype = SAMP_LONG;
  567. break;
  568. case(INT2424):
  569. #ifdef SFSYS_UNBUFFERED
  570. error!
  571. #endif
  572. sf->samptype = SAMP_2424;
  573. /*adjust sndbuffer with 3-byte alignment*/
  574. sf->true_bufsize = (sf->true_bufsize / sampsize[sf->samptype]) * sampsize[sf->samptype];
  575. break;
  576. case(INT2024):
  577. #ifdef SFSYS_UNBUFFERED
  578. error!
  579. #endif
  580. sf->samptype = SAMP_2024;
  581. /*adjust sndbuffer with 3-byte alignment*/
  582. sf->true_bufsize = (sf->true_bufsize / sampsize[sf->samptype]) * sampsize[sf->samptype];
  583. break;
  584. case(SAMP_MASKED):
  585. #ifdef SFSYS_UNBUFFERED
  586. error!
  587. #endif
  588. /*don't know how to do this yet...*/
  589. rsferrno = ESFBADPARAM;
  590. rsferrstr = "cannot write masked sample type";
  591. return -1;
  592. default:
  593. rsferrno = ESFBADPARAM;
  594. rsferrstr = "unknown sample type";
  595. return -1;
  596. break;
  597. }
  598. /*sf->samptype = (props->samptype == FLOAT32 ? SAMP_FLOAT : SAMP_SHORT);*/
  599. smpsize = sampsize[sf->samptype];
  600. /*need to return to outsize: size / smpsize - check this...*/
  601. if((sf->fd = sfcreat_ex(name, (__int64)size*smpsize, (__int64 *)0,
  602. props,min_header,mode)) < 0) {
  603. freesndfd(fd);
  604. return -1;
  605. }
  606. #ifdef SFSYS_UNBUFFERED
  607. sf->remain = (SECSIZE*sf->bufsiz)/smpsize;
  608. #else
  609. sf->remain = sf->true_bufsize / smpsize;
  610. #endif
  611. #ifdef NOTDEF
  612. if(sndfilbuf(sf))
  613. sf->remain = -1;
  614. #endif
  615. return fd+SNDFDBASE;
  616. }
  617. /*
  618. * close a sndfile
  619. */
  620. int
  621. sndclose(int fd)
  622. {
  623. /* DEPRECATED! */
  624. return -1;
  625. }
  626. int
  627. sndcloseEx(int fd)
  628. {
  629. register struct sndfile *sf;
  630. int rc = 0;
  631. __int64 length, pos;
  632. if(!mapsndfd(&fd))
  633. return -1;
  634. sf = sndfiles[fd];
  635. if(sf->flags&SNDFLG_TRUNC) {
  636. length = sfsize(sf->fd);
  637. pos = sndtellEx(fd + SNDFDBASE); //RWD 12-12-19 make sure of 64bit ints in calcs
  638. pos *= sampsize[sf->samptype];
  639. if(sf->flags & SNDFLG_WRITTEN ) /* should never exec */
  640. sndflsbufEx(sf); /* rsfsize does it! */
  641. if((rc = sfadjust(sf->fd,pos-length)) < 0) {
  642. rsferrno = ESFWRERR;
  643. rsferrstr = "can't truncate SFfile";
  644. }
  645. } else if(sf->flags & SNDFLG_WRITTEN )
  646. sndflsbufEx(sf);
  647. rc |= sfclose(sf->fd);
  648. freesndfd(fd);
  649. return rc;
  650. }
  651. /*RWD.6.98 needed for Release98!*/
  652. int sndunlink(int sndfd)
  653. {
  654. //int size;
  655. struct sndfile *sf;
  656. (void)sndseekEx(sndfd,0,0); /*RWD.7.98 hack to fix bug when closing empty file*/
  657. if(!mapsndfd(&sndfd))
  658. return -1;
  659. sf = sndfiles[sndfd];
  660. return sfunlink(sf->fd);
  661. }
  662. /*
  663. * Return the size (in samples) of a sndfile
  664. * NOTE
  665. * the first sndseek will flush buffer if necessary
  666. */
  667. int
  668. sndsizeEx(int sfd)
  669. {
  670. int oldpos;
  671. int size;
  672. if((oldpos = sndtellEx(sfd)) < 0)
  673. return -1;
  674. if((size = sndseekEx(sfd, 0L, 2)) < 0) {
  675. size = -1;
  676. rsferrno = ESFNOSEEK;
  677. rsferrstr = "can't seek to end of file to find size";
  678. }
  679. if(sndseekEx(sfd, oldpos, 0) < 0) {
  680. rsferrno = ESFNOSEEK;
  681. rsferrstr = "can't restore position after finding file size";
  682. return -1;
  683. }
  684. return size;
  685. }
  686. /*
  687. * seek in a sndfile (of SHORTS or FLOATS)
  688. */
  689. int
  690. sndseek(int fd, int dist, int whence)
  691. {
  692. //return sndseekEx(fd,dist,whence);
  693. return -1;
  694. }
  695. int
  696. sndseekEx(int fd, int dist, int whence)
  697. {
  698. register struct sndfile *sf;
  699. long bufsize;
  700. #ifdef FILE64_WIN
  701. __int64 secpos;
  702. __int64 newpos;
  703. __int64 gotpos;
  704. #else
  705. __int64 secpos;
  706. __int64 newpos = 0;
  707. __int64 gotpos;
  708. #endif
  709. if(!mapsndfd(&fd))
  710. return -1;
  711. sf = sndfiles[fd];
  712. #ifdef SFSYS_UNBUFFERED
  713. bufsize = sf->bufsiz<<LOGSECSIZE;
  714. #else
  715. bufsize = sf->true_bufsize;
  716. #endif
  717. if((sf->flags & SNDFLG_WRITTEN) && sndflsbufEx(sf))
  718. return -1;
  719. switch(whence) {
  720. case 0:
  721. newpos = dist; /*in SAMPLES: NB must deal with 8bit files!*/
  722. break;
  723. case 1:
  724. newpos = sndtellEx(fd+SNDFDBASE) + dist;
  725. break;
  726. case 2:
  727. newpos = sfsize(sf->fd); /*size-specific:SHORTSAMS, from datachunksize*/
  728. newpos = (newpos / sampsize[sf->samptype]) + dist; /*make non-size-specific*/
  729. break;
  730. }
  731. if(newpos < 0)
  732. newpos = 0;
  733. newpos *= sampsize[sf->samptype]; /* byte offset */ /*restore size-specific for doseek*/
  734. /*RWD.6.99 still need to do this - not a SECSIZE calc, but just cdp_round to our buffersize*/
  735. secpos = (newpos/bufsize)*bufsize; /* cdp_round down */
  736. /*RWD 2007: NB for FILE64_WIN doseekEx takes and returns __int64 */
  737. if((gotpos = doseekEx(sf, secpos, 0)) < 0)/*NB seek might be truncated */ /*gotpos = non-size-specific*/
  738. return -1;
  739. sf->flags &= ~SNDFLG_ATEND;
  740. if(sndfilbuf(sf)) { /* if sndfilbuf fails... */
  741. sf->next = sf->buffer;
  742. sf->remain = 0;
  743. return -1;
  744. }
  745. if(gotpos < secpos) {
  746. newpos -= sf->remain; /*RWD 2007 !!! remain supposed to count ~samples~ */
  747. sf->remain = 0;
  748. }
  749. #ifdef FILE64_WIN
  750. sf->next = &sf->buffer[(unsigned long)newpos % bufsize];
  751. #else
  752. sf->next = &sf->buffer[(unsigned long)newpos%bufsize];
  753. #endif
  754. newpos /= sampsize[sf->samptype];
  755. sf->remain = (sf->endbuf - sf->next)/sampsize[sf->samptype];
  756. #ifdef FILE64_WIN
  757. return (long) newpos;
  758. #else
  759. return (long) newpos;
  760. #endif
  761. }
  762. /*
  763. * Where are we in the present sndfile
  764. * NOTE
  765. * This does not need to flush buffers, etc
  766. */
  767. int
  768. sndtell(int fd)
  769. {
  770. return -1;
  771. }
  772. /*RWD 2007 FIXME for 64bit reads: */
  773. /* doseekEx must return unsigned long, or __int64 value */
  774. int
  775. sndtellEx(int fd)
  776. {
  777. struct sndfile *sf;
  778. #ifdef FILE64_WIN
  779. __int64 off;
  780. #else
  781. //long off;
  782. __int64 off;
  783. #endif
  784. if(!mapsndfd(&fd))
  785. return -1;
  786. sf = sndfiles[fd];
  787. if((off = doseekEx(sf, 0L, 1)) < 0) { /*NB: must return cnt of samples * sizeof(type=SHORTS or FLOATS)*/
  788. rsferrno = ESFNOSEEK;
  789. rsferrstr = "can't seek to find present position in file";
  790. return -1;
  791. }
  792. if(sf->flags & SNDFLG_LASTWR) /*RWD.5.1.99 fails for short sndfiles within a buffer*/
  793. #ifdef SFSY_UNBUFFERED
  794. off += sf->bufsiz<<LOGSECSIZE;
  795. #else
  796. off += sf->true_bufsize;
  797. #endif
  798. if(sf->flags & SNDFLG_ATEND)
  799. off = sfsize(sf->fd); /*bytes, of SHORTS or FLOATS samps*/
  800. off /= sampsize[sf->samptype];
  801. #ifdef FILE64_WIN
  802. return (int)(off - ( (sf->remain < 0) ? 0 : sf->remain));
  803. #else
  804. return (int)(off - ( (sf->remain < 0) ? 0 : sf->remain));
  805. #endif
  806. }
  807. /*
  808. * let the user supply a larger buffer
  809. */
  810. /*RWD.6.99 NB bufsize is in SECTORS - may need new version for new formats...*/
  811. int
  812. sndsetbuf(int sfd, char *buf, int bufsize)
  813. {
  814. struct sndfile *sf;
  815. if(!mapsndfd(&sfd))
  816. return -1;
  817. sf = sndfiles[sfd];
  818. if(sf->remain != 0) {
  819. rsferrno = ESFLOSEDATA;
  820. rsferrstr = "sndsetbuf would lose data";
  821. return -1;
  822. }
  823. freesndbuf(sfd);
  824. sf->buffer = buf;
  825. sf->bufsiz = bufsize;
  826. #ifdef CDP97
  827. sf->true_bufsize = sf->bufsiz << LOGSECSIZE;
  828. #endif
  829. sf->flags |= SNDFLG_USERBUF;
  830. return 0;
  831. }
  832. /*
  833. * snd I/O routines
  834. */
  835. /*
  836. * fgetfloat - read the next float
  837. */
  838. int
  839. fgetfloat(float *fp, int sfd)
  840. {
  841. register struct sndfile *sfp;
  842. if(!mapsndfd(&sfd))
  843. return -1;
  844. sfp = sndfiles[sfd];
  845. if(sfp->remain < 0)
  846. return 0;
  847. if(sfp->remain-- == 0) {
  848. if(sndfilbuf(sfp))
  849. return -1;
  850. if(sfp->remain-- <= 0)
  851. return 0;
  852. }
  853. if(sfp->samptype == SAMP_FLOAT) {
  854. *fp = *(float *)sfp->next;
  855. sfp->next += sizeof(float);
  856. } else {
  857. *fp = (float)(*(short *)sfp->next) / (float)MAXSHORT;
  858. sfp->next += sizeof(short);
  859. }
  860. return 1;
  861. }
  862. int
  863. fgetfloatEx(float *fp, int sfd,int expect_floats)
  864. {
  865. register struct sndfile *sfp;
  866. long lword = 0;
  867. long mask; /*we need signed ints*/
  868. SND_SAMP ssamp;
  869. if(!mapsndfd(&sfd))
  870. return -1;
  871. sfp = sndfiles[sfd];
  872. if(sfp->remain < 0)
  873. return 0;
  874. if(sfp->remain-- == 0) {
  875. if(sndfilbuf(sfp))
  876. return -1;
  877. if(sfp->remain-- <= 0)
  878. return 0;
  879. }
  880. ssamp.lsamp = 0;
  881. switch(sfp->samptype){
  882. case(SAMP_FLOAT):
  883. *fp = *(float *)sfp->next;
  884. sfp->next += sizeof(float);
  885. break;
  886. case(SAMP_SHORT):
  887. *fp = (float)(*(short *)sfp->next) / (float)MAXSHORT;
  888. sfp->next += sizeof(short);
  889. break;
  890. case(SAMP_LONG):
  891. if(expect_floats){
  892. *fp = *(float *)sfp->next;
  893. sfp->next += sizeof(float);
  894. }
  895. else{
  896. *fp = (float)((double) (*(int *)sfp->next) / (float)MAXINT);
  897. sfp->next += sizeof(int);
  898. }
  899. break;
  900. case(SAMP_2432):
  901. /*mask the word first*/
  902. lword = *(long *)sfp->next;
  903. lword &= 0xffffff00;
  904. *fp = (float)((double)lword / MAXINT);
  905. sfp->next += sizeof(int);
  906. break;
  907. case(SAMP_2024): /*need to mask it?*/
  908. ssamp.lsamp = 0;
  909. mask = _rsf_getbitmask(sfp->fd);
  910. if(mask==0)
  911. return -1;
  912. #ifdef LSBFIRST
  913. ssamp.bytes[1] = sfp->next[0];
  914. ssamp.bytes[2] = sfp->next[1];
  915. ssamp.bytes[3] = sfp->next[2];
  916. #else
  917. ssamp.bytes[0] = sfp->next[0];
  918. ssamp.bytes[1] = sfp->next[1];
  919. ssamp.bytes[2] = sfp->next[2];
  920. #endif
  921. *fp = (float)((double)(ssamp.lsamp & mask) / MAXINT);
  922. sfp->next += 3;
  923. break;
  924. case(SAMP_2424):
  925. #ifdef LSBFIRST
  926. ssamp.bytes[1] = sfp->next[0];
  927. ssamp.bytes[2] = sfp->next[1];
  928. ssamp.bytes[3] = sfp->next[2];
  929. #else
  930. ssamp.bytes[0] = sfp->next[0];
  931. ssamp.bytes[1] = sfp->next[1];
  932. ssamp.bytes[2] = sfp->next[2];
  933. #endif
  934. *fp = (float)((double)(ssamp.lsamp) / MAXINT);
  935. sfp->next += 3;
  936. break;
  937. default:
  938. rsferrno = ESFBADPARAM;
  939. rsferrstr = "attempted to read unknown sample format";
  940. return -1; /*do others later...*/
  941. break;
  942. }
  943. return 1;
  944. }
  945. /*
  946. * fputfloat - write the next float
  947. */
  948. int
  949. fputfloat(float *fp, int sfd)
  950. {
  951. register struct sndfile *sfp;
  952. if(!mapsndfd(&sfd))
  953. return -1;
  954. sfp = sndfiles[sfd];
  955. if(sfp->flags&SNDFLG_ATEND)
  956. return 0;
  957. sfp->flags |= SNDFLG_WRITTEN;
  958. #ifdef CDP97
  959. /* sndtell checks this*/
  960. sfp->flags |= SNDFLG_LASTWR;
  961. #endif
  962. if(sfp->samptype == SAMP_FLOAT) {
  963. *(float *)sfp->next = *fp;
  964. sfp->next += sizeof(float);
  965. } else {
  966. /* *(short *)sfp->next = (short) floor(0.5 + *fp * MAXSHORT);*/
  967. *(short *)sfp->next = (short) cdp_round( *fp * MAXSHORT);
  968. sfp->next += sizeof(short);
  969. }
  970. if(sfp->next > sfp->endbuf)
  971. sfp->endbuf = sfp->next;
  972. if(--sfp->remain == 0) {
  973. if(sndflsbuf(sfp))
  974. return -1;
  975. }
  976. return 1;
  977. }
  978. /*RWD.7.99 replace floor calc with cdp_round(): more accurate!*/
  979. int
  980. fputfloatEx(float *fp, int sfd)
  981. {
  982. register struct sndfile *sfp;
  983. SND_SAMP ssamp;
  984. if(!mapsndfd(&sfd))
  985. return -1;
  986. sfp = sndfiles[sfd];
  987. if(sfp->flags&SNDFLG_ATEND)
  988. return 0;
  989. sfp->flags |= SNDFLG_WRITTEN;
  990. #ifdef CDP97
  991. /* sndtell checks this*/
  992. sfp->flags |= SNDFLG_LASTWR;
  993. #endif
  994. ssamp.lsamp = 0;
  995. switch(sfp->samptype){
  996. case(SAMP_FLOAT):
  997. *(float *)sfp->next = *fp;
  998. sfp->next += sizeof(float);
  999. break;
  1000. case(SAMP_SHORT):
  1001. /* *(short *)sfp->next = (short)floor(0.5 + *fp * MAXSHORT);*/
  1002. *(short *)sfp->next = (short) cdp_round( *fp * MAXSHORT);
  1003. sfp->next += sizeof(short);
  1004. break;
  1005. case(SAMP_2024):
  1006. /*ssamp.lsamp = (int) floor(0.5 + *fp * MAXINT);*/
  1007. ssamp.lsamp = (int) cdp_round(*fp * MAXINT);
  1008. #ifdef LSBFIRST
  1009. sfp->next[0] = ssamp.bytes[1] & 0xf0;
  1010. sfp->next[1] = ssamp.bytes[2];
  1011. sfp->next[2] = ssamp.bytes[3];
  1012. #else
  1013. sfp->next[0] = ssamp.bytes[0] & 0xf0;
  1014. sfp->next[1] = ssamp.bytes[1];
  1015. sfp->next[2] = ssamp.bytes[2];
  1016. #endif
  1017. sfp->next += 3;
  1018. break;
  1019. case(SAMP_2424):
  1020. /*ssamp.lsamp = (int) floor(0.5 + *fp * MAXINT);*/
  1021. ssamp.lsamp = (int) cdp_round(*fp * MAXINT);
  1022. #ifdef LSBFIRST
  1023. sfp->next[0] = ssamp.bytes[1];
  1024. sfp->next[1] = ssamp.bytes[2];
  1025. sfp->next[2] = ssamp.bytes[3];
  1026. #else
  1027. sfp->next[0] = ssamp.bytes[0];
  1028. sfp->next[1] = ssamp.bytes[1];
  1029. sfp->next[2] = ssamp.bytes[2];
  1030. #endif
  1031. sfp->next += 3;
  1032. break;
  1033. case(SAMP_LONG):
  1034. /* *(long *)sfp->next = (long) floor(0.5 + *fp * MAXINT);*/
  1035. *(int *)sfp->next = (int) cdp_round(*fp * MAXINT);
  1036. sfp->next += sizeof(int);
  1037. break;
  1038. case(SAMP_2432):
  1039. /*ssamp.lsamp = (int) floor(0.5 + *fp * MAXINT);*/
  1040. ssamp.lsamp = (int) cdp_round(*fp * MAXINT);
  1041. ssamp.bytes[0] = 0;
  1042. *(int *)sfp->next = ssamp.lsamp;
  1043. sfp->next += sizeof(int);
  1044. break;
  1045. default:
  1046. rsferrno = ESFBADPARAM;
  1047. rsferrstr = "attempted to write unknown sample format";
  1048. return -1; /*do others later...*/
  1049. break;
  1050. }
  1051. if(sfp->next > sfp->endbuf)
  1052. sfp->endbuf = sfp->next;
  1053. if(--sfp->remain == 0) {
  1054. if(sndflsbufEx(sfp))
  1055. return -1;
  1056. }
  1057. return 1;
  1058. }
  1059. /*
  1060. * fgetfbuf - get a sequence of float-sams
  1061. */
  1062. int
  1063. fgetfbuf(float *fp, int n, int sfd)
  1064. {
  1065. register struct sndfile *sfp;
  1066. int chunk;
  1067. int cnt = 0;
  1068. if(!mapsndfd(&sfd))
  1069. return -1;
  1070. sfp = sndfiles[sfd];
  1071. if(sfp->samptype == SAMP_SHORT) {
  1072. sfd += SNDFDBASE;
  1073. while(cnt < n && fgetfloat(fp++, sfd) > 0)
  1074. cnt++;
  1075. return cnt;
  1076. }
  1077. while(cnt < n) {
  1078. if(sfp->remain == 0) {
  1079. if(sndfilbuf(sfp) || sfp->remain == 0)
  1080. return cnt;
  1081. }
  1082. chunk = n - cnt;
  1083. if(chunk > sfp->remain)
  1084. chunk = sfp->remain;
  1085. memcpy((char *)fp, sfp->next, chunk*sizeof(float));
  1086. sfp->remain -= chunk;
  1087. sfp->next += chunk*sizeof(float);
  1088. cnt += chunk;
  1089. fp += chunk;
  1090. }
  1091. return cnt;
  1092. }
  1093. /*RWD.6.99 probably the tidiest way of dealing with old floatsam files
  1094. * expect_float must be non-zero to trigger
  1095. */
  1096. int
  1097. fgetfbufEx(float *fp, int n, int sfd,int expect_floats)
  1098. {
  1099. register struct sndfile *sfp;
  1100. int chunk;
  1101. int cnt = 0;
  1102. if(!mapsndfd(&sfd))
  1103. return -1;
  1104. sfp = sndfiles[sfd];
  1105. if(sfp->samptype==SAMP_FLOAT || ((sfp->samptype==INT_32) && expect_floats)){
  1106. while(cnt < n) {
  1107. if(sfp->remain == 0) {
  1108. if(sndfilbuf(sfp) || sfp->remain == 0)
  1109. return cnt;
  1110. }
  1111. chunk = n - cnt;
  1112. if(chunk > sfp->remain)
  1113. chunk = sfp->remain;
  1114. memcpy((char *)fp, sfp->next, chunk*sizeof(float));
  1115. sfp->remain -= chunk;
  1116. sfp->next += chunk*sizeof(float);
  1117. cnt += chunk;
  1118. fp += chunk;
  1119. }
  1120. }
  1121. else{
  1122. sfd += SNDFDBASE;
  1123. while(cnt < n && (fgetfloatEx(fp++, sfd,expect_floats) > 0))
  1124. cnt++;
  1125. /*return cnt;*/
  1126. }
  1127. return cnt;
  1128. }
  1129. /*
  1130. * fputfbuf - put a sequence of float-sams
  1131. */
  1132. int
  1133. fputfbuf(float *fp, int n, int sfd)
  1134. {
  1135. register struct sndfile *sfp;
  1136. int chunk;
  1137. int cnt = 0;
  1138. if(!mapsndfd(&sfd))
  1139. return -1;
  1140. sfp = sndfiles[sfd];
  1141. if(sfp->samptype == SAMP_SHORT) {
  1142. sfd += SNDFDBASE;
  1143. while(cnt < n && fputfloat(fp++, sfd) > 0)
  1144. cnt++;
  1145. return cnt;
  1146. }
  1147. while(cnt < n) {
  1148. sfp->flags |= SNDFLG_WRITTEN;
  1149. #ifdef CDP97
  1150. /* sndtell checks this*/
  1151. sfp->flags |= SNDFLG_LASTWR;
  1152. #endif
  1153. chunk = n - cnt;
  1154. if(chunk > sfp->remain)
  1155. chunk = sfp->remain;
  1156. memcpy(sfp->next, (char *)fp, chunk*sizeof(float));
  1157. sfp->remain -= chunk;
  1158. sfp->next += chunk*sizeof(float);
  1159. if(sfp->next > sfp->endbuf)
  1160. sfp->endbuf = sfp->next;
  1161. cnt += chunk;
  1162. fp += chunk;
  1163. if(sfp->remain == 0) {
  1164. if(sndflsbuf(sfp))
  1165. return -1;
  1166. if(sfp->remain == 0)
  1167. return cnt;
  1168. }
  1169. }
  1170. return cnt;
  1171. }
  1172. int
  1173. fputfbufEx(float *fp, int n, int sfd)
  1174. {
  1175. register struct sndfile *sfp;
  1176. int chunk;
  1177. int cnt = 0;
  1178. if(!mapsndfd(&sfd))
  1179. return -1;
  1180. sfp = sndfiles[sfd];
  1181. if(sfp->samptype == SAMP_SHORT) {
  1182. sfd += SNDFDBASE;
  1183. while(cnt < n && fputfloatEx(fp++, sfd) > 0)
  1184. cnt++;
  1185. return cnt;
  1186. }
  1187. if(sfp->samptype == SAMP_FLOAT){
  1188. while(cnt < n) {
  1189. sfp->flags |= SNDFLG_WRITTEN;
  1190. #ifdef CDP97
  1191. /* sndtell checks this*/
  1192. sfp->flags |= SNDFLG_LASTWR;
  1193. #endif
  1194. chunk = n - cnt;
  1195. if(chunk > sfp->remain)
  1196. chunk = sfp->remain;
  1197. memcpy(sfp->next, (char *)fp, chunk*sizeof(float));
  1198. sfp->remain -= chunk;
  1199. sfp->next += chunk*sizeof(float);
  1200. if(sfp->next > sfp->endbuf)
  1201. sfp->endbuf = sfp->next;
  1202. cnt += chunk;
  1203. fp += chunk;
  1204. if(sfp->remain == 0) {
  1205. if(sndflsbufEx(sfp))
  1206. return -1;
  1207. if(sfp->remain == 0)
  1208. return cnt;
  1209. }
  1210. }
  1211. }
  1212. else {
  1213. sfd += SNDFDBASE;
  1214. while(cnt < n && fputfloatEx(fp++, sfd) > 0)
  1215. cnt++;
  1216. return cnt;
  1217. }
  1218. return cnt;
  1219. }
  1220. /*
  1221. * fgetshort - read the next short
  1222. */
  1223. int
  1224. fgetshort(short *sp, int sfd)
  1225. {
  1226. register struct sndfile *sfp;
  1227. if(!mapsndfd(&sfd))
  1228. return -1;
  1229. sfp = sndfiles[sfd];
  1230. if(sfp->remain < 0)
  1231. return 0;
  1232. if(sfp->remain-- == 0) {
  1233. if(sndfilbuf(sfp))
  1234. return -1;
  1235. if(sfp->remain-- <= 0)
  1236. return 0;
  1237. }
  1238. if(sfp->samptype == SAMP_FLOAT) {
  1239. #ifdef CDP97
  1240. if(sfp->scale_floats==1)
  1241. /* *sp = (short)(floor(0.5 + (sfp->fscalefac * (*(float *)sfp->next * MAXSHORT)))); */
  1242. *sp = (short) cdp_round((sfp->fscalefac * (*(float *)sfp->next * MAXSHORT)));
  1243. else
  1244. #endif
  1245. *sp = (short) cdp_round( *(float *)sfp->next * MAXSHORT);
  1246. sfp->next += sizeof(float);
  1247. } else {
  1248. /*RWD does this read 8bit words properly ?*/
  1249. *sp = *(short *)sfp->next;
  1250. sfp->next += sizeof(short);
  1251. }
  1252. return 1;
  1253. }
  1254. /* RWD.7.99 use cdp_round() instead of floor(): later, try shoft/truncate and/or dithering! */
  1255. int
  1256. fgetshortEx(short *sp, int sfd,int expect_floats)
  1257. {
  1258. struct sndfile *sfp;
  1259. int lword = 0;
  1260. int mask;
  1261. SND_SAMP ssamp;
  1262. if(!mapsndfd(&sfd))
  1263. return -1;
  1264. sfp = sndfiles[sfd];
  1265. if(sfp->remain < 0)
  1266. return 0;
  1267. if(sfp->remain-- == 0) {
  1268. if(sndfilbuf(sfp))
  1269. return -1;
  1270. if(sfp->remain-- <= 0)
  1271. return 0;
  1272. }
  1273. ssamp.lsamp = 0;
  1274. switch(sfp->samptype){
  1275. case(SAMP_FLOAT):
  1276. #ifdef CDP97
  1277. if(sfp->scale_floats==1)
  1278. /* *sp = (short)(floor(0.5 + (sfp->fscalefac * (*(float *)sfp->next * MAXSHORT))));*/
  1279. *sp = (short) cdp_round((sfp->fscalefac * (*(float *)sfp->next * MAXSHORT)));
  1280. else
  1281. #endif
  1282. /* *sp = (short)floor(0.5 + *(float *)sfp->next * MAXSHORT);*/
  1283. *sp = (short) cdp_round( *(float *)sfp->next * MAXSHORT);
  1284. sfp->next += sizeof(float);
  1285. break;
  1286. case(SAMP_SHORT):
  1287. *sp = *(short *)sfp->next;
  1288. sfp->next += sizeof(short);
  1289. break;
  1290. case(SAMP_LONG):
  1291. if(expect_floats){
  1292. #ifdef CDP97
  1293. if(sfp->scale_floats==1)
  1294. /* *sp = (short)(floor(0.5 + (sfp->fscalefac * (*(float *)sfp->next * MAXSHORT))));*/
  1295. *sp = (short) cdp_round((sfp->fscalefac * (*(float *)sfp->next * MAXSHORT)));
  1296. else
  1297. #endif
  1298. /* *sp = (short)floor(0.5 + *(float *)sfp->next * MAXSHORT);*/
  1299. *sp = (short) cdp_round( *(float *)sfp->next * MAXSHORT);
  1300. sfp->next += sizeof(float);
  1301. }
  1302. else{
  1303. *sp = (short)( (*(int *)sfp->next) >> 16);
  1304. sfp->next += sizeof(int);
  1305. }
  1306. break;
  1307. case(SAMP_2432):
  1308. /*mask the word first*/
  1309. lword = *(int *)sfp->next;
  1310. lword &= 0xffffff00;
  1311. *sp = (short)(lword >> 16);
  1312. sfp->next += sizeof(int);
  1313. break;
  1314. case(SAMP_2024): /*need to mask it?*/
  1315. mask = _rsf_getbitmask(sfp->fd);
  1316. if(mask==0)
  1317. return -1;
  1318. ssamp.bytes[1] = sfp->next[0];
  1319. ssamp.bytes[2] = sfp->next[1];
  1320. ssamp.bytes[3] = sfp->next[2];
  1321. *sp = (short)((ssamp.lsamp & mask) >> 16);
  1322. sfp->next += 3;
  1323. break;
  1324. case(SAMP_2424):
  1325. ssamp.bytes[1] = sfp->next[0];
  1326. ssamp.bytes[2] = sfp->next[1];
  1327. ssamp.bytes[3] = sfp->next[2];
  1328. *sp = (short)(ssamp.lsamp >> 16);
  1329. sfp->next += 3;
  1330. break;
  1331. default:
  1332. rsferrno = ESFBADPARAM;
  1333. rsferrstr = "attempted to read unknown sample format";
  1334. return -1; /*do others later...*/
  1335. break;
  1336. }
  1337. return 1;
  1338. }
  1339. /*
  1340. * fputshort - write the next short
  1341. */
  1342. int
  1343. fputshort(short *sp, int sfd)
  1344. {
  1345. register struct sndfile *sfp;
  1346. if(!mapsndfd(&sfd))
  1347. return -1;
  1348. sfp = sndfiles[sfd];
  1349. if(sfp->flags&SNDFLG_ATEND)
  1350. return 0;
  1351. sfp->flags |= SNDFLG_WRITTEN;
  1352. #ifdef CDP97
  1353. /* sndtell checks this*/
  1354. sfp->flags |= SNDFLG_LASTWR;
  1355. #endif
  1356. if(sfp->samptype == SAMP_FLOAT) {
  1357. *(float *)sfp->next = (float)*sp / (float)MAXSHORT;
  1358. sfp->next += sizeof(float);
  1359. } else {
  1360. *(short *)sfp->next = *sp;
  1361. sfp->next += sizeof(short);
  1362. }
  1363. if(sfp->next > sfp->endbuf)
  1364. sfp->endbuf = sfp->next;
  1365. if(--sfp->remain == 0) {
  1366. if(sndflsbuf(sfp))
  1367. return -1;
  1368. }
  1369. return 1;
  1370. }
  1371. int
  1372. fputshortEx(short *sp, int sfd)
  1373. {
  1374. register struct sndfile *sfp;
  1375. SND_SAMP ssamp;
  1376. if(!mapsndfd(&sfd))
  1377. return -1;
  1378. sfp = sndfiles[sfd];
  1379. if(sfp->flags&SNDFLG_ATEND)
  1380. return 0;
  1381. sfp->flags |= SNDFLG_WRITTEN;
  1382. #ifdef CDP97
  1383. /* sndtell checks this*/
  1384. sfp->flags |= SNDFLG_LASTWR;
  1385. #endif
  1386. ssamp.lsamp = 0;
  1387. switch(sfp->samptype){
  1388. case(SAMP_FLOAT):
  1389. *(float *)sfp->next = (float)*sp / (float)MAXSHORT;
  1390. sfp->next += sizeof(float);
  1391. break;
  1392. case(SAMP_SHORT):
  1393. *(short *)sfp->next = *sp;
  1394. sfp->next += sizeof(short);
  1395. break;
  1396. case(SAMP_2024):
  1397. /*no need to mask; 16 bits anyway!*/
  1398. case(SAMP_2424):
  1399. ssamp.lsamp = (int) ((*sp) << 16);
  1400. sfp->next[0] = ssamp.bytes[1];
  1401. sfp->next[1] = ssamp.bytes[2];
  1402. sfp->next[2] = ssamp.bytes[3];
  1403. sfp->next += 3;
  1404. break;
  1405. case(SAMP_LONG):
  1406. case(SAMP_2432):
  1407. ssamp.lsamp = (int) ((*sp) << 16);
  1408. *(int *)sfp->next = ssamp.lsamp;
  1409. sfp->next += sizeof(int);
  1410. break;
  1411. default:
  1412. rsferrno = ESFBADPARAM;
  1413. rsferrstr = "attempted to write unknown sample format";
  1414. return -1; /*do others later...*/
  1415. break;
  1416. }
  1417. if(sfp->next > sfp->endbuf)
  1418. sfp->endbuf = sfp->next;
  1419. if(--sfp->remain == 0) {
  1420. if(sndflsbufEx(sfp))
  1421. return -1;
  1422. }
  1423. return 1;
  1424. }
  1425. /*
  1426. * fgetsbuf - get a sequence of short-sams
  1427. */
  1428. int
  1429. fgetsbuf(short *sp, int n, int sfd)
  1430. {
  1431. register struct sndfile *sfp;
  1432. int chunk;
  1433. int cnt = 0;
  1434. if(!mapsndfd(&sfd))
  1435. return -1;
  1436. sfp = sndfiles[sfd];
  1437. if(sfp->samptype == SAMP_FLOAT) {
  1438. sfd += SNDFDBASE;
  1439. while(cnt < n && fgetshort(sp++, sfd) > 0)
  1440. cnt++;
  1441. return cnt;
  1442. }
  1443. /*RWD: now, may be either SHORTS or BYTES samples!*/
  1444. while(cnt < n) {
  1445. if(sfp->remain == 0) {
  1446. if(sndfilbuf(sfp) || sfp->remain == 0)
  1447. return cnt;
  1448. }
  1449. chunk = n - cnt;
  1450. if(chunk > sfp->remain)
  1451. chunk = sfp->remain;
  1452. memcpy((char *)sp, sfp->next, chunk*sizeof(short));
  1453. sfp->remain -= chunk;
  1454. sfp->next += chunk*sizeof(short);
  1455. cnt += chunk;
  1456. sp += chunk;
  1457. }
  1458. return cnt;
  1459. }
  1460. int
  1461. fgetsbufEx(short *sp, int n, int sfd,int expect_floats)
  1462. {
  1463. register struct sndfile *sfp;
  1464. int chunk;
  1465. int cnt = 0;
  1466. if(!mapsndfd(&sfd))
  1467. return -1;
  1468. sfp = sndfiles[sfd];
  1469. switch(sfp->samptype){
  1470. case(SAMP_SHORT):
  1471. while(cnt < n) {
  1472. if(sfp->remain <= 0) { /*RWD.6.99 was == 0*/
  1473. if(sndfilbuf(sfp) || (sfp->remain == 0))
  1474. return cnt;
  1475. }
  1476. chunk = n - cnt;
  1477. if(chunk > sfp->remain)
  1478. chunk = sfp->remain;
  1479. memcpy((char *)sp, sfp->next, chunk*sizeof(short));
  1480. sfp->remain -= chunk;
  1481. sfp->next += chunk*sizeof(short);
  1482. cnt += chunk;
  1483. sp += chunk;
  1484. }
  1485. break;
  1486. default:
  1487. sfd += SNDFDBASE;
  1488. while(cnt < n && fgetshortEx(sp++, sfd,expect_floats) > 0)
  1489. cnt++;
  1490. break;
  1491. }
  1492. return cnt;
  1493. }
  1494. /*
  1495. * fputsbuf - put a sequence of short-sams
  1496. */
  1497. int
  1498. fputsbuf(short *sp, int n, int sfd)
  1499. {
  1500. register struct sndfile *sfp;
  1501. int chunk;
  1502. int cnt = 0;
  1503. if(!mapsndfd(&sfd))
  1504. return -1;
  1505. sfp = sndfiles[sfd];
  1506. if(sfp->samptype == SAMP_FLOAT) {
  1507. sfd += SNDFDBASE;
  1508. while(cnt < n && fputshort(sp++, sfd) > 0)
  1509. cnt++;
  1510. return cnt;
  1511. }
  1512. while(cnt < n) {
  1513. sfp->flags |= SNDFLG_WRITTEN;
  1514. #ifdef CDP97
  1515. /* sndtell checks this*/
  1516. sfp->flags |= SNDFLG_LASTWR;
  1517. #endif
  1518. chunk = n - cnt;
  1519. if(chunk > sfp->remain)
  1520. chunk = sfp->remain;
  1521. memcpy(sfp->next, (char *)sp, chunk*sizeof(short));
  1522. sfp->remain -= chunk;
  1523. sfp->next += chunk*sizeof(short);
  1524. if(sfp->next > sfp->endbuf)
  1525. sfp->endbuf = sfp->next;
  1526. cnt += chunk;
  1527. sp += chunk;
  1528. if(sfp->remain == 0) {
  1529. if(sndflsbuf(sfp))
  1530. return -1;
  1531. if(sfp->remain == 0)
  1532. return cnt;
  1533. }
  1534. }
  1535. return cnt;
  1536. }
  1537. int
  1538. fputsbufEx(short *sp, int n, int sfd)
  1539. {
  1540. register struct sndfile *sfp;
  1541. int chunk;
  1542. int cnt = 0;
  1543. if(!mapsndfd(&sfd))
  1544. return -1;
  1545. sfp = sndfiles[sfd];
  1546. switch(sfp->samptype){
  1547. case(SAMP_SHORT):
  1548. while(cnt < n) {
  1549. sfp->flags |= SNDFLG_WRITTEN;
  1550. #ifdef CDP97
  1551. /* sndtell checks this*/
  1552. sfp->flags |= SNDFLG_LASTWR;
  1553. #endif
  1554. chunk = n - cnt;
  1555. if(chunk > sfp->remain)
  1556. chunk = sfp->remain;
  1557. memcpy(sfp->next, (char *)sp, chunk*sizeof(short));
  1558. sfp->remain -= chunk;
  1559. sfp->next += chunk*sizeof(short);
  1560. if(sfp->next > sfp->endbuf)
  1561. sfp->endbuf = sfp->next;
  1562. cnt += chunk;
  1563. sp += chunk;
  1564. if(sfp->remain == 0) {
  1565. if(sndflsbufEx(sfp))
  1566. return -1;
  1567. if(sfp->remain == 0)
  1568. return cnt;
  1569. }
  1570. }
  1571. break;
  1572. default:
  1573. sfd += SNDFDBASE;
  1574. while(cnt < n && fputshortEx(sp++, sfd) > 0)
  1575. cnt++;
  1576. break;
  1577. }
  1578. return cnt;
  1579. }
  1580. /*
  1581. * The property stuff, for sndfiles
  1582. */
  1583. int
  1584. sndgetprop(int sfd, char *prop, char *dest, int lim)
  1585. {
  1586. if(!mapsndfd(&sfd))
  1587. return -1;
  1588. return sfgetprop(sndfiles[sfd]->fd, prop, dest, lim);
  1589. }
  1590. int
  1591. sndputprop(int sfd, char *prop, char *src, int size)
  1592. {
  1593. if(!mapsndfd(&sfd))
  1594. return -1;
  1595. if(strcmp(prop, "sample type") == 0) {
  1596. rsferrno = ESFNOSTYPE;
  1597. rsferrstr = "can't change sample type on sndfile";
  1598. return -1;
  1599. }
  1600. return sfputprop(sndfiles[sfd]->fd, prop, src, size);
  1601. }
  1602. int
  1603. sndrmprop(int sfd, char *prop)
  1604. {
  1605. if(!mapsndfd(&sfd))
  1606. return -1;
  1607. if(strcmp(prop, "sample type") == 0) {
  1608. rsferrno = ESFNOSTYPE;
  1609. rsferrstr = "can't remove sample type on sndfile";
  1610. return -1;
  1611. }
  1612. return sfrmprop(sndfiles[sfd]->fd, prop);
  1613. }
  1614. int
  1615. snddirprop(int sfd, int (*func)(char *propname, int propsize))
  1616. {
  1617. if(!mapsndfd(&sfd))
  1618. return -1;
  1619. return sfdirprop(sndfiles[sfd]->fd, func);
  1620. }
  1621. /*RWD OCT97*/
  1622. int sndgetwordsize(int sfd)
  1623. {
  1624. if(!mapsndfd(&sfd))
  1625. return -1;
  1626. return sfgetwordsize(sndfiles[sfd]->fd);
  1627. }
  1628. /*recognise shortcuts in WIN32*/
  1629. #if defined CDP97 && defined _WIN32
  1630. /*TODO: add arg for full targetname*/
  1631. int snd_is_shortcut(int sfd)
  1632. {
  1633. if(!mapsndfd(&sfd))
  1634. return -1;
  1635. return sf_is_shortcut(sndfiles[sfd]->fd,NULL);
  1636. }
  1637. #endif
  1638. /*RWD.5.99*/
  1639. int snd_fileformat(int sfd, fileformat *pfmt)
  1640. {
  1641. if(!mapsndfd(&sfd))
  1642. return -1;
  1643. return sfformat(sndfiles[sfd]->fd,pfmt);
  1644. }
  1645. int sndgetchanmask(int sfd)
  1646. {
  1647. if(!mapsndfd(&sfd))
  1648. return -1;
  1649. return sfgetchanmask(sndfiles[sfd]->fd);
  1650. }
  1651. int snd_getchanformat(int sfd, channelformat *chformat)
  1652. {
  1653. if(!mapsndfd(&sfd))
  1654. return -1;
  1655. return sf_getchanformat(sndfiles[sfd]->fd,chformat);
  1656. }
  1657. int sndreadpeaks(int sfd,int channels,CHPEAK peakdata[],int *peaktime)
  1658. {
  1659. if(!mapsndfd(&sfd))
  1660. return -1;
  1661. return sfreadpeaks(sndfiles[sfd]->fd,(int) channels,peakdata,peaktime);
  1662. }
  1663. int sndputpeaks(int sfd,int channels,const CHPEAK peakdata[])
  1664. {
  1665. if(!mapsndfd(&sfd))
  1666. return -1;
  1667. return sfputpeaks(sndfiles[sfd]->fd,channels,peakdata);
  1668. }
  1669. const char * snd_getfilename(int sfd)
  1670. {
  1671. if(!mapsndfd(&sfd))
  1672. return NULL;
  1673. return sf_getfilename(sndfiles[sfd]->fd);
  1674. }
  1675. extern int sf_makepath(char path[], const char* sfname);
  1676. int snd_makepath(char path[], const char* sfname)
  1677. {
  1678. return sf_makepath(path,sfname);
  1679. }