mixshuf0.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498
  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: no changes */
  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 <mix.h>
  32. #include <cdpmain.h>
  33. #include <sfsys.h>
  34. #include <osbind.h>
  35. static int get_times(double *timestor,dataptr dz);
  36. static int adjust_stereo(int lineno,int total_words,int wordcnt,double param,dataptr dz);
  37. static int adjust_position(char **thisword,double param,dataptr dz);
  38. static int treat_short_mono_line(int lineno,int wordno,double param,dataptr dz);
  39. static int treat_short_stereo_line(int lineno,int wordno,double param,dataptr dz);
  40. static int investigate_timings(double *duration,double *min_time,dataptr dz);
  41. /************************* MIX_SHUFL ******************************/
  42. int mix_shufl(dataptr dz)
  43. {
  44. switch(dz->mode) {
  45. case(MSH_OMIT_ALT):
  46. case(MSH_OMIT): return do_time_manip(dz);
  47. case(MSH_DUPLICATE):
  48. case(MSH_DUPL_AND_RENAME): return do_time_and_name_copy(dz);
  49. case(MSH_SCATTER): return randomise_names(dz);
  50. case(MSH_REVERSE_N): return do_name_reverse(dz);
  51. case(MSH_FIXED_N): return do_name_freeze(dz);
  52. default:
  53. sprintf(errstr,"Unknown mode in mix_shufl()\n");
  54. return(PROGRAM_ERROR);
  55. }
  56. return(FINISHED); /* NOTREACHED */
  57. }
  58. /************************* MIX_TIMEWARP ******************************/
  59. int mix_timewarp(dataptr dz)
  60. {
  61. switch(dz->mode) {
  62. case(MTW_REVERSE_NT): return do_name_and_time_reverse(dz);
  63. case(MTW_FREEZE_NT): return do_name_and_time_freeze(dz);
  64. case(MTW_REVERSE_T): case(MTW_FREEZE_T): case(MTW_SCATTER): case(MTW_DOMINO):
  65. case(MTW_CREATE_TG_1): case(MTW_CREATE_TG_2): case(MTW_CREATE_TG_3): case(MTW_CREATE_TG_4):
  66. case(MTW_ENLARGE_TG_1): case(MTW_ENLARGE_TG_2): case(MTW_ENLARGE_TG_3): case(MTW_ENLARGE_TG_4):
  67. case(MTW_ADD_TO_TG): case(MTW_TIMESORT):
  68. return do_time_manip(dz);
  69. default:
  70. sprintf(errstr,"Unknown mode in mix_timewarp()\n");
  71. return(PROGRAM_ERROR);
  72. }
  73. return(FINISHED); /* NOTREACHED */
  74. }
  75. /************************* MIX_SPACEWARP ******************************/
  76. int mix_spacewarp(dataptr dz)
  77. {
  78. int exit_status;
  79. int n, total_words;
  80. int is_even = TRUE;
  81. double position = 0.0;
  82. int *maxwordsize;
  83. double duration = 0.0, min_time = 0.0, *timestor = NULL;
  84. double spacerange = 0.0, leftedge = 0.0;
  85. switch(dz->mode) {
  86. case(MSW_TWISTALL):
  87. case(MSW_TWISTONE):
  88. return mix_twisted(dz);
  89. case(MSW_LEFTWARDS):
  90. case(MSW_RIGHTWARDS):
  91. if((exit_status = investigate_timings(&duration,&min_time,dz))<0)
  92. return(exit_status);
  93. timestor = dz->parray[MSW_TIMESTOR];
  94. /* fall thro */
  95. case(MSW_RANDOM):
  96. case(MSW_RANDOM_ALT):
  97. spacerange = fabs(dz->param[MSW_POS2] - dz->param[MSW_POS1]);
  98. leftedge = min(dz->param[MSW_POS1],dz->param[MSW_POS2]);
  99. break;
  100. case(MSW_NARROWED):
  101. case(MSW_FIXED):
  102. break;
  103. default:
  104. sprintf(errstr,"Unknown mode in mix_spacewarp()\n");
  105. return(PROGRAM_ERROR);
  106. }
  107. total_words = 0;
  108. for(n=0;n<dz->iparam[MSH_STARTLINE];n++)
  109. total_words += dz->wordcnt[n];
  110. for(n=dz->iparam[MSH_STARTLINE];n<dz->iparam[MSH_ENDLINE];n++) {
  111. switch(dz->mode) {
  112. case(MSW_NARROWED):
  113. if((exit_status = adjust_stereo(n,total_words,dz->wordcnt[n],dz->param[MSW_NARROWING],dz))<0)
  114. return(exit_status);
  115. break;
  116. case(MSW_FIXED):
  117. if((exit_status = adjust_stereo(n,total_words,dz->wordcnt[n],dz->param[MSW_POS1],dz))<0)
  118. return(exit_status);
  119. break;
  120. default:
  121. switch(dz->mode) {
  122. case(MSW_RANDOM):
  123. position = (drand48() * POSITIONS)/POSITIONS;
  124. break;
  125. case(MSW_RANDOM_ALT):
  126. switch(is_even) {
  127. case(TRUE): position = (drand48() * HALF_POSTNS)/POSITIONS; break; /* Force Left */
  128. case(FALSE):position = (POSITIONS - (drand48() * HALF_POSTNS))/POSITIONS; break; /* Force Right */
  129. }
  130. is_even = !is_even;
  131. break;
  132. case(MSW_LEFTWARDS):
  133. //TW UPDATE
  134. if(duration > FLTERR)
  135. position = (timestor[n] - min_time)/duration;
  136. else {
  137. sprintf(errstr,"Files do not Progress in Time : Hence cannot MOVE Leftwards\n");
  138. return(USER_ERROR);
  139. }
  140. position = 1.0 - position;
  141. break;
  142. case(MSW_RIGHTWARDS):
  143. //TW UPDATE
  144. if(duration > FLTERR)
  145. position = (timestor[n] - min_time)/duration;
  146. else {
  147. sprintf(errstr,"Files do not Progress in Time : Hence cannot MOVE Rightwards\n");
  148. return(USER_ERROR);
  149. }
  150. break;
  151. }
  152. position *= spacerange;
  153. position += leftedge;
  154. if((exit_status = adjust_stereo(n,total_words,dz->wordcnt[n],position,dz))<0)
  155. return(exit_status);
  156. break;
  157. }
  158. total_words += dz->wordcnt[n];
  159. }
  160. if((exit_status = get_maxwordsize(&maxwordsize,dz))<0)
  161. return(exit_status);
  162. if((exit_status = output_mixfile_lines(maxwordsize,dz))<0)
  163. return(exit_status);
  164. free(maxwordsize);
  165. return(FINISHED);
  166. }
  167. /*************************** GET_TIMES ***************************/
  168. int get_times(double *timestor,dataptr dz)
  169. {
  170. int n, timeloc;
  171. int total_wordcnt = 0;
  172. for(n=0;n<dz->linecnt;n++) {
  173. if(dz->wordcnt[n] < 2) {
  174. sprintf(errstr,"PRoblem getting line times: get_times_and_timediffs()\n");
  175. return(PROGRAM_ERROR);
  176. }
  177. timeloc = total_wordcnt + MIX_TIMEPOS;
  178. if(sscanf(dz->wordstor[timeloc],"%lf",&(timestor[n]))!=1) {
  179. sprintf(errstr,"Problem reading time: get_times_and_timediffs()\n");
  180. return(PROGRAM_ERROR);
  181. }
  182. total_wordcnt += dz->wordcnt[n];
  183. }
  184. return(FINISHED);
  185. }
  186. /************************** ADJUST_STEREO **************************/
  187. int adjust_stereo(int lineno,int total_words,int wordcnt,double param,dataptr dz)
  188. {
  189. int exit_status;
  190. char *thisword;
  191. int chans;
  192. int levelwordno = total_words + MIX_LEVELPOS;
  193. int lpanwordno = total_words + MIX_PANPOS;
  194. int rpanwordno = total_words + MIX_RPANPOS;
  195. int chanwordno = total_words + MIX_CHANPOS;
  196. switch(wordcnt) {
  197. case(MIX_MINLINE):
  198. thisword = dz->wordstor[chanwordno];
  199. if(sscanf(thisword,"%d",&chans)!=1) {
  200. sprintf(errstr,"Failed to get channel count: adjust_stereo()\n");
  201. return(PROGRAM_ERROR);
  202. }
  203. switch(chans) {
  204. case(MONO):
  205. switch(dz->mode) {
  206. case(MSW_NARROWED): return(FINISHED); /* mono, unpanned, files can't be narrowed */
  207. default: return treat_short_mono_line(lineno,levelwordno,param,dz);
  208. } /* mono, unpanned, wordstor has to be extended to take 1 new vals */
  209. break; /* stereo, unpanned, wordstor has to be extended to take 3 new vals */
  210. case(STEREO): return treat_short_stereo_line(lineno,levelwordno,param,dz);
  211. default:
  212. sprintf(errstr,"Invalid channel count: adjust_stereo()\n");
  213. return(PROGRAM_ERROR);
  214. }
  215. break;
  216. case(MIX_MAXLINE):
  217. if((exit_status = adjust_position(&(dz->wordstor[rpanwordno]),param,dz))<0)
  218. return(exit_status);
  219. /* fall thro */
  220. case(MIX_MIDLINE):
  221. return adjust_position(&(dz->wordstor[lpanwordno]),param,dz);
  222. break;
  223. default:
  224. sprintf(errstr,"Impossible wordcnt: adjust_stereo()\n");
  225. return(PROGRAM_ERROR);
  226. }
  227. return(FINISHED); /* NOTREACHED */
  228. }
  229. /************************* ADJUST_POSITION ******************************/
  230. int adjust_position(char **thisword,double param,dataptr dz)
  231. {
  232. double position;
  233. int newlen;
  234. if(dz->mode==MSW_NARROWED) {
  235. if(!strcmp(*thisword,"C"))
  236. position = 0.0;
  237. else if(!strcmp(*thisword,"L"))
  238. position = -1.0;
  239. else if(!strcmp(*thisword,"R"))
  240. position = 1.0;
  241. else if(sscanf(*thisword,"%lf",&position)!=1) {
  242. sprintf(errstr,"Failed to get pan value: adjust_position()\n");
  243. return(PROGRAM_ERROR);
  244. }
  245. param *= position;
  246. }
  247. sprintf(errstr,"%.4lf",param);
  248. newlen = strlen(errstr);
  249. if(newlen > (int)strlen(*thisword)) {
  250. if((*thisword =
  251. (char *)realloc(*thisword,(newlen+1) * sizeof(char)))==NULL) {
  252. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate thisword store.\n");
  253. return(MEMORY_ERROR);
  254. }
  255. }
  256. strcpy(*thisword,errstr);
  257. return(FINISHED);
  258. }
  259. /************************* TREAT_SHORT_STEREO_LINE ******************************/
  260. int treat_short_stereo_line(int lineno,int wordno,double param,dataptr dz)
  261. {
  262. #define STEREO_EXTRA_WORDS (3)
  263. int n, m;
  264. int wordlen;
  265. if((dz->wordstor = (char **)realloc(dz->wordstor,(dz->all_words + STEREO_EXTRA_WORDS) * sizeof(char *)))==NULL) {
  266. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate word store.\n");
  267. return(MEMORY_ERROR);
  268. }
  269. for(n=0,m=dz->all_words;n<STEREO_EXTRA_WORDS;n++,m++)
  270. dz->wordstor[m] = NULL;
  271. dz->all_words += STEREO_EXTRA_WORDS;
  272. for(n=dz->all_words-STEREO_EXTRA_WORDS-1;n>wordno;n--)
  273. dz->wordstor[n+STEREO_EXTRA_WORDS] = dz->wordstor[n];
  274. dz->wordcnt[lineno] += STEREO_EXTRA_WORDS;
  275. for(n=wordno+1;n<=wordno+STEREO_EXTRA_WORDS;n++)
  276. dz->wordstor[n] = NULL;
  277. switch(dz->mode) {
  278. case(MSW_NARROWED): sprintf(errstr,"%.4lf",-param); break;
  279. default: sprintf(errstr,"%.4lf",param); break;
  280. }
  281. wordlen = strlen(errstr);
  282. if((dz->wordstor[wordno+1] = (char *)malloc((wordlen+1) * sizeof(char)))==NULL) {
  283. sprintf(errstr,"INSUFFICIENT MEMORY to allocate wordstore %d\n",wordno+1+1);
  284. return(MEMORY_ERROR);
  285. }
  286. strcpy(dz->wordstor[wordno+1],errstr);
  287. wordlen = strlen(dz->wordstor[wordno]);
  288. if((dz->wordstor[wordno+2] = (char *)malloc((wordlen+1) * sizeof(char)))==NULL) {
  289. sprintf(errstr,"INSUFFICIENT MEMORY to allocate wordstore %d\n",wordno+2+1);
  290. return(MEMORY_ERROR);
  291. }
  292. strcpy(dz->wordstor[wordno+2],dz->wordstor[wordno]);
  293. sprintf(errstr,"%.4lf",param);
  294. wordlen = strlen(errstr);
  295. if((dz->wordstor[wordno+3] = (char *)malloc((wordlen+1) * sizeof(char)))==NULL) {
  296. sprintf(errstr,"INSUFFICIENT MEMORY to allocate wordstore %d\n",wordno+3+1);
  297. return(MEMORY_ERROR);
  298. }
  299. strcpy(dz->wordstor[wordno+3],errstr);
  300. return(FINISHED);
  301. }
  302. /************************* TREAT_SHORT_MONO_LINE ******************************/
  303. int treat_short_mono_line(int lineno,int wordno,double param,dataptr dz)
  304. {
  305. #define MONO_EXTRA_WORDS (1)
  306. int n, m;
  307. int wordlen;
  308. if((dz->wordstor = (char **)realloc(dz->wordstor,(dz->all_words + MONO_EXTRA_WORDS) * sizeof(char *)))==NULL) {
  309. sprintf(errstr,"INSUFFICIENT MEMORY for word stores.\n");
  310. return(MEMORY_ERROR);
  311. }
  312. for(n=0,m=dz->all_words;n<MONO_EXTRA_WORDS;n++,m++)
  313. dz->wordstor[m] = NULL;
  314. dz->all_words += MONO_EXTRA_WORDS;
  315. for(n=dz->all_words-MONO_EXTRA_WORDS-1;n>wordno;n--)
  316. dz->wordstor[n+MONO_EXTRA_WORDS] = dz->wordstor[n];
  317. dz->wordcnt[lineno] += MONO_EXTRA_WORDS;
  318. dz->wordstor[wordno+1] = NULL;
  319. sprintf(errstr,"%.4lf",param);
  320. wordlen = strlen(errstr);
  321. if((dz->wordstor[wordno+1] = (char *)malloc((wordlen+1) * sizeof(char)))==NULL) {
  322. sprintf(errstr,"INSUFFICIENT MEMORY for word store %d\n",wordno+1+1);
  323. return(MEMORY_ERROR);
  324. }
  325. strcpy(dz->wordstor[wordno+1],errstr);
  326. return(FINISHED);
  327. }
  328. /************************* INVESTIGATE_TIMINGS ******************************/
  329. int investigate_timings(double *duration,double *min_time,dataptr dz)
  330. {
  331. int exit_status;
  332. int n;
  333. double *timestor;
  334. double max_time;
  335. if((dz->parray[MSW_TIMESTOR] = (double *)malloc(dz->linecnt * sizeof(double)))==NULL) {
  336. sprintf(errstr,"INSUFFICIENT MEMORY for times store.\n");
  337. return(MEMORY_ERROR);
  338. }
  339. timestor = dz->parray[MSW_TIMESTOR];
  340. if((exit_status = get_times(timestor,dz))<0)
  341. return(exit_status);
  342. max_time = timestor[dz->iparam[MSH_STARTLINE]];
  343. *min_time = timestor[dz->iparam[MSH_STARTLINE]];
  344. for(n=dz->iparam[MSH_STARTLINE]+1;n<dz->iparam[MSH_ENDLINE];n++) {
  345. max_time = max(timestor[n],max_time);
  346. *min_time = min(timestor[n],*min_time);
  347. }
  348. *duration = max_time - *min_time;
  349. return(FINISHED);
  350. }
  351. //TW UPDATE: NEW FUNCTION
  352. /************************* PANMIX ******************************/
  353. int panmix(dataptr dz)
  354. {
  355. int newlen, exit_status;
  356. int baspos = 0, basposnext = 0, n, linelen; /*RWD Nov 2003 added init for basposnext */
  357. int levelwordno, lpanwordno, rpanwordno;
  358. double time, level;
  359. char temp[200];
  360. int *maxwordsize;
  361. for(n=0;n<dz->linecnt;n++) {
  362. basposnext += dz->wordcnt[n];
  363. levelwordno = baspos + MIX_LEVELPOS;
  364. lpanwordno = baspos + MIX_PANPOS;
  365. rpanwordno = baspos + MIX_RPANPOS;
  366. //chanwordno = baspos + MIX_CHANPOS;
  367. time = atof(dz->wordstor[baspos + 1]);
  368. if(dz->brksize[PAN_PAN]) {
  369. if((exit_status = read_value_from_brktable(time,PAN_PAN,dz))<0)
  370. return(exit_status);
  371. }
  372. linelen = basposnext - baspos;
  373. switch(linelen) {
  374. case(MIX_MINLINE): /* STEREO CASE : SHORT LINE */
  375. level = atof(dz->wordstor[levelwordno]);
  376. level /= 2.0;
  377. sprintf(errstr,"%.4lf",level);
  378. strcat(errstr," ");
  379. sprintf(temp,"%.4lf",dz->param[PAN_PAN]);
  380. strcat(temp," ");
  381. strcat(errstr,temp);
  382. strcpy(temp,errstr);
  383. strcat(errstr,temp);
  384. newlen = strlen(errstr);
  385. if(newlen > (int)strlen(dz->wordstor[levelwordno])) {
  386. if((dz->wordstor[levelwordno] =
  387. (char *)realloc(dz->wordstor[levelwordno],(newlen+1) * sizeof(char)))==NULL) {
  388. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate thisword store.\n");
  389. return(MEMORY_ERROR);
  390. }
  391. }
  392. strcpy(dz->wordstor[levelwordno],errstr);
  393. break;
  394. case(MIX_MAXLINE): /* STEREO CASE : LONG LINE */
  395. level = atof(dz->wordstor[levelwordno]);
  396. level += atof(dz->wordstor[levelwordno+2]);
  397. level /= 4.0; /* Average level: = (level_left + level-right) / 2.0 */
  398. /* This average level from BOTH channels is to be put at SAME position */
  399. /* Therefore, divide by two again */
  400. sprintf(errstr,"%.4lf",level);
  401. newlen = strlen(errstr);
  402. if(newlen > (int)strlen(dz->wordstor[levelwordno])) {
  403. if((dz->wordstor[levelwordno] =
  404. (char *)realloc(dz->wordstor[levelwordno],(newlen+1) * sizeof(char)))==NULL) {
  405. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate thisword store.\n");
  406. return(MEMORY_ERROR);
  407. }
  408. }
  409. if(newlen > (int)strlen(dz->wordstor[levelwordno+2])) {
  410. if((dz->wordstor[levelwordno+2] =
  411. (char *)realloc(dz->wordstor[levelwordno+2],(newlen+1) * sizeof(char)))==NULL) {
  412. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate thisword store.\n");
  413. return(MEMORY_ERROR);
  414. }
  415. }
  416. strcpy(dz->wordstor[levelwordno],errstr);
  417. strcpy(dz->wordstor[levelwordno+2],errstr);
  418. sprintf(errstr,"%.4lf",dz->param[PAN_PAN]);
  419. if(newlen > (int)strlen(dz->wordstor[lpanwordno])) {
  420. if((dz->wordstor[lpanwordno] =
  421. (char *)realloc(dz->wordstor[lpanwordno],(newlen+1) * sizeof(char)))==NULL) {
  422. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate thisword store.\n");
  423. return(MEMORY_ERROR);
  424. }
  425. }
  426. if(newlen > (int)strlen(dz->wordstor[rpanwordno])) {
  427. if((dz->wordstor[rpanwordno] =
  428. (char *)realloc(dz->wordstor[rpanwordno],(newlen+1) * sizeof(char)))==NULL) {
  429. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate thisword store.\n");
  430. return(MEMORY_ERROR);
  431. }
  432. }
  433. strcpy(dz->wordstor[lpanwordno],errstr);
  434. strcpy(dz->wordstor[rpanwordno],errstr);
  435. break;
  436. case(MIX_MIDLINE): /* MONO CASE */
  437. sprintf(errstr,"%.4lf",dz->param[PAN_PAN]);
  438. newlen = strlen(errstr);
  439. if(newlen > (int)strlen(dz->wordstor[lpanwordno])) {
  440. if((dz->wordstor[lpanwordno] =
  441. (char *)realloc(dz->wordstor[lpanwordno],(newlen+1) * sizeof(char)))==NULL) {
  442. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate thisword store.\n");
  443. return(MEMORY_ERROR);
  444. }
  445. }
  446. strcpy(dz->wordstor[lpanwordno],errstr);
  447. break;
  448. }
  449. baspos = basposnext;
  450. }
  451. if((exit_status = get_maxwordsize(&maxwordsize,dz))<0)
  452. return(exit_status);
  453. if((exit_status = output_mixfile_lines(maxwordsize,dz))<0)
  454. return(exit_status);
  455. free(maxwordsize);
  456. return(FINISHED);
  457. }