pulse.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767
  1. /*
  2. * Copyright (c) 1983-2013 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 <structures.h>
  24. #include <cdpmain.h>
  25. #include <tkglobals.h>
  26. #include <pnames.h>
  27. #include <distort.h>
  28. #include <processno.h>
  29. #include <modeno.h>
  30. #include <globcon.h>
  31. #include <logic.h>
  32. #include <filetype.h>
  33. #include <mixxcon.h>
  34. #include <distort1.h>
  35. #include <flags.h>
  36. #include <speccon.h>
  37. #include <arrays.h>
  38. #include <special.h>
  39. #include <formants.h>
  40. #include <sfsys.h>
  41. #include <osbind.h>
  42. #include <string.h>
  43. #include <arrays.h>
  44. #include <math.h>
  45. #include <ctype.h>
  46. /*
  47. PRESCALE PULSE-ENVELOPE FILE BETWEEN 0 and 1 in time and copy into parray[PULSENV]
  48. PRESCALE PULSE-TRANSPOS FILE BETWEEN 0 and 1 in time and copy into parray[PULSTRN]
  49. NB randomisation pulse-transposition only works if it's a brktable
  50. HAS TO BE MONO SNDFILE;
  51. */
  52. static int write_pulse_to_output(int *pbufpos,int *obufpos,dataptr dz);
  53. static void randomise_pulse_transposition(dataptr dz);
  54. static int randomise_pulse_envelope(int obufpos,dataptr dz);
  55. static double gen_sndtabindex(int obufpos,double *sndtabindex,double *pulsenvindex,double *envstep,
  56. int insertsmps,double tablen,int randomise_transpos,dataptr dz);
  57. static int extract_waveform(int *waveset_start,dataptr dz);
  58. static int get_wavesetstart(int ibufpos,dataptr dz);
  59. /* in ap_distort */
  60. static int prescale_pulse_transpos(dataptr dz);
  61. static int read_impulse_amp_val(double thistime,double *amp,dataptr dz);
  62. /************************************* PREPROCESS_PULSE *************************************/
  63. int preprocess_pulse(dataptr dz)
  64. {
  65. double k;
  66. int exit_status;
  67. if(dz->iparam[PULSE_ENVSIZE] > 0) {
  68. if((dz->parray[PULSENV] = (double *)malloc((dz->iparam[PULSE_ENVSIZE] * 2) * sizeof(double)))==NULL) {
  69. sprintf(errstr,"Out of memory for storing backup of original pulse envelope.\n");
  70. return(MEMORY_ERROR);
  71. }
  72. memcpy((char *)dz->parray[PULSENV],(char *)dz->parray[ORIG_PULSENV],(dz->iparam[PULSE_ENVSIZE] * 2) * sizeof(double));
  73. /* copy original envelope into parray */
  74. if((dz->iparray[0] = (int *)malloc(dz->iparam[PULSE_ENVSIZE] * sizeof(int)))==NULL) {
  75. sprintf(errstr,"Out of memory for storing markers for envelope warping.\n");
  76. return(MEMORY_ERROR);
  77. }
  78. }
  79. if(dz->brksize[PULSE_TRANSPOS] > 0) {
  80. if((exit_status = prescale_pulse_transpos(dz))<0)
  81. return(exit_status);
  82. } else {
  83. k = dz->param[PULSE_TRANSPOS] / 12.0;
  84. dz->param[PULSE_TRANSPOS] = pow(2.0,k); /* convert semitones to frq-ratio */
  85. }
  86. return(FINISHED);
  87. }
  88. /*********************************** PRESCALE_PULSE_TRANSPOS *************************************/
  89. int prescale_pulse_transpos(dataptr dz)
  90. {
  91. int brklen = dz->brksize[PULSE_TRANSPOS] * 2;
  92. int maxtimindx = brklen - 2;
  93. int n,m;
  94. double maxtime = dz->brk[PULSE_TRANSPOS][maxtimindx], scaler;
  95. scaler = 1.0/maxtime;
  96. for(n=0,m=1;n<brklen;n+=2,m+=2)
  97. dz->brk[PULSE_TRANSPOS][n] *= scaler; /* scale to 0 to 1 time range */
  98. dz->brk[PULSE_TRANSPOS][maxtimindx] = 1.0;
  99. if((dz->parray[PULSTRN] = (double *)malloc(brklen * sizeof(double)))==NULL) {
  100. sprintf(errstr,"Out of memory for storing backup of original pulse transposition envelope\n");
  101. return(MEMORY_ERROR);
  102. }
  103. memcpy((char *)dz->parray[PULSTRN],(char *)dz->brk[PULSE_TRANSPOS],brklen * sizeof(double));
  104. return(FINISHED);
  105. }
  106. /************************************* DO_PULSETRAIN *************************************/
  107. int do_pulsetrain(dataptr dz)
  108. {
  109. int exit_status;
  110. float *ibuf = dz->sampbuf[0]; /* stores input */
  111. float *obuf = dz->sampbuf[1]; /* stores output */
  112. float *sbuf = dz->sampbuf[2]; /* stores waveset cycoes, for SYN option */
  113. float *pbuf = dz->sampbuf[3]; /* stores pulse, before writing to output */
  114. int srate = dz->infile->srate;
  115. float *spliceptr, *obufend = obuf + dz->buflen;
  116. int startsamp = round(dz->param[PULSE_STARTTIME] * srate);
  117. int insertdur = round(dz->param[PULSE_DUR] * srate);
  118. int last_total_ssampsread, total_ssampsread = 0, ssampsread = 0, insertsmps = 0;
  119. int smpsecsize = F_SECSIZE, secsleft, edit_todo = (int)round(ENDBIT_SPLICE);
  120. int ibufpos = 0, ibufleft, obufpos = 0, pbufpos = 0, obufleft;
  121. double amp, frq, sndtabindex, pulsenvindex;
  122. int waveset_len = 0;
  123. double envstep;
  124. int randomise_transpos = 0, firsttime = 1;
  125. int smps_pretime, waveset_start;
  126. double interp, valdiff, k;
  127. float val, upval;
  128. int here, n, m;
  129. if(dz->mode == PULSE_SYNI)
  130. startsamp = dz->iparam[PULSE_STARTTIME];
  131. else
  132. startsamp = round(dz->param[PULSE_STARTTIME] * srate);
  133. /* PROCESS FILE PRIOR TO PULSE-TRAIN'S START, IF NESS */
  134. if(dz->mode == PULSE_IMP) {
  135. k = dz->duration;
  136. if(!dz->vflag[PULSE_KEEPSTART]) {
  137. k -= dz->param[PULSE_STARTTIME];
  138. if(!dz->vflag[PULSE_KEEPEND])
  139. k = min(dz->param[PULSE_DUR],k);
  140. } else if(!dz->vflag[PULSE_KEEPEND]) {
  141. k = dz->param[PULSE_STARTTIME] + dz->param[PULSE_DUR];
  142. k = min(dz->duration,k);
  143. }
  144. } else {
  145. k = dz->param[PULSE_DUR];
  146. if(dz->vflag[PULSE_KEEPEND]) {
  147. k += dz->duration;
  148. if(!dz->vflag[PULSE_KEEPSTART])
  149. k -= dz->param[PULSE_STARTTIME];
  150. } else if(dz->vflag[PULSE_KEEPSTART])
  151. k += dz->param[PULSE_STARTTIME];
  152. }
  153. dz->tempsize = (int)round(k * (dz->infile->srate));
  154. while(total_ssampsread + dz->buflen < startsamp) {
  155. if(( exit_status = read_samps(ibuf,dz)) < 0) {
  156. sprintf(errstr, "Can't read samps from input soundfile\n");
  157. return(SYSTEM_ERROR);
  158. }
  159. ssampsread = dz->ssampsread;
  160. last_total_ssampsread = total_ssampsread;
  161. total_ssampsread += ssampsread;
  162. if(dz->vflag[PULSE_KEEPSTART]) {
  163. if(ssampsread > 0) {
  164. if((exit_status = write_samps(ibuf,ssampsread,dz))<0)
  165. return(exit_status);
  166. }
  167. }
  168. }
  169. if((secsleft = (startsamp - total_ssampsread)/smpsecsize)> 0) {
  170. if(( ssampsread = fgetfbufEx(ibuf,secsleft * F_SECSIZE, dz->ifd[0],0)) < 0) {
  171. sprintf(errstr, "Can't read samps from input soundfile\n");
  172. return(SYSTEM_ERROR);
  173. }
  174. last_total_ssampsread = total_ssampsread;
  175. total_ssampsread += ssampsread;
  176. if(dz->vflag[PULSE_KEEPSTART]) {
  177. if(ssampsread > 0) {
  178. if((exit_status = write_samps(ibuf,ssampsread,dz))<0)
  179. return(exit_status);
  180. }
  181. }
  182. }
  183. smps_pretime = startsamp - total_ssampsread; /* no of samples before param-specified time */
  184. if(( ssampsread = fgetfbufEx(ibuf, dz->buflen + F_SECSIZE, dz->ifd[0],0)) < 0) {
  185. sprintf(errstr, "Can't read samples from input soundfile\n"); /* To get wraparound points */
  186. return(SYSTEM_ERROR);
  187. }
  188. last_total_ssampsread = total_ssampsread;
  189. if(ssampsread > dz->buflen) {
  190. sndseekEx(dz->ifd[0],last_total_ssampsread + dz->buflen,0);
  191. total_ssampsread = last_total_ssampsread + dz->buflen;
  192. } else { /* We'RE AT END oF FILE... */
  193. total_ssampsread = last_total_ssampsread + ssampsread;
  194. ibuf[ssampsread] = 0.0; /* CREATE zero-val wraparound points */
  195. }
  196. /* FIND START OF WAVESETS */
  197. if((waveset_start = get_wavesetstart(smps_pretime,dz)) < 0) {
  198. sprintf(errstr,"Can't find the required waveset start within a single buffer.\n");
  199. return(GOAL_FAILED);
  200. }
  201. if((waveset_start > 0) && dz->vflag[PULSE_KEEPSTART]) {
  202. memcpy((char *)obuf,(char *)ibuf,waveset_start * sizeof(float));
  203. obufpos = waveset_start; /* copy any inbuf remnant prior to pulsing, to outbuf */
  204. }
  205. ibufpos = waveset_start;
  206. if(dz->mode!=PULSE_IMP) {
  207. if((waveset_len = extract_waveform(&waveset_start,dz))<0) { /* NB copy rounding sample[s] at end */
  208. sprintf(errstr,"Can't find the required wavesets within a single buffer.\n");
  209. return(GOAL_FAILED);
  210. }
  211. sndtabindex = 0.0; /* position in storage buffer */
  212. } else
  213. sndtabindex = (double)waveset_start; /* position in input buffer */
  214. /* INITIALISE SHAPE AND LENGTH OF FIRST IMPULSE */
  215. if(dz->iparam[PULSE_ENVSIZE] > 0)
  216. randomise_pulse_envelope(obufpos,dz); /* randomise shape of pulse, and copy reshaped pulse to read-env-table */
  217. /* +insert edit shoulders at start and end */
  218. if(!flteq(dz->param[PULSE_PITCHRAND],0.0)) {
  219. randomise_transpos = 1;
  220. if(dz->brksize[PULSE_TRANSPOS] <= 0) {
  221. fprintf(stdout,"WARNING: Randomisation of transposition only applies to a transposition TABLE\n");
  222. fflush(stdout);
  223. randomise_transpos = 0;
  224. } else
  225. randomise_pulse_transposition(dz);
  226. } else if (dz->brksize[PULSE_TRANSPOS] > 0) { /* if NOT randomised, convert to frqratio NOW */
  227. for(n=0,m=1;n<dz->brksize[PULSE_TRANSPOS];n++,m+=2) {
  228. k = dz->parray[PULSTRN][m]/SEMITONES_PER_OCTAVE;
  229. dz->brk[PULSE_TRANSPOS][m] = pow(2.0,k);
  230. }
  231. }
  232. pulsenvindex = 0.0;
  233. if(dz->iparam[PULSE_ENVSIZE] <= 0)
  234. amp = 1.0;
  235. else
  236. amp = dz->parray[PULSENV][0];
  237. if(dz->brksize[PULSE_FRQ] > 0) {
  238. if((exit_status = read_value_from_brktable(0.0,PULSE_FRQ,dz))<0)
  239. return exit_status;
  240. }
  241. frq = dz->param[PULSE_FRQ];
  242. if(dz->param[PULSE_FRQRAND] > 0.0) {
  243. k = ((drand48() * 2.0) - 1.0) * dz->param[PULSE_FRQRAND];
  244. k /= SEMITONES_PER_OCTAVE;
  245. k = pow(2.0,k);
  246. frq *= k;
  247. }
  248. envstep = frq/srate;
  249. /* DO IMPULSE TRAIN */
  250. while(insertsmps < insertdur) {
  251. if(!firsttime && flteq(pulsenvindex,0.0)) { /* if at start of new pulse */
  252. if((exit_status = write_pulse_to_output(&pbufpos,&obufpos,dz))<0)
  253. return(exit_status);
  254. }
  255. firsttime = 0;
  256. if(dz->mode!=PULSE_IMP) {
  257. interp = fmod(sndtabindex,1.0);
  258. here = (int)floor(sndtabindex);
  259. val = sbuf[here++];
  260. upval = sbuf[here];
  261. valdiff = (upval - val) * interp;
  262. pbuf[pbufpos++] = (float)((val + valdiff) * amp);
  263. if(pbufpos >= dz->buflen) {
  264. sprintf(errstr,"Pulse length exceeds length of internal buffer : cannot proceed.\n");
  265. return(GOAL_FAILED);
  266. }
  267. } else {
  268. interp = fmod(sndtabindex,1.0);
  269. ibufpos = (int)floor(sndtabindex);
  270. while(ibufpos >= ssampsread) {
  271. /* read extra sector, for wraparound vals for interpolation */
  272. if(( ssampsread = fgetfbufEx(ibuf, dz->buflen + F_SECSIZE, dz->ifd[0],0)) < 0) {
  273. sprintf(errstr, "Can't read samps from input soundfile\n"); /* read failed */
  274. return(SYSTEM_ERROR);
  275. }
  276. if(ssampsread <= 0) { /* read zero bytes = EOF */
  277. if(obufpos > 0) {
  278. if((exit_status = write_samps(obuf,obufpos,dz))<0)
  279. return(exit_status);
  280. }
  281. return(FINISHED);
  282. }
  283. if(ssampsread <= dz->buflen) { /* generate zero-val wraparound points if buffer+wrap not full */
  284. ibuf[ssampsread] = 0.0;
  285. total_ssampsread += ssampsread;
  286. } else {
  287. last_total_ssampsread = total_ssampsread;
  288. ssampsread = dz->buflen; /* effective read is a buffer-full */
  289. total_ssampsread += ssampsread;
  290. sndseekEx(dz->ifd[0],last_total_ssampsread + dz->buflen,0);
  291. }
  292. ibufpos -= dz->buflen; /* as current read succeeded, last input buffer was full: so this val is >= 0 */
  293. sndtabindex -= (double)dz->buflen;
  294. }
  295. val = ibuf[ibufpos++];
  296. upval = ibuf[ibufpos];
  297. valdiff = (upval - val) * interp;
  298. pbuf[pbufpos++] = (float)((val + valdiff) * amp);
  299. if(pbufpos >= dz->buflen) {
  300. sprintf(errstr,"Pulse length exceeds length of internal buffer : cannot proceed\n");
  301. return(GOAL_FAILED);
  302. }
  303. }
  304. amp = gen_sndtabindex(obufpos,&sndtabindex,&pulsenvindex,&envstep,insertsmps,(double)waveset_len,randomise_transpos,dz);
  305. insertsmps++;
  306. }
  307. if(pbufpos > 0) {
  308. if((exit_status = write_pulse_to_output(&pbufpos,&obufpos,dz))<0)
  309. return(exit_status);
  310. }
  311. /* DO REST OF INPUT FILE AFTER PULSETRAIN, IF NESS */
  312. if(dz->vflag[PULSE_KEEPEND]) {
  313. for(;;) {
  314. ibufleft = ssampsread - ibufpos;
  315. obufleft = dz->buflen - obufpos;
  316. spliceptr = obuf+obufpos;
  317. if(ibufleft >= obufleft) {
  318. memcpy((char *)(obuf+obufpos),(char *)(ibuf+ibufpos),obufleft * sizeof(float));
  319. while(edit_todo > 0) {
  320. k = *spliceptr * ((ENDBIT_SPLICE - (double)edit_todo)/ENDBIT_SPLICE);
  321. *spliceptr++ = (float)k;
  322. edit_todo--;
  323. if(spliceptr >= obufend)
  324. break;
  325. }
  326. ibufpos += obufleft;
  327. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  328. return(exit_status);
  329. obufpos = 0;
  330. } else {
  331. memcpy((char *)(obuf+obufpos),(char *)(ibuf+ibufpos),ibufleft * sizeof(float));
  332. while(edit_todo > 0) {
  333. k = *spliceptr * ((ENDBIT_SPLICE - (double)edit_todo)/ENDBIT_SPLICE);
  334. *spliceptr++ = (float)k;
  335. edit_todo--;
  336. if(spliceptr >= obufend)
  337. break;
  338. }
  339. obufpos += ibufleft;
  340. if(( exit_status = read_samps(ibuf, dz)) < 0) {
  341. sprintf(errstr, "Can't read samps from input soundfile\n");
  342. return(SYSTEM_ERROR);
  343. }
  344. ssampsread = dz->ssampsread;
  345. if(ssampsread <= 0)
  346. break;
  347. ibufpos = 0;
  348. }
  349. }
  350. }
  351. if(obufpos > 0) {
  352. if((exit_status = write_samps(obuf,obufpos,dz))<0)
  353. return(exit_status);
  354. }
  355. return(FINISHED);
  356. }
  357. /************************************* GET_WAVESETSTART *************************************/
  358. int get_wavesetstart(int ibufpos,dataptr dz)
  359. {
  360. float *ibuf = dz->sampbuf[0];
  361. if(ibuf[ibufpos] > 0.0) {
  362. while(ibuf[ibufpos] > 0.0) {
  363. if(++ibufpos >= dz->buflen)
  364. return(-1);
  365. }
  366. } else if(ibuf[ibufpos] < 0.0) {
  367. while(ibuf[ibufpos] < 0.0) {
  368. if(++ibufpos >= dz->buflen)
  369. return(-1);
  370. }
  371. } else {
  372. while(smpflteq(ibuf[ibufpos],0.0)) {
  373. if(++ibufpos >= dz->buflen)
  374. return(-1);
  375. }
  376. }
  377. return(ibufpos);
  378. }
  379. /************************************* EXTRACT_WAVEFORM *************************************/
  380. // NOV 2002 MAXSAMP -> F_MAXSAMP as well as short -> float
  381. int extract_waveform(int *waveset_start,dataptr dz)
  382. {
  383. int ibufpos = *waveset_start, waveform_len = 0;
  384. float *ibuf = dz->sampbuf[0];
  385. float *sbuf = dz->sampbuf[2];
  386. double frqlimit = dz->infile->srate/PULSE_FRQLIM;
  387. double amplimit = dbtogain((double)PULSE_DBLIM) * F_MAXSAMP;
  388. int capture_samps = 0, capture_wavesets = 0;
  389. int last_waveform_len = 0;
  390. double maxval, last_maxval = 0.0, wcntr = 0;
  391. if(dz->mode == PULSE_SYN)
  392. capture_samps = (int)round(dz->param[PULSE_WAVETIME] * dz->infile->srate);
  393. else
  394. capture_wavesets = dz->iparam[PULSE_WAVETIME];
  395. while(smpflteq(ibuf[ibufpos],0.0)) {
  396. if(++ibufpos >= dz->buflen)
  397. return(-1);
  398. }
  399. *waveset_start = ibufpos;
  400. maxval = fabs(ibuf[ibufpos]);
  401. switch(dz->mode) {
  402. case(PULSE_SYN):
  403. for(;;) {
  404. if(ibuf[ibufpos] > 0.0) {
  405. while(ibuf[ibufpos] > 0.0) {
  406. if(++ibufpos >= dz->buflen)
  407. return(-1);
  408. maxval = max(maxval,fabs(ibuf[ibufpos]));
  409. }
  410. while(ibuf[ibufpos] <= 0.0) {
  411. if(++ibufpos >= dz->buflen)
  412. return(-1);
  413. maxval = max(maxval,fabs(ibuf[ibufpos]));
  414. }
  415. } else if(ibuf[ibufpos] < 0.0) {
  416. while(ibuf[ibufpos] < 0.0) {
  417. if(++ibufpos >= dz->buflen)
  418. return(-1);
  419. maxval = max(maxval,fabs(ibuf[ibufpos]));
  420. }
  421. while(ibuf[ibufpos] >= 0.0) {
  422. if(++ibufpos >= dz->buflen)
  423. return(-1);
  424. maxval = max(maxval,fabs(ibuf[ibufpos]));
  425. }
  426. }
  427. if((waveform_len = ibufpos - *waveset_start) >= capture_samps)
  428. break;
  429. else {
  430. last_waveform_len = waveform_len;
  431. last_maxval = maxval;
  432. }
  433. }
  434. if(capture_samps - last_waveform_len < waveform_len - capture_samps) {
  435. waveform_len = last_waveform_len;
  436. maxval = last_maxval;
  437. }
  438. break;
  439. case(PULSE_SYNI):
  440. while(wcntr < capture_wavesets) {
  441. if(ibuf[ibufpos] > 0.0) {
  442. while(ibuf[ibufpos] > 0.0) {
  443. if(++ibufpos >= dz->buflen)
  444. return(-1);
  445. maxval = max(maxval,fabs(ibuf[ibufpos]));
  446. }
  447. while(ibuf[ibufpos] <= 0.0) {
  448. if(++ibufpos >= dz->buflen)
  449. return(-1);
  450. maxval = max(maxval,fabs(ibuf[ibufpos]));
  451. }
  452. } else if(ibuf[ibufpos] < 0.0) {
  453. while(ibuf[ibufpos] < 0.0) {
  454. if(++ibufpos >= dz->buflen)
  455. return(-1);
  456. maxval = max(maxval,fabs(ibuf[ibufpos]));
  457. }
  458. while(ibuf[ibufpos] >= 0.0) {
  459. if(++ibufpos >= dz->buflen)
  460. return(-1);
  461. maxval = max(maxval,fabs(ibuf[ibufpos]));
  462. }
  463. }
  464. wcntr++;
  465. }
  466. waveform_len = ibufpos - *waveset_start;
  467. break;
  468. }
  469. if(waveform_len <= 0) {
  470. sprintf(errstr,"Failed to establish a viable sound to loop\n");
  471. return(GOAL_FAILED);
  472. } else if((double)waveform_len <= frqlimit) {
  473. frqlimit = (double)dz->infile->srate/(double)waveform_len;
  474. fprintf(stdout,"WARNING: Waveset length is only %d samples, corresponding to frq >= %.1lf hz\n",waveform_len,frqlimit);
  475. fflush(stdout);
  476. }
  477. if((double)maxval <= amplimit) {
  478. fprintf(stdout,"WARNING: Waveset amplitude is <= %lf dB\n",(double)PULSE_DBLIM);
  479. fflush(stdout);
  480. }
  481. memcpy((char *)sbuf,(char *)(ibuf + *waveset_start),waveform_len * sizeof(float));
  482. return(waveform_len);
  483. }
  484. /************************************* GEN_TABINDEX *************************************/
  485. double gen_sndtabindex(int obufpos,double *sndtabindex,double *pulsenvindex,double *envstep,
  486. int insertsmps,double tablen,int randomise_transpos,dataptr dz)
  487. {
  488. int exit_status;
  489. double thistime, amp, frq, k;
  490. *pulsenvindex += *envstep;
  491. if(*pulsenvindex >= 1.0) {
  492. if(dz->iparam[PULSE_ENVSIZE] <= 0) { /* no impulse: must continue to end of sndtable (zero-cross) to avoid glitch */
  493. *sndtabindex += dz->param[PULSE_TRANSPOS]; /* transpos sticks at previous value as table end has been reached */
  494. if(*sndtabindex >= tablen) {
  495. *pulsenvindex = 0.0; /* reset to start of envelope */
  496. *sndtabindex = 0.0;
  497. thistime = (double)insertsmps/(double)dz->infile->srate;
  498. if(dz->brksize[PULSE_FRQ] > 0) {
  499. if((exit_status = read_value_from_brktable(thistime,PULSE_FRQ,dz))<0)
  500. return exit_status;
  501. }
  502. frq = dz->param[PULSE_FRQ];
  503. if(dz->param[PULSE_FRQRAND] > 0.0) {
  504. k = ((drand48() * 2.0) - 1.0) * dz->param[PULSE_FRQRAND];
  505. k /= SEMITONES_PER_OCTAVE;
  506. k = pow(2.0,k);
  507. frq *= k;
  508. }
  509. *envstep = frq/dz->infile->srate;
  510. if(randomise_transpos && (dz->param[PULSE_PITCHRAND] > 0.0))
  511. randomise_pulse_transposition(dz);
  512. }
  513. return(1.0); /* no impulse: amplitude is always 1.0 */
  514. }
  515. /* GET NEW VALUE OF PULSE FRQ, AND HENCE OF STEP IN ENVEL TABLE */
  516. thistime = (double)insertsmps/(double)dz->infile->srate;
  517. if(dz->brksize[PULSE_FRQ] > 0) {
  518. if((exit_status = read_value_from_brktable(thistime,PULSE_FRQ,dz))<0)
  519. return exit_status;
  520. }
  521. frq = dz->param[PULSE_FRQ];
  522. if(dz->param[PULSE_FRQRAND] > 0.0) {
  523. k = ((drand48() * 2.0) - 1.0) * dz->param[PULSE_FRQRAND];
  524. k /= SEMITONES_PER_OCTAVE;
  525. k = pow(2.0,k);
  526. frq *= k;
  527. }
  528. *envstep = frq/dz->infile->srate;
  529. if(dz->iparam[PULSE_ENVSIZE] > 0)
  530. randomise_pulse_envelope(obufpos,dz); /* randomise shape of pulse, and copy reshaped pulse to read-env-table */
  531. /* insert edit shoulders at start and end */
  532. /* orig envelope has been copied to parray[PULSENV], variant copied back to brk[] */
  533. if(randomise_transpos && (dz->param[PULSE_PITCHRAND] > 0.0))
  534. randomise_pulse_transposition(dz);
  535. *pulsenvindex = 0.0; /* reset to start of envelope */
  536. if((exit_status = read_impulse_amp_val(*pulsenvindex,&amp,dz))<0)
  537. return exit_status;
  538. if(dz->mode!=PULSE_IMP)
  539. *sndtabindex = 0.0;
  540. else
  541. *sndtabindex = floor(*sndtabindex + 1.0); /* sync table pointer with actual samples in input stream */
  542. } else {
  543. if(dz->iparam[PULSE_ENVSIZE] <= 0) { /* no impulse */
  544. if(dz->brksize[PULSE_TRANSPOS]) {
  545. if((exit_status = read_value_from_brktable(*pulsenvindex,PULSE_TRANSPOS,dz))<0)
  546. return exit_status;
  547. }
  548. *sndtabindex += dz->param[PULSE_TRANSPOS];
  549. *sndtabindex = fmod(*sndtabindex,tablen); /* cycle around soundtable */
  550. return(1.0); /* no impulse: amplitude is always 1.0 */
  551. }
  552. if((exit_status = read_impulse_amp_val(*pulsenvindex,&amp,dz))<0)
  553. return exit_status;
  554. if(dz->brksize[PULSE_TRANSPOS]) {
  555. if((exit_status = read_value_from_brktable(*pulsenvindex,PULSE_TRANSPOS,dz))<0)
  556. return exit_status;
  557. }
  558. *sndtabindex += dz->param[PULSE_TRANSPOS];
  559. if(dz->mode!=PULSE_IMP)
  560. *sndtabindex = fmod(*sndtabindex,tablen);
  561. }
  562. return amp;
  563. }
  564. /************************************* RANDOMISE_PULSE_ENVELOPE *************************************/
  565. int randomise_pulse_envelope(int obufpos,dataptr dz)
  566. {
  567. int n, m, kk, maxpos, maxmark;
  568. int *mark = dz->iparray[0];
  569. double ratio, above, below, randmove, k, maxi, timearound;
  570. double convertor = (dz->param[PULSE_FRQ] * ENDBIT_SPLICE)/(double)dz->infile->srate;
  571. double abovestep, belowstep, minbelowtime, minabovetime;
  572. int not_above, not_below;
  573. dz->parray[PULSENV][0] = dz->parray[ORIG_PULSENV][0];
  574. for(n=3;n<dz->iparam[PULSE_ENVSIZE]*2;n+=2) {
  575. if(dz->parray[ORIG_PULSENV][n] < dz->parray[ORIG_PULSENV][n-2]) {
  576. ratio = dz->parray[PULSENV][n-2]/dz->parray[ORIG_PULSENV][n-2]; /* ratio of previous val's new height to it's old height */
  577. above = (dz->parray[ORIG_PULSENV][n-2] - dz->parray[ORIG_PULSENV][n]) * ratio; /* vert distance twixt preceding point & this, scaled */
  578. below = (dz->parray[ORIG_PULSENV][n]) * ratio; /* vert distance twixt 0 & this, scaled */
  579. k = ((drand48() * 2.0) - 1.0) * dz->param[PULSE_SHAPERAND];
  580. if(k >= 0.0)
  581. randmove = above * k;
  582. else
  583. randmove = below * k;
  584. dz->parray[PULSENV][n] = below + randmove;
  585. } else if(dz->parray[ORIG_PULSENV][n] > dz->parray[ORIG_PULSENV][n-2]) {
  586. ratio = (1.0 - dz->parray[PULSENV][n-2])/(1.0 - dz->parray[ORIG_PULSENV][n-2]); /* simil ratio of dist from top [1.0] */
  587. above = (1.0 - dz->parray[ORIG_PULSENV][n]) * ratio; /* vert distance twixt top [1.0] & this point, scaled */
  588. below = (dz->parray[ORIG_PULSENV][n] - dz->parray[ORIG_PULSENV][n-2]) * ratio; /* vert distance preceeding pnt & this, scaled */
  589. k = ((drand48() * 2.0) - 1.0) * dz->param[PULSE_SHAPERAND];
  590. if(k >= 0.0)
  591. randmove = above * k;
  592. else
  593. randmove = below * k;
  594. dz->parray[PULSENV][n] = dz->parray[PULSENV][n-2] + below + randmove;
  595. } else {
  596. dz->parray[PULSENV][n] = dz->parray[PULSENV][n-2];
  597. }
  598. }
  599. /* randomise pulse-env timings */
  600. for(m=1;m < dz->iparam[PULSE_ENVSIZE]-1; m++)
  601. mark[m] = 0;
  602. kk = dz->iparam[PULSE_ENVSIZE] - 2;
  603. while(kk>0) {
  604. maxi = 0.0;
  605. maxpos = 0;
  606. maxmark = 0;
  607. not_above = 0;
  608. not_below = 0;
  609. for(m=1,n=2;n < (dz->iparam[PULSE_ENVSIZE]-1) * 2; n+=2,m++) {
  610. if(mark[m]==0) {
  611. timearound = dz->parray[PULSENV][n+2] - dz->parray[PULSENV][n-2];
  612. if(timearound > maxi) {
  613. maxi = timearound;
  614. maxpos = n;
  615. maxmark = m;
  616. }
  617. }
  618. }
  619. abovestep = dz->parray[PULSENV][maxpos+3] - dz->parray[PULSENV][maxpos+1];
  620. belowstep = dz->parray[PULSENV][maxpos+1] - dz->parray[PULSENV][maxpos-1];
  621. minbelowtime = fabs(convertor * belowstep);
  622. minabovetime = fabs(convertor * abovestep);
  623. if((above = dz->parray[PULSENV][maxpos+2] - dz->parray[PULSENV][maxpos]) < minabovetime)
  624. not_above = 1;
  625. if((below = dz->parray[PULSENV][maxpos] - dz->parray[PULSENV][maxpos-2]) < minbelowtime)
  626. not_below = 1;
  627. if(not_above) {
  628. if(not_below) {
  629. sprintf(errstr,"WARNING: possible glitch, due to sudden envelope change, after %lf secs\n",
  630. (dz->total_samps_written + obufpos)/(double)dz->infile->srate);
  631. fflush(stdout);
  632. k = 0.0;
  633. } else
  634. k = drand48() * -1.0 * dz->param[PULSE_TIMERAND];
  635. } else if(not_below)
  636. k = drand48() * dz->param[PULSE_TIMERAND];
  637. else
  638. k = ((drand48() * 2.0) - 1.0) * dz->param[PULSE_TIMERAND];
  639. /* KLUDGE --> */
  640. k *= 0.5;
  641. /* <-- KLUDGE */
  642. if(k >= 0.0)
  643. randmove = above * k;
  644. else
  645. randmove = below * k;
  646. dz->parray[PULSENV][maxpos] += randmove;
  647. mark[maxmark] = 1;
  648. kk--;
  649. }
  650. return(FINISHED);
  651. }
  652. /************************************* RANDOMISE_PULSE_TRANSPOSITION *************************************/
  653. void randomise_pulse_transposition(dataptr dz)
  654. {
  655. int n, m;
  656. double k;
  657. for(n=0,m=1;n<dz->brksize[PULSE_TRANSPOS];n++,m+=2) {
  658. if(flteq(dz->brk[PULSE_TRANSPOS][m],0.0))
  659. dz->brk[PULSE_TRANSPOS][m] = 1.0;
  660. else {
  661. k = ((drand48() * 2.0) - 1.0) * dz->param[PULSE_PITCHRAND];
  662. k *= dz->parray[PULSTRN][m]/SEMITONES_PER_OCTAVE;
  663. dz->brk[PULSE_TRANSPOS][m] = pow(2.0,k);
  664. }
  665. }
  666. }
  667. /************************************* WRITE_PULSE_TO_OUTPUT *************************************/
  668. int write_pulse_to_output(int *pbufpos,int *obufpos,dataptr dz)
  669. {
  670. int exit_status;
  671. float *obuf = dz->sampbuf[1];
  672. float *pbuf = dz->sampbuf[3];
  673. int n, m;
  674. if(dz->iparam[PULSE_ENVSIZE] > 0) {
  675. for(n=0;n<round(ENDBIT_SPLICE);n++) /* WRITE PULSE-BUFFER TO OUTPUT, with relevant splices if there's an impulse envelope */
  676. pbuf[n] = (float)(pbuf[n] * (double)n/ENDBIT_SPLICE);
  677. for(m = *pbufpos-1,n=0;n<round(ENDBIT_SPLICE);n++,m--)
  678. pbuf[m] = (float)(pbuf[m] * (double)n/ENDBIT_SPLICE);
  679. }
  680. for(n=0;n<*pbufpos;n++) {
  681. obuf[(*obufpos)++] = pbuf[n];
  682. if(*obufpos >= dz->buflen) {
  683. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  684. return(exit_status);
  685. *obufpos = 0;
  686. }
  687. }
  688. *pbufpos = 0;
  689. return(FINISHED);
  690. }
  691. /**************************** READ_IMPULSE_AMP_VAL *****************************/
  692. int read_impulse_amp_val(double thistime,double *amp,dataptr dz)
  693. {
  694. double *p, lotime, loval, hitime, hival, timediff, step, ratio;
  695. p = dz->parray[PULSENV];
  696. if(flteq(thistime,0.0)) {
  697. *amp = dz->parray[PULSENV][1];
  698. return(FINISHED);
  699. }
  700. while(*p < thistime)
  701. p += 2;
  702. p -= 2;
  703. lotime = *p++;
  704. loval = *p++;
  705. hitime = *p++;
  706. hival = *p++;
  707. timediff = thistime - lotime;
  708. step = hival - loval;
  709. ratio = timediff/(hitime-lotime);
  710. *amp = loval + (step * ratio);
  711. return(FINISHED);
  712. }