distintlv.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  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 read_samps_bb(int k,int *bsamps_left,int *sampsread,dataptr dz);
  35. static int get_initial_phases(float **sampbuf,int *samps_read,int *initial_phase,int *rephase);
  36. static int get_cycle(int *p,int *q,int n,int *initial_phase,int rephase,int *bsamps_left,int *samps_read,dataptr dz);
  37. static int write_inverted_block(float *b,int obuf_endwrite,int *obufpos,int *last_read_marker,dataptr dz);
  38. static int write_this_block(float *b,int samps_to_copy,int obuf_endwrite,int *obufpos,int *last_read_marker,dataptr dz);
  39. /***************************** TWO_INFILES_PROCESS *****************************/
  40. int two_infiles_interleave_process(dataptr dz)
  41. {
  42. int exit_status;
  43. int bsamps_left[2], samps_read[2];
  44. int initial_phase[2];
  45. int rephase = FALSE;
  46. int i1 = 0, i2 = 0, j = 0;
  47. bsamps_left[0] = dz->insams[0];
  48. bsamps_left[1] = dz->insams[1];
  49. if((exit_status = read_samps_bb(0,bsamps_left,samps_read,dz))<0
  50. || (exit_status = read_samps_bb(1,bsamps_left,samps_read,dz))<0)
  51. return(exit_status);
  52. if((exit_status = get_initial_phases(dz->sampbuf,samps_read,initial_phase,&rephase))<0)
  53. return(exit_status);
  54. switch(dz->mode) {
  55. case(DISTINT_INTRLV):
  56. do {
  57. if((exit_status = get_cycle(&i1,&j,0,initial_phase,rephase,bsamps_left,samps_read,dz))!=CONTINUE)
  58. break;
  59. exit_status = get_cycle(&i2,&j,1,initial_phase,rephase,bsamps_left,samps_read,dz);
  60. } while(exit_status==CONTINUE);
  61. break;
  62. default:
  63. sprintf(errstr,"Unknown case in two_infiles_interleave_process()\n");
  64. return(PROGRAM_ERROR);
  65. }
  66. if(exit_status<0)
  67. return(exit_status);
  68. if(j > 0)
  69. return write_samps(dz->sampbuf[2],j,dz);
  70. return FINISHED;
  71. }
  72. /**************************** READ_SAMPS_BB ****************************/
  73. int read_samps_bb(int k,int *bsamps_left,int *samps_read,dataptr dz)
  74. {
  75. int /*bytes_read*/sampsread;
  76. if(( sampsread = fgetfbufEx(dz->sampbuf[k], dz->buflen,dz->ifd[k],0)) < 0) {
  77. sprintf(errstr, "Can't read from input soundfile %d\n",k+1);
  78. return(SYSTEM_ERROR);
  79. }
  80. bsamps_left[k] -= sampsread;
  81. if(sloom)
  82. dz->total_samps_read = (bsamps_left[0] + bsamps_left[1]) >> 1;
  83. samps_read[k] = sampsread;
  84. return(FINISHED);
  85. }
  86. /********************************** GET_CYCLE ******************************/
  87. int get_cycle(int *p,int *q,int n,int *initial_phase,int rephase,int *bsamps_left,int *samps_read,dataptr dz)
  88. {
  89. int exit_status;
  90. int startphase = initial_phase[n];
  91. float *b = dz->sampbuf[n];
  92. int samples = samps_read[n];
  93. int samps_to_copy, obuf_endwrite;
  94. register int ibufpos = *p;
  95. int obufpos = *q;
  96. int last_read_marker = ibufpos;
  97. int in_1st_half_of_cycle = TRUE, OK = TRUE;
  98. switch(startphase) {
  99. case(1):
  100. while(b[ibufpos]>=0) {
  101. if(++ibufpos >= samples) {
  102. OK = FALSE;
  103. break;
  104. }
  105. }
  106. if(!OK)
  107. break;
  108. in_1st_half_of_cycle = FALSE;
  109. while(b[ibufpos]<=0) {
  110. if(++ibufpos >= samples)
  111. break;
  112. }
  113. break;
  114. case(-1):
  115. while(b[ibufpos]<=0) {
  116. if(++ibufpos >= samples) {
  117. OK = FALSE;
  118. break;
  119. }
  120. }
  121. if(!OK)
  122. break;
  123. in_1st_half_of_cycle = FALSE;
  124. while(b[ibufpos]>=0) {
  125. if(++ibufpos >= samples)
  126. break;
  127. }
  128. break;
  129. }
  130. samps_to_copy = ibufpos - last_read_marker; /* may be only PART of cycle, if end of input buf was encountered */
  131. obuf_endwrite = obufpos + samps_to_copy;
  132. if(n==1 && rephase) /* if this is 2nd snd, and phase is different from 1st snd, invert all vals */
  133. exit_status = write_inverted_block(b,obuf_endwrite,&obufpos,&last_read_marker,dz);
  134. else
  135. exit_status = write_this_block(b,samps_to_copy,obuf_endwrite,&obufpos,&last_read_marker,dz);
  136. if(exit_status < 0)
  137. return(exit_status);
  138. if(ibufpos>=samples) { /* if we reached input buffer end */
  139. if(bsamps_left[n] <= 0) { /* if we reached file end */
  140. *q = obufpos;
  141. return(FINISHED);
  142. } /* else, deal with part-cycle in next buffer */
  143. read_samps_bb(n,bsamps_left,samps_read,dz);
  144. last_read_marker = 0;
  145. ibufpos = 0;
  146. switch(startphase) {
  147. case(1):
  148. if(in_1st_half_of_cycle) {
  149. while(b[ibufpos]>=0) {
  150. if(++ibufpos >= dz->buflen) {
  151. sprintf(errstr,"Cyclelen exceeeds buffer_size: cannot proceed\n");
  152. return(GOAL_FAILED);
  153. }
  154. }
  155. }
  156. while(b[ibufpos]<=0) {
  157. if(++ibufpos >= dz->buflen) {
  158. sprintf(errstr,"Cyclelen exceeeds buffer_size: cannot proceed\n");
  159. return(GOAL_FAILED);
  160. }
  161. }
  162. break;
  163. case(-1):
  164. if(in_1st_half_of_cycle) {
  165. while(b[ibufpos]<=0) {
  166. if(++ibufpos >= dz->buflen) {
  167. sprintf(errstr,"Cyclelen exceeeds buffer_size: cannot proceed\n");
  168. return(GOAL_FAILED);
  169. }
  170. }
  171. }
  172. while(b[ibufpos]>=0) {
  173. if(++ibufpos >= dz->buflen) {
  174. sprintf(errstr,"Cyclelen exceeeds buffer_size: cannot proceed\n");
  175. return(GOAL_FAILED);
  176. }
  177. }
  178. break;
  179. }
  180. samps_to_copy = ibufpos;
  181. obuf_endwrite = obufpos + samps_to_copy;
  182. if(n==1 && rephase)
  183. exit_status = write_inverted_block(b,obuf_endwrite,&obufpos,&last_read_marker,dz);
  184. else
  185. exit_status = write_this_block(b,samps_to_copy,obuf_endwrite,&obufpos,&last_read_marker,dz);
  186. if(exit_status < 0)
  187. return(exit_status);
  188. }
  189. *p = ibufpos;
  190. *q = obufpos;
  191. return(CONTINUE);
  192. }
  193. /*************************** GET_INITIAL_PHASES **********************/
  194. int get_initial_phases(float **sampbuf,int *samps_read,int *initial_phase,int *rephase)
  195. {
  196. int bufpos = 0;
  197. //TW CHANGED
  198. while(smpflteq(sampbuf[0][bufpos],0.0) && bufpos < samps_read[0])
  199. bufpos++;
  200. if(bufpos >= samps_read[0]) {
  201. sprintf(errstr,"No siginificant data in first buffer of file 1\n");
  202. return(DATA_ERROR);
  203. }
  204. if(sampbuf[0][bufpos] > 0)
  205. initial_phase[0] = 1;
  206. else
  207. initial_phase[0] = -1;
  208. bufpos = 0;
  209. //TW CHANGED
  210. while(smpflteq(sampbuf[1][bufpos],0.0) && bufpos < samps_read[1])
  211. bufpos++;
  212. if(bufpos >= samps_read[1]) {
  213. sprintf(errstr,"No siginificant data in first buffer of file 2\n");
  214. return(DATA_ERROR);
  215. }
  216. if(sampbuf[1][bufpos] > 0)
  217. initial_phase[1] = 1;
  218. else
  219. initial_phase[1] = -1;
  220. if(initial_phase[0] != initial_phase[1])
  221. *rephase = TRUE;
  222. return(FINISHED);
  223. }
  224. /*************************** WRITE_INVERTED_CYCLE **********************/
  225. int write_inverted_block(float *b,int obuf_endwrite,int *obufpos,int *last_read_marker,dataptr dz)
  226. {
  227. int exit_status;
  228. int outremain = obuf_endwrite - dz->buflen;
  229. register int i = *obufpos;
  230. register int j = *last_read_marker;
  231. if(outremain>0) {
  232. while(i<dz->buflen)
  233. dz->sampbuf[2][i++] = (float) -b[j++]; /*RWD added cast, also below */
  234. if((exit_status = write_samps(dz->sampbuf[2],dz->buflen,dz))<0) {
  235. sprintf(errstr,"Failed to write samps in write_inverted_block()\n");
  236. return(SYSTEM_ERROR);
  237. }
  238. i = 0;
  239. while(i<outremain)
  240. dz->sampbuf[2][i++] = (float) -b[j++];
  241. } else {
  242. while(i<obuf_endwrite)
  243. dz->sampbuf[2][i++] = (float) -b[j++];
  244. }
  245. *obufpos = i;
  246. *last_read_marker = j;
  247. return(FINISHED);
  248. }
  249. /*************************** WRITE_THIS_CYCLE **********************/
  250. int write_this_block(float *b,int samps_to_copy,int obuf_endwrite,int *obufpos,int *last_read_marker,dataptr dz)
  251. {
  252. int exit_status;
  253. int outremain = obuf_endwrite - dz->buflen;
  254. int part_writelen;
  255. if(outremain > 0) {
  256. part_writelen = dz->buflen - *obufpos;
  257. memmove((char *)(dz->sampbuf[2] + *obufpos),(char *)(b + *last_read_marker),part_writelen * sizeof(float));
  258. if((exit_status = write_samps(dz->sampbuf[2],dz->buflen ,dz))<0) {
  259. sprintf(errstr,"Failed to write samps in write_this_block()\n");
  260. return(SYSTEM_ERROR);
  261. }
  262. *last_read_marker += part_writelen;
  263. samps_to_copy -= part_writelen;
  264. memmove((char *)(dz->sampbuf[2]),(char *)(b + *last_read_marker),samps_to_copy * sizeof(float));
  265. *obufpos = outremain;
  266. *last_read_marker += samps_to_copy;
  267. } else {
  268. memmove((char *)(dz->sampbuf[2] + *obufpos),(char *)(b + *last_read_marker),samps_to_copy * sizeof(float));
  269. *obufpos = obuf_endwrite;
  270. *last_read_marker += samps_to_copy;
  271. }
  272. return FINISHED; /*RWD*/
  273. }