wave.c 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003
  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. /* RWD 22/02/2018 changed sndfile interleave code to eliminate glitch on ch2
  22. only suffix number to outfile name for sloom
  23. */
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <structures.h>
  27. #include <tkglobals.h>
  28. #include <globcon.h>
  29. #include <cdpmain.h>
  30. #include <synth.h>
  31. #include <processno.h>
  32. #include <modeno.h>
  33. #include <pnames.h>
  34. #include <flags.h>
  35. #include <arrays.h>
  36. #include <math.h>
  37. #include <logic.h>
  38. #include <speccon.h>
  39. #include <sfsys.h>
  40. #include <osbind.h>
  41. #include <string.h> /*RWD*/
  42. //TW UPDATE
  43. #include <limits.h>
  44. #include <filetype.h>
  45. //#ifdef unix
  46. #define round(x) lround((x))
  47. //#endif
  48. static int gentable(int tabsize,dataptr dz);
  49. static int gen_wave(int sampdur,double sr,dataptr dz);
  50. static int gen_silence(int sampdur,dataptr dz);
  51. static int gen_noise(int sampdur,double sr,dataptr dz);
  52. static int update_wave_params(double *ampstep,double *frqstep,double *lastamp,double *lastfrq,double inverse_sr,
  53. int *samptime, int *nextsamptime,int blokstep,dataptr dz);
  54. static double getval(double *tab,int i,double fracstep,double amp);
  55. static int advance_in_table(int *i,double convertor,double *step,double *fracstep,
  56. double *amp,double *frq,double dtabsize,double *ampstep,double *frqstep,int *samptime,int *nextsamptime,
  57. double *lastamp,double *lastfrq,double inverse_sr,int blokstep,dataptr dz);
  58. void set_band_limits(int clength,int *supertight, double *bwidth, int *minchan, int *centrchan,
  59. double *hfbwidth, int *lo_n, int *hi_n, double *offset, double hfchwidth, dataptr dz);
  60. int do_stereo_specsynth(dataptr dz);
  61. //TW UPDATE
  62. static int gen_clicktrack(dataptr dz);
  63. static int gen_chord(int sampdur,dataptr dz);
  64. /******************************* DO_SYNTH ******************************/
  65. int do_synth(dataptr dz)
  66. {
  67. int exit_status;
  68. int sampdur = 0;
  69. double sr = 0.0;
  70. //TW UPDATES
  71. if(dz->process == CLICK)
  72. dz->infile->channels = 1;
  73. else {
  74. dz->infile->channels = dz->iparam[SYN_CHANS];
  75. dz->infile->srate = dz->iparam[SYN_SRATE];
  76. sr = (double)dz->infile->srate;
  77. sampdur = round(sr * dz->param[SYN_DUR]) * dz->iparam[SYN_CHANS];
  78. dz->tempsize = sampdur;
  79. }
  80. if(dz->floatsam_output)
  81. dz->infile->stype = SAMP_FLOAT;
  82. else
  83. dz->infile->stype = SAMP_SHORT;
  84. switch(dz->process) {
  85. case(SYNTH_SIL): return gen_silence(sampdur,dz);
  86. case(SYNTH_NOISE): return gen_noise(sampdur,sr,dz);
  87. //TW UPDATES
  88. case(CLICK): return gen_clicktrack(dz);
  89. }
  90. if((dz->parray[SYNTH_TAB] = (double *)malloc((dz->iparam[SYN_TABSIZE]+1) * sizeof(double)))==NULL) {
  91. sprintf(errstr,"Insufficient memory for wave table.\n");
  92. return(MEMORY_ERROR);
  93. }
  94. if(dz->process == MULTI_SYN)
  95. dz->mode = WAVE_SINE;
  96. if((exit_status = gentable(dz->iparam[SYN_TABSIZE],dz))<0)
  97. return(exit_status);
  98. if(dz->process == MULTI_SYN)
  99. return gen_chord(sampdur,dz);
  100. return gen_wave(sampdur,sr,dz);
  101. }
  102. /******************************* GENTABLE ******************************/
  103. int gentable(int tabsize,dataptr dz)
  104. {
  105. int n, m, k0, k1;
  106. double minstep, step;
  107. double *tab = dz->parray[SYNTH_TAB];
  108. switch(dz->mode) {
  109. case(WAVE_SINE):
  110. step = (2.0 * PI)/(double)tabsize;
  111. for(n=0;n<tabsize;n++)
  112. tab[n] = sin(step * (double)n) * F_MAXSAMP;
  113. tab[tabsize] = 0.0;
  114. break;
  115. case(WAVE_SQUARE):
  116. k0 = tabsize/2;
  117. for(n=0;n<k0;n++)
  118. tab[n] = F_MAXSAMP;
  119. for(n=k0;n<=tabsize;n++)
  120. tab[n] = -F_MAXSAMP;
  121. break;
  122. case(WAVE_SAW):
  123. k0 = tabsize/4;
  124. k1 = tabsize/2;
  125. minstep = F_MAXSAMP/(double)k0;
  126. tab[0] = 0.0;
  127. for(n=1;n<=k0;n++)
  128. tab[n] = tab[n-1] + minstep;
  129. for(n=k0,m=k0-1;n<k1;n++,m--)
  130. tab[n] = tab[m];
  131. for(n=k1,m=0;n<tabsize;n++,m++)
  132. tab[n] = -tab[m];
  133. tab[n] = 0.0;
  134. break;
  135. case(WAVE_RAMP):
  136. k0 = tabsize/2;
  137. minstep = F_MAXSAMP/(double)k0;
  138. tab[0] = F_MAXSAMP;
  139. for(n=1;n<k0;n++)
  140. tab[n] = tab[n-1] - minstep;
  141. tab[k0] = 0.0;
  142. for(n=k0+1,m=k0-1;n<=tabsize;n++,m--)
  143. tab[n] = -tab[m];
  144. break;
  145. default:
  146. sprintf(errstr,"Unknown case in gentable()\n");
  147. return(PROGRAM_ERROR);
  148. }
  149. return(FINISHED);
  150. }
  151. /****************************** GEN_WAVE *************************/
  152. int gen_wave(int sampdur,double sr,dataptr dz)
  153. {
  154. int exit_status;
  155. double inverse_sr = 1.0/sr;
  156. double step;
  157. double dtabsize = (double)dz->iparam[SYN_TABSIZE];
  158. double convertor = dtabsize * inverse_sr;
  159. int m, i, k;
  160. int chans = dz->infile->channels;
  161. double timestep = 10.0 * MS_TO_SECS, ampstep, frqstep, lastamp, lastfrq, amp, frq;
  162. int blokstep = round(timestep * sr);
  163. int samptime = 0, nextsamptime = blokstep;
  164. double *tab = dz->parray[SYNTH_TAB];
  165. double fracstep = 0.0, val;
  166. int do_start = 1;
  167. int synth_splicelen = SYNTH_SPLICELEN * chans;
  168. int total_samps = 0;
  169. int startj = 0, endj = SYNTH_SPLICELEN;
  170. int total_samps_left = sampdur;
  171. int endsplicestart = sampdur - synth_splicelen;
  172. int todo;
  173. step = 0.0;
  174. i = 0;
  175. if(sampdur < (synth_splicelen * 2) + chans) {
  176. fprintf(stdout,"ERROR: Specified output duration is less then available splicing length.\n");
  177. return(DATA_ERROR);
  178. }
  179. if((exit_status = read_values_from_all_existing_brktables(0.0,dz))<0)
  180. return(exit_status);
  181. if((exit_status =
  182. update_wave_params(&ampstep,&frqstep,&lastamp,&lastfrq,inverse_sr,&samptime,&nextsamptime,blokstep,dz))<0)
  183. return(exit_status);
  184. amp = lastamp;
  185. frq = lastfrq;
  186. while(total_samps_left > 0) {
  187. if(total_samps_left/dz->buflen <= 0)
  188. todo = total_samps_left;
  189. else
  190. todo = dz->buflen;
  191. m = 0;
  192. while(m < todo) {
  193. val = getval(tab,i,fracstep,amp);
  194. if(do_start) {
  195. val *= (startj++/(double)SYNTH_SPLICELEN);
  196. if(startj >= SYNTH_SPLICELEN)
  197. do_start = 0;
  198. }
  199. if(total_samps >= endsplicestart)
  200. val *= (endj--/(double)SYNTH_SPLICELEN);
  201. for(k=0;k<chans;k++) {
  202. // dz->bigbuf[m++] = (short)round(val);
  203. dz->bigbuf[m++] = (float)val;
  204. total_samps++;
  205. }
  206. if((exit_status = advance_in_table(&i,convertor,&step,&fracstep,&amp,&frq,dtabsize,
  207. &ampstep,&frqstep,&samptime,&nextsamptime,&lastamp,&lastfrq,inverse_sr,blokstep,dz))<0)
  208. return(exit_status);
  209. }
  210. if(todo) {
  211. if((exit_status = write_samps(dz->bigbuf,todo,dz))<0)
  212. return(exit_status);
  213. }
  214. total_samps_left -= dz->buflen;
  215. }
  216. return(FINISHED);
  217. }
  218. /****************************** GEN_SILENCE *************************/
  219. int gen_silence(int sampdur,dataptr dz)
  220. {
  221. int exit_status;
  222. int n, bufcnt = sampdur/dz->buflen;
  223. int remain = sampdur - (bufcnt * dz->buflen);
  224. for(n=0;n<dz->buflen;n++)
  225. dz->bigbuf[n] = (float)0;
  226. for(n=0;n<bufcnt;n++) {
  227. if((exit_status = write_samps(dz->bigbuf,dz->buflen,dz))<0)
  228. return(exit_status);
  229. }
  230. if(remain)
  231. return write_samps(dz->bigbuf,remain,dz);
  232. return FINISHED;
  233. }
  234. /****************************** GEN_NOISE *************************/
  235. int gen_noise(int sampdur,double sr,dataptr dz)
  236. {
  237. int exit_status;
  238. int n;
  239. int k, chans = dz->infile->channels;
  240. double amp, lastamp,lastfrq,ampstep,frqstep;
  241. double inverse_sr = 1.0/sr;
  242. double timestep = 10.0 * MS_TO_SECS;
  243. int blokstep = round(timestep * sr);
  244. int samptime = 0, nextsamptime = blokstep;
  245. int total_samps = 0;
  246. int synth_splicelen = SYNTH_SPLICELEN * chans, startj = 0, endj = SYNTH_SPLICELEN;
  247. int endsplicestart = sampdur - synth_splicelen;
  248. int do_start = 1;
  249. int total_samps_left = sampdur;
  250. int todo;
  251. double val;
  252. if(sampdur < (synth_splicelen * 2) + chans) {
  253. fprintf(stdout,"ERROR: Specified output duration is less then available splicing length.\n");
  254. return(DATA_ERROR);
  255. }
  256. if((exit_status = read_values_from_all_existing_brktables(0.0,dz))<0)
  257. return(exit_status);
  258. if((exit_status =
  259. update_wave_params(&ampstep,&frqstep,&lastamp,&lastfrq,inverse_sr,&samptime,&nextsamptime,blokstep,dz))<0)
  260. return(exit_status);
  261. amp = lastamp;
  262. while(total_samps_left > 0) {
  263. if(total_samps_left/dz->buflen <= 0)
  264. todo = total_samps_left;
  265. else
  266. todo = dz->buflen;
  267. for(n=0;n<todo;n+=chans,total_samps += chans) {
  268. val = ((drand48() * 2.0) - 1.0) * amp;
  269. if(do_start) {
  270. val *= startj++/(double)SYNTH_SPLICELEN;
  271. if(startj >= SYNTH_SPLICELEN)
  272. do_start = 0;
  273. }
  274. if(total_samps >= endsplicestart)
  275. val *= endj--/(double)SYNTH_SPLICELEN;
  276. for(k=0;k<chans;k++)
  277. dz->bigbuf[n+k] = (float)val;
  278. amp += ampstep;
  279. if(++samptime >= nextsamptime) {
  280. if((exit_status = update_wave_params
  281. (&ampstep,&frqstep,&lastamp,&lastfrq,inverse_sr,&samptime,&nextsamptime,blokstep,dz))<0)
  282. return(exit_status);
  283. amp = lastamp;
  284. }
  285. }
  286. if(todo) {
  287. if((exit_status = write_samps(dz->bigbuf,todo,dz))<0)
  288. return(exit_status);
  289. }
  290. total_samps_left -= dz->buflen;
  291. }
  292. return(FINISHED);
  293. }
  294. /****************************** GETVAL *************************/
  295. double getval(double *tab,int i,double fracstep,double amp)
  296. {
  297. double diff, val = tab[i];
  298. diff = tab[i+1] - val;
  299. val += diff * fracstep;
  300. val *= amp;
  301. return(val);
  302. }
  303. /****************************** UPDATE_WAVE_PARAMS *************************/
  304. int update_wave_params(double *ampstep,double *frqstep,double *lastamp,double *lastfrq,double inverse_sr,
  305. int *samptime, int *nextsamptime,int blokstep,dataptr dz)
  306. {
  307. int exit_status;
  308. double thistime = (double)(*nextsamptime) * inverse_sr;
  309. double ratio;
  310. *lastfrq = dz->param[SYN_FRQ];
  311. *lastamp = dz->param[SYN_AMP];
  312. *ampstep = 0.0;
  313. *frqstep = 1.0;
  314. if((exit_status = read_values_from_all_existing_brktables(thistime,dz))<0)
  315. return(exit_status);
  316. if(dz->brksize[SYN_AMP])
  317. *ampstep = (dz->param[SYN_AMP] - *lastamp)/(double)blokstep;
  318. if(dz->brksize[SYN_FRQ]) {
  319. ratio = dz->param[SYN_FRQ]/(*lastfrq);
  320. *frqstep = pow(10.0,log10(ratio)/(double)blokstep);
  321. }
  322. *samptime = *nextsamptime;
  323. *nextsamptime += blokstep;
  324. return(FINISHED);
  325. }
  326. /****************************** ADVANCE_IN_TABLE *************************/
  327. static int advance_in_table(int *i,double convertor,double *step,double *fracstep,
  328. double *amp,double *frq,double dtabsize,double *ampstep,double *frqstep,int *samptime,int *nextsamptime,
  329. double *lastamp,double *lastfrq,double inverse_sr,int blokstep,dataptr dz)
  330. {
  331. int exit_status;
  332. *step += *frq * convertor;
  333. while(*step >= dtabsize)
  334. *step -= dtabsize;
  335. *i = (int)(*step); /* TRUNCATE */
  336. *fracstep = *step - (double)(*i);
  337. *amp += *ampstep;
  338. *frq *= *frqstep;
  339. if(++(*samptime) >= *nextsamptime) {
  340. if((exit_status = update_wave_params
  341. (ampstep,frqstep,lastamp,lastfrq,inverse_sr,samptime,nextsamptime,blokstep,dz))<0)
  342. return(exit_status);
  343. *amp = *lastamp;
  344. *frq = *lastfrq;
  345. }
  346. return(FINISHED);
  347. }
  348. /****************************** DO_STEREO_SPECSYNTH *************************/
  349. #define SAFETY (10)
  350. //TW CONVERTED
  351. int do_stereo_specsynth(dataptr dz)
  352. {
  353. int exit_status;
  354. double hfchwidth = dz->chwidth/2.0;
  355. float *bufend;
  356. double focusrange = 0.0, basefrq, frq, *frqq, bwidth = 0.0, hfbwidth, offset = 0.0, totalamp;
  357. double thisfocus, ampscaler, amp, wobble, dcf, hfchansprd;
  358. int minchan = 0, supertight, lo_n = 0, hi_n = 0, wcnt, jj, n, m, k;
  359. int remainder, samps_written;
  360. int clength = dz->wanted/2, centrchan = 0;
  361. int orig_process_type;
  362. char outfnam[256], outfilename[256];
  363. unsigned int samps_so_far;
  364. int floats_out = dz->wlength * dz->wanted;
  365. int samps_read1, samps_read2, samps_read;
  366. int OK = 1;
  367. int orig_process, orig_proctype, orig_chans, orig_stype;
  368. int orig_srate;
  369. //TW UPDATE CORRECTION
  370. int overlap = (dz->infile->channels - 2)/dz->infile->Dfac;
  371. int snd_floats_out = floats_out/overlap;
  372. extern int sloom;
  373. dz->tempsize = (floats_out + snd_floats_out) * 2;
  374. if((frqq = (double *)malloc(clength * sizeof(double)))==NULL) {
  375. sprintf(errstr,"No memory for initial-frequency storage-array.\n");
  376. return(MEMORY_ERROR);
  377. }
  378. bufend = dz->bigfbuf + dz->big_fsize;
  379. if(!dz->brksize[SS_FOCUS2] && !dz->brksize[SS_FOCUS])
  380. focusrange = dz->param[SS_FOCUS2] - dz->param[SS_FOCUS];
  381. /* SET BAND LIMITS */
  382. if(!dz->brksize[SS_SPREAD] && !dz->brksize[SS_CENTRFRQ])
  383. set_band_limits(clength,&supertight,&bwidth,&minchan,&centrchan,
  384. &hfbwidth,&lo_n,&hi_n,&offset,hfchwidth,dz);
  385. outfnam[0] = ENDOFSTR;
  386. strcat(outfnam,dz->wordstor[0]);
  387. //TW REVISION for new protocol: always pass file-extension on cmdline
  388. if(sloom)
  389. delete_filename_lastchar(outfnam); /* axe trailing zero on outfilename */
  390. samps_so_far = 0;
  391. for(jj=1;jj<3;jj++) {
  392. strcpy(outfilename,outfnam);
  393. //TW REVISION for new protocol: always pass file-extension on cmdline
  394. insert_new_number_at_filename_end(outfilename,jj+2,0);
  395. orig_process_type = dz->process_type;
  396. dz->process_type = BIG_ANALFILE;
  397. dz->outfiletype = ANALFILE_OUT;
  398. if((exit_status = create_sized_outfile(outfilename,dz)) < 0) {
  399. sprintf(errstr,"Cannot open temporary analysis file '%s' to generate sound data:%s\n", outfilename,sferrstr());
  400. return(SYSTEM_ERROR);
  401. }
  402. // dz->outfiletype = NO_OUTPUTFILE; /* TW */ Thought I was, for safety, resetting to its original val (changed above) but did it wrongly, but not necessary.
  403. dz->total_windows = 0;
  404. dz->time = (float)0.0;
  405. dz->flbufptr[0] = dz->bigfbuf;
  406. for(wcnt = 0; wcnt < dz->wlength; wcnt++) {
  407. memset((char *)dz->flbufptr[0],0,dz->wanted * sizeof(float));
  408. if((exit_status = read_values_from_all_existing_brktables((double)dz->time,dz))<0)
  409. return(exit_status);
  410. if(dz->brksize[SS_FOCUS2] || dz->brksize[SS_FOCUS])
  411. focusrange = dz->param[SS_FOCUS2] - dz->param[SS_FOCUS];
  412. if(dz->brksize[SS_SPREAD] || dz->brksize[SS_CENTRFRQ])
  413. set_band_limits(clength,&supertight,&bwidth,&minchan,&centrchan,
  414. &hfbwidth,&lo_n,&hi_n,&offset,hfchwidth,dz);
  415. hfchansprd = (hi_n - lo_n)/2.0;
  416. totalamp = 0.0;
  417. for(n=lo_n, m = minchan; n<hi_n; n++,m++) {
  418. basefrq = ((double)n * bwidth) + offset;
  419. if(dz->total_windows==0) { /* for 1st window, establish a channel frq */
  420. frq = (drand48() * bwidth) + basefrq;
  421. frqq[n] = frq;
  422. } else if(dz->param[SS_TRAND] > 0.0) { /* if chan frq wobbles thro time, vary it */
  423. wobble = ((drand48() * 2.0) - 1.0)/2.0;
  424. frq = frqq[n] + (wobble * bwidth * dz->param[SS_TRAND]);
  425. } else /* if not, retain frq from first window */
  426. frq = frqq[n];
  427. dcf = (double)abs(centrchan - m)/hfchansprd; /* fraction of chan-sprd we are away from centre */
  428. thisfocus = (drand48() * focusrange) + dz->param[SS_FOCUS];
  429. thisfocus = 1.0/thisfocus;
  430. dcf = pow(dcf,thisfocus); /* squeeze or unsqueeze cosin distrib */
  431. amp = (cos(dcf * PI) + 1.0)/2.0; /* cosin distrib */
  432. totalamp += amp;
  433. k = m * 2;
  434. if(dz->total_windows)
  435. dz->flbufptr[0][k] = (float)amp;
  436. dz->flbufptr[0][++k] = (float)frq;
  437. }
  438. if(dz->total_windows) {
  439. ampscaler = (double)SPECSYN_MAXAMP/totalamp;
  440. for(n=lo_n, k = minchan*2; n<hi_n; n++,k+=2)
  441. dz->flbufptr[0][k] = (float)(dz->flbufptr[0][k] * ampscaler);
  442. }
  443. if((dz->flbufptr[0] += dz->wanted) >= bufend) {
  444. if((exit_status = write_samps_no_report(dz->bigfbuf,dz->buflen,&samps_written,dz)) < 0)
  445. return(exit_status);
  446. display_virtual_time(dz->total_samps_written + samps_so_far,dz);
  447. dz->flbufptr[0] = dz->bigfbuf;
  448. }
  449. dz->time = (float)(dz->time + dz->frametime);
  450. dz->total_windows++;
  451. }
  452. if((remainder = dz->flbufptr[0] - dz->bigfbuf) > 0) {
  453. if((exit_status = write_samps_no_report(dz->bigfbuf,remainder,&samps_written,dz)) < 0)
  454. return(exit_status);
  455. display_virtual_time(dz->total_samps_written + samps_so_far,dz);
  456. }
  457. dz->process_type = orig_process_type;
  458. /* SEE NOTES IN pvoc_addon.c in PVOC directory */
  459. if((exit_status = pvoc_out(floats_out,&samps_so_far,outfilename,outfnam,jj,dz))<0)
  460. return(exit_status);
  461. }
  462. //TW NEW: merge the 2 output files
  463. reset_file_params_for_sndout(&orig_proctype,&orig_srate,&orig_chans,&orig_stype,dz);
  464. for(jj=0;jj<2;jj++) {
  465. strcpy(outfilename,outfnam);
  466. insert_new_number_at_filename_end(outfilename,jj+1,0);
  467. if((dz->ifd[jj] = sndopenEx(outfilename,0,CDP_OPEN_RDONLY)) < 0) {
  468. sprintf(errstr,"Cannot reopen mono file '%s' to convert to stereo :%s\n", outfilename,sferrstr());
  469. return(SYSTEM_ERROR);
  470. }
  471. }
  472. dz->insams[0] *= 2;
  473. dz->process_type = EQUAL_SNDFILE;
  474. dz->infile->channels = dz->outfile->channels = STEREO;
  475. dz->infile->filetype = SNDFILE; /* forces formatted sndfile creation */
  476. strcpy(outfilename,outfnam);
  477. if(dz->floatsam_output)
  478. dz->infile->stype = SAMP_FLOAT;
  479. else
  480. dz->infile->stype = SAMP_SHORT;
  481. dz->infile->srate = round(dz->param[SS_SRATE]);
  482. dz->outfiletype = SNDFILE_OUT;
  483. orig_process = dz->process;
  484. dz->process = EDIT_CUT; /* any process creating a standard sound outfile */
  485. dz->infile->srate = (int)round(dz->param[SS_SRATE]);
  486. if(sloom) /* TW 24/2/18 */
  487. insert_new_number_at_filename_end(outfilename,0,0);
  488. if((exit_status = create_sized_outfile(outfilename,dz)) < 0) {
  489. sprintf(errstr,"Cannot open temporary soundfile '%s' to generate sound data:%s\n", outfilename,sferrstr());
  490. return(SYSTEM_ERROR);
  491. }
  492. if((exit_status = reset_peak_finder(dz))<0)
  493. return(exit_status);
  494. dz->insams[0] /= 2;
  495. OK = 1;
  496. while(OK) {
  497. memset((char *)dz->bigfbuf,0,dz->buflen * sizeof(float));
  498. memset((char *)dz->flbufptr[2],0,dz->buflen * sizeof(float));
  499. memset((char *)dz->flbufptr[3],0,dz->buflen * sizeof(float));
  500. if((samps_read1 = fgetfbufEx(dz->flbufptr[2],dz->buflen,dz->ifd[0],0))<=0) {
  501. if(samps_read1 < 0) {
  502. sprintf(errstr,"Sample read failed: ");
  503. for(jj=0;jj<2;jj++) {
  504. char pfname[_MAX_PATH];
  505. strcpy(pfname, snd_getfilename(dz->ifd[jj]));
  506. sndcloseEx(dz->ifd[jj]);
  507. if(remove(/*outfilename*/pfname)<0) {
  508. fprintf(stdout,"WARNING: Tempfile %s not removed: ",outfilename);
  509. fflush(stdout);
  510. }
  511. }
  512. strcat(errstr,"\n");
  513. return(SYSTEM_ERROR);
  514. } else
  515. break;
  516. }
  517. if((samps_read2 = fgetfbufEx(dz->flbufptr[3],dz->buflen,dz->ifd[1],0))<=0) {
  518. if(samps_read2< 0) {
  519. sprintf(errstr,"Sample read failed: ");
  520. for(jj=0;jj<2;jj++) {
  521. char pfname[_MAX_PATH];
  522. strcpy(pfname, snd_getfilename(dz->ifd[jj]));
  523. sndcloseEx(dz->ifd[jj]);
  524. if(remove(/*outfilename*/pfname)<0) {
  525. fprintf(stdout,"WARNING: Tempfile %s not removed: ",outfilename);
  526. fflush(stdout);
  527. }
  528. }
  529. strcat(errstr,"\n");
  530. return(SYSTEM_ERROR);
  531. } else
  532. break;
  533. }
  534. if((samps_read = min(samps_read1,samps_read2)) <= 0)
  535. break;
  536. #ifdef NOTDEF
  537. for(n = 0,k=0; n < samps_read-1;n++,k+=2) {
  538. dz->bigfbuf[k] = dz->flbufptr[2][n];
  539. dz->bigfbuf[k+1] = dz->flbufptr[3][n];
  540. }
  541. dz->bigfbuf[k] = dz->flbufptr[2][n];
  542. #else
  543. for(n = 0,k=0; n < samps_read;n++,k+=2) {
  544. dz->bigfbuf[k] = dz->flbufptr[2][n];
  545. dz->bigfbuf[k+1] = dz->flbufptr[3][n];
  546. }
  547. #endif
  548. /* last samp remains in situ */
  549. if((exit_status = write_samps(dz->bigfbuf,samps_read * 2,dz))<0) {
  550. sprintf(errstr,"Sample write failed: ");
  551. for(jj=0;jj<2;jj++) {
  552. char pfname[_MAX_PATH];
  553. strcpy(pfname, snd_getfilename(dz->ifd[jj]));
  554. sndcloseEx(dz->ifd[jj]);
  555. if(remove(/*outfilename*/pfname)<0) {
  556. fprintf(stdout,"WARNING: Tempfile %s not removed: ",outfilename);
  557. fflush(stdout);
  558. }
  559. }
  560. strcat(errstr,"\n");
  561. return(SYSTEM_ERROR);
  562. }
  563. }
  564. for(jj=0;jj<2;jj++) {
  565. /*RWD Feb 2004 */
  566. char pfname[_MAX_PATH];
  567. strcpy(pfname, snd_getfilename(dz->ifd[jj]));
  568. sndcloseEx(dz->ifd[jj]);
  569. if(remove(/*outfilename*/pfname)<0) {
  570. fprintf(stdout,"WARNING: Tempfile %s not removed: ",outfilename);
  571. fflush(stdout);
  572. }
  573. }
  574. dz->process = orig_process;
  575. // In order to correctly write header, process_type should remain EQUAL_SNDFILE
  576. // dz->process_type = OTHER_PROCESS;
  577. return(FINISHED);
  578. }
  579. /****
  580. With cosinusoidal energy distribution
  581. -------------------------------------
  582. DCF(dist-from-centre-frq) = fabs(frq - centre-frq) (range 0 - 1)
  583. -------------------
  584. half-interval-spread
  585. To focus energy towards centre, we squeeze values towards position 0
  586. --------------------------------------------------------------------
  587. DCF^focus
  588. if(focus > 1) squeezes
  589. if(focus < 1) braodens
  590. ampscaler = (cos(CDF*PI) + 1)/2.0;
  591. ****/
  592. /****************************** SET_BAND_LIMITS *************************/
  593. void set_band_limits(int clength,int *supertight, double *bwidth, int *minchan, int *centrchan,
  594. double *hfbwidth, int *lo_n, int *hi_n, double *offset, double hfchwidth, dataptr dz)
  595. {
  596. int chancnt;
  597. double hifrq, lofrq, frqsprd;
  598. int lochan, hichan, chanspreadmin;
  599. if(dz->vflag[SS_PICHSPRD]) {
  600. if(dz->param[SS_SPREAD] < 1.0)
  601. dz->param[SS_SPREAD] = 1.0/dz->param[SS_SPREAD];
  602. hifrq = min(dz->param[SS_CENTRFRQ] * dz->param[SS_SPREAD],dz->nyquist);
  603. lofrq = max(dz->param[SS_CENTRFRQ] / dz->param[SS_SPREAD],SPEC_MINFRQ);
  604. } else {
  605. hifrq = min(dz->param[SS_CENTRFRQ] + dz->param[SS_SPREAD],dz->nyquist);
  606. lofrq = max(dz->param[SS_CENTRFRQ] - dz->param[SS_SPREAD],SPEC_MINFRQ);
  607. }
  608. frqsprd = hifrq - lofrq;
  609. /* ESTABLISH WHICH CHANS INVOLVED */
  610. lochan = (int)floor((lofrq + hfchwidth)/dz->chwidth) - 1;
  611. hichan = (int)floor((hifrq + hfchwidth)/dz->chwidth) - 1;
  612. //TW UPDATES
  613. lochan = max(lochan,0);
  614. hichan = max(hichan,0);
  615. chancnt = hichan - lochan + 1;
  616. chanspreadmin = (CHANUP * 2) + 1;
  617. if (chancnt < chanspreadmin) {
  618. chancnt = chanspreadmin;
  619. *bwidth = frqsprd/chanspreadmin;
  620. *centrchan = (int)floor((dz->param[SS_CENTRFRQ] + hfchwidth)/dz->chwidth) - 1;
  621. if(*centrchan - CHANUP < 0)
  622. *minchan = 0;
  623. else if (*centrchan + CHANUP > clength)
  624. *minchan = clength - chanspreadmin;
  625. else
  626. *minchan = *centrchan - CHANUP;
  627. *centrchan = *minchan + CHANUP;
  628. *supertight = 1;
  629. } else {
  630. *bwidth = dz->chwidth;
  631. *minchan = lochan;
  632. *supertight = 0;
  633. }
  634. *hfbwidth = (*bwidth)/2.0;
  635. if(*supertight) {
  636. *lo_n = 0;
  637. *hi_n = chancnt;
  638. *offset = lofrq;
  639. } else {
  640. *lo_n = lochan;
  641. *hi_n = hichan;
  642. *centrchan = (lochan + hichan)/2;
  643. *offset = -(*hfbwidth);
  644. }
  645. }
  646. //TW UPDATE: New Function
  647. /****************************** GEN_CLICKTRACK *************************/
  648. #define LINE_TIMES (0)
  649. int gen_clicktrack(dataptr dz)
  650. {
  651. double *clikdata = dz->parray[0], *clik = dz->parray[1];
  652. double amp, tottime;
  653. int n, m, j = 0, bufsamptime, bufsampendtime, samptime, tcnt = 0;
  654. float *buf = dz->sampbuf[0];
  655. int k, exit_status;
  656. int from_start = 1;
  657. int to_end = 1;
  658. double click_ofset = 0.0, starttime_offset = 0.0;
  659. if(dz->mode == CLICK_BY_LINE) {
  660. if(dz->iparam[CLIKOFSET] > 0)
  661. click_ofset = dz->parray[2][dz->iparam[CLIKOFSET]];
  662. dz->param[CLIKSTART] = dz->parray[2][dz->iparam[CLIKSTART]] - click_ofset;
  663. if(dz->iparam[CLIKEND] + 1 == dz->iparam[CLICKTIME])
  664. dz->iparam[CLIKEND]++;
  665. else
  666. to_end = 0;
  667. dz->param[CLIKEND] = dz->parray[2][dz->iparam[CLIKEND]] - click_ofset;
  668. }
  669. if(sloom) {
  670. tottime = dz->param[CLIKEND] - dz->param[CLIKSTART];
  671. if((dz->tempsize = (int)round(tottime * CLICK_SRATE)) < 0) {
  672. fprintf(stdout,"WARNING: File is too long to give accurate progress display on Progress Bar.\n");
  673. fflush(stdout);
  674. dz->tempsize = INT_MAX;
  675. }
  676. }
  677. if(!flteq(dz->param[CLIKSTART],0.0))
  678. from_start = 0;
  679. if(dz->iparam[CLIKOFSET] > 0) {
  680. click_ofset = dz->parray[2][dz->iparam[CLIKOFSET]];
  681. if(!from_start)
  682. starttime_offset = dz->param[CLIKSTART] + click_ofset;
  683. dz->param[CLIKEND] += click_ofset;
  684. fprintf(stdout,"INFO: MUSIC STARTS %lf secs AFTER CLICKS\n",click_ofset);
  685. fflush(stdout);
  686. } else
  687. starttime_offset = dz->param[CLIKSTART];
  688. for(n=dz->itemcnt-2;n >=0;n-=2) { /* throw away data beyond endtime of generating clicks */
  689. if((dz->parray[0][n] < dz->param[CLIKEND]) || flteq(dz->parray[0][n],dz->param[CLIKEND])) {
  690. dz->itemcnt = n+2;
  691. break;
  692. }
  693. }
  694. if(!to_end)
  695. dz->itemcnt -= 2;
  696. if(!from_start) { /* throw away data before starttime of generating clicks */
  697. while(dz->parray[0][0] < starttime_offset) {
  698. dz->parray[0]+=2;
  699. if((dz->itemcnt-=2) <= 0) {
  700. sprintf(errstr,"No click data found between the specified times.\n");
  701. return(DATA_ERROR);
  702. }
  703. }
  704. for(n=0;n < dz->itemcnt;n+=2) /* and adjust data time values so generation starts at outfile starttime 0.0 */
  705. dz->parray[0][n] -= starttime_offset;
  706. }
  707. if(dz->vflag[LINE_TIMES]) {
  708. tcnt = 0; /* skip over times-of-lines prior to start of click-generation */
  709. while(dz->parray[2][tcnt] < starttime_offset) {
  710. if(++tcnt >= dz->iparam[CLICKTIME]) {
  711. sprintf(errstr,"Anomaly in data about timing of data lines.\n");
  712. return(PROGRAM_ERROR);
  713. }
  714. }
  715. }
  716. clikdata = dz->parray[0];
  717. memset((char *)buf,0,dz->buflen * sizeof(float));
  718. for(n=0,m=1;n<dz->itemcnt;n+=2,m+=2) {
  719. samptime = (int)round(clikdata[n] * dz->infile->srate);
  720. if(dz->vflag[LINE_TIMES] && (tcnt < dz->iparam[CLICKTIME])) {
  721. if(flteq(dz->parray[2][tcnt],(clikdata[n] + starttime_offset))) {
  722. fprintf(stdout,"INFO: LINE %d at %lf\n",tcnt+1,(dz->parray[2][tcnt] - click_ofset));
  723. fflush(stdout);
  724. tcnt++;
  725. } else if(dz->parray[2][tcnt] < (clikdata[n] + starttime_offset))
  726. tcnt++; /* skips lines which start with unaccented beat */
  727. }
  728. bufsamptime = samptime - dz->total_samps_written;
  729. while(bufsamptime >= dz->buflen) {
  730. if((exit_status = write_samps(dz->bigbuf,dz->buflen,dz))<0)
  731. return(exit_status);
  732. memset((char *)buf,0,dz->buflen * sizeof(float));
  733. bufsamptime = samptime - dz->total_samps_written;
  734. }
  735. bufsampendtime = bufsamptime + CLICKLEN + 1;
  736. amp = clikdata[m];
  737. k = 0;
  738. if(bufsampendtime <= dz->buflen) {
  739. for(j = bufsamptime; j < bufsampendtime; j++)
  740. buf[j] = (float)((double)clik[k++] * amp);
  741. } else {
  742. for(j = bufsamptime; j < dz->buflen; j++)
  743. buf[j] = (float)((double)clik[k++] * amp);
  744. if((exit_status = write_samps(dz->bigbuf,dz->buflen,dz))<0)
  745. return(exit_status);
  746. memset((char *)buf,0,dz->buflen * sizeof(float));
  747. j = 0;
  748. while(k <= CLICKLEN)
  749. buf[j++] = (float)((double)clik[k++] * amp);
  750. }
  751. }
  752. if(j > 0) {
  753. if((exit_status = write_samps(dz->bigbuf,j,dz))<0)
  754. return(exit_status);
  755. }
  756. return(FINISHED);
  757. }
  758. /****************************** GEN_CHORD *************************/
  759. #define JITTER_RANGE (1.0)
  760. #define JITTERSTEP (8)
  761. int gen_chord(int sampdur,dataptr dz)
  762. {
  763. int exit_status;
  764. double dtabsize = (double)dz->iparam[SYN_TABSIZE];
  765. int m, n, k, kk;
  766. int chans = dz->infile->channels;
  767. double amp = dz->param[SYN_AMP];
  768. double *tab = dz->parray[SYNTH_TAB];
  769. double val;
  770. int do_start = 1, jittercnt = 0;
  771. int synth_splicelen = SYNTH_SPLICELEN * chans;
  772. int total_samps = 0;
  773. int startj = 0, endj = SYNTH_SPLICELEN, this_chordend, this_chordstart, thischord_notecnt;
  774. int total_samps_left = sampdur;
  775. int endsplicestart = sampdur - synth_splicelen;
  776. int todo = 0, total_samps_done;
  777. double *step = dz->parray[1];
  778. double *pos = dz->parray[2];
  779. double *fracstep = dz->parray[3];
  780. int *samppos = dz->lparray[0];
  781. double *jitter=NULL, *lastjitter=NULL, *thisjitstep=NULL, *thisjitter=NULL;
  782. if ((jitter = (double *)malloc(dz->itemcnt * sizeof(double)))==NULL) {
  783. fprintf(stdout,"WARNING: Insufficient memory to add jitter.\n");
  784. fflush(stdout);
  785. } else if ((thisjitter = (double *)malloc(dz->itemcnt * sizeof(double)))==NULL) {
  786. fprintf(stdout,"WARNING: Insufficient memory (2) to add jitter.\n");
  787. fflush(stdout);
  788. } else if ((lastjitter = (double *)malloc(dz->itemcnt * sizeof(double)))==NULL) {
  789. fprintf(stdout,"WARNING: Insufficient memory (3) to add jitter.\n");
  790. fflush(stdout);
  791. } else if ((thisjitstep = (double *)malloc(dz->itemcnt * sizeof(double)))==NULL) {
  792. fprintf(stdout,"WARNING: Insufficient memory (4) to add jitter.\n");
  793. fflush(stdout);
  794. } else {
  795. for(n=0;n<dz->itemcnt;n++) {
  796. jitter[n] = step[n] * (pow(SEMITONE_INTERVAL,JITTER_RANGE) - 1.0); /* Jitter within 0.5 of a semitone */
  797. lastjitter[n] = 0.0;
  798. thisjitter[n] = ((drand48() * 2.0) - 1.0) * jitter[n]; /* +- within jitter range */
  799. thisjitstep[n] = thisjitter[n]/(double)JITTERSTEP;
  800. }
  801. }
  802. if(sampdur < (synth_splicelen * 2) + chans) {
  803. fprintf(stdout,"ERROR: Specified output duration is less then available splicing length.\n");
  804. return(DATA_ERROR);
  805. }
  806. if(dz->ringsize > 1) {
  807. total_samps_left = (int)round((double)(sampdur/chans)/(double)dz->ringsize) * chans;
  808. total_samps_done = 0;
  809. m = 0;
  810. this_chordend = -1;
  811. for(kk=0; kk < dz->ringsize; kk++) {
  812. do_start = 1;
  813. startj = 0;
  814. endj = SYNTH_SPLICELEN;
  815. if(kk == dz->ringsize - 1)
  816. total_samps_left = sampdur - total_samps_done;
  817. endsplicestart = total_samps_left - synth_splicelen;
  818. this_chordend++;
  819. this_chordstart = this_chordend;
  820. while(step[this_chordend] > 0) {
  821. if(++this_chordend >= dz->itemcnt)
  822. break;
  823. }
  824. thischord_notecnt = this_chordend - this_chordstart;
  825. todo = min(m + total_samps_left,dz->buflen);
  826. total_samps = 0;
  827. while(total_samps_left > 0) {
  828. while(m < todo) {
  829. val = 0.0;
  830. for(n=this_chordstart;n < this_chordend;n++)
  831. val += getval(tab,samppos[n],fracstep[n],amp);
  832. val /= (double)thischord_notecnt;
  833. if(do_start) {
  834. val *= (startj++/(double)SYNTH_SPLICELEN);
  835. if(startj >= SYNTH_SPLICELEN)
  836. do_start = 0;
  837. }
  838. if(total_samps >= endsplicestart)
  839. val *= (endj--/(double)SYNTH_SPLICELEN);
  840. for(k=0;k<chans;k++) {
  841. dz->bigbuf[m++] = (float)val;
  842. total_samps++;
  843. total_samps_done++;
  844. }
  845. if(jitter != NULL) {
  846. if(++jittercnt >= JITTERSTEP) {
  847. for(n=this_chordstart;n<this_chordend;n++) {
  848. lastjitter[n] = thisjitter[n];
  849. thisjitter[n] = ((drand48() * 2.0) - 1.0) * jitter[n]; /* +- within jitter range */
  850. thisjitstep[n] = (thisjitter[n] - lastjitter[n])/(double)JITTERSTEP;
  851. }
  852. jittercnt = 0;
  853. }
  854. }
  855. for(n=this_chordstart;n<this_chordend;n++) {
  856. pos[n] += step[n];
  857. if(jitter != NULL)
  858. pos[n] += thisjitstep[n];
  859. while(pos[n] >= dtabsize)
  860. pos[n] -= dtabsize;
  861. samppos[n] = (int)pos[n];
  862. fracstep[n] = pos[n] - (double)samppos[n];
  863. }
  864. }
  865. total_samps_left -= todo;
  866. if(m >= dz->buflen) {
  867. if((exit_status = write_samps(dz->bigbuf,dz->buflen,dz))<0)
  868. return(exit_status);
  869. todo = min(total_samps_left,dz->buflen);
  870. m = 0;
  871. }
  872. }
  873. }
  874. if(todo > 0) {
  875. if((exit_status = write_samps(dz->bigbuf,todo,dz))<0)
  876. return(exit_status);
  877. }
  878. } else {
  879. while(total_samps_left > 0) {
  880. if(total_samps_left/dz->buflen <= 0)
  881. todo = total_samps_left;
  882. else
  883. todo = dz->buflen;
  884. m = 0;
  885. while(m < todo) {
  886. val = 0.0;
  887. for(n=0;n < dz->itemcnt;n++)
  888. val += getval(tab,samppos[n],fracstep[n],amp);
  889. val /= (double)dz->itemcnt;
  890. if(do_start) {
  891. val *= (startj++/(double)SYNTH_SPLICELEN);
  892. if(startj >= SYNTH_SPLICELEN)
  893. do_start = 0;
  894. }
  895. if(total_samps >= endsplicestart)
  896. val *= (endj--/(double)SYNTH_SPLICELEN);
  897. for(k=0;k<chans;k++) {
  898. dz->bigbuf[m++] = (float)val;
  899. total_samps++;
  900. }
  901. if(jitter != NULL) {
  902. if(++jittercnt >= JITTERSTEP) {
  903. for(n=0;n<dz->itemcnt;n++) {
  904. lastjitter[n] = thisjitter[n];
  905. thisjitter[n] = ((drand48() * 2.0) - 1.0) * jitter[n]; /* +- within jitter range */
  906. thisjitstep[n] = (thisjitter[n] - lastjitter[n])/(double)JITTERSTEP;
  907. }
  908. jittercnt = 0;
  909. }
  910. }
  911. for(n=0;n<dz->itemcnt;n++) {
  912. pos[n] += step[n];
  913. if(jitter != NULL)
  914. pos[n] += thisjitstep[n];
  915. while(pos[n] >= dtabsize)
  916. pos[n] -= dtabsize;
  917. samppos[n] = (int)pos[n];
  918. fracstep[n] = pos[n] - (double)samppos[n];
  919. }
  920. }
  921. if((exit_status = write_samps(dz->bigbuf,todo,dz))<0)
  922. return(exit_status);
  923. total_samps_left -= dz->buflen;
  924. }
  925. }
  926. return(FINISHED);
  927. }