drunk.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616
  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. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include <structures.h>
  25. #include <tkglobals.h>
  26. #include <globcon.h>
  27. #include <processno.h>
  28. #include <modeno.h>
  29. #include <arrays.h>
  30. #include <extend.h>
  31. #include <cdpmain.h>
  32. #include <sfsys.h>
  33. #include <osbind.h>
  34. //#ifdef unix
  35. #define round(x) lround((x))
  36. //#endif
  37. int drunk(int here,int *obufpos,int *thisbuf,int thisdur,double pregain,int *endwrite,int outbufspace,dataptr dz);
  38. int do_pause(int here,int *obufpos,int *endwrite,int *thisbuf,int thisdur,double pregain,int outbufspace,dataptr dz);
  39. int get_thisdur(int *thisdur,int *goalpcnt,int *pcnt,dataptr dz);
  40. int get_pos_and_dur_for_pause(int *here,int *thisdur,int *thisbuf,int *ibufpos,double pregain,dataptr dz);
  41. int get_pos(int *here,int thisdur,dataptr dz);
  42. void do_pregain(double pregain,dataptr dz);
  43. int is_paus(int *goalpcnt,int *pcnt,dataptr dz);
  44. int convert_time_to_samplecnts(int paramno,dataptr dz);
  45. int convert_sec_steps_to_grain_steps(dataptr dz);
  46. int adjust_bufs(int here,int *ibufpos,int *thisbuf,double pregain,dataptr dz);
  47. int do_intermediate_write(int *endwrite,int *obufpos,dataptr dz);
  48. int make_drnk_splicetab(dataptr dz);
  49. void setup_paus_params(dataptr dz);
  50. int get_maxvalue(int paramno,double *maxval,dataptr dz);
  51. double get_pregain(dataptr dz);
  52. int do_start_splice(int chans,float *obuf,int *obufpos,float *ibuf,int *ibufpos,int *thisbuf,double pregain,
  53. int *endwrite,int outbufspace,dataptr dz);
  54. int do_end_splice(int chans,float *obuf,int *obufpos,float *ibuf,int *ibufpos,int *thisbuf,double pregain,dataptr dz);
  55. int bounce_off_file_end_if_necessary(int *here,int thisdur,int chans,int splicelen,dataptr dz);
  56. int get_pausdur(int *here,int splicelen,int chans,int *thisdur,dataptr dz);
  57. int get_step(int chans,dataptr dz);
  58. int get_new_pos(int here,int ambitus,int locus,int step);
  59. int get_new_locus_pos(int here,int ambitus,int locus,int step);
  60. /*************************** DO_DRUNKEN_WALK *************************/
  61. int do_drunken_walk(dataptr dz)
  62. {
  63. int exit_status;
  64. int here = 0, ibufpos, obufpos = 0, samps_processed = 0;
  65. double outsamptime;
  66. double pregain = 1.0;
  67. int thisdur, endwrite = 0;
  68. int thisbuf;
  69. int is_a_pause;
  70. int goalpcnt = -1; /* total events needed before pause: initialisation value -1 */
  71. int pcnt = 0; /* count of events since last pause: initial val 0 > -1 */
  72. int chans = dz->infile->channels;
  73. int finished = FALSE;
  74. int outbufspace = dz->sampbuf[3] - dz->sampbuf[1];
  75. display_virtual_time(0,dz);
  76. if((exit_status = read_samps(dz->sampbuf[0],dz))<0)
  77. return(exit_status);
  78. if(dz->vflag[IS_DRNK_OVERLAP]) {
  79. pregain = get_pregain(dz);
  80. do_pregain(pregain,dz);
  81. }
  82. while(samps_processed < dz->iparam[DRNK_TOTALDUR]) {
  83. outsamptime = (double)((obufpos + dz->total_samps_written)/chans);
  84. if((exit_status = read_values_from_all_existing_brktables(outsamptime,dz))<0)
  85. return(exit_status);
  86. while((is_a_pause = get_thisdur(&thisdur,&goalpcnt,&pcnt,dz))==TRUE) {
  87. setup_paus_params(dz);
  88. if((exit_status = get_pos_and_dur_for_pause(&here,&thisdur,&thisbuf,&ibufpos,pregain,dz))<0)
  89. return(exit_status);
  90. if((exit_status = do_pause(ibufpos,&obufpos,&endwrite,&thisbuf,thisdur,pregain,outbufspace,dz))<0)
  91. return(exit_status);
  92. if((samps_processed = dz->total_samps_written + endwrite) >= dz->iparam[DRNK_TOTALDUR]) {
  93. finished = TRUE;
  94. break;
  95. }
  96. outsamptime = (double)((obufpos + dz->total_samps_written)/chans);
  97. if((exit_status = read_values_from_all_existing_brktables(outsamptime,dz))<0)
  98. return(exit_status);
  99. }
  100. if(finished)
  101. break;
  102. if((exit_status = get_pos(&here,thisdur,dz))<0)
  103. return(exit_status);
  104. if((exit_status = adjust_bufs(here,&ibufpos,&thisbuf,pregain,dz))<0)
  105. return(exit_status);
  106. if((exit_status = drunk(ibufpos,&obufpos,&thisbuf,thisdur,pregain,&endwrite,outbufspace,dz))<0)
  107. return(exit_status);
  108. if(obufpos >= dz->buflen) {
  109. if((exit_status = do_intermediate_write(&endwrite,&obufpos,dz))<0)
  110. return(exit_status);
  111. }
  112. samps_processed = dz->total_samps_written + endwrite;
  113. }
  114. if(endwrite > 0) {
  115. if((exit_status = write_samps(dz->sampbuf[1],endwrite,dz))<0)
  116. return(exit_status);
  117. }
  118. display_virtual_time(dz->total_samps_written,dz);
  119. return(FINISHED);
  120. }
  121. /**************************** DRUNK **************************/
  122. int drunk(int ibufpos,int *obufpos,int *thisbuf,int thisdur,double pregain,int *endwrite,int outbufspace,dataptr dz)
  123. {
  124. int exit_status;
  125. int n, overlap, copyblk;
  126. int chans = dz->infile->channels;
  127. int splicelen = dz->iparam[DRNK_SPLICELEN] * chans;
  128. int outbpos;
  129. float *ibuf = dz->sampbuf[0], *thisin;
  130. float *obuf = dz->sampbuf[1];
  131. int available_insamps;
  132. if((exit_status = do_start_splice(chans,obuf,obufpos,ibuf,&ibufpos,thisbuf,pregain,endwrite,outbufspace,dz))<0)
  133. return(exit_status);
  134. outbpos = *obufpos;
  135. copyblk = thisdur - splicelen;
  136. available_insamps = dz->ssampsread - ibufpos;
  137. while(available_insamps < copyblk) {
  138. thisin = ibuf+ibufpos;
  139. for(n=0;n<available_insamps;n++) {
  140. if(outbpos >= outbufspace) {
  141. *endwrite = outbpos;
  142. if((exit_status = do_intermediate_write(endwrite,&outbpos,dz))<0)
  143. return(exit_status);
  144. }
  145. obuf[outbpos++] += thisin[n];
  146. }
  147. if((exit_status = read_samps(dz->sampbuf[0],dz))<0)
  148. return(exit_status);
  149. if(dz->vflag[IS_DRNK_OVERLAP])
  150. do_pregain(pregain,dz);
  151. (*thisbuf)++;
  152. ibufpos = 0;
  153. copyblk -= available_insamps;
  154. available_insamps = dz->ssampsread;
  155. }
  156. if(copyblk > 0) {
  157. thisin = ibuf+ibufpos;
  158. for(n=0;n<copyblk;n++) {
  159. if(outbpos >= outbufspace) {
  160. *endwrite = outbpos;
  161. if((exit_status = do_intermediate_write(endwrite,&outbpos,dz))<0)
  162. return(exit_status);
  163. }
  164. obuf[outbpos++] += thisin[n];
  165. }
  166. ibufpos += copyblk;
  167. }
  168. if((exit_status = do_end_splice(chans,obuf,&outbpos,ibuf,&ibufpos,thisbuf,pregain,dz))<0)
  169. return(exit_status);
  170. *endwrite = outbpos;
  171. outbpos -= splicelen;
  172. if(dz->vflag[IS_DRNK_OVERLAP]) {
  173. overlap = round((double)(thisdur/chans) * dz->param[DRNK_OVERLAP]) * chans;
  174. outbpos -= overlap;
  175. }
  176. *obufpos = outbpos;
  177. return(FINISHED);
  178. }
  179. /**************************** DO_PAUSE **************************/
  180. int do_pause(int ibufpos,int *obufpos,int *endwrite,int *thisbuf,int thisdur,double pregain,
  181. int outbufspace,dataptr dz)
  182. {
  183. int exit_status;
  184. int n, copyblk, write_block;
  185. int outbpos;
  186. int chans = dz->infile->channels;
  187. int splicelen = dz->iparam[DRNK_SPLICELEN] * chans;
  188. float *ibuf = dz->sampbuf[0], *thisin;
  189. float *obuf = dz->sampbuf[1], *thisout;
  190. int available_insamps, available_outspace;
  191. /* ?? */
  192. if((exit_status = do_start_splice(chans,obuf,obufpos,ibuf,&ibufpos,thisbuf,pregain,endwrite,outbufspace,dz))<0)
  193. return(exit_status);
  194. outbpos = *obufpos;
  195. copyblk = thisdur - splicelen;
  196. write_block = dz->sampbuf[3] - dz->sampbuf[1]; /* writeable block = outbuf + overflow */
  197. available_outspace = write_block - outbpos;
  198. available_insamps = dz->ssampsread - ibufpos;
  199. while(copyblk >= available_outspace) {
  200. while(available_insamps <= available_outspace) {
  201. thisout = obuf+outbpos;
  202. thisin = ibuf+ibufpos;
  203. for(n=0;n<available_insamps;n++)
  204. thisout[n] += thisin[n];
  205. if((exit_status = read_samps(dz->sampbuf[0],dz))<0)
  206. return(exit_status);
  207. if(dz->vflag[IS_DRNK_OVERLAP])
  208. do_pregain(pregain,dz);
  209. (*thisbuf)++;
  210. ibufpos = 0;
  211. outbpos += available_insamps;
  212. copyblk -= available_insamps;
  213. available_outspace -= available_insamps;
  214. available_insamps = dz->ssampsread;
  215. }
  216. if(available_outspace > 0) {
  217. thisout = obuf+outbpos;
  218. thisin = ibuf+ibufpos;
  219. for(n=0;n<available_outspace;n++)
  220. thisout[n] += thisin[n];
  221. ibufpos += available_outspace;
  222. outbpos += available_outspace;
  223. copyblk -= available_outspace;
  224. available_insamps = dz->ssampsread - ibufpos;
  225. }
  226. if(write_block > 0) {
  227. if((exit_status = write_samps(dz->sampbuf[1],write_block,dz))<0)
  228. return(exit_status);
  229. }
  230. display_virtual_time(dz->total_samps_written,dz);
  231. memset((char *)dz->sampbuf[1],0,write_block * sizeof(float));
  232. write_block = dz->sampbuf[2] - dz->sampbuf[1]; /* change writeable block to outbuf only */
  233. outbpos = 0;
  234. available_outspace = dz->buflen;
  235. }
  236. while(available_insamps < copyblk) {
  237. thisout = obuf+outbpos;
  238. thisin = ibuf+ibufpos;
  239. for(n=0;n<available_insamps;n++)
  240. thisout[n] += thisin[n];
  241. if((exit_status = read_samps(dz->sampbuf[0],dz))<0)
  242. return(exit_status);
  243. if(dz->vflag[IS_DRNK_OVERLAP])
  244. do_pregain(pregain,dz);
  245. (*thisbuf)++;
  246. ibufpos = 0;
  247. outbpos += available_insamps;
  248. copyblk -= available_insamps;
  249. available_insamps = dz->ssampsread;
  250. }
  251. if(copyblk > 0) {
  252. thisout = obuf+outbpos;
  253. thisin = ibuf+ibufpos;
  254. for(n=0;n<copyblk;n++)
  255. thisout[n] += thisin[n];
  256. ibufpos += copyblk;
  257. outbpos += copyblk;
  258. }
  259. if((exit_status = do_end_splice(chans,obuf,&outbpos,ibuf,&ibufpos,thisbuf,pregain,dz))<0)
  260. return(exit_status);
  261. *endwrite = outbpos;
  262. outbpos -= splicelen;
  263. if(outbpos >= dz->buflen) { /* if we're now beyond outbuf end: do bufwrite & copyback */
  264. if((exit_status = do_intermediate_write(endwrite,&outbpos,dz))<0)
  265. return(exit_status);
  266. }
  267. *obufpos = outbpos;
  268. return FINISHED;
  269. }
  270. /***************************** GET_THISDUR *******************************/
  271. int get_thisdur(int *thisdur,int *goalpcnt,int *pcnt,dataptr dz)
  272. {
  273. double randv;
  274. if(dz->mode==HAS_SOBER_MOMENTS && is_paus(goalpcnt,pcnt,dz))
  275. return TRUE;
  276. randv = drand48() * dz->param[DRNK_CLOKRND];
  277. if((*thisdur = round((double)dz->iparam[DRNK_CLOKTIK] * (1.0 + randv)))<dz->iparam[DRNK_SPLICELEN])
  278. *thisdur = round((double)dz->iparam[DRNK_CLOKTIK] * (1.0 - randv));
  279. *thisdur *= dz->infile->channels;
  280. return FALSE;
  281. }
  282. /***************************** GET_POS_AND_DUR_FOR_PAUSE *******************************/
  283. int get_pos_and_dur_for_pause(int *here,int *thisdur,int *thisbuf,int *ibufpos,double pregain,dataptr dz)
  284. {
  285. int exit_status;
  286. int step;
  287. int chans = dz->infile->channels;
  288. int ambitus = dz->iparam[DRNK_AMBITUS] * chans;
  289. int locus = dz->iparam[DRNK_LOCUS] * chans;
  290. int splicelen = dz->iparam[DRNK_SPLICELEN] * chans;
  291. if(ambitus>0 && (step = get_step(chans,dz))!=0)
  292. *here = get_new_pos(*here,ambitus,locus,step);
  293. if((exit_status = get_pausdur(here,splicelen,chans,thisdur,dz))<0)
  294. return(exit_status);
  295. return adjust_bufs(*here,ibufpos,thisbuf,pregain,dz);
  296. }
  297. /***************************** GET_POS *******************************/
  298. int get_pos(int *here,int thisdur,dataptr dz)
  299. {
  300. int step = 0;
  301. int chans = dz->infile->channels;
  302. int ambitus = dz->iparam[DRNK_AMBITUS] * chans;
  303. int locus = dz->iparam[DRNK_LOCUS] * chans;
  304. int splicelen = dz->iparam[DRNK_SPLICELEN] * chans;
  305. if(ambitus > 0 && (step = get_step(chans,dz))!=0)
  306. *here = get_new_pos(*here,ambitus,locus,step);
  307. else if(dz->iparam[DRNK_LAST_LOCUS] != dz->iparam[DRNK_LOCUS])
  308. *here = get_new_locus_pos(*here,ambitus,locus,step);
  309. dz->iparam[DRNK_LAST_LOCUS] = dz->iparam[DRNK_LOCUS];
  310. return bounce_off_file_end_if_necessary(here,thisdur,chans,splicelen,dz);
  311. }
  312. /*************************** PREGAIN ****************************
  313. *
  314. * Allows for effect of overlapping segments.
  315. */
  316. void do_pregain(double pregain,dataptr dz)
  317. {
  318. int i;
  319. double j;
  320. float *iptr = dz->sampbuf[0];
  321. for(i=0;i<dz->ssampsread;i++) {
  322. j = (*iptr) * pregain;
  323. *iptr++ = (float) /*round*/j;
  324. }
  325. }
  326. /******************************* IS_PAUS *******************************/
  327. int is_paus(int *goalpcnt,int *pcnt,dataptr dz)
  328. {
  329. if(*goalpcnt < 0) { /* if 1st time */
  330. setup_paus_params(dz);
  331. *goalpcnt = round(drand48() * (double)dz->iparam[DRNK_DRNKTIK_RANG]);
  332. *goalpcnt += dz->iparam[DRNK_MIN_DRNKTIK];
  333. } else if((*pcnt)++ >= *goalpcnt) { /* if counted enough events to insert pause */
  334. setup_paus_params(dz);
  335. *goalpcnt = round(drand48() * (double)dz->iparam[DRNK_DRNKTIK_RANG]);
  336. *goalpcnt += dz->iparam[DRNK_MIN_DRNKTIK];
  337. *pcnt = 0; /* Reset event counter to zero */
  338. return TRUE; /* Flag that pz has been returned */
  339. }
  340. return FALSE; /* ELSE Flag no pz on this occasion */
  341. }
  342. /************************* ADJUST_BUFS *********************/
  343. int adjust_bufs(int here,int *ibufpos,int *thisbuf,double pregain,dataptr dz)
  344. {
  345. int exit_status;
  346. int nextbuf = here/dz->buflen;
  347. if(nextbuf != *thisbuf) {
  348. if((sndseekEx(dz->ifd[0],nextbuf * dz->buflen,0))<0) {
  349. sprintf(errstr,"seek error in adjust_bufs()\n");
  350. return(SYSTEM_ERROR);
  351. }
  352. if((exit_status = read_samps(dz->sampbuf[0],dz))<0)
  353. return(exit_status);
  354. if(dz->vflag[IS_DRNK_OVERLAP])
  355. do_pregain(pregain,dz);
  356. }
  357. *ibufpos = here % dz->buflen;
  358. if(*ibufpos >= dz->ssampsread) {
  359. sprintf(errstr,"Buffer accounting problem: adjust_bufs()\n");
  360. return(PROGRAM_ERROR);
  361. }
  362. *thisbuf = nextbuf;
  363. return FINISHED;
  364. }
  365. /************************* DO_INTERMEDIATE_WRITE *********************/
  366. int do_intermediate_write(int *endwrite,int *obufpos,dataptr dz)
  367. {
  368. int exit_status;
  369. int samps_to_move = *endwrite - dz->buflen;
  370. int samps_available = dz->sampbuf[3] - dz->sampbuf[1];
  371. if((exit_status = write_samps(dz->sampbuf[1],dz->buflen,dz))<0)
  372. return(exit_status);
  373. display_virtual_time(dz->total_samps_written,dz);
  374. memmove((char *)dz->sampbuf[1],(char *)dz->sampbuf[2],(size_t)(samps_to_move* sizeof(float)));
  375. memset((char *)(dz->sampbuf[1] + samps_to_move),0,(size_t)((samps_available - samps_to_move)*sizeof(float)));
  376. *endwrite -= dz->buflen;
  377. *obufpos -= dz->buflen;
  378. return(FINISHED);
  379. }
  380. /************************* SETUP_PAUS_PARAMS *********************/
  381. void setup_paus_params(dataptr dz)
  382. {
  383. int tempval;
  384. if(dz->iparam[DRNK_MIN_DRNKTIK] > dz->iparam[DRNK_MAX_DRNKTIK]) {
  385. tempval = dz->iparam[DRNK_MIN_DRNKTIK];
  386. dz->iparam[DRNK_MIN_DRNKTIK] = dz->iparam[DRNK_MAX_DRNKTIK];
  387. dz->iparam[DRNK_MAX_DRNKTIK] = tempval;
  388. }
  389. dz->iparam[DRNK_DRNKTIK_RANG] = (int)(dz->iparam[DRNK_MAX_DRNKTIK] - dz->iparam[DRNK_MIN_DRNKTIK]);
  390. if(dz->param[DRNK_MIN_PAUS] >= dz->insams[0])
  391. dz->iparam[DRNK_MAXHOLD] = TRUE;
  392. else {
  393. dz->iparam[DRNK_MAXHOLD] = FALSE;
  394. if(dz->iparam[DRNK_MIN_PAUS] > dz->iparam[DRNK_MAX_PAUS]) {
  395. tempval = dz->iparam[DRNK_MIN_PAUS];
  396. dz->iparam[DRNK_MIN_PAUS] = dz->iparam[DRNK_MAX_PAUS];
  397. dz->iparam[DRNK_MAX_PAUS] = tempval;
  398. }
  399. dz->iparam[DRNK_PAUS_RANG] = (int)(dz->iparam[DRNK_MAX_PAUS] - dz->iparam[DRNK_MIN_PAUS]);
  400. }
  401. }
  402. /************************* GET_PREGAIN *********************/
  403. double get_pregain(dataptr dz)
  404. {
  405. double val;
  406. val = 1.0 - dz->param[DRNK_MAX_OVLAP]; /* e.g. 3/4+ -> 1/4 || .76 -> .24 */
  407. val = 1.0/val; /* i.e 1/4 -> 4 || .24 -> 4+ */
  408. val += 1.0; /* i.e. 4 -> 5 || 4+ -> 5+ */
  409. //TW UPDATE
  410. // return val;
  411. return 1.0/val;
  412. }
  413. /*************************** DO_START_SPLICE **************************/
  414. int do_start_splice(int chans,float *obuf,int *obufpos,float *ibuf,int *ibufpos,int *thisbuf,
  415. double pregain,int *endwrite,int outbufspace,dataptr dz)
  416. {
  417. int exit_status;
  418. int n;
  419. int m;
  420. int outbpos = *obufpos;
  421. int inbpos = *ibufpos;
  422. for(n=0;n<dz->iparam[DRNK_SPLICELEN];n++) {
  423. for(m=0;m<chans;m++) {
  424. if(outbpos >= outbufspace) {
  425. *endwrite = outbpos;
  426. if((exit_status = do_intermediate_write(endwrite,&outbpos,dz))<0)
  427. return(exit_status);
  428. }
  429. obuf[outbpos++] += (float)/*round*/((double)ibuf[inbpos++] * dz->parray[DRNK_SPLICETAB][n]);
  430. }
  431. if(inbpos >= dz->ssampsread) {
  432. if((exit_status = read_samps(dz->sampbuf[0],dz))<0)
  433. return(exit_status);
  434. if(dz->vflag[IS_DRNK_OVERLAP])
  435. do_pregain(pregain,dz);
  436. inbpos = 0;
  437. (*thisbuf)++;
  438. }
  439. }
  440. *obufpos = outbpos;
  441. *ibufpos = inbpos;
  442. return(FINISHED);
  443. }
  444. /*************************** DO_END_SPLICE **************************/
  445. int do_end_splice(int chans,float *obuf,int *obufpos,float *ibuf,int *ibufpos,int *thisbuf,double pregain,dataptr dz)
  446. {
  447. int exit_status;
  448. int n;
  449. int m;
  450. int outbpos = *obufpos;
  451. int inbpos = *ibufpos;
  452. for(n=dz->iparam[DRNK_SPLICELEN]-1;n>=0;n--) {
  453. for(m=0;m<chans;m++)
  454. obuf[outbpos++] += (float)/*round*/((double)ibuf[inbpos++] * dz->parray[DRNK_SPLICETAB][n]);
  455. if(inbpos >= dz->ssampsread) {
  456. if((exit_status = read_samps(dz->sampbuf[0],dz))<0)
  457. return(exit_status);
  458. if(dz->vflag[IS_DRNK_OVERLAP])
  459. do_pregain(pregain,dz);
  460. inbpos = 0;
  461. (*thisbuf)++;
  462. }
  463. }
  464. *obufpos = outbpos;
  465. *ibufpos = inbpos;
  466. return(FINISHED);
  467. }
  468. /*************************** GET_NEW_POS **************************/
  469. int get_new_pos(int here,int ambitus,int locus,int step)
  470. {
  471. int current_stray = here - locus; /* distance frm start available seg (locus) to current pos*/
  472. int new_stray = current_stray + step; /* new_stray = distance from locus */
  473. int otherstray, newstep;
  474. if(new_stray > ambitus || new_stray < -ambitus ) { /* if new_stray greater than ambitus */
  475. otherstray = current_stray - step;
  476. if(otherstray >= 0 && otherstray <= ambitus)
  477. here = locus + otherstray; /* try reversing step */
  478. else if(otherstray <0 && otherstray >= -ambitus)
  479. here = locus + otherstray;
  480. else {
  481. newstep = abs(new_stray) % ambitus; /* otherwise take modulus */
  482. if(step >= 0)
  483. here = locus + newstep;
  484. else
  485. here = locus - newstep;
  486. }
  487. } else
  488. here += step;
  489. if(here<0) /* Bounce off start of buffer if ness */
  490. here = -here;
  491. return(here);
  492. }
  493. /*************************** GET_NEW_LOCUS_POS **************************/
  494. int get_new_locus_pos(int here,int ambitus,int locus,int step)
  495. {
  496. int current_stray = here - locus; /* distance frm start available seg (locus) to current pos*/
  497. int new_stray = current_stray + step; /* new_stray = distance from locus */
  498. if(new_stray > ambitus || new_stray < -ambitus) /* if new_stray greater than ambitus */
  499. here = locus + step;
  500. else
  501. here += step;
  502. if(here<0) /* Bounce off start of buffer if ness */
  503. here = -here;
  504. return(here);
  505. }
  506. /*************************** GET_STEP **************************/
  507. int get_step(int chans,dataptr dz)
  508. {
  509. int step;
  510. double dstep = (drand48() * 2.0) - 1.0; /* range +1 to -1 */
  511. dstep *= dz->param[DRNK_GSTEP]; /* range +gstep to -gstep */
  512. step = round(dstep); /* Current stepsize in mintime-grains */
  513. step *= dz->iparam[DRNK_LGRAIN]; /* Current stepsize in samples */
  514. step *= chans;
  515. return step;
  516. }
  517. /*************************** GET_PAUSDUR **************************/
  518. int get_pausdur(int *here,int splicelen,int chans,int *thisdur,dataptr dz)
  519. {
  520. int this_pause;
  521. int max_pause = dz->insams[0] - *here - splicelen;
  522. if(EVEN(chans) && ODD(max_pause)) {
  523. sprintf(errstr,"Stereo anomaly at file end: get_pausdur()\n");
  524. return(PROGRAM_ERROR);
  525. }
  526. if(max_pause < 0) {
  527. sprintf(errstr,"Negative pause duration: get_pausdur()\n");
  528. return(PROGRAM_ERROR);
  529. }
  530. if(dz->iparam[DRNK_MAXHOLD])
  531. *thisdur = max_pause;
  532. else {
  533. this_pause = round(drand48() * dz->iparam[DRNK_PAUS_RANG]); /* gen pause dur between */
  534. this_pause += dz->iparam[DRNK_MIN_PAUS]; /* given limits */
  535. this_pause *= chans;
  536. *thisdur = min(this_pause,max_pause); /* but not >endoffile */
  537. }
  538. return(FINISHED);
  539. }
  540. /*************************** BOUNCE_OFF_FILE_END_IF_NECESSARY **************************/
  541. //TW MY CURRENT CODE AGREES WITH THIS, so removed #ifdef
  542. int bounce_off_file_end_if_necessary(int *here,int thisdur,int chans,int splicelen,dataptr dz)
  543. {
  544. int diff, initial_diff, needed;
  545. initial_diff = abs(dz->insams[0] - *here); /* Ensure enough room to read final segment and splice */
  546. if(EVEN(chans) && ODD(initial_diff)) {
  547. sprintf(errstr,"Stereo anomaly at file end: bounce_off_file_end_if_necessary()\n");
  548. return(PROGRAM_ERROR);
  549. }
  550. if((needed = thisdur + splicelen) > dz->insams[0]) {
  551. sprintf(errstr,"Segment duration exceeds size of sound\n");
  552. return(DATA_ERROR);
  553. }
  554. while((diff = dz->insams[0] - *here) < needed) {
  555. *here -= initial_diff; /* Bounce off end of buffer if ness */
  556. if(*here < 0 || initial_diff == 0) { /* But, if it bounces off BOTH ends !! */
  557. *here = (dz->insams[0] - needed)/dz->infile->channels;
  558. *here = (int)round(*here * drand48()) * dz->infile->channels;
  559. }
  560. }
  561. return(FINISHED);
  562. }