distresize.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  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. #define FIRST_FILE (0)
  34. #define SECOND_FILE (1)
  35. static int get_initial_phases_for_resize(float *samplebuf0,int sampcnt0,float *samplebuf1,int sampcnt1,int *initial_phase);
  36. static int read_samps_cc(int k,int current_buf,int *bsamps_left,int *samps_read,int *in_samps,dataptr dz);
  37. static int get_cycles_and_resize(int *,int *,int *,int *,int *,int *,int *,int *,dataptr);
  38. static int switchbuf(float **b,int *current_buf,int *i,int *samps_left,int *samps_read,int *in_samps,dataptr dz);
  39. static int read_cycle_from_file0(int *,int *,int *,int *,int *,int *,int,dataptr);
  40. static int read_cycle_from_file1(int *,int *,int *,int *,int *,int *,int,dataptr);
  41. static int write_scaled_cycle_to_outbuf(int lastzero,int cyclelen0,int cyclelen1,int current_buf,int *obufpos,dataptr dz);
  42. /***************************** TWO_INFILES_RESIZE_PROCESS *****************************/
  43. int two_infiles_resize_process(dataptr dz)
  44. {
  45. int exit_status;
  46. int bsamps_left[2],samps_read[2],in_samps;
  47. int current_buf = 0, initial_phase[2];
  48. int bufpos_file0 = 0, bufpos_file1 = 0, obufpos = 0;
  49. bsamps_left[0] = dz->insams[0];
  50. bsamps_left[1] = dz->insams[1];
  51. if((exit_status = read_samps_cc(FIRST_FILE,current_buf,bsamps_left,samps_read,&in_samps,dz))<0
  52. || (exit_status = read_samps_cc(SECOND_FILE,current_buf,bsamps_left,samps_read,&in_samps,dz))<0)
  53. return(exit_status);
  54. if((exit_status = get_initial_phases_for_resize(dz->sampbuf[3],in_samps,dz->sampbuf[0],samps_read[0],initial_phase))<0)
  55. return(exit_status);
  56. do {
  57. exit_status = get_cycles_and_resize
  58. (&bufpos_file0,&bufpos_file1,&obufpos,initial_phase,&current_buf,bsamps_left,samps_read,&in_samps,dz);
  59. } while(exit_status==CONTINUE);
  60. if(obufpos > 0)
  61. return write_samps(dz->sampbuf[2],obufpos,dz);
  62. return FINISHED;
  63. }
  64. /**************************** READ_SAMPS_CC ****************************/
  65. int read_samps_cc(int k,int current_buf,int *bsamps_left,int *samps_read,int *in_samps,dataptr dz)
  66. {
  67. int sampsread;
  68. switch(k) {
  69. case(0):
  70. if((sampsread = fgetfbufEx(dz->sampbuf[3], dz->buflen,dz->ifd[0],0)) < 0) {
  71. sprintf(errstr, "Can't read from 1st input soundfile\n");
  72. return(SYSTEM_ERROR);
  73. }
  74. bsamps_left[0] -= sampsread;
  75. *in_samps = sampsread;
  76. break;
  77. case(1):
  78. if((sampsread = fgetfbufEx(dz->sampbuf[current_buf], dz->buflen,dz->ifd[1],0)) < 0) {
  79. sprintf(errstr, "Can't read from 2nd input soundfile\n");
  80. return(SYSTEM_ERROR);
  81. }
  82. bsamps_left[1] -= sampsread;
  83. samps_read[current_buf] = sampsread;
  84. break;
  85. default:
  86. sprintf(errstr,"Unknown case in read_samps_cc()\n");
  87. return(PROGRAM_ERROR);
  88. }
  89. return(FINISHED);
  90. }
  91. /*************************** GET_INITIAL_PHASES_FOR_RESIZE **********************/
  92. int get_initial_phases_for_resize(float *samplebuf0,int sampcnt0,float *samplebuf1,int sampcnt1,int *initial_phase)
  93. {
  94. int bufpos = 0;
  95. while(samplebuf0[bufpos]==0.0 && bufpos < sampcnt0)
  96. bufpos++;
  97. if(bufpos >= sampcnt0) {
  98. sprintf(errstr,"No siginificant data in first buffer of file 1\n");
  99. return(DATA_ERROR);
  100. }
  101. if(samplebuf0[bufpos] > 0.0)
  102. initial_phase[0] = 1;
  103. else
  104. initial_phase[0] = -1;
  105. bufpos = 0;
  106. //TW
  107. // while(samplebuf1[bufpos]==0 && bufpos < sampcnt1)
  108. while(smpflteq(samplebuf1[bufpos],0.0) && bufpos < sampcnt1)
  109. bufpos++;
  110. if(bufpos >= sampcnt1) {
  111. sprintf(errstr,"No siginificant data in first buffer of file 2\n");
  112. return(DATA_ERROR);
  113. }
  114. if(samplebuf1[bufpos] > 0.0)
  115. initial_phase[1] = 1;
  116. else
  117. initial_phase[1] = -1;
  118. return(FINISHED);
  119. }
  120. /********************************** GET_CYCLES_AND_RESIZE *******************************/
  121. int get_cycles_and_resize(int *bufpos_file0,int *bufpos_file1,int *obufpos,
  122. int *initial_phase,int *current_buf,int *bsamps_left,int *samps_read,int *in_samps,dataptr dz)
  123. {
  124. int exit_status;
  125. int cyclelen[2] = {0,0};
  126. int lastzero = *bufpos_file1;
  127. if((exit_status = read_cycle_from_file0
  128. (bufpos_file0,&(cyclelen[0]),in_samps,bsamps_left,samps_read,current_buf,initial_phase[0],dz))!=CONTINUE)
  129. return(exit_status);
  130. if((exit_status = read_cycle_from_file1
  131. (bufpos_file1,&(cyclelen[1]),in_samps,bsamps_left,samps_read,current_buf,initial_phase[1],dz))!=CONTINUE)
  132. return(exit_status);
  133. return write_scaled_cycle_to_outbuf(lastzero,cyclelen[0],cyclelen[1],*current_buf,obufpos,dz);
  134. }
  135. /**************************** SWITCHBUF *****************************
  136. *
  137. * Switch to other input buffer for 2nd infile.
  138. */
  139. int switchbuf(float **b,int *current_buf,int *i,int *bsamps_left,int *samps_read,int *in_samps,dataptr dz)
  140. {
  141. int exit_status;
  142. if(bsamps_left[1]<=0)
  143. return(FINISHED);
  144. *current_buf = !(*current_buf);
  145. *b = dz->sampbuf[*current_buf];
  146. if((exit_status = read_samps_cc(SECOND_FILE,*current_buf,bsamps_left,samps_read,in_samps,dz))<0)
  147. return(exit_status);
  148. *i = 0;
  149. return(CONTINUE);
  150. }
  151. /**************************** READ_CYCLE_FROM_FILE0 *****************************/
  152. int read_cycle_from_file0
  153. (int *bufpos_file0,int *cyclelen0,int *in_samps,int *bsamps_left,int *samps_read,
  154. int *current_buf,int initial_phase, dataptr dz)
  155. {
  156. int exit_status;
  157. int i = *bufpos_file0;
  158. int cyclen = *cyclelen0;
  159. float *b = dz->sampbuf[3];
  160. switch(initial_phase) {
  161. case(1):
  162. while(b[i]>=0.0) {
  163. cyclen++;
  164. if(++i >= *in_samps) {
  165. if(bsamps_left[0]<=0)
  166. return(FINISHED);
  167. if((exit_status = read_samps_cc(FIRST_FILE,*current_buf,bsamps_left,samps_read,in_samps,dz))<0)
  168. return(exit_status);
  169. i = 0;
  170. }
  171. }
  172. while(b[i]<=0.0) {
  173. cyclen++;
  174. if(++i >= *in_samps) {
  175. if(bsamps_left[0]<=0)
  176. return(FINISHED);
  177. if((exit_status = read_samps_cc(FIRST_FILE,*current_buf,bsamps_left,samps_read,in_samps,dz))<0)
  178. return(exit_status);
  179. i = 0;
  180. }
  181. }
  182. break;
  183. case(-1):
  184. while(b[i]<=0.0) {
  185. cyclen++;
  186. if(++i >= *in_samps) {
  187. if(bsamps_left[0]<=0)
  188. return(FINISHED);
  189. if((exit_status = read_samps_cc(FIRST_FILE,*current_buf,bsamps_left,samps_read,in_samps,dz))<0)
  190. return(exit_status);
  191. i = 0;
  192. }
  193. }
  194. while(b[i]>=0.0) {
  195. cyclen++;
  196. if(++i >= *in_samps) {
  197. if(bsamps_left[0]<=0)
  198. return(FINISHED);
  199. if((exit_status = read_samps_cc(FIRST_FILE,*current_buf,bsamps_left,samps_read,in_samps,dz))<0)
  200. return(exit_status);
  201. i = 0;
  202. }
  203. }
  204. break;
  205. }
  206. *bufpos_file0 = i;
  207. *cyclelen0 = cyclen;
  208. return(CONTINUE);
  209. }
  210. /**************************** READ_CYCLE_FROM_FILE1 *****************************/
  211. int read_cycle_from_file1
  212. (int *bufpos_file1,int *cyclelen1,int *in_samps,int *bsamps_left,int *samps_read,
  213. int *current_buf,int initial_phase,dataptr dz)
  214. {
  215. int exit_status;
  216. int i = *bufpos_file1;
  217. float *b = dz->sampbuf[*current_buf];
  218. int cyclen = *cyclelen1;
  219. switch(initial_phase) {
  220. case(1):
  221. while(b[i]>=0.0) {
  222. cyclen++;
  223. if(++i >= samps_read[*current_buf]) {
  224. if((exit_status = switchbuf(&b,current_buf,&i,bsamps_left,samps_read,in_samps,dz))!=CONTINUE)
  225. return(exit_status);
  226. }
  227. }
  228. while(b[i]<=0.0) {
  229. cyclen++;
  230. if(++i >= samps_read[*current_buf]) {
  231. if((exit_status = switchbuf(&b,current_buf,&i,bsamps_left,samps_read,in_samps,dz))!=CONTINUE)
  232. return(exit_status);
  233. }
  234. }
  235. break;
  236. case(-1):
  237. while(b[i]<=0.0) {
  238. cyclen++;
  239. if(++i >= samps_read[*current_buf]) {
  240. if((exit_status = switchbuf(&b,current_buf,&i,bsamps_left,samps_read,in_samps,dz))!=CONTINUE)
  241. return(exit_status);
  242. }
  243. }
  244. while(b[i]>=0.0) {
  245. cyclen++;
  246. if(++i >= samps_read[*current_buf]) {
  247. if((exit_status = switchbuf(&b,current_buf,&i,bsamps_left,samps_read,in_samps,dz))!=CONTINUE)
  248. return(exit_status);
  249. }
  250. }
  251. break;
  252. }
  253. *bufpos_file1 = i;
  254. *cyclelen1 = cyclen;
  255. return(CONTINUE);
  256. }
  257. /**************************** WRITE_SCALED_CYCLE_TO_OUTBUF *****************************/
  258. int write_scaled_cycle_to_outbuf(int lastzero,int cyclelen0,int cyclelen1,int current_buf,int *obufpos,dataptr dz)
  259. {
  260. int exit_status;
  261. float *b;
  262. int j = *obufpos;
  263. int in_previous_buf = FALSE;
  264. int sampcnt, index;
  265. double scaler = (double)cyclelen1/(double)cyclelen0;
  266. if(lastzero + cyclelen1 >= dz->buflen) {
  267. b = dz->sampbuf[!current_buf];
  268. in_previous_buf = TRUE;
  269. for(sampcnt=0;sampcnt<cyclelen0;sampcnt++) {
  270. index = round((double)sampcnt * scaler);
  271. index += lastzero;
  272. if(in_previous_buf) {
  273. if(index >= dz->buflen) {
  274. index -= dz->buflen;
  275. b = dz->sampbuf[current_buf];
  276. in_previous_buf = FALSE;
  277. }
  278. } else
  279. index -= dz->buflen;
  280. dz->sampbuf[2][j] = b[index];
  281. if(++j >= dz->buflen) {
  282. if((exit_status = write_samps(dz->sampbuf[2],dz->buflen,dz))<0) {
  283. sprintf(errstr,"write_samps failed in write_scaled_cycle_to_outbuf()\n");
  284. return(exit_status);
  285. }
  286. j = 0;
  287. }
  288. }
  289. } else {
  290. b = dz->sampbuf[current_buf];
  291. for(sampcnt=0;sampcnt<cyclelen0;sampcnt++) {
  292. index = round((double)sampcnt * scaler);
  293. dz->sampbuf[2][j] = b[index + lastzero];
  294. if(++j >= dz->buflen) {
  295. if((exit_status = write_samps(dz->sampbuf[2],dz->buflen,dz))<0) {
  296. sprintf(errstr,"write_samps failed in write_scaled_cycle_to_outbuf()\n");
  297. return(exit_status);
  298. }
  299. j = 0;
  300. }
  301. }
  302. }
  303. *obufpos = j;
  304. return(CONTINUE);
  305. }