mixshuf2.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  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 <filetype.h>
  32. #include <mix.h>
  33. #include <cdpmain.h>
  34. #include <sfsys.h>
  35. #include <osbind.h>
  36. static int check_chans(int lineno,int oldwordpos,dataptr dz);
  37. static void insert_word(char **permm,int permlen,int *name_index,int m,int t,dataptr dz);
  38. static void prefix_word(char **perm,int permlen,int *name_index,int m,dataptr dz);
  39. static void shuflup_words(char **perm,int permlen,int k);
  40. static int output_mixfile_line(char **wordstor,int total_words,int wordcnt,int *maxwordsize,dataptr dz);
  41. /************************* DO_TIME_AND_NAME_COPY ************************/
  42. int do_time_and_name_copy(dataptr dz)
  43. {
  44. int exit_status;
  45. int extra_words = 0;
  46. int *maxwordsize;
  47. int total_words = 0, new_words = 0, words_above = 0, moveindex;
  48. int new_total_words, oldwordpos, orig_oldwordpos, newwordpos;
  49. int n, lineno, wordno, newlines, oldlinecnt;
  50. if(dz->mode==MSH_DUPL_AND_RENAME) { /* space for the new sndfilename must bhave been allocated */
  51. if(dz->extra_word<0) {
  52. sprintf(errstr,"extra_word not accounted for: do_time_and_name_copy()\n");
  53. return(PROGRAM_ERROR);
  54. }
  55. extra_words = 1;
  56. }
  57. newlines = dz->iparam[MSH_ENDLINE] - dz->iparam[MSH_STARTLINE];
  58. //lines_above = dz->linecnt - dz->iparam[MSH_ENDLINE];
  59. for(n=0;n<dz->linecnt;n++)
  60. total_words += dz->wordcnt[n];
  61. for(n=dz->iparam[MSH_ENDLINE];n<dz->linecnt;n++)
  62. words_above += dz->wordcnt[n];
  63. for(n=dz->iparam[MSH_STARTLINE];n<dz->iparam[MSH_ENDLINE];n++)
  64. new_words += dz->wordcnt[n];
  65. new_total_words = total_words + new_words;
  66. if((dz->wordstor = (char **)realloc(dz->wordstor,(new_total_words+extra_words) * sizeof(char *)))==NULL) {
  67. sprintf(errstr,"INSUFFICIENT MEMORY for word store.\n");
  68. return(MEMORY_ERROR); /* alloc space for all new words */
  69. }
  70. for(n=total_words+extra_words; n < new_total_words+extra_words;n++)
  71. dz->wordstor[n] = NULL;
  72. oldlinecnt = dz->linecnt;
  73. dz->linecnt += newlines;
  74. if((dz->wordcnt = (int *)realloc(dz->wordcnt,dz->linecnt * sizeof(int)))==NULL) {
  75. sprintf(errstr,"INSUFFICIENT MEMORY for word count store.\n");
  76. return(MEMORY_ERROR); /* alloc space for all new line wordcnts */
  77. }
  78. for(n=oldlinecnt; n < dz->linecnt;n++)
  79. dz->wordcnt[n] = 0;
  80. dz->all_words += new_words; /* update total wordcnt: good housekeeping */
  81. oldwordpos = total_words + extra_words - 1;
  82. newwordpos = new_total_words + extra_words - 1;
  83. /* 'MOVE' WORDS BEYOND THE ACTED-ON LINES + ANY EXTRA_WORD */
  84. for(n=0;n<(words_above+extra_words);n++) {
  85. dz->wordstor[newwordpos] = dz->wordstor[oldwordpos];
  86. newwordpos--;
  87. oldwordpos--;
  88. if(oldwordpos<0) {
  89. sprintf(errstr,"Accounting problem 0: do_time_and_name_copy()\n");
  90. return(PROGRAM_ERROR);
  91. }
  92. }
  93. for(n=oldlinecnt;n<dz->linecnt;n++) /* Put correct wordcnt in place for these moved lines */
  94. dz->wordcnt[n] = dz->wordcnt[n - newlines];
  95. if(dz->mode==MSH_DUPL_AND_RENAME) /* adjust address where new sndfilename is now found */
  96. dz->extra_word += new_words;
  97. oldwordpos = 0; /* GO TO THE END OF THE WORDS TO DUPLICATE */
  98. for(lineno=0;lineno<dz->iparam[MSH_ENDLINE];lineno++)
  99. oldwordpos += dz->wordcnt[lineno];
  100. oldwordpos--;
  101. newwordpos = oldwordpos + new_words; /* MOVING BACKWARDS, DUPLICATE THE ACTED-ON LINES */
  102. for(lineno = dz->iparam[MSH_ENDLINE]-1,moveindex = newlines;lineno>=dz->iparam[MSH_STARTLINE];lineno--,moveindex--) {
  103. orig_oldwordpos = oldwordpos; /* CREATE WORDS IN A DUPLICATE LINE */
  104. for(wordno=dz->wordcnt[lineno]-1;wordno>=0;wordno--) {
  105. /* CHECKING THE CHANNEL If process DEMANDS IT */
  106. if(wordno==MIX_CHANPOS && dz->mode==MSH_DUPL_AND_RENAME && dz->vflag[MSH_NOCHECK]==FALSE) {
  107. if((exit_status = check_chans(lineno,oldwordpos,dz))<0)
  108. return(exit_status);
  109. } /* SUBSTITUTING NEW NAME: IF process DEMANDS IT */
  110. if(wordno==MIX_NAMEPOS && dz->mode==MSH_DUPL_AND_RENAME)
  111. dz->wordstor[newwordpos] = dz->wordstor[dz->extra_word];
  112. else
  113. dz->wordstor[newwordpos] = dz->wordstor[oldwordpos];
  114. oldwordpos--;
  115. newwordpos--;
  116. if(lineno > 0 && wordno > 0) {
  117. if(oldwordpos<0) {
  118. sprintf(errstr,"Accounting problem 1: do_time_and_name_copy()\n");
  119. return(PROGRAM_ERROR);
  120. }
  121. }
  122. }
  123. dz->wordcnt[lineno+moveindex] = dz->wordcnt[lineno];
  124. oldwordpos = orig_oldwordpos; /* THEN ALSO MOVE WORDS OF ORIGINAL LINE */
  125. if(newwordpos < oldwordpos) {
  126. sprintf(errstr,"Accounting problem 2: do_time_and_name_copy()\n");
  127. return(PROGRAM_ERROR);
  128. }
  129. for(wordno=dz->wordcnt[lineno]-1;wordno>=0;wordno--) {
  130. dz->wordstor[newwordpos] = dz->wordstor[oldwordpos];
  131. oldwordpos--;
  132. newwordpos--;
  133. }
  134. if(moveindex-1 < 0) {
  135. sprintf(errstr,"Accounting problem 2a: do_time_and_name_copy()\n");
  136. return(PROGRAM_ERROR);
  137. }
  138. dz->wordcnt[lineno+moveindex-1] = dz->wordcnt[lineno];
  139. }
  140. if((exit_status = get_maxwordsize(&maxwordsize,dz))<0)
  141. return(exit_status);
  142. if((exit_status = output_mixfile_lines(maxwordsize,dz))<0)
  143. return(exit_status);
  144. free(maxwordsize);
  145. return(FINISHED);
  146. }
  147. /************************* OUTPUT_MIXFILE_LINES ******************************/
  148. int output_mixfile_lines(int *maxwordsize,dataptr dz)
  149. {
  150. int exit_status;
  151. int n;
  152. int total_words = 0;
  153. for(n=0;n<dz->linecnt;n++) {
  154. if((exit_status = output_mixfile_line(dz->wordstor,total_words,dz->wordcnt[n],maxwordsize,dz))<0)
  155. return(exit_status);
  156. total_words += dz->wordcnt[n];
  157. }
  158. return(FINISHED);
  159. }
  160. /************************* CHECK_CHANS ******************************/
  161. int check_chans(int lineno,int oldwordpos,dataptr dz)
  162. {
  163. int chans;
  164. if(sscanf(dz->wordstor[oldwordpos],"%d",&chans)!=1) {
  165. sprintf(errstr,"Failed to read channel value:line %d: check_chans()\n",lineno+1);
  166. return(PROGRAM_ERROR);
  167. }
  168. if(chans!=dz->otherfile->channels) {
  169. sprintf(errstr,"New named file has incompatible channel cnt: line %d: check_chans()\n",lineno+1);
  170. return(DATA_ERROR);
  171. }
  172. return(FINISHED);
  173. }
  174. /************************* DO_NAME_REVERSE ******************************/
  175. int do_name_reverse(dataptr dz)
  176. {
  177. int exit_status;
  178. int *maxwordsize;
  179. int *name_index;
  180. int half_linecnt;
  181. char *temp;
  182. int lineno, newlineno, total_words = 0;
  183. if((name_index = (int *)malloc(dz->linecnt * sizeof(int)))==NULL) {
  184. sprintf(errstr,"do_name_reverse()\n");
  185. return(PROGRAM_ERROR);
  186. }
  187. if((exit_status = get_maxwordsize(&maxwordsize,dz))<0) {
  188. free(name_index);
  189. return(exit_status);
  190. }
  191. for(lineno=0;lineno<dz->linecnt;lineno++) {
  192. name_index[lineno] = total_words;
  193. total_words += dz->wordcnt[lineno];
  194. }
  195. half_linecnt = dz->iparam[MSH_ENDLINE] - dz->iparam[MSH_STARTLINE];
  196. half_linecnt = half_linecnt/2; /* TRUNCATE */
  197. half_linecnt += dz->iparam[MSH_STARTLINE];
  198. for(lineno=dz->iparam[MSH_STARTLINE],newlineno=dz->iparam[MSH_ENDLINE]-1;lineno < half_linecnt;lineno++,newlineno--) {
  199. temp = dz->wordstor[name_index[lineno]];
  200. dz->wordstor[name_index[lineno]] = dz->wordstor[name_index[newlineno]];
  201. dz->wordstor[name_index[newlineno]] = temp;
  202. }
  203. if((exit_status = output_mixfile_lines(maxwordsize,dz))<0) {
  204. free(maxwordsize);
  205. free(name_index);
  206. return(exit_status);
  207. }
  208. free(maxwordsize);
  209. free(name_index);
  210. return(FINISHED);
  211. }
  212. /************************* DO_NAME_FREEZE ******************************/
  213. int do_name_freeze(dataptr dz)
  214. {
  215. int exit_status;
  216. int *maxwordsize;
  217. int *name_index;
  218. int lineno, total_words = 0;
  219. if((name_index = (int *)malloc(dz->linecnt * sizeof(int)))==NULL) {
  220. sprintf(errstr,"do_name_reverse()\n");
  221. return(PROGRAM_ERROR);
  222. }
  223. if((exit_status = get_maxwordsize(&maxwordsize,dz))<0) {
  224. free(name_index);
  225. return(exit_status);
  226. }
  227. for(lineno=0;lineno<dz->linecnt;lineno++) {
  228. name_index[lineno] = total_words;
  229. total_words += dz->wordcnt[lineno];
  230. }
  231. for(lineno=dz->iparam[MSH_STARTLINE];lineno < dz->iparam[MSH_ENDLINE];lineno++)
  232. dz->wordstor[name_index[lineno]] = dz->wordstor[name_index[dz->iparam[MSH_STARTLINE]]];
  233. if((exit_status = output_mixfile_lines(maxwordsize,dz))<0) {
  234. free(name_index);
  235. free(maxwordsize);
  236. return(exit_status);
  237. }
  238. free(name_index);
  239. free(maxwordsize);
  240. return(FINISHED);
  241. }
  242. /************************** RANDOMISE_NAMES **************************/
  243. int randomise_names(dataptr dz)
  244. {
  245. int exit_status;
  246. int *maxwordsize;
  247. int *name_index;
  248. int lineno, total_words = 0;
  249. int n, m, t;
  250. int permlen = dz->iparam[MSH_ENDLINE] - dz->iparam[MSH_STARTLINE];
  251. char **permm;
  252. if((name_index = (int *)malloc(dz->linecnt * sizeof(int)))==NULL) {
  253. sprintf(errstr,"randomise_names(): 1\n");
  254. return(PROGRAM_ERROR);
  255. }
  256. if((permm = (char **)malloc(permlen * sizeof(char *)))==NULL) {
  257. free(name_index);
  258. sprintf(errstr,"randomise_names(): 2\n");
  259. return(PROGRAM_ERROR);
  260. }
  261. if((exit_status = get_maxwordsize(&maxwordsize,dz))<0) {
  262. free(name_index);
  263. free(permm);
  264. return(exit_status);
  265. }
  266. for(lineno=0;lineno<dz->linecnt;lineno++) {
  267. name_index[lineno] = total_words;
  268. total_words += dz->wordcnt[lineno];
  269. }
  270. for(n=0;n<permlen;n++) {
  271. t = (int)(drand48() * (double)(n+1));
  272. if(t==n)
  273. prefix_word(permm,permlen,name_index,n+dz->iparam[MSH_STARTLINE],dz);
  274. else
  275. insert_word(permm,permlen,name_index,n+dz->iparam[MSH_STARTLINE],t,dz);
  276. }
  277. for(n=0,m=dz->iparam[MSH_STARTLINE];n<permlen;n++,m++)
  278. dz->wordstor[name_index[m]] = permm[n];
  279. if((exit_status = output_mixfile_lines(maxwordsize,dz))<0) {
  280. free(name_index);
  281. free(permm);
  282. free(maxwordsize);
  283. return(exit_status);
  284. }
  285. free(name_index);
  286. free(permm);
  287. free(maxwordsize);
  288. return(FINISHED);
  289. }
  290. /****************************** INSERT_WORD ****************************/
  291. void insert_word(char **permm,int permlen,int *name_index,int m,int t,dataptr dz)
  292. {
  293. shuflup_words(permm,permlen,t+1);
  294. permm[t+1] = dz->wordstor[name_index[m]];
  295. }
  296. /****************************** PREFIX_WORD ****************************/
  297. void prefix_word(char **permm,int permlen,int *name_index,int m,dataptr dz)
  298. {
  299. shuflup_words(permm,permlen,0);
  300. permm[0] = dz->wordstor[name_index[m]];
  301. }
  302. /****************************** SHUFLUP_WORDS ****************************/
  303. void shuflup_words(char **permm,int permlen,int k)
  304. {
  305. int n;
  306. char **i;
  307. int z = permlen - 1;
  308. i = &(permm[z]);
  309. for(n = z; n > k; n--) {
  310. *i = *(i-1);
  311. i--;
  312. }
  313. }
  314. /************************** OUTPUT_MIXFILE_LINE ***************************/
  315. int output_mixfile_line(char **wordstor,int total_words,int wordcnt,int *maxwordsize,dataptr dz)
  316. {
  317. int n, m, spacecnt;
  318. int wordno;
  319. for(n = 0;n<wordcnt;n++) {
  320. wordno = total_words + n;
  321. if((spacecnt = maxwordsize[n] - strlen(wordstor[wordno]))<0) {
  322. sprintf(errstr,"Word alignment error: output_mixfile_line()\n");
  323. return(PROGRAM_ERROR);
  324. }
  325. spacecnt++;
  326. fprintf(dz->fp,"%s",wordstor[wordno]);
  327. for(m=0;m<spacecnt;m++)
  328. fprintf(dz->fp," ");
  329. }
  330. fprintf(dz->fp,"\n");
  331. return(FINISHED);
  332. }