distdel.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401
  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. /* floatsam version */
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <structures.h>
  26. #include <tkglobals.h>
  27. #include <globcon.h>
  28. #include <modeno.h>
  29. #include <arrays.h>
  30. #include <distort.h>
  31. #include <cdpmain.h>
  32. #include <sfsys.h>
  33. #include <osbind.h>
  34. static int do_up_cycle(int keep_or_loose,float **buf,int *current_buf,int *current_pos_in_buf,
  35. int *lastzero,int *bufcrosing,int *obufpos,dataptr dz);
  36. static int do_dn_cycle(int keep_or_loose,float **buf,int *current_buf,int *current_pos_in_buf,
  37. int *lastzero,int *bufcrosing,int *obufpos,dataptr dz);
  38. static int do_cycle_loud(float *buf,int cyclecnt,int current_pos_in_buf,int *obufpos,dataptr dz);
  39. static int do_cycle_quiet(float *buf,int cyclecnt,int current_pos_in_buf,int *obufpos,dataptr dz);
  40. static int do_cycle_loud_crosbuf(int cyclecnt,int current_buf,int current_pos_in_buf,
  41. int cycleno_in_group_at_bufcros,int *obufpos,dataptr dz);
  42. static int do_cycle_quiet_crosbuf(int cyclecnt,int current_buf,int current_pos_in_buf,
  43. int cycleno_in_group_at_bufcros,int *obufpos,dataptr dz);
  44. static int get_loudest_cycle(int cyclecnt,dataptr dz);
  45. static int get_quietest_cycle(int cyclecnt,dataptr dz);
  46. static int write_cycle(int start, int end,float *buf,int *obufpos,dataptr dz);
  47. /********************************** DISTORT_DEL ******************************/
  48. int distort_del
  49. (int *current_buf,int *current_pos_in_buf,int phase,int *obufpos,int *cnt,dataptr dz)
  50. {
  51. int exit_status;
  52. int n;
  53. float *b = dz->sampbuf[*current_buf];
  54. int bufcrosing = FALSE;
  55. int lastzero = *current_pos_in_buf;
  56. switch(phase) {
  57. case(1):
  58. if((exit_status = do_up_cycle(KEEP,&b,current_buf,current_pos_in_buf,&lastzero,&bufcrosing,obufpos,dz))!=CONTINUE)
  59. return(exit_status);
  60. if((exit_status = do_dn_cycle(KEEP,&b,current_buf,current_pos_in_buf,&lastzero,&bufcrosing,obufpos,dz))!=CONTINUE)
  61. return(exit_status);
  62. break;
  63. case(-1):
  64. if((exit_status = do_dn_cycle(KEEP,&b,current_buf,current_pos_in_buf,&lastzero,&bufcrosing,obufpos,dz))!=CONTINUE)
  65. return(exit_status);
  66. if((exit_status = do_up_cycle(KEEP,&b,current_buf,current_pos_in_buf,&lastzero,&bufcrosing,obufpos,dz))!=CONTINUE)
  67. return(exit_status);
  68. break;
  69. }
  70. if((*current_pos_in_buf - lastzero)!=0) {
  71. if((exit_status = write_cycle(lastzero,*current_pos_in_buf,b,obufpos,dz))<0)
  72. return(exit_status);
  73. }
  74. lastzero = *current_pos_in_buf;
  75. for(n=0;n<dz->iparam[DISTDEL_CYCLECNT];n++) { /* FOR NUMBER OF UNWANTED CYCLES */
  76. switch(phase) {
  77. case(1):
  78. if((exit_status = do_up_cycle(LOSE,&b,current_buf,current_pos_in_buf,&lastzero,&bufcrosing,obufpos,dz))!=CONTINUE)
  79. return(exit_status);
  80. if((exit_status = do_dn_cycle(LOSE,&b,current_buf,current_pos_in_buf,&lastzero,&bufcrosing,obufpos,dz))!=CONTINUE)
  81. return(exit_status);
  82. break;
  83. case(-1):
  84. if((exit_status = do_dn_cycle(LOSE,&b,current_buf,current_pos_in_buf,&lastzero,&bufcrosing,obufpos,dz))!=CONTINUE)
  85. return(exit_status);
  86. if((exit_status = do_up_cycle(LOSE,&b,current_buf,current_pos_in_buf,&lastzero,&bufcrosing,obufpos,dz))!=CONTINUE)
  87. return(exit_status);
  88. break;
  89. }
  90. }
  91. (*cnt)++;
  92. return(CONTINUE);
  93. }
  94. /******************************* DISTORT_DEL_WITH_LOUDNESS ******************************/
  95. int distort_del_with_loudness(int *current_buf,int phase,int *obufpos,int *current_pos_in_buf,int *cnt,dataptr dz)
  96. {
  97. int exit_status = CONTINUE;
  98. int cyclecnt = 0; /* RWD added init */
  99. //TW CONFIRM DELETE *int bufcross = 0;
  100. register int i = *current_pos_in_buf;
  101. //TW CONFIRM DELETE int cyclestart = i;
  102. float *b = dz->sampbuf[*current_buf];
  103. int cycleno_in_group_at_bufcros = -1;
  104. switch(phase) {
  105. case(1):
  106. for(cyclecnt=0;cyclecnt<dz->iparam[DISTDEL_CYCLECNT];cyclecnt++) {
  107. /* RWD 4:2002 use lfarray as this now contains amplitudes */
  108. dz->lfarray[DISTDEL_CYCLEVAL][cyclecnt] = 0.0;
  109. dz->lparray[DISTDEL_STARTCYC][cyclecnt] = i;
  110. while(b[i]>=0) {
  111. dz->lfarray[DISTDEL_CYCLEVAL][cyclecnt] += b[i];
  112. if(++i >= dz->ssampsread) {
  113. if((exit_status = change_buff(&b,&cycleno_in_group_at_bufcros,current_buf,dz))<0)
  114. return(exit_status);
  115. cycleno_in_group_at_bufcros = cyclecnt;
  116. if(exit_status !=CONTINUE)
  117. break;
  118. i = 0;
  119. }
  120. }
  121. if(exit_status !=CONTINUE)
  122. break;
  123. while(b[i]<=0.0) {
  124. dz->lfarray[DISTDEL_CYCLEVAL][cyclecnt] -= b[i];
  125. if(++i >= dz->ssampsread) {
  126. if((exit_status = change_buff(&b,&cycleno_in_group_at_bufcros,current_buf,dz))<0)
  127. return(exit_status);
  128. cycleno_in_group_at_bufcros = cyclecnt;
  129. if(exit_status !=CONTINUE)
  130. break;
  131. i = 0;
  132. }
  133. }
  134. if(exit_status !=CONTINUE)
  135. break;
  136. }
  137. break;
  138. case(-1):
  139. for(cyclecnt=0;cyclecnt<dz->iparam[DISTDEL_CYCLECNT];cyclecnt++) {
  140. dz->lfarray[DISTDEL_CYCLEVAL][cyclecnt] = 0.0;
  141. dz->lparray[DISTDEL_STARTCYC][cyclecnt] = i;
  142. while(b[i]<=0.0) {
  143. dz->lfarray[DISTDEL_CYCLEVAL][cyclecnt] -= b[i];
  144. if(++i >= dz->ssampsread) {
  145. if((exit_status = change_buff(&b,&cycleno_in_group_at_bufcros,current_buf,dz))<0)
  146. return(exit_status);
  147. cycleno_in_group_at_bufcros = cyclecnt;
  148. if(exit_status !=CONTINUE)
  149. break;
  150. i = 0;
  151. }
  152. }
  153. if(exit_status !=CONTINUE)
  154. break;
  155. while(b[i]>=0.0) {
  156. dz->lfarray[DISTDEL_CYCLEVAL][cyclecnt] += b[i];
  157. if(++i >= dz->ssampsread) {
  158. if((exit_status = change_buff(&b,&cycleno_in_group_at_bufcros,current_buf,dz))<0)
  159. return(exit_status);
  160. cycleno_in_group_at_bufcros = cyclecnt;
  161. if(exit_status !=CONTINUE)
  162. break;
  163. i = 0;
  164. }
  165. }
  166. if(exit_status !=CONTINUE)
  167. break;
  168. }
  169. break;
  170. }
  171. if(cyclecnt) {
  172. if(cycleno_in_group_at_bufcros >= 0) { /* cycle set crosses between buffers */
  173. switch(dz->mode) {
  174. case(KEEP_STRONGEST):
  175. if((exit_status = do_cycle_loud_crosbuf(cyclecnt,*current_buf,i,cycleno_in_group_at_bufcros,obufpos,dz))<0)
  176. return(exit_status);
  177. break;
  178. case(DELETE_WEAKEST):
  179. if((exit_status = do_cycle_quiet_crosbuf(cyclecnt,*current_buf,i,cycleno_in_group_at_bufcros,obufpos,dz))<0)
  180. return(exit_status);
  181. break;
  182. }
  183. } else {
  184. switch(dz->mode) {
  185. case(KEEP_STRONGEST):
  186. if((exit_status = do_cycle_loud(b,cyclecnt,i,obufpos,dz))<0)
  187. return(exit_status);
  188. break;
  189. case(DELETE_WEAKEST):
  190. if((exit_status = do_cycle_quiet(b,cyclecnt,i,obufpos,dz))<0)
  191. return(exit_status);
  192. break;
  193. }
  194. }
  195. }
  196. *current_pos_in_buf = i;
  197. (*cnt)++;
  198. return(exit_status);
  199. }
  200. /*************************** DO_UP_CYCLE ******************************/
  201. int do_up_cycle(int keep_or_loose,float **buf,int *current_buf,int *current_pos_in_buf,
  202. int *lastzero,int *bufcrosing,int *obufpos,dataptr dz)
  203. {
  204. int exit_status;
  205. while((*buf)[*current_pos_in_buf]>=0.0) {
  206. if(++(*current_pos_in_buf) >= dz->ssampsread) {
  207. if(keep_or_loose ==KEEP) {
  208. if((exit_status= write_cycle(*lastzero,*current_pos_in_buf,*buf,obufpos,dz))< 0)
  209. return(exit_status);
  210. }
  211. if((exit_status = change_buf(current_buf,bufcrosing,buf,dz))!=CONTINUE)
  212. return(exit_status);
  213. *lastzero = *current_pos_in_buf = 0;
  214. }
  215. }
  216. return(CONTINUE);
  217. }
  218. /************************* DO_DN_CYCLE ******************************/
  219. int do_dn_cycle(int keep_or_loose,float **buf,int *current_buf,int *current_pos_in_buf,
  220. int *lastzero,int *bufcrosing,int *obufpos,dataptr dz)
  221. {
  222. int exit_status;
  223. while((*buf)[*current_pos_in_buf]<=0.0) {
  224. if(++(*current_pos_in_buf) >= dz->ssampsread) {
  225. if(keep_or_loose ==KEEP) {
  226. if((exit_status= write_cycle(*lastzero,*current_pos_in_buf,*buf,obufpos,dz))< 0)
  227. return(exit_status);
  228. }
  229. if((exit_status = change_buf(current_buf,bufcrosing,buf,dz))!=CONTINUE)
  230. return(exit_status);
  231. *lastzero = *current_pos_in_buf = 0;
  232. }
  233. }
  234. return(CONTINUE);
  235. }
  236. /************************ DO_CYCLE_LOUD **************************/
  237. int do_cycle_loud(float *buf,int cyclecnt,int current_pos_in_buf,int *obufpos,dataptr dz)
  238. {
  239. int loudest = get_loudest_cycle(cyclecnt,dz);
  240. dz->lparray[DISTDEL_STARTCYC][cyclecnt] = current_pos_in_buf;
  241. return write_cycle(dz->lparray[DISTDEL_STARTCYC][loudest],dz->lparray[DISTDEL_STARTCYC][loudest+1],buf,obufpos,dz);
  242. }
  243. /************************ DO_CYCLE_LOUD_CROSBUF **************************/
  244. int do_cycle_loud_crosbuf
  245. (int cyclecnt,int current_buf,int current_pos_in_buf,int cycleno_in_group_at_bufcros,int *obufpos,dataptr dz)
  246. {
  247. int exit_status;
  248. int loudest;
  249. float *buf;
  250. loudest = get_loudest_cycle(cyclecnt,dz);
  251. dz->lparray[DISTDEL_STARTCYC][cyclecnt] = current_pos_in_buf;
  252. if(cycleno_in_group_at_bufcros == loudest) {
  253. buf = dz->sampbuf[!current_buf]; /* GO TO PREVIOUS BUFFER */
  254. if((exit_status = write_cycle(dz->lparray[DISTDEL_STARTCYC][loudest],dz->buflen,buf,obufpos,dz))<0)
  255. return(exit_status);
  256. buf = dz->sampbuf[current_buf];
  257. exit_status = write_cycle(0L,dz->lparray[DISTDEL_STARTCYC][loudest+1],buf,obufpos,dz);
  258. } else if (cycleno_in_group_at_bufcros > loudest) {
  259. buf = dz->sampbuf[!current_buf]; /* GO TO PREVIOUS BUFFER */
  260. exit_status = write_cycle(dz->lparray[DISTDEL_STARTCYC][loudest],dz->lparray[DISTDEL_STARTCYC][loudest+1],buf,obufpos,dz);
  261. } else {
  262. buf = dz->sampbuf[current_buf]; /* GO TO PREVIOUS BUFFER */
  263. exit_status = write_cycle(dz->lparray[DISTDEL_STARTCYC][loudest],dz->lparray[DISTDEL_STARTCYC][loudest+1],buf,obufpos,dz);
  264. }
  265. return(exit_status);
  266. }
  267. /************************ GET_LOUDEST_CYCLE *******************************
  268. *
  269. * Find loudest cycle.
  270. */
  271. int get_loudest_cycle(int cyclecnt,dataptr dz)
  272. {
  273. int /*ffcycle = 0,*/ position = 0;
  274. float ffcycle = 0.0;
  275. int n;
  276. for(n=0;n<cyclecnt;n++) {
  277. if(dz->lfarray[DISTDEL_CYCLEVAL][n] > ffcycle) {
  278. ffcycle = dz->lfarray[DISTDEL_CYCLEVAL][n];
  279. position = n;
  280. }
  281. }
  282. return(position);
  283. }
  284. /***************************** DO_CYCLE_QUIET *************************/
  285. int do_cycle_quiet(float *buf,int cyclecnt,int current_pos_in_buf,int *obufpos,dataptr dz)
  286. {
  287. int exit_status;
  288. int quietest = get_quietest_cycle(cyclecnt,dz);
  289. dz->lparray[DISTDEL_STARTCYC][cyclecnt] = current_pos_in_buf;
  290. if((exit_status = write_cycle(dz->lparray[DISTDEL_STARTCYC][0],dz->lparray[DISTDEL_STARTCYC][quietest],buf,obufpos,dz))<0)
  291. return(exit_status);
  292. return write_cycle(dz->lparray[DISTDEL_STARTCYC][quietest+1],dz->lparray[DISTDEL_STARTCYC][cyclecnt],buf,obufpos,dz);
  293. }
  294. /************************** DO_CYCLE_QUIET_CROSBUF *************************/
  295. int do_cycle_quiet_crosbuf
  296. (int cyclecnt,int current_buf,int current_pos_in_buf,int cycleno_in_group_at_bufcros,int *obufpos,dataptr dz)
  297. {
  298. int exit_status;
  299. int quietest = get_quietest_cycle(cyclecnt,dz);
  300. float *buf;
  301. dz->lparray[DISTDEL_STARTCYC][cyclecnt] = current_pos_in_buf;
  302. if(cycleno_in_group_at_bufcros == quietest) {
  303. buf = dz->sampbuf[!current_buf];
  304. if((exit_status = write_cycle(dz->lparray[DISTDEL_STARTCYC][0],dz->lparray[DISTDEL_STARTCYC][quietest],buf,obufpos,dz))<0)
  305. return(exit_status);
  306. buf = dz->sampbuf[current_buf];
  307. exit_status = write_cycle(dz->lparray[DISTDEL_STARTCYC][quietest+1],dz->lparray[DISTDEL_STARTCYC][cyclecnt],buf,obufpos,dz);
  308. } else if(cycleno_in_group_at_bufcros > quietest) {
  309. buf = dz->sampbuf[!current_buf];
  310. if((exit_status = write_cycle(dz->lparray[DISTDEL_STARTCYC][0],dz->lparray[DISTDEL_STARTCYC][quietest],buf,obufpos,dz))<0)
  311. return(exit_status);
  312. if((exit_status = write_cycle(dz->lparray[DISTDEL_STARTCYC][quietest+1],dz->buflen,buf,obufpos,dz))<0)
  313. return(exit_status);
  314. buf = dz->sampbuf[current_buf];
  315. exit_status = write_cycle(0L,dz->lparray[DISTDEL_STARTCYC][cyclecnt],buf,obufpos,dz);
  316. } else {
  317. buf = dz->sampbuf[!current_buf];
  318. if((exit_status = write_cycle(dz->lparray[DISTDEL_STARTCYC][0],dz->buflen,buf,obufpos,dz))<0)
  319. return(exit_status);
  320. buf = dz->sampbuf[current_buf];
  321. if((exit_status = write_cycle(0L,dz->lparray[DISTDEL_STARTCYC][quietest],buf,obufpos,dz))<0)
  322. return(exit_status);
  323. exit_status = write_cycle(dz->lparray[DISTDEL_STARTCYC][quietest+1],dz->lparray[DISTDEL_STARTCYC][cyclecnt],buf,obufpos,dz);
  324. }
  325. return(exit_status);
  326. }
  327. /************************ GET_QUIETEST_CYCLE *******************************
  328. *
  329. * Find quietest cycle.
  330. */
  331. int get_quietest_cycle(int cyclecnt,dataptr dz)
  332. {
  333. //TW FIXED
  334. // int quiestest_cycle = dz->lparray[DISTDEL_CYCLEVAL][0], position = 0;
  335. float quiestest_cycle = dz->lfarray[DISTDEL_CYCLEVAL][0];
  336. int position = 0;
  337. int n;
  338. for(n=1;n<cyclecnt;n++) {
  339. if(dz->lfarray[DISTDEL_CYCLEVAL][n] < quiestest_cycle) {
  340. quiestest_cycle = dz->lfarray[DISTDEL_CYCLEVAL][n];
  341. position = n;
  342. }
  343. }
  344. return(position);
  345. }
  346. /***************************** WRITE_CYCLE **********************************/
  347. int write_cycle(int start,int end,float *buf,int *obufpos,dataptr dz)
  348. {
  349. int exit_status;
  350. float *obuf = dz->sampbuf[2] + *obufpos;
  351. int partoutbuf = dz->buflen - *obufpos; /* FIND HOW MUCH ROOM LEFT IN OUTBUF */
  352. int insamps_to_write = end - start; /* FIND HOW MANY SAMPLES TO WRITE */
  353. int outoverflow; /* IF SAMPS-TO-WRITE WON'T FIT IN OUTBUF */
  354. buf += start;
  355. while((outoverflow = insamps_to_write - partoutbuf) > 0) {
  356. memmove((char *)obuf,(char *)buf,partoutbuf * sizeof(float));
  357. obuf = dz->sampbuf[2];
  358. buf += partoutbuf;
  359. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  360. return(exit_status);
  361. *obufpos = 0;
  362. insamps_to_write = outoverflow;
  363. partoutbuf = dz->buflen;
  364. }
  365. memmove((char *)obuf,(char *)buf,insamps_to_write * sizeof(float));
  366. *obufpos += insamps_to_write;
  367. return(CONTINUE);
  368. }