setupmix.c 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880
  1. /*
  2. * Copyright (c) 1983-2023 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 <processno.h>
  27. #include <tkglobals.h>
  28. #include <mix.h>
  29. #include <globcon.h>
  30. #include <cdpmain.h>
  31. #include <filetype.h>
  32. #include <sfsys.h>
  33. #ifdef unix
  34. #define round(x) lround((x))
  35. #endif
  36. static int establish_action_value_storage_for_mix(dataptr dz);
  37. static int open_file_and_get_props(int filecnt,char *filename,int *srate,int chans,dataptr dz);
  38. static int allocate_actions(int filecnt,dataptr dz);
  39. static int assign_stereo_sense(int chans,double lpan,double rpan,double llevel,double rlevel,dataptr dz);
  40. static int unmark_freeable_bufs(int **bufsflag,int *bufsflagcnt,int startpos,int this,int longbitsize,dataptr dz);
  41. static int get_free_buf(int **bufsflag,int *bufsflagcnt,int longbitsize,int *thisbuf,dataptr dz);
  42. #ifdef NOTDEF
  43. static int assign_scaling(int here,double llevel,double rlevel,double lpan,double rpan,
  44. int *llscale,int *rrscale,int *lrscale,int *rlscale,dataptr dz);
  45. #else
  46. static int d_assign_scaling(int here,double llevel,double rlevel,double lpan,double rpan,
  47. double *llscale,double *rrscale,double *lrscale,double *rlscale,dataptr dz);
  48. #endif
  49. static int check_right_level(char *str,double *rlevel,int filecnt);
  50. static int check_right_pan(char *str,double *pan,int filecnt);
  51. static int check_left_pan(char *str,double *pan,int filecnt);
  52. static int check_left_level(char *str,double *level,int filecnt);
  53. static int unmark_buf(int **bufsflag,int *bufsflagcnt,int thisbuf,int longbitsize);
  54. static int mark_buf(int **bufsflag,int *bufsflagcnt,int thisbuf,int longbitsize,dataptr dz);
  55. static int reallocate_bufsflag(int z,int **bufsflag,int *bufsflagcnt);
  56. /********************** SET_UP_MIX ****************************/
  57. int set_up_mix(dataptr dz)
  58. {
  59. int exit_status;
  60. double time, llevel, lpan, rlevel, rpan;
  61. int chans;
  62. int startpos, endpos, n;
  63. int *bufsflag = NULL;
  64. int bufsflagcnt = 0;
  65. double filetime, eventend;
  66. int longbitsize = sizeof(int) * CHARBITSIZE;
  67. int srate=0, end_of_mix = -1;
  68. int mix_end_set = FALSE;
  69. int mix_end_specified = FALSE;
  70. int mix_start_set = FALSE;
  71. char *filename;
  72. int filecnt = 0;
  73. int total_words = 0;
  74. if(dz->param[MIX_START] >= dz->param[MIX_END]) {
  75. sprintf(errstr,"Mix starts after it ends.\n");
  76. return(USER_ERROR);
  77. }
  78. dz->iparam[MIX_STRTPOS] = 0;
  79. dz->iparam[MIX_STRTPOS_IN_ACTION] = 0;
  80. dz->iparam[MIX_TOTAL_ACTCNT] = 0;
  81. if((exit_status = establish_file_data_storage_for_mix(dz->linecnt,dz))<0)
  82. return(exit_status);
  83. if((exit_status = establish_action_value_storage_for_mix(dz))<0)
  84. return(exit_status);
  85. for(n=0;n<dz->linecnt;n++) { /* for each mixfile line */
  86. filename = dz->wordstor[total_words]; /* get the filename */
  87. if(strlen(filename)<=0) {
  88. sprintf(errstr,"filename error: line %d: parse_mixfile_for_data()\n",filecnt+1);
  89. return(PROGRAM_ERROR);
  90. }
  91. if((exit_status = get_mixdata_in_line
  92. (dz->wordcnt[n],dz->wordstor,total_words,&time,&chans,&llevel,&lpan,&rlevel,&rpan,filecnt,dz))<0)
  93. return(exit_status);
  94. total_words += dz->wordcnt[n];
  95. if(time >= dz->param[MIX_END]) /* If line starts after specified mix end, ignore */
  96. continue;
  97. if((exit_status = finalise_and_check_mixdata_in_line(dz->wordcnt[n],chans,llevel,&lpan,&rlevel,&rpan))<0)
  98. return(exit_status);
  99. if((exit_status = open_file_and_get_props(filecnt,filename,&srate,chans,dz))<0)
  100. return(exit_status);
  101. filetime = (double)(dz->insams[filecnt]/chans)/(double)srate;
  102. if((eventend = time + filetime) < dz->param[MIX_START]) /* If line ends before specified mix start, ignore */
  103. continue;
  104. if(!mix_start_set) { /* if mix start param not set yet, set it */
  105. dz->iparam[MIX_STRTPOS] = (int)round(dz->param[MIX_START] * (double)(srate * dz->out_chans));
  106. dz->iparam[MIX_STRTPOS_IN_ACTION] = dz->iparam[MIX_STRTPOS];
  107. mix_start_set = TRUE;
  108. }
  109. if(!mix_end_set) { /* if mix end param not set yet, set it */
  110. if(!flteq(dz->param[MIX_END],dz->application->default_val[MIX_END])) { /* if mixend param given by user */
  111. end_of_mix = round(dz->param[MIX_END] * (double)srate) * dz->out_chans;
  112. if(end_of_mix < 0) {
  113. sprintf(errstr,"Error in end_of_mix logic: parse_mixfile_for_data()\n");
  114. return(PROGRAM_ERROR);
  115. }
  116. mix_end_specified = TRUE;
  117. }
  118. mix_end_set = TRUE;
  119. }
  120. if((exit_status = allocate_actions(filecnt,dz))<0) /* assign values to mix ON and OFF actions */
  121. return(exit_status);
  122. startpos = round(time * (double)srate) * chans; /* startposition, in samples, of this file */
  123. dz->valstor[filecnt]->stereo = assign_stereo_sense(chans,lpan,rpan,llevel,rlevel,dz);
  124. if(dz->valstor[filecnt]->stereo == MONO_TO_STEREO
  125. || dz->valstor[filecnt]->stereo == MONO_TO_CENTRE
  126. || dz->valstor[filecnt]->stereo == MONO_TO_LEFT
  127. || dz->valstor[filecnt]->stereo == MONO_TO_RIGHT) {
  128. startpos *= STEREO; /* startposition, in output samples, of this file */
  129. dz->insams[filecnt] *= STEREO; /* EFFECTIVE sample-dur of file: it's converted to stereo */
  130. }
  131. if((exit_status = unmark_freeable_bufs /* finds buffers which are not (any longer) in use */
  132. (&bufsflag,&bufsflagcnt,startpos,dz->iparam[MIX_TOTAL_ACTCNT],longbitsize,dz))<0)
  133. return(exit_status);
  134. dz->valstor[filecnt]->ifd = dz->ifd[filecnt];
  135. if((exit_status = get_free_buf(&bufsflag,&bufsflagcnt,longbitsize,&(dz->valstor[filecnt]->bufno),dz))<0)
  136. return(exit_status); /* Allocate a buffer which is not currently in use */
  137. if((exit_status = d_assign_scaling(dz->iparam[MIX_TOTAL_ACTCNT],llevel,rlevel,lpan,rpan,
  138. &(dz->valstor[filecnt]->llscale),&(dz->valstor[filecnt]->rrscale),
  139. &(dz->valstor[filecnt]->lrscale),&(dz->valstor[filecnt]->rlscale),dz))<0)
  140. return(exit_status); /* Assign the input sound amplitude scaling */
  141. endpos = startpos + dz->insams[filecnt]; /* Find end-of-current-file in output stream */
  142. if(mix_end_specified && (end_of_mix < endpos)) { /* If file ends aftert mix ends */
  143. endpos = end_of_mix; /* curtail (effective) length */
  144. dz->insams[filecnt] = end_of_mix - startpos;
  145. }
  146. dz->valstor[filecnt]->samplen = dz->insams[filecnt]; /* store (effective) length */
  147. dz->act[dz->iparam[MIX_TOTAL_ACTCNT]++]->position = startpos; /* store outputstream-position of mix start */
  148. dz->act[dz->iparam[MIX_TOTAL_ACTCNT]++]->position = endpos; /* store outputstream-position of mix end */
  149. filecnt++; /* count the ACTUALLY USED lines */
  150. }
  151. if(!mix_end_set || filecnt==0) {
  152. sprintf(errstr,"No mixfile line is active within the time limits specified.\n");
  153. return(DATA_ERROR);
  154. }
  155. if(bufsflagcnt)
  156. free(bufsflag);
  157. dz->bufcnt++; /* bufcnt is number assigned to highest assigned buf, COUNTING FROM ZERO */
  158. /* Hence, actual bufcnt is 1 more than this */
  159. dz->infile->channels = dz->out_chans; /* output channels(evenutally derived from dz->infile->channels) */
  160. //TW SET UP AFTER OUTCHANS KNOWN
  161. if(dz->process!=MIXMAX) {
  162. if((exit_status = create_sized_outfile(dz->outfilename,dz))<0)
  163. return(exit_status);
  164. }
  165. return(FINISHED); /* is highest number of channels encountered in infiles */
  166. }
  167. /**************************** ESTABLISH_FILE_DATA_STORAGE_FOR_MIX ********************************/
  168. int establish_file_data_storage_for_mix(int filecnt,dataptr dz)
  169. {
  170. int n;
  171. if(dz->insams!=NULL)
  172. free(dz->insams); /* in TK insams[0] also used in parse accounting */
  173. if(dz->ifd!=NULL)
  174. free(dz->ifd);
  175. if((dz->insams = (int *)malloc(filecnt * sizeof(int)))==NULL) {
  176. sprintf(errstr,"INSUFFICIENT MEMORY to allocate infile samplesize array.\n");
  177. return(MEMORY_ERROR);
  178. }
  179. if((dz->ifd = (int *)malloc(filecnt * sizeof(int)))==NULL) {
  180. sprintf(errstr,"INSUFFICIENT MEMORY to allocate infile pointers array.\n");
  181. return(MEMORY_ERROR);
  182. }
  183. for(n=0;n<filecnt;n++)
  184. dz->ifd[n] = -1;
  185. return(FINISHED);
  186. }
  187. /**************************** ESTABLISH_ACTION_VALUE_STORAGE_FOR_MIX ********************************/
  188. int establish_action_value_storage_for_mix(dataptr dz)
  189. {
  190. int n;
  191. if((dz->valstor = (actvalptr *)malloc(dz->linecnt * sizeof(actvalptr)))==NULL) {
  192. sprintf(errstr,"INSUFFICIENT MEMORY for mix action values store.\n");
  193. return(MEMORY_ERROR);
  194. }
  195. for(n=0;n<dz->linecnt;n++) {
  196. dz->valstor[n] = NULL;
  197. if((dz->valstor[n]=(actvalptr)malloc(sizeof(struct actval)))==NULL) {
  198. sprintf(errstr,"INSUFFICIENT MEMORY for mix action value store %d\n",n+1);
  199. return(MEMORY_ERROR);
  200. }
  201. }
  202. return(FINISHED);
  203. }
  204. /**************************** GET_MIXDATA_IN_LINE ********************************/
  205. int get_mixdata_in_line(int wordcnt,char **wordstor,int total_words,double *time,int *chans,
  206. double *llevel,double *lpan,double *rlevel,double *rpan,int filecnt,dataptr dz)
  207. {
  208. int exit_status;
  209. switch(wordcnt) {
  210. case(MIX_MAXLINE):
  211. if((exit_status = check_right_level(wordstor[total_words+MIX_RLEVELPOS],rlevel,filecnt))<0) /* 6d */
  212. return(exit_status);
  213. if((exit_status = check_right_pan(wordstor[total_words+MIX_RPANPOS],rpan,filecnt))<0)
  214. return(exit_status);
  215. /* fall thro */
  216. case(MIX_MIDLINE):
  217. if((exit_status = check_left_pan(wordstor[total_words+MIX_PANPOS],lpan,filecnt))<0) /* 6c */
  218. return(exit_status);
  219. /* fall thro */
  220. case(MIX_MINLINE):
  221. if(sscanf(dz->wordstor[total_words+1],"%lf",time)!=1
  222. || sscanf(dz->wordstor[total_words+2],"%d",chans)!=1) {
  223. sprintf(errstr,"Error scanning data: get_mixdata_in_line()\n");
  224. return(PROGRAM_ERROR);
  225. }
  226. if((exit_status = check_left_level(wordstor[total_words+3],llevel,filecnt))<0)
  227. return(exit_status);
  228. break;
  229. default:
  230. sprintf(errstr,"Illegal line length: get_mixdata_in_line()\n");
  231. return(PROGRAM_ERROR);
  232. }
  233. return(FINISHED);
  234. }
  235. /**************************** FINALISE_AND_CHECK_MIXDATA_IN_LINE ********************************/
  236. int finalise_and_check_mixdata_in_line(int wordcnt,int chans,double llevel,
  237. double *lpan,double *rlevel,double *rpan)
  238. {
  239. switch(wordcnt) {
  240. case(MIX_MINLINE):
  241. switch(chans) {
  242. case(1):
  243. *lpan = 0.0; /* 6a */
  244. break;
  245. case(2):
  246. *rlevel = llevel; /* 6b */
  247. *lpan = -1.0;
  248. *rpan = 1.0;
  249. }
  250. break;
  251. case(MIX_MIDLINE):
  252. if(chans!=1) {
  253. sprintf(errstr,"Error parsing data: finalise_and_check_mixdata_in_line()\n");
  254. return(PROGRAM_ERROR);
  255. }
  256. break;
  257. case(MIX_MAXLINE):
  258. if(chans!=2) {
  259. sprintf(errstr,"Error parsing data: finalise_and_check_mixdata_in_line()\n");
  260. return(PROGRAM_ERROR);
  261. }
  262. break;
  263. }
  264. return(FINISHED);
  265. }
  266. /************************* OPEN_FILE_AND_GET_PROPS *******************************/
  267. int open_file_and_get_props(int filecnt,char *filename,int *srate,int chans,dataptr dz)
  268. {
  269. int exit_status;
  270. double maxamp, maxloc;
  271. int maxrep;
  272. int getmax = 0, getmaxinfo = 0;
  273. infileptr ifp;
  274. if((ifp = (infileptr)malloc(sizeof(struct filedata)))==NULL) {
  275. sprintf(errstr,"INSUFFICIENT MEMORY to store data on files.\n");
  276. return(MEMORY_ERROR);
  277. }
  278. if((dz->ifd[filecnt] = sndopenEx(filename,0,CDP_OPEN_RDONLY)) < 0) {
  279. sprintf(errstr,"Failed to open sndfile %s: %s\n",filename,sferrstr());
  280. return(SYSTEM_ERROR);
  281. }
  282. if((exit_status = readhead(ifp,dz->ifd[filecnt],filename,&maxamp,&maxloc,&maxrep,getmax,getmaxinfo))<0)
  283. return(exit_status);
  284. copy_to_fileptr(ifp,dz->infile);
  285. if(dz->infile->filetype!=SNDFILE) {
  286. sprintf(errstr,"Non soundfile encountered [%s]: open_file_and_get_props()\n",filename);
  287. return(PROGRAM_ERROR);
  288. }
  289. if(dz->infile->channels!=chans) {
  290. sprintf(errstr,"Incorrect channels found [%s]: open_file_and_get_props()\n",filename);
  291. return(PROGRAM_ERROR);
  292. }
  293. if(filecnt==0)
  294. *srate = dz->infile->srate;
  295. else if(dz->infile->srate != *srate) {
  296. sprintf(errstr,"incompatible srates: [file %s] open_file_and_get_props()\n",filename);
  297. return(PROGRAM_ERROR);
  298. }
  299. if((dz->insams[filecnt] = sndsizeEx(dz->ifd[filecnt]))<0) {
  300. sprintf(errstr, "Can't read size of input file %s: open_file_and_get_props()\n",filename);
  301. return(PROGRAM_ERROR);
  302. }
  303. if(dz->insams[filecnt] <=0) {
  304. sprintf(errstr, "Zero size for input file %s: open_file_and_get_props()\n",filename);
  305. return(PROGRAM_ERROR);
  306. }
  307. return(FINISHED);
  308. }
  309. /*********************** ALLOCATE_ACTIONS *************************/
  310. int allocate_actions(int filecnt,dataptr dz)
  311. {
  312. int new_total = dz->iparam[MIX_TOTAL_ACTCNT] + 2;
  313. if(dz->iparam[MIX_TOTAL_ACTCNT]==0) {
  314. if((dz->act = (actptr *)malloc(new_total * sizeof(actptr)))==NULL) {
  315. sprintf(errstr,"INSUFFICIENT MEMORY for mix actions store.\n");
  316. return(MEMORY_ERROR);
  317. }
  318. } else {
  319. if((dz->act=(actptr *)realloc(dz->act,new_total * sizeof(actptr)))==NULL) {
  320. sprintf(errstr,"INSUFFICIENT MEMORY ro reallocate mix actions store.\n");
  321. return(MEMORY_ERROR);
  322. }
  323. }
  324. if((dz->act[dz->iparam[MIX_TOTAL_ACTCNT]] = (actptr)malloc(sizeof(struct action)))==NULL) {
  325. sprintf(errstr,"INSUFFICIENT MEMORY for final mix action store.\n");
  326. return(MEMORY_ERROR);
  327. }
  328. dz->act[dz->iparam[MIX_TOTAL_ACTCNT]]->val = dz->valstor[filecnt];
  329. dz->act[dz->iparam[MIX_TOTAL_ACTCNT]]->role = MIX_ACTION_ON;
  330. if((dz->act[dz->iparam[MIX_TOTAL_ACTCNT]+1] = (actptr)malloc(sizeof(struct action)))==NULL) {
  331. sprintf(errstr,"INSUFFICIENT MEMORY for further mix action store.\n");
  332. return(MEMORY_ERROR);
  333. }
  334. dz->act[dz->iparam[MIX_TOTAL_ACTCNT]+1]->val = dz->valstor[filecnt];
  335. dz->act[dz->iparam[MIX_TOTAL_ACTCNT]+1]->role = MIX_ACTION_OFF;
  336. return(FINISHED);
  337. }
  338. /********************* ASSIGN_STEREO_SENSE **************************/
  339. int assign_stereo_sense(int chans,double lpan,double rpan,double llevel,double rlevel,dataptr dz)
  340. {
  341. switch(chans) {
  342. case(MONO):
  343. if(dz->out_chans==MONO) return(MONO);
  344. else if(lpan <= -1.0) return(MONO_TO_LEFT);
  345. else if(lpan >= 1.0) return(MONO_TO_RIGHT);
  346. else if(flteq(lpan,0.0)) return(MONO_TO_CENTRE);
  347. else return(MONO_TO_STEREO);
  348. break;
  349. case(STEREO):
  350. if(flteq(rlevel,0.0)) {
  351. if(lpan <= -1.0) return(STEREOLEFT_TO_LEFT);
  352. else if(lpan >= 1.0) return(STEREOLEFT_TO_RIGHT);
  353. else return(STEREOLEFT_PANNED);
  354. }
  355. else if(flteq(llevel,0.0)) {
  356. if(rpan <= -1.0) return(STEREORIGHT_TO_LEFT);
  357. else if(rpan >= 1.0) return(STEREORIGHT_TO_RIGHT);
  358. else return(STEREORIGHT_PANNED);
  359. } else if(lpan <= -1.0 && rpan >= 1.0) return(STEREO);
  360. else if(lpan >= 1.0 && rpan <= -1.0) return(STEREO_MIRROR);
  361. else if(flteq(lpan,0.0) && flteq(rpan,0.0) && flteq(rlevel,llevel)) return(STEREO_TO_CENTRE);
  362. else if((lpan <= -1.0) && flteq(rpan,lpan) && flteq(rlevel,llevel)) return(STEREO_TO_LEFT);
  363. else if((rpan >= 1.0) && flteq(rpan,lpan) && flteq(rlevel,llevel)) return(STEREO_TO_RIGHT);
  364. break;
  365. }
  366. return(STEREO_PANNED);
  367. }
  368. /************************* UNMARK_FREEABLE_BUFS ***********************
  369. *
  370. * (1) If a buffer has been switched off BEFORE now, then it is
  371. * available for use!! unmark it!!
  372. * (2) If a buffer is subsequently turned back on, this catches it!!
  373. * A buffer can ONLY be turned back on LATER (!), and is hence
  374. * LATER in this list EVEN though it is not yet fully time-sorted!! (1998 ???)
  375. */
  376. int unmark_freeable_bufs(int **bufsflag,int *bufsflagcnt,int startpos,int this,int longbitsize,dataptr dz)
  377. {
  378. int exit_status;
  379. int n;
  380. for(n=0;n<this;n++) {
  381. switch(dz->act[n]->role) {
  382. case(MIX_ACTION_ON): /* 2 */
  383. if((exit_status = mark_buf(bufsflag,bufsflagcnt,dz->act[n]->val->bufno,longbitsize,dz))<0)
  384. return(exit_status);
  385. break;
  386. case(MIX_ACTION_OFF): /* 1 */
  387. if(dz->act[n]->position < startpos) {
  388. if((exit_status = unmark_buf(bufsflag,bufsflagcnt,dz->act[n]->val->bufno,longbitsize))<0)
  389. return(exit_status);
  390. }
  391. break;
  392. }
  393. }
  394. return(FINISHED);
  395. }
  396. /************************** GET_FREE_BUF ***************************
  397. *
  398. * Get the FIRST available free buffer.
  399. * (1) Going through each int.
  400. * (2) Set the mask to start of int.
  401. * (3) For each position in the int..
  402. * (4) If that byte is NOT set, break, thisbuf counts which byte
  403. * and therefore which buffer it is.
  404. * (5) Advance the mask.
  405. * (6) Advance the buffer counter.
  406. * (7) Set the appropriate bit for this buffer, return buffer no.
  407. */
  408. int get_free_buf(int **bufsflag,int *bufsflagcnt,int longbitsize,int *thisbuf,dataptr dz)
  409. {
  410. int exit_status=0;
  411. int y=0, z=0, got_it = 0;
  412. int mask=0;
  413. *thisbuf = 0;
  414. for(z=0;z<*bufsflagcnt;z++) { /* 1 */
  415. mask = 1; /* 2 */
  416. for(y=0;y<longbitsize;y++) { /* 3 */
  417. if(!(mask & (*bufsflag)[z])) { /* 4 */
  418. got_it = 1;
  419. break;
  420. }
  421. mask <<= 1; /* 5 */
  422. (*thisbuf)++; /* 6 */
  423. }
  424. if(got_it)
  425. break;
  426. }
  427. if((exit_status = mark_buf(bufsflag,bufsflagcnt,*thisbuf,longbitsize,dz))<0) /* 7 */
  428. return(exit_status);
  429. return(FINISHED);
  430. }
  431. /*************************** ASSIGN_SCALING ***************************/
  432. /*RWD gulp! */
  433. #ifdef NOTDEF
  434. int assign_scaling(int here,double llevel,double rlevel,double lpan,double rpan,
  435. int *llscale,int *rrscale,int *lrscale,int *rlscale,dataptr dz)
  436. {
  437. switch(dz->act[here]->val->stereo) {
  438. case(MONO):
  439. if(lpan < -1.0 - FLTERR) *llscale = round(llevel * TWO_POW_15/(-lpan));
  440. else if(lpan > 1.0 + FLTERR) *llscale = round(llevel * TWO_POW_15/lpan);
  441. else *llscale = round(llevel * TWO_POW_15);
  442. break;
  443. case(MONO_TO_CENTRE):
  444. case(STEREO_TO_CENTRE): *llscale = round(llevel * TWO_POW_15);
  445. break;
  446. case(MONO_TO_LEFT):
  447. case(STEREO_TO_LEFT):
  448. case(STEREOLEFT_TO_LEFT):
  449. if(lpan<(-1. - FLTERR)) *llscale = round(llevel * TWO_POW_15/(-lpan));
  450. else *llscale = round(llevel * TWO_POW_15);
  451. break;
  452. case(STEREORIGHT_TO_LEFT):
  453. if(lpan<(-1. - FLTERR)) *llscale = round(rlevel * TWO_POW_15/(-lpan));
  454. else *llscale = round(rlevel * TWO_POW_15);
  455. break;
  456. case(MONO_TO_RIGHT):
  457. case(STEREOLEFT_TO_RIGHT):
  458. if(lpan>(1. + FLTERR)) *rrscale = round(llevel * TWO_POW_15/(lpan));
  459. else *rrscale = round(llevel * TWO_POW_15);
  460. break;
  461. case(STEREO_TO_RIGHT):
  462. case(STEREORIGHT_TO_RIGHT):
  463. if(rpan>(1. + FLTERR)) *rrscale = round(rlevel * TWO_POW_15/rpan);
  464. else *rrscale = round(rlevel * TWO_POW_15);
  465. break;
  466. case(STEREO):
  467. if(lpan < -1.0 - FLTERR) *llscale = round(llevel * TWO_POW_15/(-lpan));
  468. else *llscale = round(llevel * TWO_POW_15);
  469. if(rpan > 1.0 + FLTERR) *rrscale = round(rlevel * TWO_POW_15/rpan);
  470. else *rrscale = round(rlevel * TWO_POW_15);
  471. break;
  472. case(STEREO_MIRROR):
  473. if(lpan > 1.0 + FLTERR) *llscale = round(llevel * TWO_POW_15/(lpan));
  474. else *llscale = round(llevel * TWO_POW_15);
  475. if(rpan < -1.0 - FLTERR) *rrscale = round(rlevel * TWO_POW_15/(-rpan));
  476. else *rrscale = round(rlevel * TWO_POW_15);
  477. break;
  478. case(MONO_TO_STEREO):
  479. case(STEREOLEFT_PANNED):
  480. if(lpan < -1.0 - FLTERR) { /* VERY LEFT */
  481. *llscale = round(llevel * TWO_POW_15/(-lpan));
  482. *rrscale = 0;
  483. } else if(lpan < 0.0) { /* LEFTWARDS */
  484. *llscale = round(llevel * TWO_POW_15);
  485. *rrscale = round(llevel * (1.0+lpan) * TWO_POW_15);
  486. } else if(lpan <= 1.0) { /* RIGHTWARDS */
  487. *llscale = round(llevel * (1.0-lpan) * TWO_POW_15);
  488. *rrscale = round(llevel * TWO_POW_15);
  489. } else { /* VERY RIGHT */
  490. *llscale = 0;
  491. *rrscale = round(llevel * TWO_POW_15/(lpan));
  492. }
  493. break;
  494. case(STEREORIGHT_PANNED):
  495. if(rpan < -1.0) { /* VERY LEFT */
  496. *llscale = round(rlevel * TWO_POW_15/(-rpan));
  497. *rrscale = 0;
  498. } else if(rpan < 0.0) { /* LEFTWARDS */
  499. *llscale = round(rlevel * TWO_POW_15);
  500. *rrscale = round(rlevel * (1.0+rpan) * TWO_POW_15);
  501. } else if(rpan <= 1.0) { /* RIGHTWARDS */
  502. *llscale = round(rlevel * (1.0-rpan) * TWO_POW_15);
  503. *rrscale = round(rlevel * TWO_POW_15);
  504. } else { /* VERY RIGHT */
  505. *llscale = 0;
  506. *rrscale = round(rlevel * TWO_POW_15/rpan);
  507. }
  508. break;
  509. case(STEREO_PANNED):
  510. /* LEFT STEREO INPUT PANNED ... */
  511. if(lpan < -1.0) { /* VERY LEFT */
  512. *llscale = round(llevel * TWO_POW_15/(-lpan));
  513. *lrscale = 0;
  514. } else if(lpan < 0.0) { /* LEFTWARDS */
  515. *llscale = round(llevel * TWO_POW_15);
  516. *lrscale = round(llevel * (1.0+lpan) * TWO_POW_15);
  517. } else if(lpan <= 1.0) { /* RIGHTWARDS */
  518. *llscale = round(llevel * (1.0-lpan) * TWO_POW_15);
  519. *lrscale = round(llevel * TWO_POW_15);
  520. } else { /* VERY RIGHT */
  521. *llscale = 0;
  522. *lrscale = round(llevel * TWO_POW_15/(lpan));
  523. }
  524. /* RIGHT STEREO INPUT PANNED ... */
  525. if(rpan < -1.0) { /* VERY LEFT */
  526. *rlscale = round(rlevel * TWO_POW_15/(-rpan));
  527. *rrscale = 0;
  528. } else if(rpan < 0.0) { /* LEFTWARDS */
  529. *rlscale = round(rlevel * TWO_POW_15);
  530. *rrscale = round(rlevel * (1.0+rpan) * TWO_POW_15);
  531. } else if(rpan <= 1.0) { /* RIGHTWARDS */
  532. *rlscale = round(rlevel * (1.0-rpan) * TWO_POW_15);
  533. *rrscale = round(rlevel * TWO_POW_15);
  534. } else { /* VERY RIGHT */
  535. *rlscale = 0;
  536. *rrscale = round(rlevel * TWO_POW_15/(rpan));
  537. }
  538. break;
  539. default:
  540. sprintf(errstr,"Unknown case in assign_scaling()\n");
  541. return(PROGRAM_ERROR);
  542. }
  543. return(FINISHED);
  544. }
  545. #else
  546. int d_assign_scaling(int here,double llevel,double rlevel,double lpan,double rpan,
  547. double *llscale,double *rrscale,double *lrscale,double *rlscale,dataptr dz)
  548. {
  549. switch(dz->act[here]->val->stereo) {
  550. case(MONO):
  551. if(lpan < -1.0 - FLTERR) *llscale = llevel/(-lpan);
  552. else if(lpan > 1.0 + FLTERR) *llscale = llevel/lpan;
  553. else *llscale = llevel;
  554. break;
  555. case(MONO_TO_CENTRE):
  556. case(STEREO_TO_CENTRE): *llscale = llevel;
  557. break;
  558. case(MONO_TO_LEFT):
  559. case(STEREO_TO_LEFT):
  560. case(STEREOLEFT_TO_LEFT):
  561. if(lpan<(-1. - FLTERR)) *llscale = llevel/(-lpan);
  562. else *llscale = llevel;
  563. break;
  564. case(STEREORIGHT_TO_LEFT):
  565. if(lpan<(-1. - FLTERR)) *llscale = rlevel/(-lpan);
  566. else *llscale = rlevel;
  567. break;
  568. case(MONO_TO_RIGHT):
  569. case(STEREOLEFT_TO_RIGHT):
  570. if(lpan>(1. + FLTERR)) *rrscale = llevel/lpan;
  571. else *rrscale = llevel;
  572. break;
  573. case(STEREO_TO_RIGHT):
  574. case(STEREORIGHT_TO_RIGHT):
  575. if(rpan>(1. + FLTERR)) *rrscale = rlevel/rpan;
  576. else *rrscale = rlevel;
  577. break;
  578. case(STEREO):
  579. if(lpan < -1.0 - FLTERR) *llscale = llevel/(-lpan);
  580. else *llscale = llevel;
  581. if(rpan > 1.0 + FLTERR) *rrscale = rlevel/rpan;
  582. else *rrscale = rlevel;
  583. break;
  584. case(STEREO_MIRROR):
  585. if(lpan > 1.0 + FLTERR) *llscale = llevel/lpan;
  586. else *llscale = llevel;
  587. if(rpan < -1.0 - FLTERR) *rrscale = rlevel/(-rpan);
  588. else *rrscale = rlevel;
  589. break;
  590. case(MONO_TO_STEREO):
  591. case(STEREOLEFT_PANNED):
  592. if(lpan < -1.0 - FLTERR) { /* VERY LEFT */
  593. *llscale = llevel/(-lpan);
  594. *rrscale = 0.0;
  595. } else if(lpan < 0.0) { /* LEFTWARDS */
  596. *llscale = llevel;
  597. *rrscale = llevel * (1.0+lpan);
  598. } else if(lpan <= 1.0) { /* RIGHTWARDS */
  599. *llscale = llevel * (1.0-lpan);
  600. *rrscale = llevel;
  601. } else { /* VERY RIGHT */
  602. *llscale = 0.0;
  603. *rrscale = llevel/lpan;
  604. }
  605. break;
  606. case(STEREORIGHT_PANNED):
  607. if(rpan < -1.0) { /* VERY LEFT */
  608. *llscale = rlevel/(-rpan);
  609. *rrscale = 0.0;
  610. } else if(rpan < 0.0) { /* LEFTWARDS */
  611. *llscale = rlevel;
  612. *rrscale = rlevel * (1.0+rpan);
  613. } else if(rpan <= 1.0) { /* RIGHTWARDS */
  614. *llscale = rlevel * (1.0-rpan);
  615. *rrscale = rlevel;
  616. } else { /* VERY RIGHT */
  617. *llscale = 0.0;
  618. *rrscale = rlevel/rpan;
  619. }
  620. break;
  621. case(STEREO_PANNED):
  622. /* LEFT STEREO INPUT PANNED ... */
  623. if(lpan < -1.0) { /* VERY LEFT */
  624. *llscale = llevel /(-lpan);
  625. *lrscale = 0.0;
  626. } else if(lpan < 0.0) { /* LEFTWARDS */
  627. *llscale = llevel;
  628. *lrscale = llevel * (1.0+lpan);
  629. } else if(lpan <= 1.0) { /* RIGHTWARDS */
  630. *llscale = llevel * (1.0-lpan);
  631. *lrscale = llevel;
  632. } else { /* VERY RIGHT */
  633. *llscale = 0.0;
  634. *lrscale = llevel/lpan;
  635. }
  636. /* RIGHT STEREO INPUT PANNED ... */
  637. if(rpan < -1.0) { /* VERY LEFT */
  638. *rlscale = rlevel/(-rpan);
  639. *rrscale = 0.0;
  640. } else if(rpan < 0.0) { /* LEFTWARDS */
  641. *rlscale = rlevel;
  642. *rrscale = rlevel * (1.0+rpan);
  643. } else if(rpan <= 1.0) { /* RIGHTWARDS */
  644. *rlscale = rlevel * (1.0-rpan);
  645. *rrscale = rlevel ;
  646. } else { /* VERY RIGHT */
  647. *rlscale = 0.0;
  648. *rrscale = rlevel/rpan;
  649. }
  650. break;
  651. default:
  652. sprintf(errstr,"Unknown case in assign_scaling()\n");
  653. return(PROGRAM_ERROR);
  654. }
  655. return(FINISHED);
  656. }
  657. #endif
  658. /************************** CHECK_RIGHT_LEVEL ************************/
  659. int check_right_level(char *str,double *rlevel,int filecnt)
  660. {
  661. if(is_dB(str)) {
  662. if(!get_leveldb(str,rlevel)) {
  663. sprintf(errstr,"Error1 scanning chan2 level: line %d\n",filecnt+1);
  664. return(PROGRAM_ERROR);
  665. }
  666. } else {
  667. if(sscanf(str,"%lf",rlevel)!=1) {
  668. sprintf(errstr,"Error2 scanning chan2 level: line %d\n",filecnt+1);
  669. return(PROGRAM_ERROR);
  670. }
  671. }
  672. if(*rlevel < 0.0) {
  673. sprintf(errstr,"Error3 scanning chan2 level: line %d\n",filecnt+1);
  674. return(PROGRAM_ERROR);
  675. }
  676. return(FINISHED);
  677. }
  678. /*********************** CHECK_RIGHT_PAN **********************/
  679. int check_right_pan(char *str,double *pan,int filecnt)
  680. {
  681. switch(str[0]) {
  682. case('L'): *pan = -1.0; break;
  683. case('R'): *pan = 1.0; break;
  684. case('C'): *pan = 0.5; break;
  685. default:
  686. if(sscanf(str,"%lf",pan)!=1) {
  687. sprintf(errstr,"Error1 scanning chan2 pan: line %d\n",filecnt+1);
  688. return(PROGRAM_ERROR);
  689. }
  690. if(*pan < MINPAN || *pan > MAXPAN) {
  691. sprintf(errstr,"Error2 scanning chan2 pan: line %d\n",filecnt+1);
  692. return(PROGRAM_ERROR);
  693. }
  694. break;
  695. }
  696. return(FINISHED);
  697. }
  698. /************************** CHECK_LEFT_PAN ************************/
  699. int check_left_pan(char *str,double *pan,int filecnt)
  700. {
  701. switch(str[0]) {
  702. case('L'): *pan = -1.0; break;
  703. case('R'): *pan = 1.0; break;
  704. case('C'): *pan = 0.0; break;
  705. default:
  706. if(sscanf(str,"%lf",pan)!=1) {
  707. sprintf(errstr,"Error1 scanning (chan1) pan: line %d\n",filecnt+1);
  708. return(PROGRAM_ERROR);
  709. }
  710. if(*pan < MINPAN || *pan > MAXPAN) {
  711. sprintf(errstr,"Error2 scanning (chan1) pan: line %d\n",filecnt+1);
  712. return(PROGRAM_ERROR);
  713. }
  714. }
  715. return(FINISHED);
  716. }
  717. /*************** CHECK_LEFT_LEVEL ******************/
  718. int check_left_level(char *str,double *level,int filecnt)
  719. {
  720. if(is_dB(str)) {
  721. if(!get_leveldb(str,level)) {
  722. sprintf(errstr,"Error1 scanning (chan1) level: line %d\n",filecnt+1);
  723. return(PROGRAM_ERROR);
  724. }
  725. } else {
  726. if(sscanf(str,"%lf",level)!=1) {
  727. sprintf(errstr,"Error2 scanning (chan1) level: line %d\n",filecnt+1);
  728. return(PROGRAM_ERROR);
  729. }
  730. }
  731. if(*level < 0.0) {
  732. sprintf(errstr,"Error3 scanning (chan1) level: line %d\n",filecnt+1);
  733. return(PROGRAM_ERROR);
  734. }
  735. return(FINISHED);
  736. }
  737. /************************** UNMARK_BUF ***************************/
  738. int unmark_buf(int **bufsflag,int *bufsflagcnt,int thisbuf,int longbitsize)
  739. {
  740. int exit_status;
  741. int mask = 1;
  742. int z = thisbuf/longbitsize;
  743. /* 1998 --> */
  744. if(z >= *bufsflagcnt) {
  745. if((exit_status = reallocate_bufsflag(z,bufsflag,bufsflagcnt))<0)
  746. return(exit_status);
  747. }
  748. /* <-- 1998 */
  749. thisbuf -= (z * longbitsize);
  750. mask <<= thisbuf;
  751. mask = ~mask;
  752. (*bufsflag)[z] &= mask;
  753. return(FINISHED);
  754. }
  755. /************************** MARK_BUF ***************************
  756. *
  757. * (1) Which int is the appropriate byte in.
  758. * (2) What is it's index into this int.
  759. * (3) Move mask along the int.
  760. * (4) Set bit.
  761. * (5) Keep note of max number of bufs in use.
  762. */
  763. int mark_buf(int **bufsflag,int *bufsflagcnt,int thisbuf,int longbitsize,dataptr dz)
  764. {
  765. int exit_status;
  766. int mask = 1;
  767. int z = thisbuf/longbitsize; /* 1 */
  768. /* 1998 --> */
  769. if(z >= *bufsflagcnt) {
  770. if((exit_status = reallocate_bufsflag(z,bufsflag,bufsflagcnt))<0)
  771. return(exit_status);
  772. }
  773. /* <-- 1998 */
  774. if(thisbuf > dz->bufcnt)
  775. dz->bufcnt = thisbuf;
  776. thisbuf -= (z * longbitsize); /* 2 */
  777. mask <<= thisbuf; /* 3 */
  778. (*bufsflag)[z] |= mask; /* 4 */
  779. return(FINISHED);
  780. }
  781. /**************************** REALLOCATE_BUFSFLAG ********************************/
  782. int reallocate_bufsflag(int z,int **bufsflag,int *bufsflagcnt)
  783. {
  784. int n;
  785. if(*bufsflagcnt==0)
  786. // *bufsflag = (int *) malloc((z+1) * sizeof(int));
  787. *bufsflag = (int *) calloc((z+1),sizeof(int)); //RWD 2013 needs init values
  788. else if((*bufsflag = (int *)realloc(*bufsflag,(z+1) * sizeof(int)))==NULL) {
  789. sprintf(errstr,"INSUFFICIENT MEMORY for buffer flags store.\n");
  790. return(MEMORY_ERROR);
  791. }
  792. for(n=*bufsflagcnt;n<z;n++)
  793. *bufsflag[n] = 0;
  794. *bufsflagcnt = z+1;
  795. return(FINISHED);
  796. }
  797. /**************************** MIX_MODEL ********************************/
  798. int mix_model(dataptr dz)
  799. {
  800. int n, m, k;
  801. int total_words = 0,filestart;
  802. char temp[200];
  803. filestart = dz->itemcnt;
  804. for(n=0,k=filestart;n<dz->linecnt;n++,k++) {
  805. for(m = 0;m < dz->wordcnt[n];m++) {
  806. if(m==0)
  807. strcpy(temp,dz->wordstor[k]);
  808. else {
  809. strcat(temp," ");
  810. strcat(temp,dz->wordstor[total_words]);
  811. }
  812. total_words++;
  813. }
  814. strcat(temp,"\n");
  815. if(fputs(temp,dz->fp)<0) {
  816. sprintf(errstr,"Failed to print new mixfile line %d to output file.\n",n+1);
  817. return(SYSTEM_ERROR);
  818. }
  819. }
  820. return FINISHED;
  821. }