zigzag.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735
  1. /*
  2. * Copyright (c) 1983-2023 Trevor Wishart and Composers Desktop Project Ltd
  3. * http://www.trevorwishart.co.uk
  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. /* floatsam version */
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <structures.h>
  26. #include <tkglobals.h>
  27. #include <globcon.h>
  28. #include <processno.h>
  29. #include <modeno.h>
  30. #include <arrays.h>
  31. #include <extend.h>
  32. #include <cdpmain.h>
  33. #include <sfsys.h>
  34. #include <extend.h>
  35. int reverse_it(int incnt,dataptr dz);
  36. void do_down_splice(dataptr dz);
  37. int add_to_splicebuf(float *iptr,dataptr dz);
  38. int find_zzchunk(int **thisstart,int **lastend, int *ziglistend, int *minsamp, dataptr dz);
  39. int adjust_buffer(int minsamp, int *oldminsec, int init, dataptr dz);
  40. int zig_or_zag(int direction,int *here,int *next,int is_startsplice,int is_endsplice,
  41. int *outbuf_space,int obufno,int splbufno, dataptr dz);
  42. int do_zigzags(int *thisstart,int *lastend,int *outbuf_space,int obufno,int splbufno,dataptr dz);
  43. int memcpy_with_check(char *bufptr,char *bufend,char *fromptr,int bytecnt);
  44. int setup_splices(int *base,int *last,int *here,int *next,int *after,int *end,
  45. int *is_startsplice,int *is_endsplice,dataptr dz);
  46. static void do_end_splice(int samps_left,int obufno,dataptr dz);
  47. #define ZIG (1)
  48. #define UNKNOWN (0)
  49. #define ZAG (-1)
  50. #define NORMAL (0)
  51. #define REVERSE (1)
  52. #define SECMARGIN (256)
  53. /***************************** ZIGZAG **********************************/
  54. int zigzag(dataptr dz)
  55. {
  56. int exit_status;
  57. int *thisstart, *lastend = dz->lparray[ZIGZAG_TIMES], minsamp;
  58. int oldminsec = 0;
  59. int init = 1;
  60. int *ziglistend = dz->lparray[ZIGZAG_TIMES] + dz->itemcnt;
  61. int outbuf_space = dz->buflen, samps_left;
  62. int obufno, splbufno;
  63. switch(dz->process) {
  64. case(ZIGZAG): obufno = 2; splbufno = 3; break;
  65. case(LOOP):
  66. case(SCRAMBLE): obufno = 1; splbufno = 2; break;
  67. default:
  68. sprintf(errstr,"Unknown case in zigzag()\n");
  69. return(PROGRAM_ERROR);
  70. }
  71. if((exit_status = find_zzchunk(&thisstart,&lastend,ziglistend,&minsamp,dz))!=CONTINUE) {
  72. if(exit_status == FINISHED)
  73. exit_status = GOAL_FAILED;
  74. switch(dz->process) {
  75. case(ZIGZAG): sprintf(errstr,"WARNING: No valid zigzag found\n"); break;
  76. case(LOOP): sprintf(errstr,"WARNING: No valid loop found\n"); break;
  77. case(SCRAMBLE): sprintf(errstr,"WARNING: No valid scramble found\n"); break;
  78. }
  79. return(exit_status);
  80. }
  81. if((exit_status = adjust_buffer(minsamp,&oldminsec,init,dz))<0)
  82. return(exit_status);
  83. init = 0;
  84. while(lastend < ziglistend) {
  85. if((exit_status = do_zigzags(thisstart,lastend,&outbuf_space,obufno,splbufno,dz))<0)
  86. return(exit_status);
  87. if((exit_status = find_zzchunk(&thisstart,&lastend,ziglistend,&minsamp,dz))!=CONTINUE) {
  88. if(exit_status==FINISHED)
  89. break;
  90. else
  91. return(exit_status);
  92. }
  93. if((exit_status = adjust_buffer(minsamp,&oldminsec,init,dz))<0)
  94. return(exit_status);
  95. }
  96. samps_left = dz->sbufptr[obufno] - dz->sampbuf[obufno];
  97. do_end_splice(samps_left,obufno,dz);
  98. if(samps_left > 0)
  99. return write_samps(dz->sampbuf[obufno],samps_left,dz);
  100. return FINISHED;
  101. }
  102. /************************* DO_ZIGZAGS ************************************/
  103. int do_zigzags(int *thisstart,int *lastend,int *outbuf_space,int obufno,int splbufno,dataptr dz)
  104. {
  105. int exit_status;
  106. int direction;
  107. int is_startsplice;
  108. int is_endsplice;
  109. int *last = thisstart - 1;
  110. int *here = thisstart;
  111. int *next = thisstart + 1;
  112. int *after = thisstart + 2;
  113. int *base = dz->lparray[ZIGZAG_TIMES];
  114. int *end = dz->lparray[ZIGZAG_TIMES] + dz->itemcnt;
  115. while(next <= lastend) {
  116. direction = setup_splices(base,last,here,next,after,end,&is_startsplice,&is_endsplice,dz);
  117. switch(dz->process) {
  118. case(ZIGZAG):
  119. break; /* both ZIGS (forward) and ZAGS (backwards) are played */
  120. case(LOOP):
  121. case(SCRAMBLE):
  122. if(dz->iparray[ZIGZAG_PLAY][here - base]==TRUE)
  123. direction = ZIG; /* FLAGS A (forward) PLAYED MOVE IN INFILE */
  124. else
  125. direction = ZAG; /* FLAGS A NON-PLAYED MOVE IN INFILE: which might be forward as well as backward */
  126. break;
  127. }
  128. if((exit_status = zig_or_zag(direction,here,next,is_startsplice,is_endsplice,outbuf_space,obufno,splbufno,dz))<0)
  129. return(exit_status);
  130. last++;
  131. here++;
  132. next++;
  133. after++;
  134. }
  135. return(FINISHED);
  136. }
  137. /****************************** ZIG_OR_ZAG ***********************************/
  138. int zig_or_zag
  139. (int direction,int *here,int *next,int is_startsplice,int is_endsplice,
  140. int *outbuf_space,int obufno, int splbufno, dataptr dz)
  141. {
  142. int exit_status;
  143. int bufno;
  144. int incnt = abs(*next - *here), advance;
  145. int orig_incnt = incnt;
  146. int samps_remain;
  147. float *sbufend = dz->sampbuf[NORMAL] + dz->buflen;
  148. switch(direction) {
  149. case(ZIG):
  150. bufno = NORMAL;
  151. break;
  152. case(ZAG):
  153. switch(dz->process) {
  154. case(ZIGZAG):
  155. if((exit_status = reverse_it(incnt,dz))<0)
  156. return(exit_status);
  157. bufno = REVERSE;
  158. break;
  159. case(LOOP):
  160. case(SCRAMBLE):
  161. incnt = *next - *here;
  162. if((dz->sbufptr[NORMAL] += incnt) < dz->sampbuf[NORMAL] || dz->sbufptr[NORMAL] >= sbufend) {
  163. sprintf(errstr,"Error in buffer accounting: zig_or_zag()\n");
  164. return(PROGRAM_ERROR);
  165. }
  166. return(FINISHED);
  167. default:
  168. sprintf(errstr,"Unknown case in zig_or_zag()\n");
  169. return(PROGRAM_ERROR);
  170. }
  171. break;
  172. default:
  173. sprintf(errstr,"Unknown case in zig_or_zag\n");
  174. return(PROGRAM_ERROR);
  175. }
  176. if(is_startsplice) {
  177. if((exit_status = add_to_splicebuf(dz->sbufptr[bufno],dz))<0)
  178. return(exit_status);
  179. }
  180. if(*outbuf_space >= incnt) { /* ENOUGH SPACE IN OUTBUFFER To DO EVERYTHING */
  181. if(is_startsplice) {
  182. if((exit_status = memcpy_with_check
  183. ((char *)dz->sbufptr[obufno],(char *)dz->sampbuf[splbufno],
  184. (char *)dz->extrabuf[ZIGZAG_SPLBUF],dz->iparam[ZIG_SPLSAMPS]* sizeof(float)))<0)
  185. return(exit_status);
  186. dz->sbufptr[bufno] += dz->iparam[ZIG_SPLSAMPS];
  187. dz->sbufptr[obufno] += dz->iparam[ZIG_SPLSAMPS];
  188. *outbuf_space -= dz->iparam[ZIG_SPLSAMPS];
  189. advance = incnt-(2*dz->iparam[ZIG_SPLSAMPS]);
  190. } else
  191. advance = incnt - dz->iparam[ZIG_SPLSAMPS];
  192. if(!is_endsplice)
  193. advance += dz->iparam[ZIG_SPLSAMPS];
  194. if((exit_status = memcpy_with_check
  195. ((char *)dz->sbufptr[obufno],(char *)dz->sampbuf[splbufno],(char *)dz->sbufptr[bufno],advance * sizeof(float)))<0)
  196. return(exit_status);
  197. dz->sbufptr[obufno] += advance;
  198. dz->sbufptr[bufno] += advance;
  199. *outbuf_space -= advance;
  200. if(is_endsplice) {
  201. memmove((char *)dz->extrabuf[ZIGZAG_SPLBUF],
  202. (char *)dz->sbufptr[bufno],dz->iparam[ZIG_SPLSAMPS]* sizeof(float));
  203. do_down_splice(dz);
  204. dz->sbufptr[bufno] += dz->iparam[ZIG_SPLSAMPS];
  205. }
  206. if(*outbuf_space <= 0) {
  207. if((exit_status = write_samps(dz->sampbuf[obufno],dz->buflen,dz))<0)
  208. return(exit_status);
  209. dz->sbufptr[obufno] = dz->sampbuf[obufno];
  210. *outbuf_space = dz->buflen;
  211. }
  212. } else if(is_startsplice && (*outbuf_space <= dz->iparam[ZIG_SPLSAMPS])) {
  213. /* OUTBUFFER SPACE LESS THAN (START)SPLICELEN */
  214. samps_remain = dz->iparam[ZIG_SPLSAMPS];
  215. dz->extrabufptr[ZIGZAG_SPLBUF] = dz->extrabuf[ZIGZAG_SPLBUF];
  216. if((exit_status = memcpy_with_check
  217. ((char *)dz->sbufptr[obufno],(char *)dz->sampbuf[splbufno],(char *)dz->extrabufptr[ZIGZAG_SPLBUF],(*outbuf_space) * sizeof(float)))<0)
  218. return(exit_status);
  219. if((exit_status = write_samps(dz->sampbuf[obufno],dz->buflen,dz))<0)
  220. return(exit_status);
  221. dz->extrabufptr[ZIGZAG_SPLBUF] += *outbuf_space;
  222. dz->sbufptr[obufno] = dz->sampbuf[obufno];
  223. samps_remain -= *outbuf_space;
  224. *outbuf_space = dz->buflen;
  225. if(samps_remain > 0) {
  226. if((exit_status = memcpy_with_check
  227. ((char *)dz->sbufptr[obufno],(char *)dz->sampbuf[splbufno],(char *)(dz->extrabufptr[ZIGZAG_SPLBUF]),samps_remain * sizeof(float)))<0)
  228. return(exit_status);
  229. dz->sbufptr[obufno] += samps_remain;
  230. *outbuf_space -= samps_remain;
  231. }
  232. dz->sbufptr[bufno] += dz->iparam[ZIG_SPLSAMPS];
  233. advance = incnt - (2 *dz->iparam[ZIG_SPLSAMPS]);
  234. if(!is_endsplice)
  235. advance += dz->iparam[ZIG_SPLSAMPS];
  236. if((exit_status = memcpy_with_check
  237. ((char *)dz->sbufptr[obufno],(char *)dz->sampbuf[splbufno],(char *)dz->sbufptr[bufno],advance * sizeof(float)))<0)
  238. return(exit_status);
  239. dz->sbufptr[obufno] += advance;
  240. dz->sbufptr[bufno] += advance;
  241. *outbuf_space -= advance;
  242. if(is_endsplice) {
  243. memmove((char *)dz->extrabuf[ZIGZAG_SPLBUF],
  244. (char *)dz->sbufptr[bufno],(size_t)dz->iparam[ZIG_SPLSAMPS]* sizeof(float));
  245. do_down_splice(dz);
  246. dz->sbufptr[bufno] += dz->iparam[ZIG_SPLSAMPS];
  247. }
  248. } else if(*outbuf_space <= incnt - dz->iparam[ZIG_SPLSAMPS]) {
  249. /* OUTBUFFER SPACE DOESN'T REACH UP INTO ENDSPLICE */
  250. if(is_startsplice) {
  251. if((exit_status = memcpy_with_check
  252. ((char *)dz->sbufptr[obufno],(char *)dz->sampbuf[splbufno],(char *)dz->extrabuf[ZIGZAG_SPLBUF],
  253. (int)dz->iparam[ZIG_SPLSAMPS]* sizeof(float)))<0)
  254. return(exit_status);
  255. dz->sbufptr[bufno] += dz->iparam[ZIG_SPLSAMPS];
  256. dz->sbufptr[obufno] += dz->iparam[ZIG_SPLSAMPS];
  257. advance = *outbuf_space - dz->iparam[ZIG_SPLSAMPS];
  258. } else
  259. advance = *outbuf_space;
  260. if((exit_status = memcpy_with_check
  261. ((char *)dz->sbufptr[obufno],(char *)dz->sampbuf[splbufno],(char *)dz->sbufptr[bufno],advance * sizeof(float)))<0)
  262. return(exit_status);
  263. if((exit_status = write_samps(dz->sampbuf[obufno],dz->buflen,dz))<0)
  264. return(exit_status);
  265. dz->sbufptr[bufno] += advance;
  266. dz->sbufptr[obufno] = dz->sampbuf[obufno];
  267. incnt -= *outbuf_space;
  268. *outbuf_space = dz->buflen;
  269. advance = incnt - dz->iparam[ZIG_SPLSAMPS];
  270. if(!is_endsplice)
  271. advance += dz->iparam[ZIG_SPLSAMPS];
  272. if(advance > 0) {
  273. if((exit_status = memcpy_with_check
  274. ((char *)dz->sbufptr[obufno],(char *)dz->sampbuf[splbufno],(char *)dz->sbufptr[bufno],advance * sizeof(float)))<0)
  275. return(exit_status);
  276. dz->sbufptr[obufno] += advance;
  277. dz->sbufptr[bufno] += advance;
  278. *outbuf_space -= advance;
  279. }
  280. if(is_endsplice) {
  281. memmove((char *)dz->extrabuf[ZIGZAG_SPLBUF],(char *)dz->sbufptr[bufno],
  282. (size_t)dz->iparam[ZIG_SPLSAMPS]* sizeof(float));
  283. do_down_splice(dz);
  284. dz->sbufptr[bufno] += dz->iparam[ZIG_SPLSAMPS];
  285. }
  286. } else { /* OUTBUFFER SPACE REACHES INTO MIDDLE OF ENDSPLICE */
  287. if(is_startsplice) {
  288. if((exit_status = memcpy_with_check
  289. ((char *)dz->sbufptr[obufno],(char *)dz->sampbuf[splbufno],
  290. (char *)dz->extrabuf[ZIGZAG_SPLBUF],dz->iparam[ZIG_SPLSAMPS]* sizeof(float)))<0)
  291. return(exit_status);
  292. dz->sbufptr[bufno] += dz->iparam[ZIG_SPLSAMPS];
  293. dz->sbufptr[obufno] += dz->iparam[ZIG_SPLSAMPS];
  294. *outbuf_space -= dz->iparam[ZIG_SPLSAMPS];
  295. advance = incnt - (2*dz->iparam[ZIG_SPLSAMPS]);
  296. } else
  297. advance = incnt - dz->iparam[ZIG_SPLSAMPS];
  298. if(!is_endsplice) {
  299. advance += dz->iparam[ZIG_SPLSAMPS];
  300. if((exit_status = memcpy_with_check
  301. ((char *)dz->sbufptr[obufno],(char *)dz->sampbuf[splbufno],(char *)dz->sbufptr[bufno],(*outbuf_space) * sizeof(float)))<0)
  302. return(exit_status);
  303. if((exit_status = write_samps(dz->sampbuf[obufno],dz->buflen,dz))<0)
  304. return(exit_status);
  305. dz->sbufptr[bufno] += *outbuf_space;
  306. dz->sbufptr[obufno] = dz->sampbuf[obufno];
  307. advance -= *outbuf_space;
  308. *outbuf_space = dz->buflen;
  309. if((exit_status = memcpy_with_check
  310. ((char *)dz->sbufptr[obufno],(char *)dz->sampbuf[splbufno],(char *)dz->sbufptr[bufno],advance * sizeof(float)))<0)
  311. return(exit_status);
  312. dz->sbufptr[bufno] += advance;
  313. dz->sbufptr[obufno] += advance;
  314. *outbuf_space -= advance;
  315. } else {
  316. if((exit_status = memcpy_with_check
  317. ((char *)dz->sbufptr[obufno],(char *)dz->sampbuf[splbufno],(char *)dz->sbufptr[bufno],advance * sizeof(float)))<0)
  318. return(exit_status);
  319. dz->sbufptr[obufno] += advance;
  320. dz->sbufptr[bufno] += advance;
  321. memmove((char *)dz->extrabuf[ZIGZAG_SPLBUF],
  322. (char *)dz->sbufptr[bufno],dz->iparam[ZIG_SPLSAMPS]* sizeof(float));
  323. do_down_splice(dz);
  324. dz->sbufptr[bufno] += dz->iparam[ZIG_SPLSAMPS];
  325. *outbuf_space = dz->sampbuf[splbufno] - dz->sbufptr[obufno];
  326. if(*outbuf_space > dz->iparam[ZIG_SPLSAMPS]) {
  327. sprintf(errstr,"Error in counting logic: zig_or_zag()\n");
  328. return(PROGRAM_ERROR);
  329. }
  330. if(*outbuf_space <= 0) {
  331. sprintf(errstr,"Error 2 in counting logic: zig_or_zag()\n");
  332. return(PROGRAM_ERROR);
  333. }
  334. }
  335. }
  336. if(direction ==ZAG) {
  337. dz->sbufptr[0] -= orig_incnt;
  338. dz->sbufptr[1] = dz->sampbuf[1];
  339. }
  340. return(FINISHED);
  341. }
  342. /* RWD got as far as here...ARRRRGGGGHHHHH!!!!!!!! */
  343. /****************************** ADJUST_BUFFER ******************************/
  344. /* is all this simply to seek to minsamp? */
  345. int adjust_buffer(int minsamp, int *oldminsec, int init, dataptr dz)
  346. {
  347. int minsec, secchange, sampchange = 0, samp_at_sector_start = 0;
  348. minsec = minsamp/SECMARGIN; /* minimum sector in file that we need, for next read */
  349. secchange = minsec - *oldminsec; /* number of sectors we need to move buffer along */
  350. *oldminsec = minsec;
  351. if(init) { /* On first read */
  352. if(secchange<0) { /* secchange must be >= 0 from start of file */
  353. sprintf(errstr,"Anomaly in first pass of adjust_buffer()\n");
  354. return(PROGRAM_ERROR);
  355. }
  356. if(secchange) { /* seek to 1st buffer needed */
  357. sampchange = secchange * SECMARGIN;
  358. if(sndseekEx(dz->ifd[0],sampchange,0)<0) {
  359. sprintf(errstr,"sndseek: Failed in adjust_buffer()\n");
  360. return(SYSTEM_ERROR);
  361. } /* find sample-number (in file) of first sample in buffer */
  362. samp_at_sector_start = sampchange;
  363. } /* read 1st buffer */
  364. if(fgetfbufEx(dz->sampbuf[0],dz->buflen,dz->ifd[0],0)<0) {
  365. sprintf(errstr,"read() 0 Failed in adjust_buffer()\n");
  366. return(SYSTEM_ERROR);
  367. }
  368. dz->sbufptr[0] = dz->sampbuf[0] + (dz->lparray[ZIGZAG_TIMES][0] - samp_at_sector_start);
  369. return(FINISHED);
  370. } /* IF NOT in first read */
  371. //TW UPDATE (Removed below)
  372. // if(!secchange) { /* Data should have been checked to avoid zero zigs or zags */
  373. // sprintf(errstr,"Search anomaly in adjust_buffer()\n");
  374. // return(PROGRAM_ERROR);
  375. // }
  376. /* sampchange = Change in samp position in file from current buffer start to next buffer start.
  377. * NB, it should be impossible for this to exceed buffer_size
  378. * because initial point must be within current buffer,
  379. * & total length of any segment must be less than buffer_size (controlled by param range-setting) !!
  380. */
  381. if(abs(sampchange = secchange * SECMARGIN) > dz->buflen) {
  382. sprintf(errstr,"Anomaly in sampseek arithmetic: adjust_buffer()\n");
  383. return(PROGRAM_ERROR);
  384. }
  385. /* Seek first to start of current buff */
  386. /* and then, by the calculated offset, to start of new buf */
  387. if(sndseekEx(dz->ifd[0],minsec * SECMARGIN,0)<0) {
  388. sprintf(errstr,"sndseek() 1 Failed in adjust_buffer()\n");
  389. return(SYSTEM_ERROR);
  390. }
  391. /* read the new buffer */
  392. if(fgetfbufEx(dz->sampbuf[0],dz->buflen,dz->ifd[0],0)<0) {
  393. sprintf(errstr,"fgetfbufEx() Anomaly in adjust_buffer()\n");
  394. return(SYSTEM_ERROR);
  395. }
  396. /* reposition buffer pointer within NEW buffer */
  397. dz->sbufptr[0] -= sampchange;
  398. if(dz->sbufptr[0] < dz->sampbuf[0]) {
  399. sprintf(errstr,"adjust_buffer(): Input buffer anomaly - pointer off start of buffer.\n");
  400. return(PROGRAM_ERROR);
  401. }
  402. if(dz->sbufptr[0] >= dz->sampbuf[1]) {
  403. sprintf(errstr,"adjust_buffer(): Input buffer anomaly - pointer off end of buffer.\n");
  404. return(PROGRAM_ERROR);
  405. }
  406. return(FINISHED);
  407. }
  408. /*************************** FIND_ZZCHUNK ************************************/
  409. int find_zzchunk(int **thisstart,int **lastend, int *ziglistend, int *minsamp, dataptr dz)
  410. {
  411. int *p, min_samp, max_samp, lastmin_samp = 0, lastmax_samp = 0;
  412. int check;
  413. int max_smpsize = dz->buflen - SECMARGIN;
  414. /* Max zig-segment permitted, taking into a/c */
  415. /* need to round up to a whole sector AT THE ENDS!! */
  416. *thisstart = *lastend; /* Set start of current segment to end of last segment */
  417. p = *thisstart;
  418. /* WE'RE SEARCHING FOR THE earliest and latest times among successive zigtimes */
  419. min_samp = *p; /* so preset both of these to the current first zigtime */
  420. max_samp = *p;
  421. p++;
  422. while(p < ziglistend) { /* search forward through the zigtimes list */
  423. check = 0;
  424. if(*p < min_samp) { /* if this zigtime earlier than any encountered so far */
  425. lastmin_samp = min_samp; /* store last earliest elsewhere, and keep new one */
  426. min_samp = *p;
  427. check = 1; /* flag that a new earliest-time has been registered */
  428. } else if(*p > max_samp) { /* if this zigtime later than any encountered so far */
  429. lastmax_samp = max_samp; /* store last latest elsewhere, and keep new one */
  430. max_samp = *p;
  431. check = 2; /* flag that a new latest-time has been registered */
  432. }
  433. if(check) { /* If a new earliest or latest time has been found */
  434. if(max_samp - min_samp > max_smpsize) { /* If the span between earliest and latest is TOO LARGE */
  435. if(check==2) /* restore the previous earliest(or latest) time */
  436. max_samp = lastmax_samp;
  437. else
  438. min_samp = lastmin_samp;
  439. break; /* and break from the loop */
  440. } /* (Otherwise next zigtime would be beyond a bufferlength) */
  441. }
  442. p++;
  443. }
  444. if(max_samp - min_samp < 0) {
  445. sprintf(errstr,"Anomaly in find_zzchunk()\n");
  446. return(PROGRAM_ERROR);
  447. }
  448. if(max_samp - min_samp == 0)
  449. return(FINISHED);
  450. *minsamp = min_samp; /* flag position of earliest time, as a samp-count in file */
  451. /* NB...
  452. * if we reached end of ziglist (p = ziglistend), lastend = end of list = ziglistend - 1
  453. * if we dropped out of loop, because last found time was unacceptable,
  454. * we must baktrak in the the ziglist by 1. Hence...
  455. */
  456. *lastend = p - 1;
  457. return(CONTINUE);
  458. }
  459. /********************** ADD_TO_SPLICEBUF *************************/
  460. int add_to_splicebuf(float *iptr,dataptr dz)
  461. {
  462. //TW CHANGED
  463. // /*int*/float val;
  464. double val;
  465. float *sptr = dz->extrabuf[ZIGZAG_SPLBUF];
  466. int n, m;
  467. for(n=0;n<dz->iparam[ZIG_SPLICECNT];n++) {
  468. for(m=0;m<dz->infile->channels;m++) {
  469. val = *sptr + /*round*/(float)(*iptr * dz->parray[ZIGZAG_SPLICE][n]);
  470. *sptr = (float)val;
  471. sptr++;
  472. iptr++;
  473. }
  474. }
  475. return(FINISHED);
  476. }
  477. /********************** DO_DOWN_SPLICE *************************/
  478. void do_down_splice(dataptr dz)
  479. {
  480. /*int*/double val;
  481. float *sptr = dz->extrabuf[ZIGZAG_SPLBUF];
  482. int n, m;
  483. for(n=dz->iparam[ZIG_SPLICECNT]-1;n>=0;n--) {
  484. for(m = 0;m<dz->infile->channels;m++) {
  485. val = /*round*/(*sptr * dz->parray[ZIGZAG_SPLICE][n]);
  486. *sptr = (float)val;
  487. sptr++;
  488. }
  489. }
  490. }
  491. /********************** REVERSE_IT ***************************/
  492. int reverse_it(int incnt,dataptr dz)
  493. {
  494. int n;
  495. int k, chans = dz->infile->channels;
  496. float *s1ptr = dz->sbufptr[0];
  497. float *s2ptr;
  498. dz->sbufptr[1] = dz->sampbuf[1]; /* point to stsrt of reversed-segment buffer */
  499. s2ptr = dz->sbufptr[1];
  500. incnt /= chans;
  501. s1ptr -= chans;
  502. for(n=0;n<incnt;n++) {
  503. for(k=0;k<chans;k++)
  504. *s2ptr++ = *s1ptr++;
  505. s1ptr -= 2 * chans;
  506. }
  507. return(FINISHED);
  508. }
  509. /********************** MEMCPY_WITH_CHECK ***************************/
  510. int memcpy_with_check(char *bufptr,char *bufend,char *fromptr,int bytecnt)
  511. {
  512. if(bufend - bufptr < bytecnt) {
  513. sprintf(errstr,"Attempted to copy too many bytes to buffer: memcpy_with_check()\n");
  514. return(PROGRAM_ERROR);
  515. }
  516. if(bytecnt < 0) {
  517. sprintf(errstr,"Attempted to copy -ve number of bytes: memcpy_with_check()\n");
  518. return(PROGRAM_ERROR);
  519. }
  520. memmove(bufptr,fromptr,(size_t)bytecnt);
  521. return(FINISHED);
  522. }
  523. /********************** SETUP_SPLICES ***************************/
  524. int setup_splices
  525. (int *base,int *last,int *here,int *next,int *after,int *end,int *is_startsplice,int *is_endsplice,dataptr dz)
  526. {
  527. int predirection = UNKNOWN;
  528. int postdirection = UNKNOWN;
  529. int direction;
  530. int place = here - base;
  531. *is_startsplice = TRUE;
  532. *is_endsplice = TRUE;
  533. if(here > base) {
  534. if(*last < *here)
  535. predirection = ZIG;
  536. else
  537. predirection = ZAG;
  538. }
  539. if(after < end) {
  540. if(*next < *after)
  541. postdirection = ZIG;
  542. else
  543. postdirection = ZAG;
  544. }
  545. if(*here < *next)
  546. direction = ZIG;
  547. else
  548. direction = ZAG;
  549. if(direction == predirection)
  550. *is_startsplice = FALSE;
  551. if(direction == postdirection)
  552. *is_endsplice = FALSE;
  553. switch(dz->process) {
  554. case(LOOP):
  555. case(SCRAMBLE):
  556. if(here > base
  557. && dz->iparray[ZIGZAG_PLAY][place]==TRUE && dz->iparray[ZIGZAG_PLAY][place-1]==FALSE)
  558. *is_startsplice = TRUE;
  559. if(after < end
  560. && dz->iparray[ZIGZAG_PLAY][place]==TRUE && dz->iparray[ZIGZAG_PLAY][place+1]==FALSE)
  561. *is_endsplice = TRUE;
  562. break;
  563. }
  564. if(after==end && dz->iparam[ZIG_RUNSTOEND])
  565. *is_endsplice = FALSE;
  566. if(here==base && *here == 0)
  567. *is_startsplice = FALSE;
  568. return(direction);
  569. }
  570. /********************** DO_END_SPLICE ***************************/
  571. void do_end_splice(int samps_left,int obufno,dataptr dz)
  572. {
  573. //TW CHANGED
  574. // float *sptr, val;
  575. float *sptr;
  576. double val;
  577. int n/*, val*/;
  578. int m;
  579. int splicelen = dz->iparam[ZIG_SPLICECNT] * dz->infile->channels;
  580. if(samps_left < splicelen) {
  581. fprintf(stdout,"WARNING: No buffer space to do end splice. Possible click at end.\n");
  582. fflush(stdout);
  583. } else {
  584. sptr = dz->sbufptr[obufno] - splicelen;
  585. for(n=dz->iparam[ZIG_SPLICECNT]-1;n>=0;n--) {
  586. for(m = 0;m<dz->infile->channels;m++) {
  587. val = /*round*/(*sptr * dz->parray[ZIGZAG_SPLICE][n]);
  588. *sptr = (float)val;
  589. sptr++;
  590. }
  591. }
  592. }
  593. }
  594. //TW NEW FUNCTION (converted to float)
  595. /********************** DO_BTOB ***************************/
  596. int do_btob(dataptr dz)
  597. {
  598. int exit_status, chans = dz->infile->channels;
  599. float *ibuf = dz->sampbuf[0], *obuf = dz->sampbuf[1], *sbuf = dz->sampbuf[2];
  600. int total_samps_got = 0, obufcnt = 0, splicecnt = 0, startsamp, k, n, m;
  601. double spliceval = 1.0, spliceincr = 1.0/(double)(dz->iparam[BTOB_SPLEN]/chans);
  602. int samps_to_work_on = dz->insams[0] - dz->iparam[BTOB_CUT] - (dz->iparam[BTOB_SPLEN]/2);
  603. int bufcnt = dz->insams[0]/dz->buflen;
  604. int finished = 0;
  605. if(bufcnt * dz->buflen < dz->insams[0])
  606. bufcnt++;
  607. for(k = bufcnt-1; k >=0; k--) {
  608. if((sndseekEx(dz->ifd[0],k * dz->buflen,0)) < 0) {
  609. sprintf(errstr,"sndseekEx() 1 Failed in do_btob()\n");
  610. return(SYSTEM_ERROR);
  611. }
  612. if((exit_status = read_samps(ibuf,dz))<0)
  613. return(exit_status);
  614. for(n = dz->ssampsread-chans; n>=0;n-=chans) {
  615. if(obuf==sbuf) {
  616. for(m=0;m<chans;m++)
  617. sbuf[splicecnt++] = (float)(ibuf[n+m] * spliceval);
  618. spliceval -= spliceincr;
  619. if(splicecnt >= dz->iparam[BTOB_SPLEN]) {
  620. finished = 1;
  621. break;
  622. }
  623. } else { /* if NOT in splice, check whether going into splice */
  624. for(m=0;m<chans;m++)
  625. obuf[obufcnt++] = ibuf[n+m];
  626. if(obufcnt >= dz->buflen) {
  627. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  628. return(exit_status);
  629. obufcnt = 0;
  630. }
  631. if((total_samps_got += chans) >= samps_to_work_on) {
  632. obuf= sbuf;
  633. spliceval -= spliceincr;
  634. }
  635. }
  636. }
  637. if(finished)
  638. break;
  639. }
  640. startsamp = dz->iparam[BTOB_CUT] - (dz->iparam[BTOB_SPLEN]/2);
  641. k = startsamp/dz->buflen;
  642. if((sndseekEx(dz->ifd[0],k * dz->buflen,0)) < 0) {
  643. sprintf(errstr,"sndseekEx() 2 Failed in do_btob()\n");
  644. return(SYSTEM_ERROR);
  645. }
  646. startsamp -= k * dz->buflen;
  647. splicecnt = 0;
  648. spliceval = 0.0;
  649. if((exit_status = read_samps(ibuf,dz))<0)
  650. return(exit_status);
  651. do {
  652. for(n = startsamp; n <dz->ssampsread;n+=chans) {
  653. if(obuf==sbuf) {
  654. for(m=0;m<chans;m++)
  655. sbuf[splicecnt+m] = (float)((ibuf[n+m] * spliceval) + sbuf[splicecnt+m]);
  656. spliceval += spliceincr;
  657. if((splicecnt += chans) >= dz->iparam[BTOB_SPLEN]) {
  658. obuf = dz->sampbuf[1];
  659. for(m=0;m<dz->iparam[BTOB_SPLEN];m++)
  660. obuf[obufcnt++] = sbuf[m];
  661. if(obufcnt >= dz->buflen) {
  662. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  663. return(exit_status);
  664. obufcnt = 0;
  665. }
  666. }
  667. } else {
  668. for(m=0;m<chans;m++)
  669. obuf[obufcnt++] = ibuf[n+m];
  670. if(obufcnt >= dz->buflen) {
  671. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  672. return(exit_status);
  673. obufcnt = 0;
  674. }
  675. }
  676. }
  677. startsamp = 0;
  678. if((exit_status = read_samps(ibuf,dz))<0)
  679. return(exit_status);
  680. } while(dz->ssampsread > 0);
  681. if(obufcnt > 0) {
  682. if((exit_status = write_samps(obuf,obufcnt,dz))<0)
  683. return(exit_status);
  684. }
  685. return(FINISHED);
  686. }