filters1.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547
  1. /*
  2. * Copyright (c) 1983-2020 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 <tkglobals.h>
  25. #include <globcon.h>
  26. #include <processno.h>
  27. #include <modeno.h>
  28. #include <arrays.h>
  29. #include <filters.h>
  30. #include <cdpmain.h>
  31. #include <sfsys.h>
  32. #include <osbind.h>
  33. #include <string.h>
  34. #include <filters.h>
  35. #include <logic.h>
  36. //#ifdef unix
  37. #define round(x) lround((x))
  38. //#endif
  39. static int readsamps_with_wrap(dataptr dz);
  40. static double get_gain(dataptr dz);
  41. static double get_pshift(dataptr dz);
  42. static int get_next_writestart(int write_start,dataptr dz);
  43. static int iterfilt(int write_start,int *write_end,int *atten_index,
  44. int thisbuf,double orig_maxsamp,int splicelen,dataptr dz);
  45. static void reset_filters(dataptr dz);
  46. static void scale_input(dataptr dz);
  47. static void amp_smooth(dataptr dz);
  48. static void do_attenuation(int atten_index, float *ib2,dataptr dz);
  49. static void filter_normalise(float *thisbuf,double orig_maxsamp,dataptr dz);
  50. static double get_maxsamp(float *thisbuf,dataptr dz);
  51. static int do_shift_gain_and_copy_to_outbuf(float *ibuf,float *obuf,int chans,double step,
  52. double thisgain,int *write_pos,dataptr dz);
  53. static int do_iterated_filtering(int atten_index,int write_start,int *write_end,
  54. int thisbuf,double orig_maxsamp,int splicelen,dataptr dz);
  55. static void do_end_splice(float *ibuf,int seglen_in_mono,int splicelen,dataptr dz);
  56. /****************************** ITERATING_FILTER *************************/
  57. int iterating_filter(dataptr dz)
  58. {
  59. int exit_status;
  60. int tail;
  61. float *obuf = dz->sampbuf[FLT_OUTBUF];
  62. float *ovflwbuf = dz->sampbuf[FLT_OVFLWBUF];
  63. int write_start = 0, write_end;
  64. int atten_index = 2, remaining_dur = dz->iparam[FLT_OUTDUR];
  65. int thisbuf = 0;
  66. double orig_maxsamp;
  67. int splicelen = round(FLT_SPLICELEN * MS_TO_SECS * (double)dz->infile->srate);
  68. splicelen = min(splicelen,dz->iparam[FLT_INMSAMPSIZE]/2 ); /*RWD 2 signifies ???? */
  69. if((exit_status = readsamps_with_wrap(dz))<0)
  70. return(exit_status);
  71. if(!flteq(dz->param[FLT_PRESCALE],1.0))
  72. scale_input(dz);
  73. display_virtual_time(0L,dz);
  74. if(dz->vflag[FLT_EXPDEC])
  75. amp_smooth(dz);
  76. orig_maxsamp = get_maxsamp(dz->sampbuf[0],dz);
  77. memmove((char *)obuf,(char *)dz->sampbuf[0],(size_t)(dz->insams[0] * sizeof(float)));
  78. write_start = get_next_writestart(write_start,dz);
  79. write_end = dz->insams[0];
  80. while(write_start < remaining_dur) {
  81. while(write_start >= dz->buflen) { /* 'while' allows blank buffers to be copied (where delay > filesize) */
  82. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  83. return(exit_status);
  84. tail = write_end - dz->buflen;
  85. memset((char *)obuf,0,(size_t)(dz->buflen * sizeof(float)));
  86. if(tail > 0) {
  87. memmove((char *)obuf,(char *)ovflwbuf,tail * sizeof(float));
  88. memset((char *)ovflwbuf,0,(size_t) (dz->iparam[FLT_OVFLWSIZE] * sizeof(float)));
  89. }
  90. write_start -= dz->buflen;
  91. write_end -= dz->buflen;
  92. remaining_dur -= dz->buflen;
  93. }
  94. if((exit_status= iterfilt(write_start,&write_end,&atten_index,thisbuf,orig_maxsamp,splicelen,dz))<0)
  95. return(exit_status);
  96. thisbuf = !thisbuf; /* swap between buf0 and buf1 */
  97. write_start = get_next_writestart(write_start,dz);
  98. }
  99. if(write_end-1 > 0)
  100. return write_samps(obuf,write_end-1,dz);
  101. return FINISHED;
  102. }
  103. /*************************** READSAMPS_WITH_WRAP **************************/
  104. int readsamps_with_wrap(dataptr dz)
  105. {
  106. int exit_status;
  107. int j;
  108. int n;
  109. float *buf = dz->sampbuf[0];
  110. if((exit_status = read_samps(dz->sampbuf[0],dz)) < 0) {
  111. //TW MESSAGE TEXT CORRECTED
  112. sprintf(errstr, "Can't read samples from input soundfile: readsamps_with_wrap()\n");
  113. return(PROGRAM_ERROR);
  114. }
  115. if(dz->ssampsread!=dz->insams[0]) {
  116. sprintf(errstr, "Failed to read all of source file: readsamps_with_wrap()\n");
  117. return(PROGRAM_ERROR);
  118. }
  119. j = dz->ssampsread;
  120. for(n=0;n<dz->infile->channels;n++) {
  121. buf[j] = 0.0f;
  122. j++; /* INSERT GUARD POINTS FOR INTERPOLATION */
  123. }
  124. return(FINISHED);
  125. }
  126. /******************************** GET_GAIN *****************************/
  127. double get_gain(dataptr dz)
  128. {
  129. double scatter;
  130. scatter = drand48() * dz->param[FLT_AMPSHIFT];
  131. scatter = 1.0 - scatter;
  132. return scatter;
  133. }
  134. /******************************** GET_PSHIFT *****************************/
  135. double get_pshift(dataptr dz)
  136. {
  137. double scatter;
  138. scatter = (drand48() * 2.0) - 1.0;
  139. if(scatter >= 0.0) {
  140. scatter *= dz->param[FLT_PSHIFT];
  141. return(pow(2.0,scatter));
  142. }
  143. scatter = -scatter;
  144. scatter *= dz->param[FLT_PSHIFT];
  145. scatter = pow(2.0,scatter);
  146. scatter = 1.0/scatter;
  147. return(scatter);
  148. }
  149. /*************************** GET_NEXT_WRITESTART ****************************/
  150. int get_next_writestart(int write_start,dataptr dz)
  151. {
  152. int this_step;
  153. double scatter;
  154. scatter = ((drand48() * 2.0) - 1.0) * dz->param[FLT_RANDDEL];
  155. scatter += 1.0;
  156. this_step = (int)round((double)dz->iparam[FLT_MSAMPDEL] * scatter);
  157. this_step *= dz->infile->channels;
  158. write_start += this_step;
  159. return(write_start);
  160. }
  161. /******************************* ITERFILT *****************************/
  162. int iterfilt(int write_start,int *write_end,int *atten_index,int thisbuf,double orig_maxsamp,int splicelen,dataptr dz)
  163. {
  164. int exit_status;
  165. int wr_end;
  166. if((exit_status = do_iterated_filtering(*atten_index,write_start,&wr_end,thisbuf,orig_maxsamp,splicelen,dz))<0)
  167. return(exit_status);
  168. (*atten_index)++;
  169. *write_end = max(wr_end,*write_end);
  170. return(FINISHED);
  171. }
  172. /***************************** RESET_FILTERS *************************/
  173. void reset_filters(dataptr dz)
  174. {
  175. int n, chno, k;
  176. int chans = dz->infile->channels;
  177. for(n=0;n<dz->iparam[FLT_CNT];n++) {
  178. for(chno=0;chno<chans;chno++) {
  179. k = (n*chans)+chno;
  180. if(dz->vflag[FLT_DBLFILT]) {
  181. dz->parray[FLT_D][k] = 0.0;
  182. dz->parray[FLT_E][k] = 0.0;
  183. }
  184. dz->parray[FLT_Y][k] = 0.0;
  185. dz->parray[FLT_Z][k] = 0.0;
  186. }
  187. }
  188. }
  189. /******************************* SCALE_INPUT ****************************/
  190. void scale_input(dataptr dz)
  191. {
  192. int i;
  193. float *b = dz->sampbuf[0];
  194. int end = dz->insams[0];
  195. if(dz->iparam[FLT_DOFLAG]!=U_MONO && dz->iparam[FLT_DOFLAG]!=U_STEREO)
  196. end = dz->insams[0] + dz->infile->channels;
  197. for(i=0; i < end; i++)
  198. b[i] = (float)(b[i] * dz->param[FLT_PRESCALE]);
  199. }
  200. /*************************** AMP_SMOOTH ************************
  201. *
  202. * expomential attenuation to input ensures everything remains equally loud as it decays!!
  203. * attenuation when max no of signals overlayed (endatten) is 1.0/dz->iparam[FLT_MAXOVERLAY].
  204. * No of samples before this max overlay (y=attencnt)
  205. * .....is dz->iparam[FLT_MSAMPDEL] * (dz->iparam[FLT_MAXOVERLAY]-1).
  206. * If sample by sample atten is x then
  207. * pow(x,y) = endatten.
  208. * Hence x = pow(endatten,1/y);
  209. */
  210. void amp_smooth(dataptr dz)
  211. {
  212. // int k = 1;
  213. register int i = 0, n;
  214. register int m;
  215. double atten, endatten;
  216. int attencnt;
  217. int chans = dz->infile->channels;
  218. attencnt = dz->iparam[FLT_MSAMPDEL] * (dz->iparam[FLT_MAXOVERLAY]-1);
  219. endatten = 1.0/(double)dz->iparam[FLT_MAXOVERLAY];
  220. dz->param[FLT_SAMPATTEN] = pow(endatten,(1.0/(double)attencnt));
  221. atten = 1.0;
  222. for(n = 0;n < dz->insams[0]; n++) {
  223. for(m = 0; m < chans; m++) {
  224. dz->sampbuf[0][i] = (float)((double)dz->sampbuf[0][i] * atten);
  225. i++;
  226. }
  227. atten *= dz->param[FLT_SAMPATTEN];
  228. }
  229. }
  230. /*************************** DO_ATTENUATION ************************/
  231. void do_attenuation(int atten_index, float *ib2,dataptr dz)
  232. {
  233. double thisgain;
  234. // register int n, j = 0;
  235. register int n;
  236. // int chans = dz->infile->channels;
  237. int atten_factor = min(atten_index,dz->iparam[FLT_MAXOVERLAY]);
  238. thisgain = pow(dz->param[FLT_SAMPATTEN],(double)(atten_factor * dz->iparam[FLT_MSAMPDEL]));
  239. for (n = 0; n < dz->insams[0]; n++) {
  240. ib2[n] = (float)((double)ib2[n] * thisgain);
  241. // n++; /*RWD 12/20: can't be right to increment this twice */
  242. }
  243. }
  244. /************************** FILTER_NORMALISE ************************/
  245. void filter_normalise(float *thisbuf,double orig_maxsamp,dataptr dz)
  246. {
  247. int n;
  248. double maxsamp = get_maxsamp(thisbuf,dz);
  249. double thisnorm = orig_maxsamp/maxsamp;
  250. for (n = 0; n < dz->insams[0]; n++)
  251. thisbuf[n] = (float) ((double)thisbuf[n] * thisnorm);
  252. }
  253. /************************** GET_MAXSAMP ************************/
  254. double get_maxsamp(float *thisbuf,dataptr dz)
  255. {
  256. int n;
  257. double maxsamp = F_MINSAMP, minsamp = F_MAXSAMP;
  258. for (n = 0; n < dz->insams[0]; n++) {
  259. maxsamp = max(thisbuf[n],maxsamp);
  260. minsamp = min(thisbuf[n],minsamp);
  261. }
  262. maxsamp = max(fabs(maxsamp),fabs(minsamp));
  263. return(maxsamp);
  264. }
  265. /**************************** DO_ITERATED_FILTERING ***************************/
  266. int do_iterated_filtering(int atten_index,int write_start,int *write_end,
  267. int thisbuf,double orig_maxsamp,int splicelen,dataptr dz)
  268. {
  269. int exit_status;
  270. register int n;
  271. int write_pos = write_start;
  272. float *ibuf = dz->sampbuf[thisbuf];
  273. float *ibuf2= dz->sampbuf[!thisbuf];
  274. float *obuf = dz->sampbuf[FLT_OUTBUF];
  275. int chans = dz->infile->channels;
  276. double *ampl = dz->parray[FLT_AMPL];
  277. double *a = dz->parray[FLT_A];
  278. double *b = dz->parray[FLT_B];
  279. double *y = dz->parray[FLT_Y];
  280. double *z = dz->parray[FLT_Z];
  281. double *d = dz->parray[FLT_D];
  282. double *z1 = dz->parray[FLT_E];
  283. double step = 1.0;
  284. double thisgain = 1.0;
  285. int total_samps = dz->iparam[FLT_INMSAMPSIZE]*chans;
  286. if(dz->param[FLT_PSHIFT] > 0.0)
  287. step = get_pshift(dz);
  288. if(dz->param[FLT_AMPSHIFT] > 0.0)
  289. thisgain = get_gain(dz);
  290. reset_filters(dz);
  291. for (n = 0; n < total_samps; n+=chans)
  292. io_filtering(ibuf,ibuf2,chans,n,a,b,y,z,d,z1,ampl,dz);
  293. if(!dz->vflag[FLT_NONORM])
  294. filter_normalise(ibuf2,orig_maxsamp,dz);
  295. if(dz->vflag[FLT_EXPDEC])
  296. do_attenuation(atten_index,ibuf2,dz);
  297. do_end_splice(ibuf2,dz->iparam[FLT_INMSAMPSIZE],splicelen,dz);
  298. if((exit_status = do_shift_gain_and_copy_to_outbuf(ibuf2,obuf,chans,step,thisgain,&write_pos,dz))<0)
  299. return(exit_status);
  300. memset((char *)ibuf,0,(size_t)(dz->iparam[FLT_INFILESPACE] * sizeof(float)));
  301. *write_end = write_pos;
  302. return(FINISHED);
  303. }
  304. /*************************** DO_SHIFT_GAIN_AND_COPY_TO_OUTBUF *******************************/
  305. int do_shift_gain_and_copy_to_outbuf(float *ibuf,float *obuf,int chans,double step,
  306. double thisgain,int *write_pos,dataptr dz)
  307. {
  308. float val, nextval, diff;
  309. double d = 0.0, part = 0.0, input;
  310. int n = 0, z;
  311. register int j = *write_pos;
  312. register int chno;
  313. int total_samps = dz->iparam[FLT_INMSAMPSIZE] * chans;
  314. switch(dz->iparam[FLT_DOFLAG]) {
  315. case(ITER_MONO):
  316. case(ITER_STEREO):
  317. while(n < total_samps) {
  318. for(chno=0;chno<chans;chno++)
  319. obuf[j++] += (float)(ibuf[n+chno] * thisgain);
  320. n+=chans;
  321. }
  322. break;
  323. case(MN_SHIFT):
  324. while(n < dz->iparam[FLT_INMSAMPSIZE]) {
  325. obuf[j++] += (float) (ibuf[n] * thisgain);
  326. d += step;
  327. n = round(d); /* ROUND */
  328. }
  329. break;
  330. case(ST_SHIFT):
  331. while (n < dz->iparam[FLT_INMSAMPSIZE]) {
  332. for(chno = 0; chno < chans; chno++) {
  333. z = (n * chans) + chno;
  334. obuf[j++] += (float)(ibuf[z] * thisgain);
  335. }
  336. d += step;
  337. n = round(d);
  338. }
  339. break;
  340. case(MN_FLT_INTP_SHIFT):
  341. while(n < dz->iparam[FLT_INMSAMPSIZE]) {
  342. val = ibuf[n++];
  343. nextval = ibuf[n];
  344. diff = nextval - val;
  345. input = (double)val + ((double)diff * part);
  346. obuf[j++] += (float) (input * thisgain);
  347. d += step;
  348. n = (int)d; /* TRUNCATE */
  349. part = d - (double)n;
  350. }
  351. break;
  352. case(ST_FLT_INTP_SHIFT):
  353. while(n < dz->iparam[FLT_INMSAMPSIZE]) {
  354. for(chno = 0; chno < chans; chno++) {
  355. z = (n * chans) + chno;
  356. val = ibuf[z];
  357. nextval = ibuf[z+chans];
  358. diff = nextval - val;
  359. input = (double)val + ((double)diff * part);
  360. obuf[j++] += (float) (input * thisgain);
  361. }
  362. d += step;
  363. n = (int)d; /* TRUNCATE */
  364. part = d - (double)n;
  365. }
  366. break;
  367. case(U_MONO):
  368. case(U_STEREO):
  369. while(n < total_samps) {
  370. for(chno=0;chno<chans;chno++)
  371. obuf[j++] += ibuf[n+chno];
  372. n+= chans;
  373. }
  374. break;
  375. case(U_MN_SHIFT):
  376. while(n < dz->iparam[FLT_INMSAMPSIZE]) {
  377. obuf[j++] = ibuf[n];
  378. d += step;
  379. n = round(d); /* ROUND */
  380. }
  381. break;
  382. case(U_ST_SHIFT):
  383. while(n < dz->iparam[FLT_INMSAMPSIZE]) {
  384. for(chno = 0; chno < chans; chno++) {
  385. z = (n * chans) + chno;
  386. obuf[j++] += ibuf[z];
  387. }
  388. d += step;
  389. n = round(d); /* ROUND */
  390. }
  391. break;
  392. case(U_MN_INTP_SHIFT):
  393. while(n < dz->iparam[FLT_INMSAMPSIZE]) {
  394. val = ibuf[n++];
  395. nextval = ibuf[n];
  396. diff = nextval - val;
  397. input = (double)val + ((double)diff * part);
  398. obuf[j] = (float) (input + (double)obuf[j]);
  399. j++;
  400. d += step;
  401. n = (int)d; /* TRUNCATE */
  402. part = d - (double)n;
  403. }
  404. break;
  405. case(U_ST_INTP_SHIFT):
  406. while(n < dz->iparam[FLT_INMSAMPSIZE]) {
  407. for(chno = 0; chno < chans; chno++) {
  408. z = (n * chans) + chno;
  409. val = ibuf[z];
  410. nextval = ibuf[z+chans];
  411. diff = nextval - val;
  412. input = (double)val + ((double)diff * part);
  413. obuf[j] = (float)(input + (double)obuf[j]);
  414. j++;
  415. }
  416. d += step;
  417. n = (int)d; /* TRUNCATE */
  418. part = d - (double)n;
  419. }
  420. break;
  421. default:
  422. sprintf(errstr,"Unknown case in do_shift_gain_and_copy_to_outbuf()\n");
  423. return(PROGRAM_ERROR);
  424. }
  425. *write_pos = j;
  426. return(FINISHED);
  427. }
  428. /*************************************** DO_END_SPLICE **************************************/
  429. void do_end_splice(float *ibuf,int seglen_in_mono,int splicelen,dataptr dz)
  430. {
  431. int n, m, sampno, chnno, chans = dz->infile->channels;
  432. double splicestep = 1.0/(double)splicelen;
  433. double splicefact = 0.0;
  434. for(n=((seglen_in_mono*chans)-chans), m=0; m<splicelen; n-=chans ,m++) {
  435. for(chnno = 0;chnno<chans;chnno++) {
  436. sampno = n + chnno;
  437. ibuf[sampno] = (float) ((double)ibuf[sampno] * splicefact);
  438. }
  439. splicefact += splicestep;
  440. }
  441. }
  442. /*************************************** MAKE_VFILT_DATA **************************************/
  443. int make_vfilt_data(dataptr dz)
  444. {
  445. int n,k,m,j;
  446. char *q, outname[200], line[200], temp[200];
  447. double d;
  448. FILE *fp;
  449. int *thislinecnt;
  450. if((thislinecnt = (int *)malloc(dz->linecnt * sizeof(int)))==NULL) {
  451. sprintf(errstr,"No memory to distinguish lines in input data.\n");
  452. return(MEMORY_ERROR);
  453. }
  454. if((fp = fopen(dz->wordstor[0],"r"))==NULL) {
  455. sprintf(errstr,"Failed to reopen file %s for checking.\n",dz->wordstor[0]);
  456. return(DATA_ERROR);
  457. }
  458. n = 0;
  459. while(fgets(temp,200,fp)!=NULL) {
  460. q = temp;
  461. thislinecnt[n] = 0;
  462. while(get_float_from_within_string(&q,&d)) {
  463. thislinecnt[n]++;
  464. }
  465. n++;
  466. }
  467. fclose(fp);
  468. j = 0;
  469. for(n = 0; n < dz->linecnt; n++) {
  470. strcpy(outname,dz->wordstor[1]);
  471. if(sloom) {
  472. replace_filename_extension(outname,"");
  473. insert_new_number_at_filename_end(outname,n,1);
  474. } else {
  475. replace_filename_extension(outname,".txt");
  476. insert_new_number_at_filename_end(outname,n,0);
  477. }
  478. if((fp = fopen(outname,"w"))==NULL) {
  479. sprintf(errstr,"Cannot open file %s to store filter data\n",outname);
  480. return(SYSTEM_ERROR);
  481. }
  482. strcpy(line,"0");
  483. k = j;
  484. for(m=0;m<thislinecnt[n];m++) {
  485. strcat(line,"\t");
  486. sprintf(temp,"%lf",dz->parray[0][j++]);
  487. strcat(line,temp);
  488. strcat(line,"\t1");
  489. }
  490. fprintf(fp,"%s\n",line);
  491. strcpy(line,"10000");
  492. for(m=0;m<thislinecnt[n];m++) {
  493. strcat(line,"\t");
  494. sprintf(temp,"%lf",dz->parray[0][k++]);
  495. strcat(line,temp);
  496. strcat(line,"\t1");
  497. }
  498. fprintf(fp,"%s\n",line);
  499. fclose(fp);
  500. }
  501. dz->process_type = OTHER_PROCESS;
  502. return FINISHED;
  503. }