mixmerge.c 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043
  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 <processno.h>
  29. #include <modeno.h>
  30. #include <filetype.h>
  31. #include <arrays.h>
  32. #include <mix.h>
  33. #include <cdpmain.h>
  34. #include <sfsys.h>
  35. #include <mix.h>
  36. #include <limits.h>
  37. #ifdef unix
  38. #define round(x) lround((x))
  39. #endif
  40. static int do_mix2(float *inbuf1,float *inbuf2,double *dblbuf,float *obuf,dataptr dz);
  41. static int do_mix2_stagger(float *inbuf1,float *obuf,dataptr dz);
  42. static int do_mix2_skip(dataptr dz);
  43. static int cross_stagger(int *total_samps_read,int *end_of_samps_to_process,float *obuf,dataptr dz);
  44. static int pre_crossmix(int *samps_read2,int *cross_end,int *total_samps_read,
  45. int *end_of_samps_to_process,float *inbuf1,float *inbuf2,float *obuf,dataptr dz);
  46. static int crossmix(int *samps_read2,int *cross_end,int *total_samps_read,int *end_of_samps_to_process,
  47. float *inbuf1,float *inbuf2,float *obuf,dataptr dz);
  48. static int cross(int startcross,int endcross,float *inbuf1,float *inbuf2,float *obuf,dataptr dz);
  49. static double read_cos(double d,dataptr dz);
  50. static int advance_in_files(int *samps_read2,int *total_samps_read,int *end_of_samps_to_process,
  51. int *cross_end,float *inbuf1,float *inbuf2,dataptr dz);
  52. static void copy_to_channel(float *inbuf,float *obuf,int sampcnt,int outchans);
  53. static int renew_bufs(int typ,float *buf0,float *buf1,dataptr dz);
  54. static int do_stitch(int typ,int *mbf,int *sbf,float *buf0,float *buf1,double atten,int bflen,dataptr dz);
  55. static int flush_bufs(int typ,int *mbf,int *sbf,float *buf0,float *buf1,dataptr dz);
  56. //TW JAN 2010: FOR MULTICHANNEL
  57. //static int read_automix_sound(int *activebuf,int *chans,int chantype,dataptr dz);
  58. static int read_automix_sound(int *activebuf,dataptr dz);
  59. /************************************ MIXTWO ************************************/
  60. int mixtwo(dataptr dz)
  61. {
  62. int exit_status;
  63. char tempfnam[200];
  64. double *dblbuf = (double *) dz->sampbuf[3]; /* RWD I suppose we can keep this...*/
  65. float *inbuf1 = dz->sampbuf[0];
  66. float *inbuf2 = dz->sampbuf[1];
  67. float *obuf = dz->sampbuf[2];
  68. int extra_skip;
  69. if(dz->iparam[MIX_STTA] > 0) {
  70. if((sndseekEx(dz->ifd[0],dz->iparam[MIX_STTA],0))<0) {
  71. sprintf(errstr,"sndseek() failed in first file.\n");
  72. return(SYSTEM_ERROR);
  73. }
  74. }
  75. if((extra_skip = dz->iparam[MIX_STTA] - dz->iparam[MIX_STAGGER]) > 0) {
  76. if((dz->iparam[MIX_SKIP] += extra_skip) > dz->insams[1]) {
  77. sprintf(errstr,"Mix skips the 2nd file entirely.\n");
  78. return(DATA_ERROR);
  79. }
  80. }
  81. if(dz->iparam[MIX_SKIP] > 0) {
  82. if((exit_status = do_mix2_skip(dz))<0)
  83. return(exit_status);
  84. }
  85. if((dz->iparam[MIX_STAGGER] -= dz->iparam[MIX_STTA]) > 0) {
  86. if((exit_status = do_mix2_stagger(inbuf1,obuf,dz))<0)
  87. return(exit_status);
  88. } else {
  89. dz->iparam[MIX_STAGGER] = 0;
  90. }
  91. if((exit_status = do_mix2(inbuf1,inbuf2,dblbuf,obuf,dz))<0)
  92. return(exit_status);
  93. if(is_converted_to_stereo >= 0) {
  94. strcpy(tempfnam,snd_getfilename(dz->ifd[is_converted_to_stereo]));
  95. sndcloseEx(dz->ifd[is_converted_to_stereo]);
  96. if(remove(tempfnam)<0)
  97. fprintf(stdout, "ERROR: %s: Can't remove temporary stereo soundfile %s.\n",sferrstr(),tempfnam);
  98. dz->ifd[is_converted_to_stereo] = -1;
  99. }
  100. return(FINISHED);
  101. }
  102. /************************************ DO_MIX2_SKIP ************************************/
  103. int do_mix2_skip(dataptr dz)
  104. {
  105. if((sndseekEx(dz->ifd[1],dz->iparam[MIX_SKIP],0))<0) {
  106. sprintf(errstr,"sndseek() failed: do_mix2_skip()\n");
  107. return(SYSTEM_ERROR);
  108. }
  109. return(FINISHED);
  110. }
  111. /************************************ DO_MIX2_STAGGER ************************************/
  112. int do_mix2_stagger(float *inbuf1,float *obuf,dataptr dz)
  113. {
  114. int exit_status;
  115. int stagbufs,stagsamps, n;
  116. //TW
  117. int shsecsize = F_SECSIZE; /* RWD I suppose we can keep this...*/
  118. int samps_read;
  119. stagbufs = dz->iparam[MIX_STAGGER]/dz->buflen;
  120. stagsamps = dz->iparam[MIX_STAGGER] % dz->buflen;
  121. /*RWD do we still need this test? Is it still kosher ? */
  122. if(((stagsamps/shsecsize)*shsecsize) != stagsamps) {
  123. sprintf(errstr,"Error in sector arithmetic: do_mix2_stagger()\n");
  124. return(PROGRAM_ERROR);
  125. }
  126. while(stagbufs > 0) {
  127. if((samps_read = fgetfbufEx(inbuf1,dz->buflen,dz->ifd[0],0)) < dz->buflen) {
  128. if(samps_read < 0) {
  129. sprintf(errstr,"Sound read error.\n");
  130. return(SYSTEM_ERROR);
  131. } else {
  132. sprintf(errstr,"Problem 1 reading from file1 during stagger\n");
  133. return(PROGRAM_ERROR);
  134. }
  135. }
  136. for(n=0;n<dz->buflen;n++)
  137. obuf[n] = (float)(inbuf1[n] * dz->param[MIX2_GAIN1]);
  138. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  139. return(exit_status);
  140. stagbufs--;
  141. }
  142. if(stagsamps) {
  143. if((samps_read = fgetfbufEx(inbuf1,stagsamps,dz->ifd[0],0)) < stagsamps) {
  144. if(samps_read < 0) {
  145. sprintf(errstr,"Sound read error.\n");
  146. return(SYSTEM_ERROR);
  147. } else {
  148. sprintf(errstr,"Problem 2 reading from file1 during stagger\n");
  149. return(PROGRAM_ERROR);
  150. }
  151. }
  152. for(n=0;n<stagsamps;n++)
  153. obuf[n] = (float)(inbuf1[n] * dz->param[MIX2_GAIN1]);
  154. if((exit_status = write_samps(obuf,stagsamps,dz))<0)
  155. return(exit_status);
  156. }
  157. return(FINISHED);
  158. }
  159. /************************************ DO_MIX2 ************************************/
  160. int do_mix2(float *inbuf1,float *inbuf2,double *dblbuf,float *obuf,dataptr dz)
  161. {
  162. int exit_status;
  163. int gross_samps_read = 1, gross_total_samps_read = 0, cutoff_in_buf;
  164. int samps_read1, samps_read2, ssampsread, ssampsread1, ssampsread2, n;
  165. unsigned int cutoff_samps;
  166. cutoff_samps = (dz->iparam[MIX_DURA] - dz->iparam[MIX_STTA]) - dz->iparam[MIX_STAGGER];
  167. if((cutoff_samps) <= 0)
  168. cutoff_samps = UINT_MAX;
  169. while(gross_samps_read > 0) {
  170. memset((char *)inbuf1,0,(size_t)(dz->buflen * sizeof(float)));
  171. memset((char *)inbuf2,0,(size_t)(dz->buflen * sizeof(float)));
  172. memset((char *)dblbuf,0,(size_t)(dz->buflen * sizeof(double)));
  173. if((samps_read1 = fgetfbufEx(inbuf1,dz->buflen,dz->ifd[0],0))<0) {
  174. sprintf(errstr,"Problem reading from file1 during mix.\n");
  175. return(SYSTEM_ERROR);
  176. }
  177. if((samps_read2 = fgetfbufEx(inbuf2,dz->buflen,dz->ifd[1],0))<0) {
  178. sprintf(errstr,"Problem reading from file1 during mix.\n");
  179. return(SYSTEM_ERROR);
  180. }
  181. if((gross_samps_read = max(samps_read1,samps_read2))<=0)
  182. break;
  183. gross_total_samps_read += gross_samps_read;
  184. if(cutoff_samps > (unsigned int) gross_total_samps_read)
  185. cutoff_in_buf = gross_samps_read;
  186. else
  187. cutoff_in_buf = (cutoff_samps % dz->buflen);
  188. ssampsread1 = samps_read1;
  189. ssampsread1 = min(ssampsread1,cutoff_in_buf);
  190. if(ssampsread1) {
  191. for(n=0;n<ssampsread1;n++)
  192. dblbuf[n] = inbuf1[n] * dz->param[MIX2_GAIN1];
  193. if((ssampsread2 = samps_read2)>0) {
  194. ssampsread2 = min(ssampsread2,cutoff_in_buf);
  195. for(n=0;n<ssampsread2;n++)
  196. dblbuf[n] += inbuf2[n] * dz->param[MIX2_GAIN2];
  197. }
  198. } else {
  199. ssampsread2 = samps_read2;
  200. ssampsread2 = min(ssampsread2,cutoff_in_buf);
  201. for(n=0;n<ssampsread2;n++)
  202. dblbuf[n] = inbuf2[n] * dz->param[MIX2_GAIN2];
  203. }
  204. ssampsread = gross_samps_read;
  205. ssampsread = min(ssampsread,cutoff_in_buf);
  206. for(n=0;n<ssampsread;n++)
  207. obuf[n] = (float)dblbuf[n];
  208. if(ssampsread > 0) {
  209. if((exit_status = write_samps(obuf,ssampsread,dz))<0)
  210. return(exit_status);
  211. }
  212. if((unsigned int)gross_total_samps_read >= cutoff_samps)
  213. break;
  214. }
  215. return(FINISHED);
  216. }
  217. /******************************** MIX_CROSS **********************************/
  218. int mix_cross(dataptr dz)
  219. {
  220. int exit_status;
  221. float *inbuf1 = dz->sampbuf[0];
  222. float *inbuf2 = dz->sampbuf[1];
  223. float *obuf = dz->sampbuf[0];
  224. int samps_read2 = 0;
  225. int end_of_samps_to_process = dz->iparam[MCR_END];
  226. int cross_end = 0;
  227. int total_samps_read = 0;
  228. int remain;
  229. if(end_of_samps_to_process <= 0) {
  230. sprintf(errstr,"Accounting problem: mix_cross()\n");
  231. return(PROGRAM_ERROR);
  232. }
  233. display_virtual_time(0,dz);
  234. if(dz->iparam[MCR_STAGGER]>0 && (exit_status = cross_stagger(&total_samps_read,&end_of_samps_to_process,obuf,dz))<0)
  235. return(exit_status);
  236. if(end_of_samps_to_process <=0) {
  237. sprintf(errstr,"Accounting problem 1: mix_cross()\n");
  238. return(PROGRAM_ERROR);
  239. }
  240. while(total_samps_read <= dz->iparam[MCR_BEGIN]) {
  241. if((exit_status = pre_crossmix
  242. (&samps_read2,&cross_end,&total_samps_read,&end_of_samps_to_process,inbuf1,inbuf2,obuf,dz))<0)
  243. return(exit_status);
  244. if(exit_status == FINISHED)
  245. break;
  246. }
  247. if(end_of_samps_to_process <=0) {
  248. sprintf(errstr,"Accounting problem 2: mix_cross()\n");
  249. return(PROGRAM_ERROR);
  250. }
  251. remain = samps_read2 - end_of_samps_to_process;
  252. if(remain < 0) {
  253. do {
  254. if((exit_status = crossmix
  255. (&samps_read2,&cross_end,&total_samps_read,&end_of_samps_to_process,inbuf1,inbuf2,obuf,dz))<0)
  256. return(exit_status);
  257. } while((remain = samps_read2 - end_of_samps_to_process) < 0);
  258. }
  259. if(remain)
  260. memmove((char *)(obuf + cross_end),(char *)(inbuf2 + cross_end),(size_t)(remain * sizeof(float)));
  261. if(samps_read2 > 0) {
  262. if((exit_status = write_samps(obuf,samps_read2,dz))<0)
  263. return(exit_status);
  264. }
  265. while((samps_read2 = fgetfbufEx(obuf, dz->buflen,dz->ifd[1],0))>0) {
  266. if((exit_status = write_samps(obuf,samps_read2,dz))<0)
  267. return(exit_status);
  268. }
  269. if(samps_read2<0) {
  270. sprintf(errstr,"Sound read error.\n");
  271. return(SYSTEM_ERROR);
  272. }
  273. return(FINISHED);
  274. }
  275. /******************************** CROSS **********************************/
  276. int cross(int startcross,int endcross,float *inbuf1,float *inbuf2,float *obuf,dataptr dz)
  277. {
  278. double xxx, yyy;
  279. register int i;
  280. int crosindex = dz->iparam[MCR_INDEX];
  281. double crosfact = dz->param[MCR_CROSFACT];
  282. double powfac;
  283. switch(dz->iparam[MCR_CONTOUR]) {
  284. case(MCR_LINEAR): /* LINEAR */
  285. for(i=startcross;i<endcross;i++) {
  286. xxx = (double)crosindex * crosfact;
  287. yyy = 1.0 - xxx;
  288. obuf[i] = (float)((inbuf1[i] * yyy) + (inbuf2[i] * xxx));
  289. crosindex++;
  290. }
  291. break;
  292. case(MCR_COSIN): /* COSIN */
  293. for(i=startcross;i<endcross;i++) {
  294. xxx = (double)crosindex * crosfact;
  295. xxx = read_cos(xxx,dz);
  296. yyy = 1.0 - xxx;
  297. obuf[i] = (float)((inbuf1[i] * yyy) + (inbuf2[i] * xxx));
  298. crosindex++;
  299. }
  300. break;
  301. case(MCR_SKEWED): /* SKEWED COSIN */
  302. powfac = dz->param[MCR_POWFAC];
  303. for(i=startcross;i<endcross;i++) {
  304. xxx = (double)crosindex * crosfact;
  305. xxx = pow(xxx,powfac);
  306. xxx = read_cos(xxx,dz);
  307. yyy = 1.0 - xxx;
  308. obuf[i] = (float)((inbuf1[i] * yyy) + (inbuf2[i] * xxx));
  309. crosindex++;
  310. }
  311. break;
  312. }
  313. dz->iparam[MCR_INDEX] = crosindex;
  314. return(FINISHED);
  315. }
  316. /************************** READ_COS **********************/
  317. double read_cos(double d,dataptr dz)
  318. {
  319. int j, k;
  320. double frac, diff;
  321. double *costable = dz->parray[MCR_COSTABLE];
  322. d *= (double)MCR_TABLEN;
  323. j = (int)d; /* TRUNCATE */
  324. if((k=j+1)>MCR_TABLEN)
  325. return(1.0);
  326. frac = d - (double)j;
  327. diff = costable[k] - costable[j];
  328. frac *= diff;
  329. return(costable[j] + frac);
  330. }
  331. /************************** CROSSMIX **********************/
  332. int crossmix(int *samps_read2,int *cross_end,int *total_samps_read,int *end_of_samps_to_process,
  333. float *inbuf1,float *inbuf2,float *obuf,dataptr dz)
  334. {
  335. int exit_status;
  336. if((exit_status = advance_in_files
  337. (samps_read2,total_samps_read,end_of_samps_to_process,cross_end,inbuf1,inbuf2,dz))<0)
  338. return(exit_status);
  339. *cross_end = min(*cross_end,dz->buflen);
  340. if((exit_status = cross(0L,*cross_end,inbuf1,inbuf2,obuf,dz))<0)
  341. return(exit_status);
  342. if(*cross_end==dz->buflen) {
  343. if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
  344. return(exit_status);
  345. }
  346. return(FINISHED);
  347. }
  348. /************************** PRE_CROSSMIX **********************/
  349. int pre_crossmix(int *samps_read2,int *cross_end,int *total_samps_read,
  350. int *end_of_samps_to_process,float *inbuf1,float *inbuf2,float *obuf,dataptr dz)
  351. {
  352. int exit_status;
  353. int ssampstart, cross_start;
  354. int last_total_samps_read = *total_samps_read;
  355. if((exit_status = advance_in_files
  356. (samps_read2,total_samps_read,end_of_samps_to_process,cross_end,inbuf1,inbuf2,dz))<0)
  357. return(exit_status);
  358. if(*total_samps_read > dz->iparam[MCR_BEGIN]) {
  359. if((cross_start = dz->iparam[MCR_BEGIN] - last_total_samps_read)>=dz->buflen) {
  360. sprintf(errstr,"Accounting problem: pre_crossmix()\n");
  361. return(PROGRAM_ERROR);
  362. }
  363. ssampstart = cross_start;
  364. *cross_end = min(*cross_end,dz->buflen);
  365. if((exit_status = cross(ssampstart,*cross_end,inbuf1,inbuf2,obuf,dz))<0)
  366. return(exit_status);
  367. if(*cross_end < dz->buflen)
  368. return(FINISHED);
  369. }
  370. if((exit_status= write_samps(obuf,dz->buflen,dz))<0)
  371. return(exit_status);
  372. return(CONTINUE);
  373. }
  374. /************************** CROSS_STAGGER **********************/
  375. int cross_stagger(int *total_samps_read,int *end_of_samps_to_process,float *obuf,dataptr dz)
  376. {
  377. int exit_status;
  378. int samps_read1, samps_written;
  379. int stagger = dz->iparam[MCR_STAGGER];
  380. int stagbufs = stagger/dz->buflen;
  381. int stagsamps = stagger%dz->buflen;
  382. //TW SAFE??
  383. // if(((stagsamps/F_SECSIZE)*F_SECSIZE)!=stagsamps) {
  384. // sprintf(errstr,"Sector accounting problem: cross_stagger()\n");
  385. // return(PROGRAM_ERROR);
  386. // }
  387. while(stagbufs>0) {
  388. if((samps_read1 = fgetfbufEx(obuf, dz->buflen,dz->ifd[0],0))!=dz->buflen) {
  389. if(samps_read1<0) {
  390. sprintf(errstr,"Sound read error.\n");
  391. return(SYSTEM_ERROR);
  392. } else {
  393. sprintf(errstr,"First file read failed:1: cross_stagger()\n");
  394. return(PROGRAM_ERROR);
  395. }
  396. }
  397. // if((samps_written = fputfbufEx(obuf,dz->buflen,dz->ofd))!=dz->buflen) {
  398. if((exit_status = write_samps_no_report(obuf,dz->buflen,&samps_written,dz))<0)
  399. return(exit_status);
  400. if(samps_written!=dz->buflen) {
  401. sprintf(errstr,"Problem writing samps:1: cross_stagger()\n");
  402. return(PROGRAM_ERROR);
  403. }
  404. dz->total_samps_written += samps_written;
  405. *total_samps_read += dz->buflen;
  406. *end_of_samps_to_process -= dz->buflen;
  407. stagbufs--;
  408. }
  409. if(stagsamps > 0) {
  410. if((samps_read1 = fgetfbufEx(obuf, stagsamps,dz->ifd[0],0))!=stagsamps) {
  411. if(samps_read1<0) {
  412. sprintf(errstr,"Sound read error.\n");
  413. return(SYSTEM_ERROR);
  414. } else {
  415. sprintf(errstr,"First file read failed:2: cross_stagger()\n");
  416. return(PROGRAM_ERROR);
  417. }
  418. }
  419. // if((samps_written = fputfbufEx(obuf,stagsamps,dz->ofd))!=stagsamps) {
  420. if((exit_status = write_samps_no_report(obuf,stagsamps,&samps_written,dz) )< 0)
  421. return(exit_status);
  422. if(samps_written != stagsamps) {
  423. sprintf(errstr,"Problem writing samps:2: cross_stagger()\n");
  424. return(PROGRAM_ERROR);
  425. }
  426. dz->total_samps_written += stagsamps;
  427. *total_samps_read += stagsamps;
  428. *end_of_samps_to_process -= stagsamps;
  429. }
  430. return(FINISHED);
  431. }
  432. /************************** ADVANCE_IN_FILES **********************/
  433. int advance_in_files(int *samps_read2,int *total_samps_read,int *end_of_samps_to_process,
  434. int *cross_end,float *inbuf1,float *inbuf2,dataptr dz)
  435. {
  436. int samps_read1;
  437. *end_of_samps_to_process = dz->iparam[MCR_END] - *total_samps_read;
  438. if((samps_read1 = fgetfbufEx(inbuf1, dz->buflen,dz->ifd[0],0))<0) {
  439. sprintf(errstr,"First file read failed: advance_in_files()\n");
  440. return(SYSTEM_ERROR);
  441. }
  442. if((*samps_read2 = fgetfbufEx(inbuf2, dz->buflen,dz->ifd[1],0))<0) {
  443. sprintf(errstr,"Second file read failed: advance_in_files()\n");
  444. return(SYSTEM_ERROR);
  445. }
  446. *total_samps_read += *samps_read2; /* BECAUSE FADE IS TOWARDS FILE 2: and fade must END before then */
  447. *cross_end = *end_of_samps_to_process;
  448. return(FINISHED);
  449. }
  450. /************************************ MIX_INTERL ************************************/
  451. int mix_interl(dataptr dz)
  452. {
  453. int exit_status;
  454. float *inbuf = dz->sampbuf[0];
  455. float *outbuf = dz->sampbuf[1]; /* NB this buffer is large enough to take output */
  456. int samps_read, samps_left[MAX_MI_OUTCHANS];
  457. int n, gross_samps_read, gross_samps_left = 0, last_total_samps_written, samps_to_write;
  458. for(n=0;n<dz->infilecnt;n++) {
  459. samps_left[n] = dz->insams[n];
  460. gross_samps_left = max(gross_samps_left,samps_left[n]);
  461. }
  462. while(gross_samps_left) {
  463. memset((char *)outbuf,0,(size_t)(dz->buflen * dz->infilecnt * sizeof(float)));
  464. gross_samps_read = 0;
  465. gross_samps_left = 0;
  466. for(n=0;n<dz->infilecnt;n++) {
  467. if(samps_left[n]>0) {
  468. if((samps_read = fgetfbufEx(inbuf,dz->buflen,dz->ifd[n],0))<0) {
  469. sprintf(errstr,"Failed to read data from file %d: mix_interl()\n",n+1);
  470. return(SYSTEM_ERROR);
  471. }
  472. samps_left[n] -= samps_read;
  473. copy_to_channel(inbuf,outbuf+n,samps_read,dz->infilecnt);
  474. gross_samps_read = max(gross_samps_read,samps_read);
  475. gross_samps_left = max(gross_samps_left,samps_left[n]);
  476. }
  477. }
  478. samps_to_write = gross_samps_read*dz->infilecnt;
  479. last_total_samps_written = dz->total_samps_written;
  480. if(samps_to_write) {
  481. if((exit_status = write_samps(outbuf,samps_to_write,dz))<0)
  482. return(exit_status);
  483. }
  484. if(dz->total_samps_written - last_total_samps_written != samps_to_write) {
  485. sprintf(errstr,"Problem writing data: mix_interl()\n");
  486. return(PROGRAM_ERROR);
  487. }
  488. }
  489. // TW
  490. // /*RWD too late here! */
  491. // dz->infile->channels = dz->infilecnt; /* Force output to final channel-count */
  492. return(FINISHED);
  493. }
  494. /************************************ COPY_TO_CHANNEL ************************************/
  495. void copy_to_channel(float *inbuf,float *outbuf,int sampcnt,int outchans)
  496. {
  497. int n, m;
  498. for(n=0,m=0;n<sampcnt;n++,m+=outchans)
  499. outbuf[m] = inbuf[n];
  500. }
  501. /******************************** CROSS_STITCH *****************************/
  502. int cross_stitch(dataptr dz) {
  503. double srate = (double)dz->infile->srate;
  504. int n = 0, mbf, sbf, procend, input_procend;
  505. int exit_status, t = 0,v=0,m=0,done = 0;
  506. double *brrk = NULL, thisval, nextval = 0.0, valincr, atten = 0.0, val_here;
  507. double time_here, lastrtime,nextrtime, lastval, tratio;
  508. int nexttime = 0, thistime;
  509. float *buf0 = dz->sampbuf[0];
  510. float *buf1 = dz->sampbuf[1];
  511. int typ;
  512. int input_procskip, samps_to_skip = 0;
  513. if(dz->param[MIX_SKEW] <= dz->param[MIX_SKIP]) {
  514. sprintf(errstr,"Start and end times of mix are reversed, or equal.\n");
  515. return(DATA_ERROR);
  516. }
  517. /* RWD make this samps */
  518. dz->tempsize =
  519. (int)round((dz->param[MIX_SKEW] - dz->param[MIX_SKIP]) * (double)(srate *
  520. max(dz->infile->channels,dz->otherfile->channels)));
  521. display_virtual_time(0,dz);
  522. if(dz->infile->channels > 2) {
  523. typ = 4; /* multichan multichan */
  524. } else if(dz->infile->channels==1) {
  525. if(dz->otherfile->channels==1) {
  526. typ = 0; /* mono mono */
  527. } else {
  528. typ = 1; /* mono stereo */
  529. }
  530. } else {
  531. if(dz->otherfile->channels==1) {
  532. typ = 2; /* stereo mono */
  533. } else {
  534. typ = 3; /* stereo stereo */
  535. }
  536. }
  537. procend = dz->insams[0]/dz->infile->channels;
  538. input_procend = (int)round(dz->param[MIX_SKEW] * srate);
  539. procend = min(procend,input_procend);
  540. if((input_procskip = (int)round(dz->param[MIX_SKIP] * srate)) > 0) {
  541. samps_to_skip = input_procskip * dz->infile->channels;
  542. //TW SAFE??
  543. // samps_to_skip /= (F_SECSIZE * dz->infile->channels);
  544. // samps_to_skip *= (F_SECSIZE * dz->infile->channels); /* skip to nearest sector */
  545. if((sndseekEx(dz->ifd[0],samps_to_skip,0))<0) {
  546. sprintf(errstr,"seek() failed searching for startpoint of mix in first file.\n");
  547. return(SYSTEM_ERROR);
  548. }
  549. samps_to_skip = input_procskip * dz->otherfile->channels;
  550. //TW SAFE??
  551. // samps_to_skip /= (F_SECSIZE * dz->otherfile->channels);
  552. // samps_to_skip *= (F_SECSIZE * dz->otherfile->channels); /* skip to nearest sector */
  553. if((sndseekEx(dz->ifd[1],samps_to_skip,0))<0) {
  554. sprintf(errstr,"sndseek() failed searching for startpoint of mix in second file.\n");
  555. return(SYSTEM_ERROR);
  556. }
  557. }
  558. if(dz->brksize[MIX_STAGGER]) {
  559. brrk = dz->brk[MIX_STAGGER];
  560. if(input_procskip > 0) {
  561. thistime = samps_to_skip/dz->otherfile->channels;
  562. time_here = (double)thistime/srate;
  563. m = 0;
  564. while(brrk[m] <= time_here) {
  565. m += 2;
  566. if(m >= dz->brksize[MIX_STAGGER]) { /* IF beyond end of brk */
  567. dz->param[MIX_STAGGER] = brrk[m-1]; /* set atten to last brkval */
  568. dz->brksize[MIX_STAGGER] = 0; /* set brkfile as not existing */
  569. break;
  570. }
  571. }
  572. if(dz->brksize[MIX_STAGGER]) { /* If still in brkfile */
  573. lastrtime = brrk[m-2]; /* Note previous brkpnt-time+val */
  574. lastval = brrk[m-1];
  575. n = thistime; /* set the internal sample counter to here */
  576. t = m; /* set pointer for (following) brkpnt times */
  577. v = m+1; /* set pointer for (following) brkpnt vals */
  578. m /= 2; /* set position in brk-pairs */
  579. nextrtime = brrk[t];
  580. nexttime = round(nextrtime * srate);
  581. nextval = brrk[v];
  582. /* calc value at start-time */
  583. tratio = (double)(time_here - lastrtime)/(double)(nextrtime - lastrtime);
  584. val_here = ((nextval - lastval) * tratio) + lastval;
  585. nexttime = thistime; /* set up starting time & val */
  586. nextval = val_here;
  587. }
  588. } else {
  589. nexttime = round(brrk[0] * srate);
  590. nextval = brrk[1]; /* set up starting time & val */
  591. n = 0; /* set the internal sample counter to start */
  592. t = 2; /* set pointer for (following) brkpnt times */
  593. v = 3; /* set pointer for (following) brkpnt vals */
  594. m = 1; /* set position in brk-pairs */
  595. }
  596. } else {
  597. n = input_procskip;
  598. }
  599. memset((char *)buf0,0,dz->buflen * dz->infile->channels* sizeof(float));
  600. memset((char *)buf1,0,dz->buflen * dz->otherfile->channels * sizeof(float));
  601. if((fgetfbufEx(buf0,dz->buflen * dz->infile->channels,dz->ifd[0],0)) < 0) {
  602. sprintf(errstr,"Can't read samps from 1st soundfile.\n");
  603. return(SYSTEM_ERROR);
  604. }
  605. if((fgetfbufEx(buf1,dz->buflen * dz->otherfile->channels,dz->ifd[1],0)) < 0) {
  606. sprintf(errstr,"Can't read samps from 2nd soundfile.\n");
  607. return(SYSTEM_ERROR);
  608. }
  609. mbf = 0;
  610. sbf = 0;
  611. if(dz->brksize[MIX_STAGGER] == 0)
  612. atten = dz->param[MIX_STAGGER];
  613. else {
  614. for(; m < dz->brksize[MIX_STAGGER]; m++,t+=2,v+=2) {
  615. thistime = nexttime;
  616. thisval = nextval;
  617. nexttime = round(brrk[t] * srate);
  618. nextval = brrk[v];
  619. valincr = (nextval - thisval)/(double)(nexttime - thistime);
  620. if(nexttime >= procend) { /* IF brktable extends beyond end of sound */
  621. nexttime = procend;
  622. done = 1;
  623. }
  624. atten = thisval;
  625. while(n < nexttime) {
  626. if(do_stitch(typ,&mbf,&sbf,buf0,buf1,atten,dz->buflen,dz)) {
  627. if((exit_status = renew_bufs(typ,buf0,buf1,dz))<0)
  628. return(exit_status);
  629. mbf = 0;
  630. sbf = 0;
  631. }
  632. atten += valincr;
  633. n++;
  634. }
  635. if(done) /* IF brktable extends beyond end of sound: break */
  636. break;
  637. }
  638. }
  639. while(n < procend) { /* IF brktable stops short of end of sound, or no brktable */
  640. if(do_stitch(typ,&mbf,&sbf,buf0,buf1,atten,dz->buflen,dz)) {
  641. if((exit_status = renew_bufs(typ,buf0,buf1,dz))<0)
  642. return(exit_status);
  643. mbf = 0;
  644. sbf = 0;
  645. }
  646. n++;
  647. }
  648. return flush_bufs(typ,&mbf,&sbf,buf0,buf1,dz);
  649. }
  650. /******************************** DO_STITCH *****************************/
  651. int do_stitch(int typ,int *mbf,int *sbf,float *buf0,float *buf1,double atten,int bflen,dataptr dz)
  652. {
  653. int bufdone = 0, k;
  654. switch(typ) {
  655. case(0):
  656. buf0[*mbf] = (float)((buf0[*mbf] * atten) + (buf1[*mbf] * (1.0 - atten)));
  657. if(++(*mbf) >= bflen)
  658. bufdone = 1;
  659. break;
  660. case(1):
  661. buf1[*sbf] = (float)((buf0[*mbf] * atten) + (buf1[*sbf] * (1.0 - atten)));
  662. (*sbf)++;
  663. buf1[*sbf] = (float)((buf0[*mbf] * atten) + (buf1[*sbf] * (1.0 - atten)));
  664. (*sbf)++;
  665. if(++(*mbf) >= bflen)
  666. bufdone = 1;
  667. break;
  668. case(2):
  669. buf0[*sbf] = (float)((buf0[*sbf] * atten) + (buf1[*mbf] * (1.0 - atten)));
  670. (*sbf)++;
  671. buf0[*sbf] = (float)((buf0[*sbf] * atten) + (buf1[*mbf] * (1.0 - atten)));
  672. (*sbf)++;
  673. if(++(*mbf) >= bflen)
  674. bufdone = 1;
  675. break;
  676. case(3):
  677. buf0[*sbf] = (float)((buf0[*sbf] * atten) + (buf1[*sbf] * (1.0 - atten)));
  678. (*sbf)++;
  679. buf0[*sbf] = (float)((buf0[*sbf] * atten) + (buf1[*sbf] * (1.0 - atten)));
  680. if(++(*sbf) >= bflen * 2)
  681. bufdone = 1;
  682. break;
  683. case(4):
  684. for(k=0; k < dz->infile->channels; k++) {
  685. buf0[*sbf] = (float)((buf0[*sbf] * atten) + (buf1[*sbf] * (1.0 - atten)));
  686. (*sbf)++;
  687. }
  688. if(*sbf >= bflen * dz->infile->channels)
  689. bufdone = 1;
  690. break;
  691. }
  692. return(bufdone);
  693. }
  694. /******************************** RENEW_BUFS *****************************/
  695. int renew_bufs(int typ,float *buf0,float *buf1,dataptr dz)
  696. {
  697. int exit_status;
  698. switch(typ) {
  699. case(0):
  700. if((exit_status = write_samps(buf0,dz->buflen,dz))<0)
  701. return(exit_status);
  702. memset((char *)buf0,0,dz->buflen * sizeof(float));
  703. memset((char *)buf1,0,dz->buflen * sizeof(float));
  704. break;
  705. case(1):
  706. if((exit_status = write_samps(buf1,dz->buflen * 2,dz))<0)
  707. return(exit_status);
  708. memset((char *)buf0,0,dz->buflen * sizeof(float));
  709. memset((char *)buf1,0,dz->buflen * 2 * sizeof(float));
  710. break;
  711. case(2):
  712. if((exit_status = write_samps(buf0,dz->buflen * 2,dz))<0)
  713. return(exit_status);
  714. memset((char *)buf0,0,dz->buflen * 2 * sizeof(float));
  715. memset((char *)buf1,0,dz->buflen * sizeof(float));
  716. break;
  717. case(3):
  718. if((exit_status = write_samps(buf0,dz->buflen * 2,dz))<0)
  719. return(exit_status);
  720. memset((char *)buf0,0,dz->buflen * 2 * sizeof(float));
  721. memset((char *)buf1,0,dz->buflen * 2 * sizeof(float));
  722. break;
  723. case(4):
  724. if((exit_status = write_samps(buf0,dz->buflen * dz->infile->channels,dz))<0)
  725. return(exit_status);
  726. memset((char *)buf0,0,dz->buflen * dz->infile->channels * sizeof(float));
  727. memset((char *)buf1,0,dz->buflen * dz->otherfile->channels * sizeof(float));
  728. break;
  729. }
  730. if((fgetfbufEx(buf0,dz->buflen * dz->infile->channels,dz->ifd[0],0)) < 0) {
  731. sprintf(errstr,"Can't read samps from 1st soundfile.\n");
  732. return(SYSTEM_ERROR);
  733. }
  734. if((fgetfbufEx(buf1,dz->buflen * dz->otherfile->channels,dz->ifd[1],0)) < 0) {
  735. sprintf(errstr,"Can't read samps from 2nd soundfile.\n");
  736. return(SYSTEM_ERROR);
  737. }
  738. return(FINISHED);
  739. }
  740. /******************************** FLUSH_BUFS *****************************/
  741. int flush_bufs(int typ,int *mbf,int *sbf,float *buf0,float *buf1,dataptr dz)
  742. {
  743. int exit_status;
  744. switch(typ) {
  745. case(0): /* Output file takes its channel cnt from 1st input file : HENCE.... */
  746. if(*mbf > 0) {
  747. if((exit_status = write_samps(buf0,*mbf,dz))<0)
  748. return(exit_status);
  749. } /* 1st input file MONO : output file MONO */
  750. break;
  751. case(1):
  752. if(*sbf > 0) {
  753. if((exit_status = write_samps(buf1,*sbf,dz))<0)
  754. return(exit_status);
  755. } /* 1st input file MONO : output file STEREO */
  756. dz->infile->channels = 2; /* Force output file to have stereo header */
  757. break;
  758. case(2): /* 1st input file STEREO : output file STEREO */
  759. case(3):
  760. case(4):
  761. if(*sbf > 0) {
  762. if((exit_status = write_samps(buf0,*sbf,dz))<0)
  763. return(exit_status);
  764. }
  765. break;
  766. }
  767. return(FINISHED);
  768. }
  769. //TW JANUARY 2010: MODIFIED FOR MULTICHANNEL
  770. /*************************** DO_AUTOMIX *******************************/
  771. int do_automix(dataptr dz)
  772. {
  773. double srate = (double)dz->infile->srate;
  774. unsigned int nexttime, thistime, outcnt = 0, bufcnt = 0;
  775. int outchans = 1, exit_status;
  776. double *p = dz->parray[0], *arrayend = dz->parray[0] + dz->itemcnt;
  777. double *thislevel, *nextlevel, *incr, sum, convertor_to_time, convertor_to_smps;
  778. int *activebuf, overflows = 0;
  779. unsigned int max_insams = 0;
  780. int *chans, n;
  781. // RWD 2025 now use calloc to pacify gcc
  782. if((chans = (int *) calloc(dz->infilecnt, sizeof(int)))==NULL) {
  783. sprintf(errstr,"Insufficient memory for level stores\n");
  784. return(MEMORY_ERROR);
  785. }
  786. if((thislevel = (double *)malloc(dz->infilecnt * sizeof(double)))==NULL) {
  787. sprintf(errstr,"Insufficient memory for level stores\n");
  788. return(MEMORY_ERROR);
  789. }
  790. if((nextlevel = (double *)malloc(dz->infilecnt * sizeof(double)))==NULL) {
  791. sprintf(errstr,"Insufficient memory for level stores\n");
  792. return(MEMORY_ERROR);
  793. }
  794. if((incr = (double *)malloc(dz->infilecnt * sizeof(double)))==NULL) {
  795. sprintf(errstr,"Insufficient memory for level stores\n");
  796. return(MEMORY_ERROR);
  797. }
  798. if((activebuf = (int *)malloc(dz->infilecnt * sizeof(int)))==NULL) {
  799. sprintf(errstr,"Insufficient memory for level stores\n");
  800. return(MEMORY_ERROR);
  801. }
  802. for(n=0;n<dz->infilecnt;n++) {
  803. activebuf[n] = 1;
  804. if(sndgetprop(dz->ifd[n],"channels", (char *)&(chans[n]), sizeof(int)) < 0) {
  805. sprintf(errstr,"Failure to read channel data, for input file %d\n",n+1);
  806. return(DATA_ERROR);
  807. }
  808. if(n>0 && chans[n] != chans[0]) {
  809. sprintf(errstr,"Process only works with files having the same number of channels: file %d will not work\n",n+1);
  810. return(DATA_ERROR);
  811. }
  812. }
  813. outchans = chans[0];
  814. convertor_to_smps = srate * outchans;
  815. convertor_to_time = 1.0/convertor_to_smps;
  816. for(n=0;n<dz->infilecnt;n++)
  817. max_insams = max(max_insams,(unsigned int)dz->insams[n]);
  818. dz->tempsize = max_insams; /* for scrollbar display */
  819. if((exit_status = create_sized_outfile(dz->outfilename,dz))<0)
  820. return(exit_status);
  821. if((exit_status = read_automix_sound(activebuf,dz))<0)
  822. return(exit_status);
  823. nexttime = (unsigned int)round(*p++ * convertor_to_smps);
  824. for(n = 0;n<dz->infilecnt; n++)
  825. nextlevel[n] = *p++;
  826. while(outcnt < max_insams) {
  827. thistime = nexttime; /* establish amplitude ramps */
  828. for(n = 0; n<dz->infilecnt; n++)
  829. thislevel[n] = nextlevel[n];
  830. if(p < arrayend) {
  831. nexttime = (unsigned int)round(*p++ * convertor_to_smps);
  832. for(n = 0;n<dz->infilecnt; n++) {
  833. nextlevel[n] = *p++;
  834. incr[n] = (nextlevel[n] - thislevel[n])/(double)(nexttime - thistime);
  835. }
  836. } else { /* if amp-data runs out */
  837. for(n = 0;n<dz->infilecnt; n++) /* set amp increments to zero */
  838. incr[n] = 0.0;
  839. nexttime = max_insams; /* and proceed to end of file */
  840. }
  841. nexttime = min(nexttime, max_insams); /* if snd-data runs out, curtail loop to snd-data end */
  842. while(outcnt < nexttime) {
  843. sum = 0.0;
  844. for(n=0;n<dz->infilecnt;n++) {
  845. if(activebuf[n]) {
  846. sum += dz->sampbuf[n][bufcnt] * thislevel[n];
  847. thislevel[n] += incr[n];
  848. if(outcnt >= (unsigned int)dz->insams[n])
  849. activebuf[n] = 0;
  850. }
  851. }
  852. if(fabs(sum) > F_MAXSAMP)
  853. overflows++;
  854. dz->sampbuf[dz->infilecnt][bufcnt] = (float)(sum * dz->param[0]);
  855. if(++bufcnt >= (unsigned int)dz->buflen) {
  856. if((exit_status = write_samps(dz->sampbuf[dz->infilecnt],dz->buflen,dz))<0)
  857. return(exit_status);
  858. if((exit_status = read_automix_sound(activebuf,dz))<0)
  859. return(exit_status);
  860. bufcnt = 0;
  861. }
  862. outcnt++;
  863. if(dz->brksize[0]) {
  864. if((exit_status = read_value_from_brktable((double)outcnt * convertor_to_time,0,dz))<0)
  865. return(exit_status);
  866. }
  867. }
  868. }
  869. if(bufcnt) {
  870. if((exit_status = write_samps(dz->sampbuf[dz->infilecnt],bufcnt,dz))<0)
  871. return(exit_status);
  872. }
  873. if(overflows) {
  874. fprintf(stdout,"WARNING: %d samples were clipped.\n",overflows);
  875. fflush(stdout);
  876. }
  877. return(FINISHED);
  878. }
  879. /*************************** READ_AUTOMIX_SOUND *******************************/
  880. int read_automix_sound(int *activebuf,dataptr dz)
  881. {
  882. int n;
  883. for(n=0;n<dz->infilecnt;n++) {
  884. if(!activebuf[n]) /* only read from files with data remaining */
  885. continue;
  886. if((dz->ssampsread = fgetfbufEx(dz->sampbuf[n],dz->buflen,dz->ifd[n],0)) < 0) {
  887. sprintf(errstr,"Can't read samps from input soundfile %d.\n",n+1);
  888. return(SYSTEM_ERROR);
  889. }
  890. }
  891. return(FINISHED);
  892. }
  893. /************************************ MIXMANY ************************************/
  894. int mixmany(dataptr dz)
  895. {
  896. int exit_status;
  897. int gross_samps_read, n, m;
  898. int ssampsread;
  899. double *dblbuf = (double *)dz->sampbuf[2], maxdsamp = 0.0;
  900. float *ibuf = dz->sampbuf[0];
  901. float *obuf = dz->sampbuf[1];
  902. dz->tempsize = 0;
  903. for(n=0;n<=dz->infilecnt;n++)
  904. dz->tempsize = max(dz->tempsize,dz->insams[n]);
  905. display_virtual_time(0L,dz);
  906. fprintf(stdout,"INFO: Finding maximum level\n");
  907. fflush(stdout);
  908. do {
  909. memset((char *)ibuf,0,(size_t)dz->buflen * sizeof(float));
  910. memset((char *)dblbuf,0,(size_t)dz->buflen * sizeof(double));
  911. gross_samps_read = 0;
  912. for(n=0;n<dz->infilecnt;n++) {
  913. if((ssampsread = fgetfbufEx(ibuf,dz->buflen,dz->ifd[n],0))<0) {
  914. sprintf(errstr,"Problem reading from file %d\n",n+1);
  915. return(SYSTEM_ERROR);
  916. }
  917. gross_samps_read = max(gross_samps_read,ssampsread);
  918. if(ssampsread > 0) {
  919. for(m=0;m<ssampsread;m++)
  920. dblbuf[m] += (double)ibuf[m];
  921. }
  922. }
  923. if(gross_samps_read<=0)
  924. break;
  925. for(m=0;m<gross_samps_read;m++)
  926. maxdsamp = max(maxdsamp,fabs(dblbuf[m]));
  927. } while(gross_samps_read > 0);
  928. maxdsamp = F_MAXSAMP/maxdsamp;
  929. for(n=0;n<dz->infilecnt;n++) {
  930. if(sndseekEx(dz->ifd[n],0,0)<0) {
  931. sprintf(errstr,"seek failed for file %d\n",n+1);
  932. return(SYSTEM_ERROR);
  933. }
  934. }
  935. dz->total_samps_written = 0;
  936. display_virtual_time(0,dz);
  937. fprintf(stdout,"INFO: Doing the mix.\n");
  938. fflush(stdout);
  939. do {
  940. memset((char *)ibuf,0,(size_t)dz->buflen * sizeof(float));
  941. memset((char *)dblbuf,0,(size_t)dz->buflen * sizeof(double));
  942. gross_samps_read = 0;
  943. for(n=0;n<dz->infilecnt;n++) {
  944. if((ssampsread = fgetfbufEx(ibuf,dz->buflen,dz->ifd[n],0))<0) {
  945. sprintf(errstr,"Problem reading from file %d during mix.\n",n+1);
  946. return(SYSTEM_ERROR);
  947. }
  948. gross_samps_read = max(gross_samps_read,ssampsread);
  949. if(ssampsread > 0) {
  950. for(m=0;m<ssampsread;m++)
  951. dblbuf[m] += (double)ibuf[m];
  952. }
  953. }
  954. if(gross_samps_read<=0)
  955. break;
  956. for(m=0;m<gross_samps_read;m++)
  957. obuf[m] = (float)(dblbuf[m] * maxdsamp);
  958. if((exit_status = write_samps(obuf,gross_samps_read,dz))<0)
  959. return(exit_status);
  960. } while(gross_samps_read > 0);
  961. return(FINISHED);
  962. }