newmix0.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685
  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 <arrays.h>
  31. #include <filetype.h>
  32. #include <mix.h>
  33. #include <cdpmain.h>
  34. #include <sfsys.h>
  35. static int test_mixdata_in_line(int wordcnt,char **wordstor,int total_words,int *chans,int lineno,dataptr dz);
  36. static int test_right_level(char *str,int lineno);
  37. static int test_right_pan(char *str,int lineno);
  38. static int test_left_level(char *str,int lineno);
  39. static int test_left_pan(char *str,int lineno);
  40. static int open_file_and_test_props(int filecnt,char *filename,int *srate,int chans,int lineno,dataptr dz);
  41. static int syntax_check_mix(dataptr dz);
  42. //TW UPDATED FUNCTION
  43. static int create_and_output_mixfile_line(int infilno,int max_namelen,double *running_total,dataptr dz);
  44. static int output_mixfile_line(char **wordstor,int *maxwordsize,int start_word_no,int words_in_line,dataptr dz);
  45. static int twist_mixfile_line(char **wordstor,int *maxwordsize,int start_word_no,int words_in_line,dataptr dz);
  46. static int output_aligned_word(char *thisword,int maxthiswordsize,dataptr dz);
  47. static int mirror_panning(char *thisword, int maxthiswordsize,dataptr dz);
  48. /*************************** MIX_SYNTAX_CHECK *************************/
  49. int mix_syntax_check(dataptr dz)
  50. {
  51. int exit_status;
  52. if((exit_status = syntax_check_mix(dz))<0)
  53. return(exit_status);
  54. if(exit_status==CONTINUE)
  55. sprintf(errstr,"MIX SYNTAX IS CORRECT.\n");
  56. return(FINISHED);
  57. }
  58. /********************** SYNTAX_CHECK_MIX ****************************/
  59. int syntax_check_mix(dataptr dz)
  60. {
  61. int exit_status;
  62. int chans;
  63. int srate=0;
  64. char *filename;
  65. int filecnt = 0;
  66. int total_words = 0, n;
  67. if(dz->infile->filetype == MIXFILE)
  68. return(CONTINUE);
  69. if((exit_status = establish_file_data_storage_for_mix((int)1,dz))<0)
  70. return(exit_status);
  71. for(n=0;n<dz->linecnt;n++) { /* for each mixfile line */
  72. if(dz->wordstor[total_words][0]==';') {
  73. total_words += dz->wordcnt[n];
  74. continue;
  75. }
  76. filename = dz->wordstor[total_words]; /* get the filename */
  77. if(strlen(filename)<=0) {
  78. sprintf(errstr,"filename error: line %d\n",dz->linecnt+1);
  79. return(FINISHED);
  80. }
  81. if((exit_status = test_mixdata_in_line(dz->wordcnt[n],dz->wordstor,total_words,&chans,n,dz))!=CONTINUE)
  82. return(FINISHED);
  83. total_words += dz->wordcnt[n];
  84. if((exit_status = open_file_and_test_props(filecnt,filename,&srate,chans,n,dz))<0)
  85. return(exit_status);
  86. if(exit_status!=CONTINUE)
  87. return(FINISHED);
  88. filecnt++; /* count the ACTUALLY USED lines: ignore comments */
  89. }
  90. if(filecnt==0) {
  91. sprintf(errstr,"No active mixfile lines.\n");
  92. return(FINISHED);
  93. }
  94. return(CONTINUE);
  95. }
  96. /**************************** TEST_MIXDATA_IN_LINE ********************************/
  97. int test_mixdata_in_line(int wordcnt,char **wordstor,int total_words,int *chans,int lineno,dataptr dz)
  98. {
  99. int exit_status;
  100. double time;
  101. switch(wordcnt) {
  102. case(MIX_MAXLINE):
  103. if((exit_status = test_right_level(wordstor[total_words+MIX_RLEVELPOS],lineno))!=CONTINUE) /* 6d */
  104. return(FINISHED);
  105. if((exit_status = test_right_pan(wordstor[total_words+MIX_RPANPOS],lineno))!=CONTINUE)
  106. return(FINISHED);
  107. /* fall thro */
  108. case(MIX_MIDLINE):
  109. if((exit_status = test_left_pan(wordstor[total_words+MIX_PANPOS],lineno))!=CONTINUE) /* 6c */
  110. return(FINISHED);
  111. /* fall thro */
  112. case(MIX_MINLINE):
  113. if(sscanf(dz->wordstor[total_words+MIX_TIMEPOS],"%lf",&time)!=1) {
  114. sprintf(errstr,"Cannot read time data: line %d\n",lineno+1);
  115. return(FINISHED);
  116. }
  117. if(time < 0.0) {
  118. sprintf(errstr,"time value less than 0.0 time: line %d\n",lineno+1);
  119. return(FINISHED);
  120. }
  121. if(sscanf(dz->wordstor[total_words+MIX_CHANPOS],"%d",chans)!=1) {
  122. sprintf(errstr,"Cannot read channel data: line %d\n",lineno+1);
  123. return(FINISHED);
  124. }
  125. if(*chans < MONO || *chans > STEREO) {
  126. sprintf(errstr,"channel value out of range: line %d\n",lineno+1);
  127. return(FINISHED);
  128. }
  129. if((exit_status = test_left_level(wordstor[total_words+MIX_LEVELPOS],lineno))!=CONTINUE)
  130. return(FINISHED);
  131. break;
  132. default:
  133. sprintf(errstr,"Illegal mixfile line-length: line %d\n",lineno+1);
  134. return(FINISHED);
  135. }
  136. if(wordcnt==MIX_MIDLINE && *chans!=MONO) {
  137. sprintf(errstr,"Invalid channel count, or line length: line %d\n",lineno+1);
  138. return(FINISHED);
  139. }
  140. if(wordcnt==MIX_MAXLINE && *chans!=STEREO) {
  141. sprintf(errstr,"Invalid channel count, or line too long: line %d\n",lineno+1);
  142. return(FINISHED);
  143. }
  144. return(CONTINUE);
  145. }
  146. /************************** TEST_RIGHT_LEVEL ************************/
  147. int test_right_level(char *str,int lineno)
  148. {
  149. double rlevel;
  150. if(is_dB(str)) {
  151. if(!get_leveldb(str,&rlevel)) {
  152. sprintf(errstr,"Error in chan2 level: line %d\n",lineno+1);
  153. return(FINISHED);
  154. }
  155. } else {
  156. if(sscanf(str,"%lf",&rlevel)!=1) {
  157. sprintf(errstr,"Error2 in chan2 level: line %d\n",lineno+1);
  158. return(FINISHED);
  159. }
  160. }
  161. if(rlevel < 0.0) {
  162. sprintf(errstr,"chan2 level out of range: line %d\n",lineno+1);
  163. return(FINISHED);
  164. }
  165. return(CONTINUE);
  166. }
  167. /*********************** TEST_RIGHT_PAN **********************/
  168. int test_right_pan(char *str,int lineno)
  169. {
  170. double pan;
  171. switch(str[0]) {
  172. case('L'):
  173. case('R'):
  174. case('C'): return(CONTINUE);
  175. default:
  176. if(sscanf(str,"%lf",&pan)!=1) {
  177. sprintf(errstr,"Error in chan2 pan: line %d\n",lineno+1);
  178. return(FINISHED);
  179. }
  180. if(pan < MINPAN || pan > MAXPAN) {
  181. sprintf(errstr,"chan2 pan out of range: line %d\n",lineno+1);
  182. return(FINISHED);
  183. }
  184. break;
  185. }
  186. return(CONTINUE);
  187. }
  188. /*************** TEST_LEFT_LEVEL ******************/
  189. int test_left_level(char *str,int lineno)
  190. {
  191. double level;
  192. if(is_dB(str)) {
  193. if(!get_leveldb(str,&level)) {
  194. sprintf(errstr,"Error in (chan1) level: line %d\n",lineno+1);
  195. return(FINISHED);
  196. }
  197. } else {
  198. if(sscanf(str,"%lf",&level)!=1) {
  199. sprintf(errstr,"Error in (chan1) level: line %d\n",lineno+1);
  200. return(FINISHED);
  201. }
  202. }
  203. if(level < 0.0) {
  204. sprintf(errstr,"(chan1) level out of range: line %d\n",lineno+1);
  205. return(FINISHED);
  206. }
  207. return(CONTINUE);
  208. }
  209. /************************** TEST_LEFT_PAN ************************/
  210. int test_left_pan(char *str,int lineno)
  211. {
  212. double pan;
  213. switch(str[0]) {
  214. case('L'):
  215. case('R'):
  216. case('C'): return(CONTINUE);
  217. default:
  218. if(sscanf(str,"%lf",&pan)!=1) {
  219. sprintf(errstr,"Error in (chan1) pan: line %d\n",lineno+1);
  220. return(FINISHED);
  221. }
  222. if(pan < MINPAN || pan > MAXPAN) {
  223. sprintf(errstr,"(chan1) pan out of range: line %d\n",lineno+1);
  224. return(FINISHED);
  225. }
  226. }
  227. return(CONTINUE);
  228. }
  229. /************************* OPEN_FILE_AND_TEST_PROPS *******************************/
  230. int open_file_and_test_props(int filecnt,char *filename,int *srate,int chans,int lineno,dataptr dz)
  231. {
  232. int exit_status;
  233. double maxamp, maxloc;
  234. int maxrep;
  235. int getmax = 0, getmaxinfo = 0;
  236. infileptr ifp;
  237. if((ifp = (infileptr)malloc(sizeof(struct filedata)))==NULL) {
  238. sprintf(errstr,"INSUFFICIENT MEMORY to store data on files.\n");
  239. return(MEMORY_ERROR);
  240. }
  241. if((dz->ifd[0] = sndopenEx(filename,0,CDP_OPEN_RDONLY)) < 0) {
  242. sprintf(errstr,"Failed to open sndfile %s: line %d\n",filename,lineno+1);
  243. return(FINISHED);
  244. }
  245. if((exit_status = readhead(ifp,dz->ifd[0],filename,&maxamp,&maxloc,&maxrep,getmax,getmaxinfo))<0)
  246. return(exit_status);
  247. copy_to_fileptr(ifp,dz->infile);
  248. if(dz->infile->filetype!=SNDFILE) {
  249. sprintf(errstr,"%s is not a soundfile: line %d\n",filename,lineno+1);
  250. return(FINISHED);
  251. }
  252. if(dz->infile->channels!=chans) {
  253. sprintf(errstr,"channel-cnt in file '%s' different to channel value given: line %d\n",filename,lineno+1);
  254. return(FINISHED);
  255. }
  256. if(filecnt==0)
  257. *srate = dz->infile->srate;
  258. else if(dz->infile->srate != *srate) {
  259. sprintf(errstr,"incompatible srate: file %s: line %d\n",filename,lineno+1);
  260. return(FINISHED);
  261. }
  262. if((dz->insams[0] = sndsizeEx(dz->ifd[0]))<0) {
  263. sprintf(errstr, "Can't read size of input file %s: line %d\n",filename,lineno+1);
  264. return(PROGRAM_ERROR);
  265. }
  266. if(dz->insams[0] <=0) {
  267. sprintf(errstr, "Zero size for input file %s: line %d\n",filename,lineno+1);
  268. return(FINISHED);
  269. }
  270. if(sndcloseEx(dz->ifd[0])<0) {
  271. sprintf(errstr, "Failed to close input file %s: line %d\n",filename,lineno+1);
  272. return(SYSTEM_ERROR);
  273. }
  274. dz->ifd[0] = -1;
  275. return(CONTINUE);
  276. }
  277. /********************** CREATE_MIXDUMMY ****************************/
  278. int create_mixdummy(dataptr dz)
  279. {
  280. int exit_status;
  281. int srate;
  282. int this_namelen, max_namelen = 0;
  283. int n;
  284. double running_total = 0.0;
  285. sndcloseEx(dz->ifd[0]);
  286. dz->ifd[0] = -1;
  287. if(dz->all_words==0) {
  288. sprintf(errstr,"No words in source file.\n");
  289. return(PROGRAM_ERROR);
  290. }
  291. dz->infilecnt = 1; /* program now utilises only 1 file at a time : needs data storage for only 1 file */
  292. if((exit_status = establish_file_data_storage_for_mix((int)1,dz))<0)
  293. return(exit_status);
  294. for(n=0;n<dz->all_words;n++) { /* for each sndfile name */
  295. if((this_namelen = strlen(dz->wordstor[n]))<=0) {
  296. sprintf(errstr,"filename error: line %d\n",dz->linecnt+1);
  297. return(PROGRAM_ERROR);
  298. }
  299. max_namelen = max(max_namelen,this_namelen);
  300. }
  301. for(n=0;n<dz->all_words;n++) { /* for each sndfile name */
  302. if((exit_status = open_file_and_retrieve_props(n,dz->wordstor[n],&srate,dz))<0)
  303. return(exit_status);
  304. if(dz->mode == 2 && dz->infile->channels != 1) {
  305. sprintf(errstr,"This process only works with mono input files.\n");
  306. return(DATA_ERROR);
  307. }
  308. if((exit_status = create_and_output_mixfile_line(n,max_namelen,&running_total,dz))<0)
  309. return(exit_status);
  310. }
  311. return(FINISHED);
  312. }
  313. /************************* CREATE_AND_OUTPUT_MIXFILE_LINE *******************************/
  314. //TW FUNCTION UPDATED (including flotsam conversion)
  315. int create_and_output_mixfile_line(int infilno,int max_namelen,double *running_total,dataptr dz)
  316. {
  317. int space_count, n;
  318. double filetime = 0.0; /* default value : MIXDUMMY , mode MD_TOGETHER */
  319. if((space_count = max_namelen - strlen(dz->wordstor[infilno]))<0) {
  320. sprintf(errstr,"Anomaly in space counting: create_and_output_mixfile_line()\n");
  321. return(PROGRAM_ERROR);
  322. }
  323. space_count++;
  324. fprintf(dz->fp,"%s",dz->wordstor[infilno]);
  325. for(n=0;n<space_count;n++)
  326. fprintf(dz->fp," ");
  327. switch(dz->process) {
  328. case(MIXDUMMY):
  329. if(dz->mode == MD_FOLLOW) {
  330. filetime = *running_total;
  331. *running_total += (double)(dz->insams[0]/dz->infile->channels)/(double)dz->infile->srate;
  332. }
  333. break;
  334. case(MIX_ON_GRID):
  335. filetime = dz->parray[0][infilno];
  336. break;
  337. case(MIX_AT_STEP):
  338. filetime = *running_total;
  339. *running_total += dz->param[MIX_STEP];
  340. break;
  341. }
  342. switch(dz->infile->channels) {
  343. case(MONO):
  344. if(dz->process == MIXDUMMY && dz->mode == 2) {
  345. if(infilno == 0)
  346. fprintf(dz->fp,"%.4lf 1 1.0 L\n",filetime);
  347. else
  348. fprintf(dz->fp,"%.4lf 1 1.0 R\n",filetime);
  349. } else
  350. fprintf(dz->fp,"%.4lf 1 1.0 C\n",filetime);
  351. break;
  352. case(STEREO): fprintf(dz->fp,"%.4lf 2 1.0 L 1.0 R\n",filetime); break;
  353. default:
  354. sprintf(errstr,"Invalid number of input channels for one of mix input files (Must be mono or stereo).\n");
  355. return(DATA_ERROR);
  356. }
  357. return(FINISHED);
  358. }
  359. /********************** OUTPUT_MIXFILE_LINE ****************************/
  360. int output_mixfile_line(char **wordstor,int *maxwordsize,int start_word_no,int words_in_line,dataptr dz)
  361. {
  362. int space_count, n, m;
  363. int wordno;
  364. for(n = 0;n < words_in_line; n++) {
  365. wordno = start_word_no + n;
  366. fprintf(dz->fp,"%s",wordstor[wordno]);
  367. if((space_count = maxwordsize[n] - strlen(wordstor[wordno]))<0) {
  368. sprintf(errstr,"Error in space_count: output_mixfile_line()\n");
  369. return(PROGRAM_ERROR);
  370. }
  371. space_count++;
  372. for(m=0; m < space_count;m++)
  373. fprintf(dz->fp," ");
  374. }
  375. fprintf(dz->fp,"\n");
  376. return(FINISHED);
  377. }
  378. /********************** MIX_TWISTED ****************************/
  379. int mix_twisted(dataptr dz)
  380. {
  381. int exit_status;
  382. double time, llevel, lpan, rlevel, rpan;
  383. int chans, m;
  384. int n;
  385. char *filename;
  386. int filecnt = 0;
  387. int total_words = 0, initial_total_words;
  388. int *maxwordsize;
  389. if((maxwordsize = (int *)malloc(MIX_MAXLINE * sizeof(int)))==NULL) {
  390. sprintf(errstr,"INSUFFICIENT MEMORY to store maximum word sizes.\n");
  391. return(MEMORY_ERROR);
  392. }
  393. for(m=0;m<MIX_MAXLINE;m++)
  394. maxwordsize[m] = 0;
  395. for(n=0;n<dz->linecnt;n++) {
  396. filename = dz->wordstor[total_words];
  397. if(strlen(filename)<=0) {
  398. free(maxwordsize);
  399. sprintf(errstr,"filename error: line %d: mix_twisted()\n",filecnt+1);
  400. return(PROGRAM_ERROR);
  401. }
  402. if((exit_status = get_mixdata_in_line
  403. (dz->wordcnt[n],dz->wordstor,total_words,&time,&chans,&llevel,&lpan,&rlevel,&rpan,filecnt,dz))<0) {
  404. free(maxwordsize);
  405. return(exit_status);
  406. }
  407. initial_total_words = total_words;
  408. for(m=0;m<dz->wordcnt[n];m++)
  409. maxwordsize[m] = (int)max((int)maxwordsize[m],(int)strlen(dz->wordstor[initial_total_words+m]));
  410. total_words += dz->wordcnt[n];
  411. if((exit_status = finalise_and_check_mixdata_in_line(dz->wordcnt[n],chans,llevel,&lpan,&rlevel,&rpan))<0) {
  412. free(maxwordsize);
  413. return(exit_status);
  414. }
  415. filecnt++;
  416. }
  417. maxwordsize[MIX_PANPOS] = (int)max((int)maxwordsize[MIX_PANPOS],(int)3); /* allow pan to be converted text to number */
  418. maxwordsize[MIX_RPANPOS] = (int)max((int)maxwordsize[MIX_RPANPOS],(int)3);
  419. maxwordsize[MIX_PANPOS]++; /* allow for pan to become negative */
  420. maxwordsize[MIX_RPANPOS]++;
  421. total_words = 0;
  422. filecnt = 0;
  423. for(n=0;n<dz->linecnt;n++) {
  424. filename = dz->wordstor[total_words];
  425. initial_total_words = total_words;
  426. total_words += dz->wordcnt[n];
  427. switch(dz->mode) {
  428. case(MSW_TWISTALL):
  429. if(ODD(filecnt)) {
  430. if((exit_status = twist_mixfile_line(dz->wordstor,maxwordsize,initial_total_words,dz->wordcnt[n],dz))<0) {
  431. free(maxwordsize);
  432. return(exit_status);
  433. }
  434. } else {
  435. if((exit_status = output_mixfile_line(dz->wordstor,maxwordsize,initial_total_words,dz->wordcnt[n],dz))<0) {
  436. free(maxwordsize);
  437. return(exit_status);
  438. }
  439. }
  440. break;
  441. case(MSW_TWISTONE):
  442. if(filecnt == dz->iparam[MSW_TWLINE]) {
  443. if((exit_status = twist_mixfile_line(dz->wordstor,maxwordsize,initial_total_words,dz->wordcnt[n],dz))<0) {
  444. free(maxwordsize);
  445. return(exit_status);
  446. }
  447. } else {
  448. if((exit_status = output_mixfile_line(dz->wordstor,maxwordsize,initial_total_words,dz->wordcnt[n],dz))<0) {
  449. free(maxwordsize);
  450. return(exit_status);
  451. }
  452. }
  453. break;
  454. default:
  455. sprintf(errstr,"Unknown mode in mix_twisted()\n");
  456. return(PROGRAM_ERROR);
  457. }
  458. filecnt++;
  459. }
  460. free(maxwordsize);
  461. return(FINISHED);
  462. }
  463. /********************** TWIST_MIXFILE_LINE ****************************/
  464. int twist_mixfile_line(char **wordstor,int *maxwordsize,int start_word_no,int words_in_line,dataptr dz)
  465. {
  466. int exit_status;
  467. int n;
  468. int wordno;
  469. for(n = 0;n < words_in_line; n++) {
  470. wordno = n + start_word_no;
  471. switch(n) {
  472. case(MIX_NAMEPOS):
  473. case(MIX_TIMEPOS):
  474. case(MIX_CHANPOS):
  475. case(MIX_LEVELPOS):
  476. case(MIX_RLEVELPOS):
  477. if((exit_status = output_aligned_word(wordstor[wordno],maxwordsize[n],dz))<0)
  478. return(exit_status);
  479. break;
  480. case(MIX_PANPOS):
  481. case(MIX_RPANPOS):
  482. if((exit_status = mirror_panning(wordstor[wordno],maxwordsize[n],dz))<0)
  483. return(exit_status);
  484. break;
  485. default:
  486. sprintf(errstr,"Impossible word no: twist_mixfile_line()\n");
  487. return(PROGRAM_ERROR);
  488. }
  489. }
  490. fprintf(dz->fp,"\n");
  491. return(FINISHED);
  492. }
  493. /********************** MIRROR_PANNING ****************************/
  494. int mirror_panning(char *thisword, int maxthiswordsize,dataptr dz)
  495. {
  496. int exit_status;
  497. double pan;
  498. int was_neg = FALSE, newlen, leading_zero_cnt = 0;
  499. char *p;
  500. if(!strcmp(thisword,"C"))
  501. return output_aligned_word(thisword,maxthiswordsize,dz);
  502. else if(!strcmp(thisword,"L"))
  503. return output_aligned_word("R",maxthiswordsize,dz);
  504. else if(!strcmp(thisword,"R"))
  505. return output_aligned_word("L",maxthiswordsize,dz);
  506. else if(sscanf(thisword,"%lf",&pan)!=1) {
  507. sprintf(errstr,"Failed to get pan value 1: mirror_panning()\n");
  508. return(PROGRAM_ERROR);
  509. }
  510. if(flteq(pan,0.0)) {
  511. if((exit_status = output_aligned_word(thisword,maxthiswordsize,dz))<0)
  512. return(exit_status);
  513. } else {
  514. if(pan < 0.0)
  515. was_neg = TRUE;
  516. pan = -pan;
  517. sprintf(errstr,"%lf",pan);
  518. newlen = strlen(thisword);
  519. leading_zero_cnt = 0;
  520. p = thisword;
  521. if(was_neg)
  522. p = thisword+1;
  523. while(*p=='0') {
  524. leading_zero_cnt++;
  525. p++;
  526. }
  527. if(*p=='.') {
  528. if(leading_zero_cnt==0)
  529. newlen++; /* Allow for leading 0 being added */
  530. else
  531. newlen -= leading_zero_cnt - 1; /* Allow for xs leading zeroes being taken away */
  532. }
  533. if(was_neg) newlen--; /* Allow for decimal point being removed */
  534. else newlen++; /* Allow for decimal point being added */
  535. *(errstr + newlen) = ENDOFSTR;
  536. if((exit_status = output_aligned_word(errstr,maxthiswordsize,dz))<0)
  537. return(exit_status);
  538. }
  539. return(FINISHED);
  540. }
  541. /********************** OUTPUT_ALIGNED_WORD ****************************/
  542. int output_aligned_word(char *thisword,int maxthiswordsize,dataptr dz)
  543. {
  544. int space_count, n;
  545. fprintf(dz->fp,"%s",thisword);
  546. if((space_count = maxthiswordsize - strlen(thisword))<0) {
  547. sprintf(errstr,"Error in space_count: output_aligned_word()\n");
  548. return(PROGRAM_ERROR);
  549. }
  550. space_count++;
  551. for(n=0; n < space_count;n++)
  552. fprintf(dz->fp," ");
  553. return(FINISHED);
  554. }
  555. //TW UPDATE: NEW FUNCTION
  556. /********************** ADDTOMIX ****************************/
  557. int addtomix(dataptr dz)
  558. {
  559. int exit_status;
  560. int total_wordcnt, *chans;
  561. int n, m, sndfiles_in = dz->infilecnt - 1;
  562. char temp[200], temp2[200];
  563. infileptr fq;
  564. double maxamp, maxloc;
  565. int maxrep;
  566. int getmax = 0, getmaxinfo = 0;
  567. if(sndfiles_in <= 0) {
  568. sprintf(errstr,"No new sound files remembered.\n");
  569. return(PROGRAM_ERROR);
  570. }
  571. if(dz->linecnt <= 0) {
  572. sprintf(errstr,"None of original mixdata remembered.\n");
  573. return(PROGRAM_ERROR);
  574. }
  575. if((fq = (infileptr)malloc(sizeof(struct filedata)))==NULL) {
  576. sprintf(errstr,"INSUFFICIENT MEMORY to store data on files.\n");
  577. return(MEMORY_ERROR);
  578. }
  579. if ((chans = (int *)malloc(sndfiles_in * sizeof(int)))==NULL) {
  580. sprintf(errstr,"INSUFFICIENT MEMORY to store channel count information.\n");
  581. return(MEMORY_ERROR);
  582. }
  583. for(n = sndfiles_in,m = dz->all_words - 1; n>=1; n--,m--) {
  584. if((exit_status = readhead(fq,dz->ifd[n],dz->wordstor[m],&maxamp,&maxloc,&maxrep,getmax,getmaxinfo))<0) {
  585. sprintf(errstr,"Cannot read header of soundfile %s\n",dz->wordstor[m]);
  586. return(USER_ERROR);
  587. }
  588. if(((chans[n-1] = fq->channels) < 1) || (chans[n-1] > 2)) {
  589. sprintf(errstr,"Soundfile %s has wrong number of channels [%d] for this process.\n",dz->wordstor[m],chans[n-1]);
  590. return(DATA_ERROR);
  591. }
  592. }
  593. total_wordcnt = 0;
  594. for(n=0;n< dz->linecnt;n++) {
  595. for(m=0;m<dz->wordcnt[n];m++) {
  596. if(m==0)
  597. strcpy(temp,dz->wordstor[total_wordcnt++]);
  598. else {
  599. strcat(temp," ");
  600. strcat(temp,dz->wordstor[total_wordcnt++]);
  601. }
  602. if(total_wordcnt >= dz->all_words) {
  603. sprintf(errstr,"Word Count error.\n");
  604. return(PROGRAM_ERROR);
  605. }
  606. }
  607. strcat(temp,"\n");
  608. if(fputs(temp,dz->fp)<0) {
  609. sprintf(errstr,"Failed to write mixfile line %d to output file.\n",n+1);
  610. return(SYSTEM_ERROR);
  611. }
  612. }
  613. m = 0;
  614. while(total_wordcnt < dz->all_words) {
  615. strcpy(temp,dz->wordstor[total_wordcnt]);
  616. sprintf(temp2,"%lf",dz->duration);
  617. strcat(temp," ");
  618. strcat(temp,temp2);
  619. if(chans[m] == 1)
  620. strcat(temp," 1 1.0 C\n");
  621. else
  622. strcat(temp," 2 1.0 L 1.0 R\n");
  623. if(fputs(temp,dz->fp)<0) {
  624. sprintf(errstr,"Failed to write mixfile line %d to output file.\n",n+1);
  625. return(SYSTEM_ERROR);
  626. }
  627. if(++total_wordcnt > dz->all_words) {
  628. sprintf(errstr,"Word Count error.\n");
  629. return(PROGRAM_ERROR);
  630. }
  631. m++;
  632. n++;
  633. }
  634. return(FINISHED);
  635. }