/* * Copyright (c) 1983-2023 Trevor Wishart and Composers Desktop Project Ltd * http://www.trevorwishart.co.uk * http://www.composersdesktop.com * This file is part of the CDP System. The CDP System is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The CDP System is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the CDP System; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ /* floatsam version : no changes */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include static int check_chans(int lineno,int oldwordpos,dataptr dz); static void insert_word(char **permm,int permlen,int *name_index,int m,int t,dataptr dz); static void prefix_word(char **perm,int permlen,int *name_index,int m,dataptr dz); static void shuflup_words(char **perm,int permlen,int k); static int output_mixfile_line(char **wordstor,int total_words,int wordcnt,int *maxwordsize,dataptr dz); /************************* DO_TIME_AND_NAME_COPY ************************/ int do_time_and_name_copy(dataptr dz) { int exit_status; int extra_words = 0; int *maxwordsize; int total_words = 0, new_words = 0, words_above = 0, moveindex; int new_total_words, oldwordpos, orig_oldwordpos, newwordpos; int n, lineno, wordno, newlines, oldlinecnt; if(dz->mode==MSH_DUPL_AND_RENAME) { /* space for the new sndfilename must bhave been allocated */ if(dz->extra_word<0) { sprintf(errstr,"extra_word not accounted for: do_time_and_name_copy()\n"); return(PROGRAM_ERROR); } extra_words = 1; } newlines = dz->iparam[MSH_ENDLINE] - dz->iparam[MSH_STARTLINE]; //lines_above = dz->linecnt - dz->iparam[MSH_ENDLINE]; for(n=0;nlinecnt;n++) total_words += dz->wordcnt[n]; for(n=dz->iparam[MSH_ENDLINE];nlinecnt;n++) words_above += dz->wordcnt[n]; for(n=dz->iparam[MSH_STARTLINE];niparam[MSH_ENDLINE];n++) new_words += dz->wordcnt[n]; new_total_words = total_words + new_words; if((dz->wordstor = (char **)realloc(dz->wordstor,(new_total_words+extra_words) * sizeof(char *)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY for word store.\n"); return(MEMORY_ERROR); /* alloc space for all new words */ } for(n=total_words+extra_words; n < new_total_words+extra_words;n++) dz->wordstor[n] = NULL; oldlinecnt = dz->linecnt; dz->linecnt += newlines; if((dz->wordcnt = (int *)realloc(dz->wordcnt,dz->linecnt * sizeof(int)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY for word count store.\n"); return(MEMORY_ERROR); /* alloc space for all new line wordcnts */ } for(n=oldlinecnt; n < dz->linecnt;n++) dz->wordcnt[n] = 0; dz->all_words += new_words; /* update total wordcnt: good housekeeping */ oldwordpos = total_words + extra_words - 1; newwordpos = new_total_words + extra_words - 1; /* 'MOVE' WORDS BEYOND THE ACTED-ON LINES + ANY EXTRA_WORD */ for(n=0;n<(words_above+extra_words);n++) { dz->wordstor[newwordpos] = dz->wordstor[oldwordpos]; newwordpos--; oldwordpos--; if(oldwordpos<0) { sprintf(errstr,"Accounting problem 0: do_time_and_name_copy()\n"); return(PROGRAM_ERROR); } } for(n=oldlinecnt;nlinecnt;n++) /* Put correct wordcnt in place for these moved lines */ dz->wordcnt[n] = dz->wordcnt[n - newlines]; if(dz->mode==MSH_DUPL_AND_RENAME) /* adjust address where new sndfilename is now found */ dz->extra_word += new_words; oldwordpos = 0; /* GO TO THE END OF THE WORDS TO DUPLICATE */ for(lineno=0;linenoiparam[MSH_ENDLINE];lineno++) oldwordpos += dz->wordcnt[lineno]; oldwordpos--; newwordpos = oldwordpos + new_words; /* MOVING BACKWARDS, DUPLICATE THE ACTED-ON LINES */ for(lineno = dz->iparam[MSH_ENDLINE]-1,moveindex = newlines;lineno>=dz->iparam[MSH_STARTLINE];lineno--,moveindex--) { orig_oldwordpos = oldwordpos; /* CREATE WORDS IN A DUPLICATE LINE */ for(wordno=dz->wordcnt[lineno]-1;wordno>=0;wordno--) { /* CHECKING THE CHANNEL If process DEMANDS IT */ if(wordno==MIX_CHANPOS && dz->mode==MSH_DUPL_AND_RENAME && dz->vflag[MSH_NOCHECK]==FALSE) { if((exit_status = check_chans(lineno,oldwordpos,dz))<0) return(exit_status); } /* SUBSTITUTING NEW NAME: IF process DEMANDS IT */ if(wordno==MIX_NAMEPOS && dz->mode==MSH_DUPL_AND_RENAME) dz->wordstor[newwordpos] = dz->wordstor[dz->extra_word]; else dz->wordstor[newwordpos] = dz->wordstor[oldwordpos]; oldwordpos--; newwordpos--; if(lineno > 0 && wordno > 0) { if(oldwordpos<0) { sprintf(errstr,"Accounting problem 1: do_time_and_name_copy()\n"); return(PROGRAM_ERROR); } } } dz->wordcnt[lineno+moveindex] = dz->wordcnt[lineno]; oldwordpos = orig_oldwordpos; /* THEN ALSO MOVE WORDS OF ORIGINAL LINE */ if(newwordpos < oldwordpos) { sprintf(errstr,"Accounting problem 2: do_time_and_name_copy()\n"); return(PROGRAM_ERROR); } for(wordno=dz->wordcnt[lineno]-1;wordno>=0;wordno--) { dz->wordstor[newwordpos] = dz->wordstor[oldwordpos]; oldwordpos--; newwordpos--; } if(moveindex-1 < 0) { sprintf(errstr,"Accounting problem 2a: do_time_and_name_copy()\n"); return(PROGRAM_ERROR); } dz->wordcnt[lineno+moveindex-1] = dz->wordcnt[lineno]; } if((exit_status = get_maxwordsize(&maxwordsize,dz))<0) return(exit_status); if((exit_status = output_mixfile_lines(maxwordsize,dz))<0) return(exit_status); free(maxwordsize); return(FINISHED); } /************************* OUTPUT_MIXFILE_LINES ******************************/ int output_mixfile_lines(int *maxwordsize,dataptr dz) { int exit_status; int n; int total_words = 0; for(n=0;nlinecnt;n++) { if((exit_status = output_mixfile_line(dz->wordstor,total_words,dz->wordcnt[n],maxwordsize,dz))<0) return(exit_status); total_words += dz->wordcnt[n]; } return(FINISHED); } /************************* CHECK_CHANS ******************************/ int check_chans(int lineno,int oldwordpos,dataptr dz) { int chans; if(sscanf(dz->wordstor[oldwordpos],"%d",&chans)!=1) { sprintf(errstr,"Failed to read channel value:line %d: check_chans()\n",lineno+1); return(PROGRAM_ERROR); } if(chans!=dz->otherfile->channels) { sprintf(errstr,"New named file has incompatible channel cnt: line %d: check_chans()\n",lineno+1); return(DATA_ERROR); } return(FINISHED); } /************************* DO_NAME_REVERSE ******************************/ int do_name_reverse(dataptr dz) { int exit_status; int *maxwordsize; int *name_index; int half_linecnt; char *temp; int lineno, newlineno, total_words = 0; if((name_index = (int *)malloc(dz->linecnt * sizeof(int)))==NULL) { sprintf(errstr,"do_name_reverse()\n"); return(PROGRAM_ERROR); } if((exit_status = get_maxwordsize(&maxwordsize,dz))<0) { free(name_index); return(exit_status); } for(lineno=0;linenolinecnt;lineno++) { name_index[lineno] = total_words; total_words += dz->wordcnt[lineno]; } half_linecnt = dz->iparam[MSH_ENDLINE] - dz->iparam[MSH_STARTLINE]; half_linecnt = half_linecnt/2; /* TRUNCATE */ half_linecnt += dz->iparam[MSH_STARTLINE]; for(lineno=dz->iparam[MSH_STARTLINE],newlineno=dz->iparam[MSH_ENDLINE]-1;lineno < half_linecnt;lineno++,newlineno--) { temp = dz->wordstor[name_index[lineno]]; dz->wordstor[name_index[lineno]] = dz->wordstor[name_index[newlineno]]; dz->wordstor[name_index[newlineno]] = temp; } if((exit_status = output_mixfile_lines(maxwordsize,dz))<0) { free(maxwordsize); free(name_index); return(exit_status); } free(maxwordsize); free(name_index); return(FINISHED); } /************************* DO_NAME_FREEZE ******************************/ int do_name_freeze(dataptr dz) { int exit_status; int *maxwordsize; int *name_index; int lineno, total_words = 0; if((name_index = (int *)malloc(dz->linecnt * sizeof(int)))==NULL) { sprintf(errstr,"do_name_reverse()\n"); return(PROGRAM_ERROR); } if((exit_status = get_maxwordsize(&maxwordsize,dz))<0) { free(name_index); return(exit_status); } for(lineno=0;linenolinecnt;lineno++) { name_index[lineno] = total_words; total_words += dz->wordcnt[lineno]; } for(lineno=dz->iparam[MSH_STARTLINE];lineno < dz->iparam[MSH_ENDLINE];lineno++) dz->wordstor[name_index[lineno]] = dz->wordstor[name_index[dz->iparam[MSH_STARTLINE]]]; if((exit_status = output_mixfile_lines(maxwordsize,dz))<0) { free(name_index); free(maxwordsize); return(exit_status); } free(name_index); free(maxwordsize); return(FINISHED); } /************************** RANDOMISE_NAMES **************************/ int randomise_names(dataptr dz) { int exit_status; int *maxwordsize; int *name_index; int lineno, total_words = 0; int n, m, t; int permlen = dz->iparam[MSH_ENDLINE] - dz->iparam[MSH_STARTLINE]; char **permm; if((name_index = (int *)malloc(dz->linecnt * sizeof(int)))==NULL) { sprintf(errstr,"randomise_names(): 1\n"); return(PROGRAM_ERROR); } if((permm = (char **)malloc(permlen * sizeof(char *)))==NULL) { free(name_index); sprintf(errstr,"randomise_names(): 2\n"); return(PROGRAM_ERROR); } if((exit_status = get_maxwordsize(&maxwordsize,dz))<0) { free(name_index); free(permm); return(exit_status); } for(lineno=0;linenolinecnt;lineno++) { name_index[lineno] = total_words; total_words += dz->wordcnt[lineno]; } for(n=0;niparam[MSH_STARTLINE],dz); else insert_word(permm,permlen,name_index,n+dz->iparam[MSH_STARTLINE],t,dz); } for(n=0,m=dz->iparam[MSH_STARTLINE];nwordstor[name_index[m]] = permm[n]; if((exit_status = output_mixfile_lines(maxwordsize,dz))<0) { free(name_index); free(permm); free(maxwordsize); return(exit_status); } free(name_index); free(permm); free(maxwordsize); return(FINISHED); } /****************************** INSERT_WORD ****************************/ void insert_word(char **permm,int permlen,int *name_index,int m,int t,dataptr dz) { shuflup_words(permm,permlen,t+1); permm[t+1] = dz->wordstor[name_index[m]]; } /****************************** PREFIX_WORD ****************************/ void prefix_word(char **permm,int permlen,int *name_index,int m,dataptr dz) { shuflup_words(permm,permlen,0); permm[0] = dz->wordstor[name_index[m]]; } /****************************** SHUFLUP_WORDS ****************************/ void shuflup_words(char **permm,int permlen,int k) { int n; char **i; int z = permlen - 1; i = &(permm[z]); for(n = z; n > k; n--) { *i = *(i-1); i--; } } /************************** OUTPUT_MIXFILE_LINE ***************************/ int output_mixfile_line(char **wordstor,int total_words,int wordcnt,int *maxwordsize,dataptr dz) { int n, m, spacecnt; int wordno; for(n = 0;nfp,"%s",wordstor[wordno]); for(m=0;mfp," "); } fprintf(dz->fp,"\n"); return(FINISHED); }