distrpl.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  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 <structures.h>
  25. #include <tkglobals.h>
  26. #include <globcon.h>
  27. #include <modeno.h>
  28. #include <arrays.h>
  29. #include <distort.h>
  30. #include <cdpmain.h>
  31. #include <sfsys.h>
  32. #include <osbind.h>
  33. static int do_cycle_loudrep(int n,int current_buf,int current_pos_in_buf,int *obufpos,dataptr dz);
  34. static int do_cycle_loudrep_crosbuf
  35. (int n,int cycleno_in_group_at_bufcross,int *current_buf,int current_pos_in_buf,int *obufpos,dataptr dz);
  36. static int get_ffcycle(int,dataptr);
  37. static int write_cycle(int start, int end, int current_buf, int *obufpos,dataptr dz);
  38. /******************************* DISTORT_RPL *****************************/
  39. int distort_rpl(int *current_buf,int initial_phase,int *obufpos,int *current_pos_in_buf,int *cnt,dataptr dz)
  40. {
  41. int exit_status;
  42. int n = 0;
  43. register int i = *current_pos_in_buf;
  44. int cycleno_in_group_at_bufcross = -1;
  45. float *b = dz->sampbuf[*current_buf];
  46. switch(initial_phase) {
  47. case(1):
  48. for(n=0;n<dz->iparam[DISTRPL_CYCLECNT];n++) {
  49. dz->lfarray[DISTRPL_CYCLEVAL][n] = 0;
  50. dz->lparray[DISTRPL_STARTCYC][n] = i;
  51. while(b[i]>=0.0) { /* 8 */
  52. dz->lfarray[DISTRPL_CYCLEVAL][n] += (float) fabs(b[i]);
  53. if(++i >= dz->ssampsread) { /* 10 */
  54. if((exit_status = change_buff(&b,&cycleno_in_group_at_bufcross,current_buf,dz))!=CONTINUE)
  55. return(exit_status);
  56. cycleno_in_group_at_bufcross = n;
  57. i = 0;
  58. }
  59. }
  60. while(b[i]<=0.0) { /* 18a */
  61. dz->lfarray[DISTRPL_CYCLEVAL][n] += (float) fabs(b[i]);
  62. if(++i >= dz->ssampsread) {
  63. if((exit_status = change_buff(&b,&cycleno_in_group_at_bufcross,current_buf,dz))!=CONTINUE)
  64. return(exit_status);
  65. cycleno_in_group_at_bufcross = n;
  66. i = 0;
  67. }
  68. }
  69. }
  70. break;
  71. case(-1): /* 18b */
  72. for(n=0;n<dz->iparam[DISTRPL_CYCLECNT];n++) {
  73. dz->lfarray[DISTRPL_CYCLEVAL][n] = 0.0;
  74. dz->lparray[DISTRPL_STARTCYC][n] = i;
  75. while(b[i]<=0.0) {
  76. dz->lfarray[DISTRPL_CYCLEVAL][n] += (float) fabs(b[i]);
  77. if(++i >= dz->ssampsread) {
  78. if((exit_status = change_buff(&b,&cycleno_in_group_at_bufcross,current_buf,dz))!=CONTINUE)
  79. return(exit_status);
  80. cycleno_in_group_at_bufcross = n;
  81. i = 0;
  82. }
  83. }
  84. while(b[i]>=0.0) {
  85. dz->lfarray[DISTRPL_CYCLEVAL][n] += (float) fabs(b[i]);
  86. if(++i >= dz->ssampsread) {
  87. if((exit_status = change_buff(&b,&cycleno_in_group_at_bufcross,current_buf,dz))!=CONTINUE)
  88. return(exit_status);
  89. cycleno_in_group_at_bufcross = n;
  90. i = 0;
  91. }
  92. }
  93. }
  94. break;
  95. }
  96. if(n) {
  97. if(cycleno_in_group_at_bufcross >=0)
  98. do_cycle_loudrep_crosbuf(n,cycleno_in_group_at_bufcross,current_buf,i,obufpos,dz);
  99. else
  100. do_cycle_loudrep(n,*current_buf,i,obufpos,dz);
  101. }
  102. *current_pos_in_buf = i;
  103. (*cnt)++;
  104. return(CONTINUE);
  105. }
  106. /************************** DO_CYCLE_LOUDREP ************************/
  107. int do_cycle_loudrep(int n,int current_buf,int current_pos_in_buf,int *obufpos,dataptr dz)
  108. {
  109. int exit_status;
  110. int loudest, k;
  111. dz->lparray[DISTRPL_STARTCYC][n] = current_pos_in_buf;
  112. loudest = get_ffcycle(n,dz);
  113. for(k=0;k<dz->iparam[DISTRPL_CYCLECNT];k++) {
  114. if((exit_status =
  115. write_cycle(dz->lparray[DISTRPL_STARTCYC][loudest],dz->lparray[DISTRPL_STARTCYC][loudest+1],current_buf,obufpos,dz))<0)
  116. return(exit_status);
  117. }
  118. return(FINISHED);
  119. }
  120. /************************** DO_CYCLE_LOUDREP_CROSBUF ************************/
  121. int do_cycle_loudrep_crosbuf
  122. (int n,int cycleno_in_group_at_bufcross,int *current_buf,int current_pos_in_buf,int *obufpos,dataptr dz)
  123. {
  124. #define LOUDEST_CYCLE_AFTER_BUFCROSS (0)
  125. #define LOUDEST_CYCLE_AT_BUFCROSS (1)
  126. #define LOUDEST_CYCLE_BEFORE_BUFCROSS (2)
  127. int exit_status;
  128. int loudest, k;
  129. int is_cross;
  130. dz->lparray[DISTRPL_STARTCYC][n] = current_pos_in_buf;
  131. loudest = get_ffcycle(n,dz);
  132. if(loudest > cycleno_in_group_at_bufcross)
  133. is_cross = LOUDEST_CYCLE_AFTER_BUFCROSS;
  134. else if(cycleno_in_group_at_bufcross == loudest)
  135. is_cross = LOUDEST_CYCLE_AT_BUFCROSS;
  136. else
  137. is_cross = LOUDEST_CYCLE_BEFORE_BUFCROSS;
  138. for(k=0;k<dz->iparam[DISTRPL_CYCLECNT];k++) {
  139. switch(is_cross) {
  140. case(LOUDEST_CYCLE_AFTER_BUFCROSS):
  141. if((exit_status =
  142. write_cycle(dz->lparray[DISTRPL_STARTCYC][loudest],dz->lparray[DISTRPL_STARTCYC][loudest+1],*current_buf,obufpos,dz))<0)
  143. return(exit_status);
  144. break;
  145. case(LOUDEST_CYCLE_AT_BUFCROSS):
  146. (*current_buf) = !(*current_buf); /* LOOK IN OTHER BUFFER */
  147. if((exit_status =
  148. write_cycle(dz->lparray[DISTRPL_STARTCYC][loudest],dz->buflen,*current_buf,obufpos,dz))<0)
  149. return(exit_status);
  150. (*current_buf) = !(*current_buf); /* THEN IN CURRENT BUFFER */
  151. if((exit_status =
  152. write_cycle(0L,dz->lparray[DISTRPL_STARTCYC][loudest+1],*current_buf,obufpos,dz))<0)
  153. return(exit_status);
  154. break;
  155. case(LOUDEST_CYCLE_BEFORE_BUFCROSS):
  156. (*current_buf) = !(*current_buf); /* LOOK IN OTHER BUFFER */
  157. if((exit_status =
  158. write_cycle(dz->lparray[DISTRPL_STARTCYC][loudest],dz->lparray[DISTRPL_STARTCYC][loudest+1],*current_buf,obufpos,dz))<0)
  159. return(exit_status);
  160. (*current_buf) = !(*current_buf); /* RETURN TO CURRENT BUFFER */
  161. break;
  162. default:
  163. sprintf(errstr,"Unknown case in do_cycle_loudrep_crosbuf()\n");
  164. return(PROGRAM_ERROR);
  165. }
  166. }
  167. return(FINISHED);
  168. }
  169. /************************ GET_FFCYCLE *******************************
  170. *
  171. * Find loudest cycle.
  172. */
  173. int get_ffcycle(int k,dataptr dz)
  174. {
  175. int /*ffcycle = 0,*/ position = 0;
  176. float ffcycle = 0;
  177. int n;
  178. for(n=0;n<k;n++) {
  179. if(dz->lfarray[DISTRPL_CYCLEVAL][n] > ffcycle) {
  180. ffcycle = dz->lfarray[DISTRPL_CYCLEVAL][n];
  181. position = n;
  182. }
  183. }
  184. return(position);
  185. }
  186. /***************************** WRITE_CYCLE **********************************/
  187. int write_cycle(int start, int end,int current_buf, int *obufpos,dataptr dz)
  188. {
  189. int exit_status;
  190. float *b = dz->sampbuf[current_buf];
  191. int k;
  192. int partoutbuf = dz->buflen - *obufpos; /* FIND HOW MUCH ROOM LEFT IN OUTBUF */
  193. int insamps_to_write = end - start; /* FIND HOW MANY SAMPLES TO WRITE */
  194. int outoverflow; /* IF SAMPS-TO-WRITE WON'T FIT IN OUTBUF */
  195. if((outoverflow = insamps_to_write - partoutbuf) > 0) {
  196. while(*obufpos < dz->buflen) /* WRITE UP TO END OF OUTBUF */
  197. dz->sampbuf[2][(*obufpos)++] = b[start++];
  198. if((exit_status = write_samps(dz->sampbuf[2],dz->buflen,dz))<0)
  199. return(exit_status);
  200. /* WRITE OUTBUF TO FILE */
  201. *obufpos = 0; /* RESET OUTBUF BUFFER INDEX TO START OF BUF */
  202. insamps_to_write = outoverflow; /* RESET INSAMPS-TO-WRITE TO OVERFLOW */
  203. }
  204. for(k = 0;k < insamps_to_write; k++)
  205. dz->sampbuf[2][(*obufpos)++] = b[start++]; /*WRITE (REMAINING) INSMPS TO OUTBUF */
  206. return(FINISHED);
  207. }