/* * Copyright (c) 1983-2013 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 * */ #include #include #include static void sort_set(double *set,int setcnt); static void do_search(double thisval,double error,int **adjusted); static void adjust_all_vals(double thisval,double gap,int n,int m); /************************************** COMPRESS_SEQUENCE **************************************** * * parameter is interval compression multiplier. */ void compress_sequence(int multi) { int n; int m, hdcnt = ifactor; char temp[200]; double interval, nunote; if(multi) { sprintf(errstr,"%lf",number[0]); for(n=1;n< hdcnt;n++) { sprintf(temp," %lf",number[n]); strcat(errstr,temp); } strcat(errstr,"\n"); fprintf(stdout,"INFO: %s\n",errstr); for(n = 0,m = hdcnt;m < cnt;n++, m++) number[n] = number[m]; cnt -= hdcnt; } if(multi) { fprintf(stdout,"INFO: %d %lf %lf %lf %lf\n",(int)number[0],number[1],number[2],number[3],number[4]); nunote = number[2]; for(n=5;n 1\n"); fflush(stdout); exit(1); } ifactor = (int)round(factor + 0.5); if((set = (double *)malloc((cnt * ifactor) * sizeof(double)))==NULL) { fprintf(stdout,"ERROR: Insufficient memory to store pitch set.\n"); fflush(stdout); exit(1); } setcnt = 0; if(multi) { for(n=2;n= setcnt) { /* if beyond existing set */ qq = qn%setcnt; /* cyclically find appropriate set member */ qoct = qn/setcnt; transpos = 12.0 * qoct; number[n] = set[qq] + transpos; } else if(qn < 0) { /* if below existing set */ qoct = 0; /* simil */ while(qn < 0) { qn += setcnt; qoct++; } transpos = -(12.0 * qoct); number[n] = set[qn] + transpos; } else number[n] = set[qn]; break; } } } for(n=5;n= setcnt) { /* if beyond existing set */ qq = qn%setcnt; /* cyclically find appropriate set member */ qoct = qn/setcnt; transpos = 12.0 * qoct; number[n] = set[qq] + transpos; } else number[n] = set[qn]; break; } } } for(n=0;n= 0;te-=5,n+=5) { fprintf(stdout,"INFO: %d %lf %lf %lf %lf\n",(int)number[n],totaldur,number[te+1],number[te+2],number[n+4]); totaldur += number[te] - number[te - 5]; } } else { for(te = tend;te >= 0;te-=3) { fprintf(stdout,"INFO: %lf %lf %lf\n",totaldur,number[te+1],number[te+2]); totaldur += number[te] - number[te - 3]; } } fflush(stdout); } /************************************** LOOP_SEQUENCE ************************************** * * params are loopcnt and lastdur. */ void loop_sequence(int multi) { int n, m, loopcnt = (int)factor; double lastdur = thresh, totaldur, basetime; int hdcnt = ifactor; char temp[200]; if(multi) { sprintf(errstr,"%lf",number[0]); for(n=1;n< hdcnt;n++) { sprintf(temp," %lf",number[n]); strcat(errstr,temp); } strcat(errstr,"\n"); fprintf(stdout,"INFO: %s\n",errstr); for(n = 0,m = hdcnt;m < cnt;n++, m++) number[n] = number[m]; cnt -= hdcnt; totaldur = number[cnt-4] + lastdur; } else { totaldur = number[cnt-3] + lastdur; } if(lastdur <= 0.0) { fprintf(stdout,"ERROR: final event duration is <= zero\n"); fflush(stdout); exit(1); } if(loopcnt < 2) { fprintf(stdout,"ERROR: Loopcnt is <= 1\n"); fflush(stdout); exit(1); } basetime = 0.0; for(n = 0; n dn) { if(gap < up) { adjust_all_vals(thisval,gap,n,m); adjusted[n][m] = 1; } else break; } } } } void adjust_all_vals(double thisval,double gap,int n,int m) { int k; double thisgap; double adjust_within = thisval/gap; double discrep_beyond = thisval - gap; number[m] = number[n] + thisval; for(k = m+1; k < cnt; k++) number[k] += discrep_beyond; for(k = n+1; k < m; k++) { thisgap = number[k] - number[n]; number[k] = number[n] + (thisgap * adjust_within); } } /************************************** ROTATE_LIST *****************************************/ void rotate_list(int reversed) { int n; if(reversed) { for(n=1;n < stringscnt; n++) fprintf(stdout,"INFO: %s\n",strings[n]); fprintf(stdout,"INFO: %s\n",strings[0]); } else { fprintf(stdout,"INFO: %s\n",strings[stringscnt - 1]); for(n=0;n < stringscnt-1; n++) fprintf(stdout,"INFO: %s\n",strings[n]); } fflush(stdout); } /************************************** SPLICE_POS *****************************************/ #define SHSECSIZE 256 void splice_pos(void) { double splicelen = (number[cnt]+ .5)/1000.0; int srate = round(number[cnt+1]); int chans = round(number[cnt+2]); int chcnt = round(number[cnt+3]); int splen = round(splicelen * srate) * chans; int seccnt, k1, k2; int n; if(((seccnt = splen / SHSECSIZE) * SHSECSIZE) < splen) seccnt++; splen = seccnt * SHSECSIZE; splen /= chcnt; for(n=0;n 0)\n",number[m]); exit(1); } } fprintf(stdout,"INFO: %lf\n",0.0); sum = 0.0; m = firstcnt; for(n=1;n= cnt) break; } if(m < cnt) { nexttime = number[m]; nextval = number[m+1]; thistime = number[m-2]; thisval = number[m-1]; step = nexttime - thistime; frac = (number[n] - thistime)/step; val = ((nextval - thisval) * frac) + thisval; } else { val = number[cnt-1]; } gap = number[n] - number[n-1]; val *= gap; sum += val; fprintf(stdout,"INFO: %lf\n",sum); } fflush(stdout); } /************************************** LIST_WARP *****************************************/ void list_warp() { int m, n; int sizz = firstcnt-1; double index, thistime, nexttime, lasttime, thisval, nextval, step, frac, val; m = firstcnt; if(!flteq(number[firstcnt],0.0)) { fprintf(stdout,"ERROR: First time in warping file must be ZERO\n"); exit(1); } number[firstcnt] = 0.0; lasttime = number[cnt-2]; for(m=firstcnt;m= cnt) break; } if(m < cnt) { nexttime = number[m]; nextval = number[m+1]; thistime = number[m-2]; thisval = number[m-1]; step = nexttime - thistime; frac = (index - thistime)/step; val = ((nextval - thisval) * frac) + thisval; } else val = number[cnt-1]; fprintf(stdout,"INFO: %lf\n",number[n] * val); } fflush(stdout); } /************************************** BRKWARP_TIMES *****************************************/ void brktime_warp() { int m, n; double thistime, nexttime, thisval, nextval, step, frac, val, gap, sum; for(m=firstcnt+1;m 0)\n",number[m]); exit(1); } } if(!flteq(number[0],0.0)) { fprintf(stdout,"ERROR: Breakpoint file to BE warped must begin at time ZERO\n"); exit(1); } number[0] = 0.0; fprintf(stdout,"INFO: %lf %lf\n",number[0], number[1]); sum = 0.0; m = firstcnt; for(n=2;n= cnt) break; } if(m < cnt) { nexttime = number[m]; nextval = number[m+1]; thistime = number[m-2]; thisval = number[m-1]; step = nexttime - thistime; frac = (number[n] - thistime)/step; val = ((nextval - thisval) * frac) + thisval; } else { val = number[cnt-1]; } gap = number[n] - number[n-2]; val *= gap; sum += val; fprintf(stdout,"INFO: %lf %lf\n",sum, number[n+1]); } fflush(stdout); } /************************************** SEQWARP_TIMES *****************************************/ void seqtime_warp() { int m, n, OK = 1; double thistime, nexttime, thisval, nextval, step, frac, val, gap, sum, lasttime; if(((firstcnt/3) * 3) != firstcnt) OK = 0; else if(!flteq(number[0],0.0)) OK = 0; else { number[0] = 0.0; lasttime = number[0]; for(n=3;n 0)\n",number[m]); exit(1); } } if(!flteq(number[0],0.0)) { fprintf(stdout,"ERROR: Breakpoint file to BE warped must begin at time ZERO\n"); exit(1); } number[0] = 0.0; fprintf(stdout,"INFO: %lf %lf %lf\n",number[0],number[1],number[2]); sum = 0.0; m = firstcnt; for(n=3;n= cnt) break; } if(m < cnt) { nexttime = number[m]; nextval = number[m+1]; thistime = number[m-2]; thisval = number[m-1]; step = nexttime - thistime; frac = (number[n] - thistime)/step; val = ((nextval - thisval) * frac) + thisval; } else { val = number[cnt-1]; } gap = number[n] - number[n-3]; val *= gap; sum += val; fprintf(stdout,"INFO: %lf %lf %lf\n",sum, number[n+1], number[n+2]); } fflush(stdout); } /************************************** BRKVAL_WARP *****************************************/ void brkval_warp() { int m, n; double thistime, nexttime, thisval, nextval, step, frac, val; if(!flteq(number[0],0.0)) { fprintf(stdout,"ERROR: Breakpoint file to BE warped must begin at time ZERO\n"); exit(1); } if(!flteq(number[firstcnt],0.0)) { fprintf(stdout,"ERROR: Warping file must begin at time ZERO\n"); exit(1); } m = firstcnt; for(n=2;n= cnt) break; } if(m < cnt) { nexttime = number[m]; nextval = number[m+1]; thistime = number[m-2]; thisval = number[m-1]; step = nexttime - thistime; frac = (number[n] - thistime)/step; val = ((nextval - thisval) * frac) + thisval; } else val = number[cnt-1]; fprintf(stdout,"INFO: %lf %lf\n",number[n], number[n+1] * val); } fflush(stdout); } /************************************** DUPLICATE_LIST_AT_STEP *****************************************/ void duplicate_list_at_step() { int n, m; double base = 0.0; double step = number[cnt+1]; ifactor = round(number[cnt]); step = number[cnt-1] - number[0] + step; for(m=0;m>1)) { if(cnt & mask) { fprintf(stdout,"ERROR: Number of steps must be a multiple of 2.\n"); fflush(stdout); exit(1); } mask <<= 1; } free(number); if((number = (double *)malloc((cnt+1) * 2 * sizeof(double)))==NULL) { fprintf(stdout,"ERROR: Insufficient memory to store interpolated values.\n"); fflush(stdout); exit(1); } number[0] = bottime; number[cnt] = toptime; number[cnt+1] = botval; number[(cnt*2)+1] = topval; div = 2; span = cnt/2; while(div <= cnt) { n = 1; while(n < div) { index = (cnt * n)/div; /* ODD denominators, factor of 2 numerators */ step = number[index+span] - number[index-span]; /* i.e. 1/2 : 1/4,3/4 : 1/8,3/8,5/8,7/8 etc */ step *= timefrac; number[index] = number[index-span] + step; step = number[valbase+index+span] - number[valbase+index-span]; step *= valfrac; number[valbase+index] = number[valbase+index-span] + step; n += 2; } div *= 2; span /= 2; } for(n=0; n<= cnt;n++) fprintf(stdout,"INFO: %lf %lf\n",number[n],number[valbase+n]); fflush(stdout); } /****************************** REVERSE_TIME_INTERVALS2 ******************************/ void reverse_time_intervals2(void) { int n; double k = number[0]; fprintf(stdout,"INFO: %lf\n",k); for(n = cnt-1;n>=1;n--) { k += (number[n] - number[n-1]); fprintf(stdout,"INFO: %lf\n",k); } fflush(stdout); } /****************************** INTERP_N_VALS ******************************/ void interp_n_vals(void) { int n, m, subcnt = cnt - 1; double k, difdiv, diff; if(ifactor < 1) { fprintf(stdout,"ERROR: Invalid number (%d) of interpolated values\n",ifactor); fflush(stdout); exit(1); } ifactor++; difdiv = (double)ifactor; for(n = 0;n< subcnt;n++) { k = number[n]; diff = (number[n+1] - k)/difdiv; for(m=0;m= endtime) { val = endval; } else if(thistime <= number[0]) { val = number[1]; } else { lastn = n; while(thistime > number[n]) n += 2; if(n != lastn) { timediff = (number[n] - number[n-2]); valdiff = (number[n+1] - number[n-1]); } frac = (thistime - number[n-2])/timediff; val = (valdiff * frac) + number[n-1]; } sum += val; thistime += timestep; } val = sum * timestep; if(isdiff) vals[k++] = val - number[m]; else vals[k++] = val; } for(n=0;n= valcnt) { fprintf(stdout,"ERROR: Internal error calculating memory required.\n"); fflush(stdout); exit(1); } switch(cycle_point) { case(0): vals[n++] = time; vals[n++] = startpos; time += nexttimestep; nexttimestep = -1.0; if(time >= duration) dostop = 1; /* fall thro */ case(1): vals[n++] = time; if(dostop) { dostop++; break; } if(nexttimestep > 0.0) { vals[n++] = startpos; time += nexttimestep; nexttimestep = -1.0; } else { vals[n++] = left_pos; time += large_tstep; } if(time >= duration) dostop = 1; /* fall thro */ case(2): vals[n++] = time; if(dostop) { dostop++; break; } if(nexttimestep > 0.0) { vals[n++] = startpos; time += nexttimestep; nexttimestep = -1.0; } else { vals[n++] = right_pos; time += small_tstep; } if(time >= duration) dostop = 1; /* fall thro */ case(3): vals[n++] = time; if(dostop) { dostop++; break; } if(nexttimestep > 0.0) { vals[n++] = startpos; time += nexttimestep; nexttimestep = -1.0; } else { vals[n++] = far_right_pos; time += small_tstep; } if(time >= duration) dostop = 1; /* fall thro */ case(4): vals[n++] = time; if(dostop) { dostop++; break; } if(nexttimestep > 0.0) { vals[n++] = startpos; time+= nexttimestep; nexttimestep = -1.0; } else { vals[n++] = right_pos; time += large_tstep; } if(time >= duration) dostop = 1; /* fall thro */ case(5): vals[n++] = time; if(dostop) { dostop++; break; } if(nexttimestep > 0.0) { vals[n++] = startpos; time+= nexttimestep; nexttimestep = -1.0; } else { vals[n++] = left_pos; time += small_tstep; } if(time >= duration) dostop = 1; break; } if(dostop < 2) { for (;;) { if(n + 12 >= valcnt) { fprintf(stdout,"ERROR: Internal error calculating memory required.\n"); fflush(stdout); exit(1); } vals[n++] = time; vals[n++] = far_left_pos; if(dostop) break; time += small_tstep; if(time >= duration) dostop = 1; vals[n++] = time; vals[n++] = left_pos; if(dostop) break; time += large_tstep; if(time >= duration) dostop = 1; vals[n++] = time; vals[n++] = right_pos; if(dostop) break; time += small_tstep; if(time >= duration) dostop = 1; vals[n++] = time; vals[n++] = far_right_pos; if(dostop) break; time += small_tstep; if(time >= duration) dostop = 1; vals[n++] = time; vals[n++] = right_pos; if(dostop) break; time += large_tstep; if(time >= duration) dostop = 1; vals[n++] = time; vals[n++] = left_pos; if(dostop) break; time += small_tstep; if(time >= duration) dostop = 1; } } valcnt = n; for(n = 0;n < valcnt; n +=2) { fprintf(stdout,"INFO: %lf %lf\n",vals[n],vals[n+1]); } fflush(stdout); } /**************************** SINJOIN *****************************/ void sinjoin(char c) { double startval = number[0], endval = number[1]; double starttime = number[2], endtime = number[3]; int n, pointcnt = (int)round(number[4]), inverse = 0; double val = 0.0, valdiff = endval - startval; double timediff = endtime - starttime; double timestep = timediff/(double)pointcnt; double startrad = 0.0; double nstep_cosin = (PI/(double)pointcnt); double nstep_sin = (PI/(2.0 * (double)pointcnt)); if((c == 'x' && valdiff < 0.0) || (c=='v' && valdiff > 0.0)) { inverse = 1; nstep_sin = -nstep_sin; startrad = PI/2.0; } else if(c=='c') startrad = PI; fprintf(stdout,"INFO: %lf %lf\n",starttime,startval); for(n = 1; n< pointcnt;n++) { switch(c) { case('c'): startrad += nstep_cosin; val = (cos(startrad) + 1.0) / 2.0; break; case('v'): case('x'): startrad += nstep_sin; val = sin(startrad); if(inverse) val = 1.0 - val; break; } val *= valdiff; val += startval; starttime += timestep; fprintf(stdout,"INFO: %lf %lf\n",starttime,val); } fprintf(stdout,"INFO: %lf %lf\n",endtime,endval); fflush(stdout); } /************************************** BRKTIME_OWARP *****************************************/ void brktime_owarp() { int m, n; double thistime, nexttime, thisval, nextval, step, frac, val, gap, sum; for(m=firstcnt+1;m 0)\n",number[m]); exit(1); } } if(!flteq(number[0],0.0)) { fprintf(stdout,"ERROR: Breakpoint file to BE warped must begin at time ZERO\n"); exit(1); } number[0] = 0.0; fprintf(stdout,"INFO: %lf %lf\n",number[0], number[1]); sum = 0.0; n = 2; m = firstcnt; for(;;) { while(number[m] <= sum) { if((m += 2) >= cnt) break; } if(m >= cnt) val = number[cnt-1]; else { nexttime = number[m]; nextval = number[m+1]; thistime = number[m-2]; thisval = number[m-1]; step = nexttime - thistime; frac = (sum - thistime)/step; val = ((nextval - thisval) * frac) + thisval; } gap = number[n] - number[n-2]; val *= gap; sum += val; fprintf(stdout,"INFO: %lf %lf\n",sum, number[n+1]); if((n += 2) >= firstcnt) break; } fflush(stdout); }