disttel.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  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_tele(int n,int current_buf,int *obufpos,dataptr dz);
  34. static int do_cycle_tele_crosbuf(int n,int cycleno_in_group_at_bufcros,int current_buf,int *obufpos,dataptr dz);
  35. static int get_longcycle(int,dataptr);
  36. static int get_meancycle(int,dataptr);
  37. static float indexed_value(float *b,int k,double ratio,dataptr dz);
  38. static float indexed_value_at_crosbuf(float *b,int k,double ratio,int current_buf,dataptr dz);
  39. /******************************* DISTORT_TEL ******************************/
  40. int distort_tel(int *current_buf,int initial_phase,int *obufpos,int *current_pos_in_buf,int *cnt,dataptr dz)
  41. {
  42. int exit_status;
  43. register int i = *current_pos_in_buf;
  44. int n = 0;
  45. int cycleno_in_group_at_bufcros = -1;
  46. float *b = dz->sampbuf[*current_buf];
  47. switch(initial_phase) { /* 4 */
  48. case(1):
  49. for(n=0;n<dz->iparam[DISTTEL_CYCLECNT];n++) { /* 5 */
  50. dz->lparray[DISTTEL_CYCLEVAL][n] = 0; /* 6 */
  51. dz->lparray[DISTTEL_STARTCYC][n] = i; /* 7 */
  52. while(b[i]>=0.0) { /* 8 */
  53. /* RWD NB this is counting samples */
  54. dz->lparray[DISTTEL_CYCLEVAL][n]++;
  55. if(++i >= dz->ssampsread) { /* 10 */
  56. if((exit_status = change_buff(&b,&cycleno_in_group_at_bufcros,current_buf,dz))!=CONTINUE)
  57. return(exit_status);
  58. cycleno_in_group_at_bufcros = n;
  59. i = 0;
  60. }
  61. }
  62. while(b[i]<=0.0) { /* 18a */
  63. dz->lparray[DISTTEL_CYCLEVAL][n]++;
  64. if(++i >= dz->ssampsread) {
  65. if((exit_status = change_buff(&b,&cycleno_in_group_at_bufcros,current_buf,dz))!=CONTINUE)
  66. return(exit_status);
  67. cycleno_in_group_at_bufcros = n;
  68. i = 0;
  69. }
  70. }
  71. }
  72. break;
  73. case(-1): /* 18b */
  74. for(n=0;n<dz->iparam[DISTTEL_CYCLECNT];n++) {
  75. dz->lparray[DISTTEL_CYCLEVAL][n] = 0;
  76. dz->lparray[DISTTEL_STARTCYC][n] = i;
  77. while(b[i]<=0.0) {
  78. dz->lparray[DISTTEL_CYCLEVAL][n]++;
  79. if(++i >= dz->ssampsread) {
  80. if((exit_status = change_buff(&b,&cycleno_in_group_at_bufcros,current_buf,dz))!=CONTINUE)
  81. return(exit_status);
  82. cycleno_in_group_at_bufcros = n;
  83. i = 0;
  84. }
  85. }
  86. while(b[i]>=0.0) {
  87. dz->lparray[DISTTEL_CYCLEVAL][n]++;
  88. if(++i >= dz->ssampsread) {
  89. if((exit_status = change_buff(&b,&cycleno_in_group_at_bufcros,current_buf,dz))!=CONTINUE)
  90. return(exit_status);
  91. cycleno_in_group_at_bufcros = n;
  92. i = 0;
  93. }
  94. }
  95. }
  96. break;
  97. }
  98. if(n) {
  99. if(cycleno_in_group_at_bufcros >= 0) {
  100. exit_status = do_cycle_tele_crosbuf(n,cycleno_in_group_at_bufcros,*current_buf,obufpos,dz);
  101. } else {
  102. exit_status = do_cycle_tele(n,*current_buf,obufpos,dz);
  103. }
  104. if(exit_status<0)
  105. return(exit_status);
  106. }
  107. *current_pos_in_buf = i;
  108. (*cnt)++;
  109. return(CONTINUE);
  110. }
  111. /*************************** DO_CYCLE_TELE *************************/
  112. int do_cycle_tele(int n,int current_buf,int *obufpos,dataptr dz)
  113. {
  114. int exit_status;
  115. float *b = dz->sampbuf[current_buf];
  116. double ratio;
  117. int k, j, reflength/*, cyclesum*/;
  118. float cyclesum;
  119. /*int*/float average_value;
  120. if(dz->vflag[IS_DISTTEL_AVG])
  121. reflength = get_meancycle(n,dz);
  122. else
  123. reflength = get_longcycle(n,dz);
  124. for(j = 0;j < reflength; j++) {
  125. ratio = (double)j/(double)reflength;
  126. cyclesum = 0.0;
  127. k = 0;
  128. while(k<n)
  129. cyclesum += indexed_value(b,k++,ratio,dz);
  130. average_value = (float) /*round*/ ((double)cyclesum/(double)n);
  131. if((exit_status = output_val(average_value,obufpos,dz))<0)
  132. return(exit_status);
  133. }
  134. return(FINISHED);
  135. }
  136. /*************************** DO_CYCLE_TELE_CROSBUF *************************/
  137. int do_cycle_tele_crosbuf(int n,int cycleno_in_group_at_bufcros,int current_buf,int *obufpos,dataptr dz)
  138. {
  139. int exit_status;
  140. float *b;
  141. double ratio;
  142. int k, j, reflength /*, cyclesum*/;
  143. float cyclesum;
  144. /*int*/float average_value;
  145. if(dz->vflag[IS_DISTTEL_AVG])
  146. reflength = get_meancycle(n,dz);
  147. else
  148. reflength = get_longcycle(n,dz);
  149. for(j = 0;j < reflength; j++) {
  150. ratio = (double)j/(double)reflength;
  151. cyclesum = 0.0;
  152. k = 0;
  153. b = dz->sampbuf[!current_buf];
  154. while(k < cycleno_in_group_at_bufcros)
  155. cyclesum += indexed_value(b,k++,ratio,dz);
  156. cyclesum += indexed_value_at_crosbuf(b,k++,ratio,current_buf,dz);
  157. b = dz->sampbuf[current_buf];
  158. while(k<n)
  159. cyclesum += indexed_value(b,k++,ratio,dz);
  160. average_value = (float) /*round*/((double)cyclesum/(double)n);
  161. if((exit_status = output_val(average_value,obufpos,dz))<0)
  162. return(exit_status);
  163. }
  164. return(FINISHED);
  165. }
  166. /***************************** INDEXED_VALUE ***********************/
  167. float indexed_value(float *b,int k,double ratio,dataptr dz)
  168. {
  169. int index = round((double)(dz->lparray[DISTTEL_CYCLEVAL][k])*ratio);
  170. index += dz->lparray[DISTTEL_STARTCYC][k];
  171. return b[index];
  172. }
  173. /*********************** INDEXED_VALUE_AT_CROSBUF ***********************/
  174. float indexed_value_at_crosbuf(float *b,int k,double ratio,int current_buf,dataptr dz)
  175. {
  176. int index = round((double)(dz->lparray[DISTTEL_CYCLEVAL][k])*ratio);
  177. index += dz->lparray[DISTTEL_STARTCYC][k];
  178. if(index >= dz->buflen) {
  179. index -= dz->buflen;
  180. b = dz->sampbuf[current_buf];
  181. }
  182. return b[index];
  183. }
  184. /************************ GET_LONGCYCLE *******************************
  185. *
  186. * Find longest cycle.
  187. */
  188. int get_longcycle(int k,dataptr dz)
  189. {
  190. int longest = 0;
  191. int n;
  192. for(n=0;n<k;n++) {
  193. if(dz->lparray[DISTTEL_CYCLEVAL][n] > longest)
  194. longest = dz->lparray[DISTTEL_CYCLEVAL][n];
  195. }
  196. return(longest);
  197. }
  198. /************************ GET_MEANCYCLE *******************************
  199. *
  200. * Find average cycle length.
  201. */
  202. int get_meancycle(int k,dataptr dz)
  203. {
  204. int sum = 0, mean;
  205. int n;
  206. for(n=0;n<k;n++)
  207. sum += dz->lparray[DISTTEL_CYCLEVAL][n];
  208. mean = round((double)sum/(double)k);
  209. return(mean);
  210. }
  211. /************************* OUTPUT_VAL **********************/
  212. int output_val(float value,int *obufpos,dataptr dz)
  213. {
  214. int exit_status;
  215. dz->sampbuf[2][(*obufpos)++] = value;
  216. if(*obufpos>=dz->buflen) {
  217. if((exit_status = write_samps(dz->sampbuf[2],dz->buflen,dz))<0)
  218. return(exit_status);
  219. *obufpos = 0;
  220. }
  221. return(FINISHED);
  222. }