distortp.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  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 vesion */
  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. #ifdef unix
  35. #define round(x) lround((x))
  36. #endif
  37. static int get_distort(int oldlen,int *pos_in_cycle_group,double *last_transpos,double *next_transpos,
  38. double *transpos_step,int *thiscyclelen,int *init,dataptr dz);
  39. static int do_distrt(int oldlen,int *pos_in_cycle_group,double *last_transpos,double *next_transpos,
  40. double *transpos_step,int *thiscyclelen,int *init,int *obufremain,int current_inbuf_pos, dataptr dz);
  41. static int move_to_outbut(int n,int *obufremain,dataptr dz);
  42. /************************* DISTORT_PITCH ***********************************
  43. *
  44. * Works on SINGLE HALF wavecycles.
  45. *
  46. * This looks for single half-wavecycles, and does not change there
  47. * number (or their phase) in the output. It therefore resets the
  48. * input & output phase on each entry.
  49. */
  50. int distort_pitch(dataptr dz)
  51. {
  52. int exit_status;
  53. int pos_in_cycle_group = 0, thiscyclelen = 0, init = 1;
  54. double last_transpos = 0.0, next_transpos = 0.0, transpos_step = 0.0;
  55. int obufremain = dz->buflen;
  56. int current_buf = 0;
  57. int current_inbuf_pos = 0;
  58. register int j = 1; /* for gardpnt */
  59. int phase, cnt = 0;
  60. float *inbuf = dz->sampbuf[0];
  61. float *cyclestore = dz->sampbuf[2];
  62. cyclestore[0] = 0; /* gardpnt for wrap_around in interpolating values */
  63. if((exit_status = read_samps(inbuf,dz))<0)
  64. return(exit_status);
  65. if((exit_status = get_initial_phase(&phase,dz))<0)
  66. return(exit_status);
  67. if((exit_status = skip_initial_cycles(&current_inbuf_pos,&current_buf,phase,DISTPCH_SKIPCNT,dz))<0)
  68. return(exit_status);
  69. do{
  70. while(current_inbuf_pos < dz->ssampsread) {
  71. switch(phase) {
  72. case(1):
  73. if(inbuf[current_inbuf_pos] >= 0) {
  74. cyclestore[j] = inbuf[current_inbuf_pos];
  75. if(++j >= dz->buflen) {
  76. sprintf(errstr,"Cycle too large for buffer at %lf\n",
  77. (double) dz->total_samps_read/(double)dz->infile->srate);
  78. return(GOAL_FAILED);
  79. }
  80. current_inbuf_pos++;
  81. } else {
  82. if(inbuf[current_inbuf_pos]<0) {
  83. phase=-1;
  84. cnt++;
  85. }
  86. }
  87. break;
  88. case(-1):
  89. if(inbuf[current_inbuf_pos] <= 0) {
  90. cyclestore[j] = inbuf[current_inbuf_pos];
  91. if(++j >= dz->buflen) {
  92. sprintf(errstr,"Cycle too large for buffer at %lf\n",
  93. (double)dz->total_samps_read/(double)dz->infile->srate);
  94. return(GOAL_FAILED);
  95. }
  96. current_inbuf_pos++;
  97. } else {
  98. if(inbuf[current_inbuf_pos]>0) {
  99. phase=1;
  100. cnt++;
  101. }
  102. }
  103. break;
  104. }
  105. if(cnt>=2) { /* i.e. once we have a complete wavecycle */
  106. if((exit_status = do_distrt
  107. (j-1,&pos_in_cycle_group,&last_transpos,&next_transpos,&transpos_step,&thiscyclelen,&init,&obufremain,current_inbuf_pos,dz))<0)
  108. return(exit_status); /* j-1 = length of cycle */
  109. cyclestore[0] = cyclestore[j-1];/* wrap_around gardpnt for interpolation of values */
  110. j = 1; /* leave space for grdpnt */
  111. cnt = 0;
  112. }
  113. }
  114. if((exit_status = read_samps(inbuf,dz))<0)
  115. return(exit_status);
  116. current_inbuf_pos = 0;
  117. } while(dz->ssampsread>0);
  118. if(dz->sbufptr[1]!=dz->sampbuf[1])
  119. return write_samps(dz->sampbuf[1],dz->sbufptr[1] - dz->sampbuf[1],dz);
  120. return(FINISHED);
  121. }
  122. /*********************** GET_DISTORT *************************/
  123. int get_distort
  124. (int oldlen,int *pos_in_cycle_group,double *last_transpos,double *next_transpos,
  125. double *transpos_step,int *thiscyclelen,int *init,dataptr dz)
  126. {
  127. int newlen;
  128. double randval;
  129. if(*init) {
  130. *thiscyclelen = round(drand48() * (double)dz->iparam[DISTPCH_CYCLECNT]) + 1;
  131. *next_transpos = ((drand48() * 2.0) - 1.0) * dz->param[DISTPCH_OCTVAR];
  132. *transpos_step = (*next_transpos - *last_transpos)/(double)(*thiscyclelen);
  133. *pos_in_cycle_group = 0;
  134. *init = 0;
  135. } else {
  136. if(++(*pos_in_cycle_group) < *thiscyclelen)
  137. *last_transpos += *transpos_step;
  138. else {
  139. *thiscyclelen = round(drand48() * (double)dz->iparam[DISTPCH_CYCLECNT]) + 1;
  140. *last_transpos = *next_transpos;
  141. *next_transpos = ((drand48() * 2.0) - 1.0) * dz->param[DISTPCH_OCTVAR];
  142. *transpos_step = (*next_transpos - *last_transpos)/(double)(*thiscyclelen);
  143. *pos_in_cycle_group = 0;
  144. }
  145. }
  146. randval = pow(2.0,*last_transpos);
  147. newlen = round((double)oldlen * randval);
  148. return(newlen);
  149. }
  150. /*********************** DO_DISTRT *************************/
  151. int do_distrt(int oldlen,int *pos_in_cycle_group,double *last_transpos,double *next_transpos,
  152. double *transpos_step,int *thiscyclelen,int *init,int *obufremain,int current_inbuf_pos, dataptr dz)
  153. {
  154. int exit_status;
  155. float *cyclestore = dz->sampbuf[2];
  156. float *warpedcycle_store = dz->sampbuf[3];
  157. int distortbuf_pos = 0, k, newlen;
  158. double step, here, ratio;
  159. float thisin, nextin;
  160. double thistime;
  161. if(*init) {
  162. if(dz->brksize[DISTPCH_OCTVAR] > 0) {
  163. if((exit_status = read_value_from_brktable(0.0,DISTPCH_OCTVAR,dz))<0)
  164. return exit_status;
  165. }
  166. if(dz->brksize[DISTPCH_CYCLECNT] > 0) {
  167. if((exit_status = read_value_from_brktable(0.0,DISTPCH_CYCLECNT,dz))<0)
  168. return exit_status;
  169. }
  170. }
  171. newlen = get_distort(oldlen,pos_in_cycle_group,last_transpos,next_transpos,transpos_step,thiscyclelen,init,dz);
  172. thistime = (double)(dz->total_samps_read - dz->ssampsread + current_inbuf_pos)/(double)dz->infile->srate;
  173. if(dz->brksize[DISTPCH_OCTVAR] > 0) {
  174. if((exit_status = read_value_from_brktable(thistime,DISTPCH_OCTVAR,dz))<0)
  175. return exit_status;
  176. }
  177. if(dz->brksize[DISTPCH_CYCLECNT] > 0) {
  178. if((exit_status = read_value_from_brktable(thistime,DISTPCH_CYCLECNT,dz))<0)
  179. return exit_status;
  180. }
  181. if(newlen <=0)
  182. newlen = 1;
  183. if(newlen == oldlen) {
  184. memmove((char *)warpedcycle_store,(char *)cyclestore,oldlen * sizeof(float));
  185. distortbuf_pos = newlen;
  186. } else {
  187. step = (double)oldlen/(double)newlen;
  188. here = step;
  189. while((k = (int)here)<oldlen) {
  190. thisin = cyclestore[k];
  191. nextin = cyclestore[k+1];
  192. ratio = here - (double)k;
  193. warpedcycle_store[distortbuf_pos++] = (float)(/*round*/((double)(nextin - thisin)*ratio) + thisin);
  194. if(distortbuf_pos >= dz->buflen) {
  195. if((exit_status = move_to_outbut(dz->buflen,obufremain,dz))<0)
  196. return(exit_status);
  197. distortbuf_pos = 0;
  198. }
  199. here += step;
  200. }
  201. }
  202. if(distortbuf_pos)
  203. return move_to_outbut(distortbuf_pos,obufremain,dz);
  204. return(FINISHED);
  205. }
  206. /*********************** MOVE_TO_OUTBUT *************************/
  207. int move_to_outbut(int n,int *obufremain,dataptr dz)
  208. {
  209. int exit_status;
  210. /* dz->sampbuf[1] = outbuf */
  211. float *warpedcycle_ptr = dz->sampbuf[3];
  212. while(n > *obufremain) {
  213. if(*obufremain) {
  214. memmove((char *)dz->sbufptr[1],(char *)warpedcycle_ptr,*obufremain * sizeof(float));
  215. warpedcycle_ptr += *obufremain;
  216. n -= *obufremain;
  217. }
  218. if((exit_status = write_samps(dz->sampbuf[1],dz->buflen,dz))<0)
  219. return(exit_status);
  220. dz->sbufptr[1] = dz->sampbuf[1];
  221. *obufremain = dz->buflen;
  222. }
  223. if(n) {
  224. memmove((char *)dz->sbufptr[1],(char *)warpedcycle_ptr,n * sizeof(float));
  225. dz->sbufptr[1] += n;
  226. *obufremain -= n;
  227. }
  228. return(FINISHED);
  229. }