/* * 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 #define MIN_TEMPO (.01666667) /* 1 beat per hour ! */ #define MAX_TEMPO (60000) /* 1 beat per millisecond ! */ int alphabetical_order(char *,char *); double leveltodb(double,int); double dbtolevel(double); void hinsert(int m,int t,int *perm,int permlen); void ascending_sort_cells(int *perm,int ccnt); void hshuflup(int k,int *perm,int permlen); void hprefix(int m,int *perm,int permlen); void randperm(int *perm, int permlen); static void invertenv(double piv); static void docross (double lastnval,double lastmval,double thisnval, double thismval,double time,int *j,double *out,int typ); static void hhinsert(int m,int t,int setlen,int *perm); static void hhprefix(int m,int setlen,int *perm); static void hhshuflup(int k,int setlen,int *perm); static void do_repet_restricted_perm(int *arr, int *perm, int arrsiz, int allowed, int endval); static void get_metre(char [],int *barlen,int *beatsize); static double get_tempo(char *str); static double get_beat(int n,int barlen); static void get_offset(char *str,double *offset); static double randoffset(double scatter); static double readbrk(float *warpvals,double time,int wcnt); /***************************** PRODUCT ***************************/ void product(void) { int n; double sum = number[0]; for(n=1;n= cnt) break; if(flteq(fmod(number[n],12.0),fmod(number[n+m],12.0))) { if((move = m_repos(n+m))<0) { failed++; } else { n += move; /* list shufld forwd, or not */ m--; /* m+1th item now at m */ } } } } if(failed) fprintf(stdout,"WARNING: %d items failed to be separated.\n",failed); for(n=0;n=0;n--) do_stringout(strings[n]); fflush(stdout); } /************************* ROTATE_MOTIF *************************/ void rotate_motif(void) { int n; for(n=cnt-ifactor;n'): if(number[n]>thresh) { if(flteq(number[n],0.0)) { if(!sloom && !sloombatch) fprintf(fp[1],"INFINITE\n"); else if(sloombatch) { fprintf(stdout,"INFINITE\n"); fflush(stdout); } else { fprintf(stdout,"ERROR: Division by zero encountered (item %d) : Impossible\n",n+1); fflush(stdout); exit(1); } } else do_valout(factor/number[n]); } else do_valout(number[n]); break; case('<'): if(number[n]=1.0) do_stringout("1\n"); else do_stringout("0\n"); } fflush(stdout); } /****************************** RANDOM_PAIRS ********************/ void random_pairs(void) { int n; double sum; int totcnt = (int)round(number[2]); char tempa[200]; char tempb[200]; sprintf(tempa,"%d",(int)round(number[0])); sprintf(tempb,"%d",(int)round(number[1])); for(n=0;n=1.0) do_stringout(tempb); else do_stringout(tempa); } fflush(stdout); } /****************************** RANDOM_0S_AND_1S_RESTRAINED ********************/ void random_0s_and_1s_restrained(void) { int n, cnt0 = 0, cnt1 = 0; double sum; int totcnt = (int)round(number[0]); int limit = (int)round(number[1]); for(n=0;n=1.0) { cnt1++; if(cnt1 <= limit) { do_stringout("1\n"); cnt0 = 0; } else { do_stringout("0\n"); cnt1 = 0; cnt0 = 1; } } else { cnt0++; if(cnt0 <= limit) { do_stringout("0\n"); cnt1 = 0; } else { do_stringout("1\n"); cnt0 = 0; cnt1 = 1; } } } fflush(stdout); } /****************************** RANDOM_PAIRS_RESTRAINED ********************/ void random_pairs_restrained(void) { int n, cnt0 = 0, cnt1 = 0; double sum; int totcnt = (int)round(number[2]); int limit = (int)round(number[3]); char tempa[200]; char tempb[200]; sprintf(tempa,"%d",(int)round(number[0])); sprintf(tempb,"%d",(int)round(number[1])); for(n=0;n=1.0) { cnt1++; if(cnt1 <= limit) { do_stringout(tempb); cnt0 = 0; } else { do_stringout(tempa); cnt1 = 0; cnt0 = 1; } } else { cnt0++; if(cnt0 <= limit) { do_stringout(tempa); cnt1 = 0; } else { do_stringout(tempb); cnt0 = 0; cnt1 = 1; } } } fflush(stdout); } /****************************** RANDOM_SCATTER **********************/ void random_scatter(void) { int n; double scatter; double *diffs = (double *)exmalloc((cnt-1)*sizeof(double)); for(n=0;n 0.0) number[n] += diffs[n] * scatter; else number[n] += diffs[n-1] * scatter; } print_numbers(); } /************************** RANDOM_ELIMINATION ***********************/ void random_elimination(void) { int n, m; for(n=0;n 0.0) { while(sum<=number[1]) { do_valout(sum); sum += interval; } } else { while(sum>=number[1]) { do_valout(sum); sum += interval; } } fflush(stdout); } /************************* LOG_EQUAL_DIVISIONS ***********************/ void log_equal_divisions(void) { double sum = log(number[0]); double top = log(number[1]); double interval = (top - sum)/factor; if(sum < top) { while(sum <= top - FLTERR) { do_valout(exp(sum)); sum += interval; } } else { while(sum >= top + FLTERR) { do_valout(exp(sum)); sum += interval; } } do_valout(number[1]); fflush(stdout); } /****************************** QUADRATIC_CURVE_STEPS ******************/ void quadratic_curve_steps(void) { double sum, diff = number[1] - number[0]; double step = fabs(1.0/(factor - 1.0)); double thisstep = 0.0; int cnt = 0, ifactor = round(factor); if(diff>0.0) number[2] = 1.0/number[2]; for(;;) { sum = pow(thisstep,number[2]); sum = (sum * diff) + number[0]; do_valout(sum); if(++cnt >= ifactor) break; thisstep += step; } fflush(stdout); } /*************************** PLAIN_BOB ***************************/ void plain_bob(void) { int n, m, k; for(n=0;n 0.0) { if(number[0] > number[1]) { top = number[0]; sum = number[1]; } } else { if(number[0] < number[1]) { top = number[0]; sum = number[1]; } } if(top >= sum ) { while(sum<=top) { do_valout(sum); sum += factor; } } else { while(sum>=top) { do_valout(sum); sum += factor; } } fflush(stdout); } /********************** CREATE_INTERVALS ***********************/ void create_intervals(void) { int n; for(n=0;n HUGE/2.0 || sum < -HUGE/2.0) { sprintf(errstr,"Calculation overflows.\n"); do_error(); } sum *= number[0]; } fflush(stdout); } /********************** CREATE_EQUAL_STEPS ***********************/ void create_equal_steps(void) { int n; double sum = number[0]; double step = (number[1] - number[0])/((double)ifactor - 1.0); for(n=0;n= stringscnt) { for(m=n;m cnt) { sprintf(errstr,"group size (N) too large for infile\n"); do_error(); } for(n=0;n<=cnt-ifactor;n++) { /*RWD: test was just < */ for(m=1;m (double)rowcnt) rowcnt++; if((rowcnt > 82) && sloom) { sprintf(errstr,"Too many (%d) rows to handle",rowcnt); do_error(); } for(n=0;n (double)rowcnt) rowcnt++; for(n=0;n= cnt) { ended = 1; break; } min_endtime = endtime[n]; for(k=0;k'): if(number[n]>thresh) number[n] /= factor; break; case('<'): if(number[n] MAXOCTTRANS) { if(!semitones) bum = number[n]; sprintf(errstr,"Item %d (%lf) is too large or small to convert.\n",n+1,bum); do_error(); } } for(n=0;n= 0 && alphabetical_order(tempp,strings[m])) { strings[m+1] = strings[m]; m--; } strings[m+1] = p; } for(n=0;n= 'A' && (x) < 'Z') int alphabetical_order(char *str1,char *str2) { char p, q; int n,m; int j = strlen(str1); int k = strlen(str2); m = min(j,k); for(n=0;n q) return(0); if(p < q) return(1); } if(k orig_cnt) { if((number = (double *)realloc((char *)number,cnt * sizeof(double)))==NULL) { fprintf(stdout,"WARNING: Out of memory for storing numbers.\n"); fflush(stdout); exit(1); } orig_cnt = cnt; } for(m = cnt-1; m >= n; m--) number[m] = number[m-1]; n++; start++; end++; break; default: /* >2 in group, bracket */ shrink--; for(m = n-1;m < cnt; m++) number[m-shrink] = number[m]; end = start; cnt -= shrink; n -= shrink; break; } start++; end++; } } shrink = end - start; switch(shrink) { case(0): cnt++; if(cnt > orig_cnt) { if((number = (double *)realloc((char *)number,cnt * sizeof(double)))==NULL) { fprintf(stdout,"WARNING: Out of memory for storing numbers.\n"); fflush(stdout); exit(1); } } for(m = cnt-1; m >= n; m--) number[m] = number[m-1]; break; case(1): break; default: shrink--; for(m = n-1;m < cnt; m++) number[m-shrink] = number[m]; cnt -= shrink; break; } for(n=0;n=0;n--) { if(number[n] < 0.0) { fprintf(stdout,"WARNING: No negative numbers allowed in this option.\n"); fflush(stdout); exit(1); } if(is_even) { number[m--] = number[n] + factor + thresh; number[m--] = number[n] + factor; } else { number[m--] = number[n]; number[m--] = max(number[n] - thresh, 0.0); } is_even = !is_even; } for(n=0;n=0;n--) { if(number[n] < 0.0) { fprintf(stdout,"WARNING: No negative numbers allowed in this option.\n"); fflush(stdout); exit(1); } number[m--] = number[n] + factor + thresh; number[m--] = number[n] + factor; number[m--] = number[n]; number[m--] = max(number[n] - thresh, 0.0); } for(n=0;n=0;n--) { if(number[n] < 0.0) { fprintf(stdout,"WARNING: No negative numbers allowed in this option.\n"); fflush(stdout); exit(1); } number[m--] = number[n] + thresh; number[m--] = number[n]; number[m--] = max(number[n] - thresh, 0.0); } for(n=0;n= ifactor; n--) number[n] = number[n-1]; } number[ifactor] = factor; cnt++; for(n=0;n= cnt) break; } here += q_per_step; } free(perm); } for(n=0;n k;n--) { *i = *(i-1); i--; } } void ascending_sort_cells(int *perm,int ccnt) { int n, m, sct; for(n=0;n<(ccnt-1);n++) { for(m=n+1;m OR < A GIVEN VAL ****************/ void replace_equal(void) { int n; double maxe = number[cnt] + FLTERR; double mine = number[cnt] - FLTERR; double replace = number[cnt+1]; for(n=0;n mine)) number[n] = replace; fprintf(stdout,"INFO: %lf\n",number[n]); } fflush(stdout); } void replace_less(void) { int n; double mine = number[cnt]; double replace = number[cnt+1]; for(n=0;n maxe) number[n] = replace; fprintf(stdout,"INFO: %lf\n",number[n]); } fflush(stdout); } /*************************** GAPPED QUANTISED GRIDS *************************/ void grid(int is_outside) { int n, k, tot; double quant = number[cnt], sum, dogrid = 0; if(quant <= .001) { fprintf(stdout,"ERROR: Quantisation step too small.\n"); fflush(stdout); return; } else if((tot = (int)ceil(number[cnt-1]/quant)) > 10000) { fprintf(stdout,"ERROR: Quantisation too small, relative to total duration.\n"); fflush(stdout); return; } else if(tot < 2) { fprintf(stdout,"ERROR: Quantisation too large, relative to total duration.\n"); fflush(stdout); return; } if((permm = (double *)malloc(tot * sizeof(double))) == NULL) { fprintf(stdout,"ERROR: Out of memory.\n"); fflush(stdout); return; } if(is_outside) dogrid = 1; n = 0; k = 0; sum = 0.0; while(n < cnt) { if(dogrid) { while(sum < number[n]) { permm[k++] = sum; sum += quant; } } else { while(sum < number[n]) sum += quant; } dogrid = !dogrid; n++; } for(n=0;n= cnt) { fprintf(stdout,"ERROR: This will delete the whole column."); fflush(stdout); return; } if(delitems < 1) { fprintf(stdout,"ERROR: Must delete 1 or more items."); fflush(stdout); return; } if(delitems > cnt/2) { /* Invert the algorithm */ inverted = 1; keptitems = delitems; delitems = cnt - keptitems; k = adj; adj = gap; gap = k; } else { keptitems = cnt - delitems; } if((vacuum = (int *)malloc(delitems * sizeof(int)))==NULL) { fprintf(stdout,"ERROR: Out of memory.\n"); fflush(stdout); return; } delset_cnt = 0; sum = 0; while(sum < delitems-1) { /* generating deletable groups of random sizes */ k = (int)floor(drand48()*adj) + 1; /* within range set by 'adj' */ if((sum+k) > delitems-1) /* once enough items deleted, break */ break; else { vacuum[delset_cnt++] = k; /* otherwise store the size of deletable group */ sum += k; } } if(sum < delitems) /* fix the size of final deletable group, to make deleted total correct */ vacuum[delset_cnt++] = delitems - sum; if((vacuum = (int *)realloc((char *)vacuum,delset_cnt * sizeof(int)))==NULL) { fprintf(stdout,"ERROR: Memory reallocation error.\n"); fflush(stdout); return; } if(delset_cnt > keptitems) { /* must be as many kept items as deleted groups, to separate those groups */ fprintf(stdout,"ERROR: Not enough undeleted items remaining to complete the task.\n"); fflush(stdout); return; } else if(delset_cnt == keptitems) { /* exactly as many keptitems as deleted groups, they must alternate */ j = 0; n = 0; i = (int)floor(drand48() * 2.0); /* select at random whether to start with deletes or not */ if(inverted) { if(i) { /* and either ... */ while(j < delset_cnt) { for(k=0;k cnt) { fprintf(stdout,"ERROR: Program anomaly in counting data. 6\n"); break; } } /* then skip 1 */ if(++n > cnt) { fprintf(stdout,"ERROR: Program anomaly in counting data. 7\n"); break; } j++; } fflush(stdout); return; } else { /* or .... */ while(j < delset_cnt) { /* skip 1 */ if(++n > cnt) { fprintf(stdout,"ERROR: Program anomaly in counting data. 8\n"); break; } for(k=0;k cnt) { fprintf(stdout,"ERROR: Program anomaly in counting data. 9\n"); break; } } j++; } fflush(stdout); return; } } else { if(i) { /* and either ... */ while(j < delset_cnt) { for(k=0;k cnt) { fprintf(stdout,"ERROR: Program anomaly in counting data. 10\n"); break; } } /* then print 1 */ fprintf(stdout,"INFO: %lf\n",number[n]); if(++n > cnt) { fprintf(stdout,"ERROR: Program anomaly in counting data. 11\n"); break; } j++; } fflush(stdout); return; } else { /* or .... */ while(j < delset_cnt) { /* print 1 */ fprintf(stdout,"INFO: %lf\n",number[n]); if(++n > cnt) { fprintf(stdout,"ERROR: Program anomaly in counting data. 12\n"); break; } for(k=0;k cnt) { fprintf(stdout,"ERROR: Program anomaly in counting data. 13\n"); break; } } j++; } fflush(stdout); return; } } } keepset_cnt = delset_cnt+1; /* otherwise, let there be 1 more sets of kept items then of deleted items */ /* This is an aesthetic, choice.. there could be an equal number */ if(( k = (int)ceil((double)keptitems/(double)keepset_cnt)) > gap) { gap = k + 1; /* if min-size of largest kept group is > gap, can't use gap value */ fprintf(stdout,"ERROR: Intergap distance incompatible with other demands. Adjusting to %d.\n",gap); fflush(stdout); } if(((box = (int *)malloc(keepset_cnt * sizeof(int)))==NULL) || ((boxcnt = (int *)malloc(keepset_cnt * sizeof(int)))==NULL) || ((box_assocd_with_cntr_no = (int *)malloc(keepset_cnt * sizeof(int)))==NULL) || ((cntr_assocd_with_box_no = (int *)malloc(keepset_cnt * sizeof(int)))==NULL)) { fprintf(stdout,"ERROR: Out of memory.\n"); fflush(stdout); return; } for(n=0;n 0) { /* if any leftover balls */ unfilled_boxes = keepset_cnt; /* set number of unfilled boxes */ for(n=0;n= gap) { /* if the box getting the ball is now full */ boxcnt[cntr_assocd_with_box_no[z]] = box[z]; /* store the count of balls in the box */ unfilled_boxes--; /* reduce number of boxes to put random balls into */ while(z < unfilled_boxes) { box[z] = box[z+1]; /* eliminate full box, by shuffling boxes above downwards */ k = cntr_assocd_with_box_no[z+1]; /* get the boxcnter associated with the next box */ box_assocd_with_cntr_no[k]--; /* force it to point to next lower box (as boxes have moved down 1) */ j = box_assocd_with_cntr_no[k]; /* get the box it now points to */ cntr_assocd_with_box_no[j] = k; /* get that to point back to the box counter */ z++; } } } } for(n=0;n cnt) { fprintf(stdout,"ERROR: Program anomaly in counting data 4.\n"); return; } } for(k=0;k cnt) { fprintf(stdout,"ERROR: Program anomaly in counting data 5.\n"); return; } } /* Note, all inverted patterns start and end with OFF events - an aesthetic decision */ j++; } } else { while(j < delset_cnt) { for(k=0;k cnt) { fprintf(stdout,"ERROR: Program anomaly in counting data 1.\n"); return; } } for(k=0;k cnt) { fprintf(stdout,"ERROR: Program anomaly in counting data 2.\n"); return; } } j++; } for(k=0;k cnt) { fprintf(stdout,"ERROR: Program anomaly in counting data 3.\n"); break; } /* Note, all patterns start and end with ON events - an aesthetic decision */ } } fflush(stdout); } /****************************** REPLACE_WITH_RAND ******************************/ void replace_with_rand(int type) { int n; double lim = number[cnt], randlo = number[cnt+1], randhi = number[cnt+2]; double k, randrang, limhi, limlo; if(randhi < randlo) { k = randhi; randhi = randlo; randlo = k; } randrang = randhi - randlo; switch(type) { case(0): /* equal */ limhi = lim + FLTERR; limlo = lim - FLTERR; for(n=0;n limlo)) number[n] = (drand48() * randrang) + randlo; fprintf(stdout,"INFO: %lf\n",number[n]); } break; case(-1): /* less */ for(n=0;n lim) number[n] = (drand48() * randrang) + randlo; fprintf(stdout,"INFO: %lf\n",number[n]); } break; } fflush(stdout); } /****************************** RANDQUANTA_IN_GAPS ******************************/ void randquanta_in_gaps(void) { int totcnt = round(number[cnt]); /* number of vals to make */ double q = number[cnt+1]; /* quantisation of grid */ int mincnt = round(number[cnt+2]), maxcnt = round(number[cnt+3]); /* min & max no of events in each time-interval */ int k,j,n,m, posibmax = 0, maxqpnts = 0, tot_boxes,minpos,maxpos,remainder,unfilled_boxes; int boxpos, orig_boxpos; int *perm,*box,*boxcnt,*qpnts,*box_assocd_with_cntr_no,*cntr_assocd_with_box_no; double mintim,maxtim; double *qbas; if(maxcnt < mincnt) { /* orient cnt-range */ n = maxcnt; maxcnt = mincnt; mincnt = n; } if(mincnt < 1) { fprintf(stdout,"ERROR: Invalid count of number of items (%d)\n",mincnt); fflush(stdout); exit(1); } if(cnt & 1) /* Force even number of pairs */ cnt--; if((tot_boxes = cnt/2) < 1) { fprintf(stdout,"Too few value pairs in input column.\n"); fflush(stdout); exit(1); } if(totcnt < tot_boxes * mincnt) { fprintf(stdout,"Insufficient items to distribute amongst the %d pairs.\n",tot_boxes); fflush(stdout); exit(1); } if(((box = (int *)malloc(tot_boxes * sizeof(int)))==NULL) /* 'boxes' store random placed 'balls' */ || ((boxcnt = (int *)malloc(tot_boxes * sizeof(int)))==NULL) /* counts of balls in 'boxes' */ || ((qpnts = (int *)malloc(tot_boxes * sizeof(int)))==NULL) /* no. of q-points in each time-interval */ /* = maximum number of balls for each box */ || ((qbas = (double *)malloc(tot_boxes * sizeof(double)))==NULL) /* first q-point time in each time-interval */ || ((box_assocd_with_cntr_no = (int *)malloc(tot_boxes * sizeof(int)))==NULL) || ((cntr_assocd_with_box_no = (int *)malloc(tot_boxes * sizeof(int)))==NULL)) { fprintf(stdout,"Out of memory.\n"); /* because boxes are 'deleted' & shuffled down */ fflush(stdout); exit(1); } for(n=0, m =0; n < cnt; n += 2,m++) { mintim = number[n]; maxtim = number[n+1]; minpos = (int)floor(mintim/q); if(((double)minpos * q) < mintim) minpos++; maxpos = (int)floor(maxtim/q); qpnts[m] = maxpos - minpos + 1; if(qpnts[m] < mincnt) { fprintf(stdout,"ERROR: timegap between %lf and %lf will not take %d items\n",number[n],number[n+1],mincnt); fflush(stdout); exit(1); } if(m == 0) maxqpnts = qpnts[0]; else maxqpnts = max(maxqpnts,qpnts[m]); qbas[m] = minpos * q; posibmax += min(qpnts[m],maxcnt); } if(posibmax < totcnt) { fprintf(stdout, "ERROR: total count of items exceeds available spaces.\n"); fflush(stdout); exit(1); } if((perm = (int *)malloc(maxqpnts * sizeof(int)))==NULL) { fprintf(stdout,"Out of memory.\n"); fflush(stdout); exit(1); } remainder = totcnt; /* DISTRIBUTE THE REMAINING ITEMS AT RANDOM (with constraints) BETWEEN THE boxcnt BOXES */ for(n=0;n 0) { /* if any leftover balls */ /* ELIMINATE ANY BOXES WHICH ARE ALREADY FULL */ unfilled_boxes = tot_boxes; /* set number of unfilled boxes as total no of boxes */ boxpos = 0; for(n=0,m=0;n= qpnts[n]) { /* if the box is already full */ boxcnt[n] = box[boxpos]; /* store the count of balls that are in the box */ unfilled_boxes--; /* reduce number of boxes to put random balls into */ orig_boxpos = boxpos; /* save the position of the full-box which is being eliminated */ while(boxpos < unfilled_boxes) { box[boxpos] = box[boxpos+1]; /* eliminate full box, by shuffling boxes above downwards */ k = cntr_assocd_with_box_no[boxpos+1]; /* get the boxcnter associated with the next box */ box_assocd_with_cntr_no[k]--; /* force it to point to next lower box (as boxes have moved down 1) */ j = box_assocd_with_cntr_no[k]; /* get the box it now points to */ cntr_assocd_with_box_no[j] = k; /* get that to point back to the box counter */ boxpos++; } boxpos = orig_boxpos; /* reset box position to where it was: now points to new box */ } else { boxpos++; /* if box getting ball is NOT full, go on to next box */ } } /* DISTRIBUTE REMAINING BALLS */ for(n=0;n= qpnts[k]) { /* if the box getting the ball is now full */ boxcnt[k] = box[boxpos]; /* store the count of balls that are in the box */ unfilled_boxes--; /* reduce number of boxes to put random balls into */ while(boxpos < unfilled_boxes) { box[boxpos] = box[boxpos+1]; /* eliminate full box, by shuffling boxes above downwards */ k = cntr_assocd_with_box_no[boxpos+1]; /* get the boxcnter associated with the next box */ box_assocd_with_cntr_no[k]--; /* force it to point to next lower box (as boxes have moved down 1) */ j = box_assocd_with_cntr_no[k]; /* get the box it now points to */ cntr_assocd_with_box_no[j] = k; /* get that to point back to the box counter */ boxpos++; } } } } for(n=0;n= cnt) break; } while(n < cnt) { if(no1[n] == no2[m]) { /* brkpnts coincide */ out[j++] = no1[n++]; m++; /* new brkpnt val is product of origs */ lastnval = thisnval; lastmval = thismval; thisnval = no1[n]; thismval = no2[m]; switch(typ) { case(MULT): out[j++] = no1[n++] * no2[m++]; break; case(ADD): out[j++] = no1[n++] + no2[m++]; break; case(SUBTRACT): out[j++] = no1[n++] - no2[m++]; break; case(ENVMAX): out[j++] = max(no1[n],no2[m]); n++; m++; break; } if(m >= cnt2) /* If at end of inserted env, break from loop */ break; } else if(no1[n] > no2[m]) { /* inserted brkpnt falls before next orig-brkpnt */ while(no1[n] > no2[m]) { time = no2[m]; /* take time from inserted brkpnt */ tdiff = no1[n] - no1[n-2]; tratio = (no2[m++] - no1[n-2])/tdiff; n++; vdiff = no1[n] - no1[n-2]; vhere = (vdiff * tratio) + no1[n-2]; /* value of orig brkpnt, at this time */ lastnval = thisnval; lastmval = thismval; thisnval = vhere; thismval = no2[m]; docross(lastnval,lastmval,thisnval,thismval,time,&j,out,typ); out[j++] = time; switch(typ) { case(MULT): out[j++] = vhere * no2[m++]; break; case(ADD): out[j++] = vhere + no2[m++]; break; case(SUBTRACT): out[j++] = vhere - no2[m++]; break; case(ENVMAX): out[j++] = max(vhere,no2[m]); m++; break; } n--; /* remain at same point in orig-brkfile */ if(m >= cnt2) break; /* If at end of inserted env, break from loop */ } } else { /* orig-brkpnt falls before next inserted brkpnt */ while(no2[m] > no1[n]) { time = no1[n]; /* take time from orig brkpnt */ tdiff = no2[m] - no2[m-2]; tratio = (no1[n++] - no2[m-2])/tdiff; m++; vdiff = no2[m] - no2[m-2]; vhere = (vdiff * tratio) + no2[m-2]; /* value of inserted brkpnt, at this time */ lastnval = thisnval; lastmval = thismval; thismval = vhere; thisnval = no1[n]; docross(lastnval,lastmval,thisnval,thismval,time,&j,out,typ); out[j++] = time; switch(typ) { case(MULT): out[j++] = vhere * no1[n++]; break; case(ADD): out[j++] = vhere + no1[n++]; break; case(SUBTRACT): out[j++] = vhere - no1[n++]; break; case(ENVMAX): out[j++] = max(vhere,no1[n]); n++; break; } m--; /* remain at same point in inserted-brkfile */ if(n >= cnt) { /* if it at end of orig file */ while(m < cnt2) { /* calc remaining inserted file points */ out[j++] = no2[m++]; switch(typ) { case(MULT): out[j++] = no2[m++] * no1[cnt-1]; break; case(ADD): out[j++] = no2[m++] + no1[cnt-1]; break; case(SUBTRACT): out[j++] = no2[m++] - no1[cnt-1]; break; case(ENVMAX): out[j++] = max(no2[m],no1[cnt-1]); m++; break; } } break; /* and break from loop */ } } } if(m >= cnt2) break; /* If at end of inserted env, break from outer loop */ } /* on leaving loop either m > cnt2 or n > cnt */ while (n < cnt) { /* if orig brkfile extends beyond inserted file */ out[j++] = no1[n++]; /* calculate remaining points */ switch(typ) { case(MULT): out[j++] = no1[n++] * no2[cnt2 - 1]; break; case(ADD): out[j++] = no1[n++] + no2[cnt2 - 1]; break; case(SUBTRACT): out[j++] = no1[n++] - no2[cnt2 - 1]; break; case(ENVMAX): out[j++] = max(no1[n],no2[cnt2 - 1]); n++; break; } } while (m < cnt2) { /* if inserted brkfile extends beyond orig file */ out[j++] = no2[m++]; /* calculate remaining points */ switch(typ) { case(MULT): out[j++] = no2[m++] * no1[cnt - 1]; break; case(ADD): out[j++] = no2[m++] + no1[cnt - 1]; break; case(SUBTRACT): out[j++] = no2[m++] - no1[cnt - 1]; break; case(ENVMAX): out[j++] = max(no2[m],no1[cnt - 1]); m++; break; } } fprintf(stdout,"INFO: %lf %lf\n",out[0],out[1]); skipped = 0; for(n=2;n lastmval) prehi = 1; else if(lastnval < lastmval) prehi = -1; if(thisnval > thismval) posthi = 1; else if(thisnval < thismval) posthi = -1; if(prehi && posthi && (prehi != posthi)) { /* curves intersect */ lasttime = out[*(j)-2]; timediff = time - lasttime; if(flteq(timediff,0.0)) { fprintf(stdout,"ERROR: Came across time step too small to calculate.\n"); fflush(stdout); exit(1); } gradn = (thisnval - lastnval)/timediff; gradm = (thismval - lastmval)/timediff; if(flteq(gradn,gradm)) { fprintf(stdout,"ERROR: possible error in curve crossing algorithm.\n"); fflush(stdout); exit(1); } timecross = (lastmval - lastnval)/(gradn - gradm); valcross = (gradn * timecross) + lastnval; out[(*j)++] = timecross + lasttime; switch(typ) { case(MULT): out[(*j)++] = (valcross * valcross); break; case(ADD): out[(*j)++] = (valcross + valcross); break; case(SUBTRACT): out[(*j)++] = 0.0; break; case(ENVMAX): out[(*j)++] = valcross; break; } } } /****************************** ENV_DEL_INV ******************************/ void env_del_inv(void) { int n, m; cnt += 2; if((number = (double *)realloc((char *)number,cnt * sizeof(double)))==NULL) { fprintf(stdout,"ERROR: Out of memory.\n"); fflush(stdout); exit(1); } m = cnt - 1; n = cnt - 3; while(n > 0) { number[m--] = 1.0 - number[n--]; /* inverse */ number[m--] = number[n--] + factor; /* delay */ } number[1] = number[3]; /* extend initial val.. */ number[0] = 0.0; /* ...back to zero time */ for(n=0;n max_int) { max_int = this_int; pos = n; } } fprintf(stdout,"WARNING: Maximum interval is %lf between entries %d and %d.\n",max_int,pos,pos+1); fflush(stdout); } else { min_int = number[1] - number[0]; for(n=2;n 0) { /* if new number not at start of column */ for(n=0;n (double)rowcnt) rowcnt++; for(n=0;n (double)rowcnt) rowcnt++; for(n=0;n= ifactor) break; k = arr[perm[m]]; fprintf(stdout,"INFO: %d\n",k); if(m >= checkpart) /* save last checkable stretch of perm */ arr2[j++] = k; } fflush(stdout); if(n >= ifactor) break; j--; endval = arr2[j--]; /* note the val at end of perm */ endcnt = 1; /* and count it */ for(k = j; k>= 0; k--) { if(arr2[k] == endval) /* check adjacent vals, for repetition of value: count */ endcnt++; else /* if no more repetitions, finish counting */ break; } allowed = repets - endcnt; /* get number of permissible repets at start of next perm */ } } /****************************** DO_REPET_RESTRICTED_PERM ****************************/ void do_repet_restricted_perm(int *arr, int *perm, int arrsiz, int allowed, int endval) { int n, t; int checklen = allowed + 1; int done = 0; while(!done) { for(n=0;n k;n--) { *i = *(i-1); i--; } } /****************************** TIME_FROM_BAR_BEAT_METRE_TEMPO ***********************************/ void time_from_bar_beat_metre_tempo(int has_offset) { int barlen, beatsize, n; double tempo,beat,beatdur,time, offset = 0.0; if((tempo = get_tempo(strings[cnt+1])) <= 0.0) exit(1); if(has_offset) get_offset(strings[cnt+2],&offset); get_metre(strings[cnt],&barlen,&beatsize); beatdur = (60.0/(double)tempo) * (4.0/(double)beatsize); for(n=0;n 1) fprintf(stdout, "ERROR: Invalid metre value. %d decimal points : must be one only.\n",pointcnt); else fprintf(stdout, "ERROR: Invalid metre value. No decimal point\n"); fflush(stdout); exit(1); } *q = ENDOFSTR; if(sscanf(start,"%d",barlen)<1) { /* SAFETY (redundant) */ fprintf(stdout, "ERROR: Invalid metre value. Cannot read barlength.\n"); fflush(stdout); exit(1); } p = q+1; if(*p==ENDOFSTR) { fprintf(stdout, "ERROR: Invalid metre value. (No denominator).\n"); fflush(stdout); exit(1); } start = p; if(*p == '0') { fprintf(stdout, "ERROR: Invalid metre value. (leading zeros in denominator).\n"); /* leading zero(s) */ fflush(stdout); exit(1); } while(*p != ENDOFSTR) { if(!isdigit(*p)) { /* non-numeric characters */ fprintf(stdout, "ERROR: Invalid metre value. (non-digit character '%c' in denominator )\n",*p); fflush(stdout); exit(1); } p++; } if(sscanf(start,"%d",beatsize)<1) { /* SAFETY (redundant) */ fprintf(stdout, "ERROR: Invalid metre value. Failed to read beatsize from %s\n",start); fflush(stdout); exit(1); } mask = 1; while(mask < 512) { /* Powers of 2 only !! Need special dispensation for Ferneyhovian metres like 4:10 */ if((*beatsize) == mask) { isvalid = 1; break; } mask <<= 1; } if(!isvalid) { fprintf(stdout, "ERROR: Invalid metre value. beatsize (%d) is invalid in standard usage\n",*beatsize); fflush(stdout); exit(1); } } /****************************** GET_BEAT ***********************************/ double get_beat(int n,int barlen) { int pointcnt = 0; char *q = NULL, *p, *start; int bar; double beat; if(strlen(strings[n]) == 0) { fprintf(stdout, "ERROR: Invalid bar:beat value at item %d. (No value found)\n",n+1); fflush(stdout); exit(1); } p = strings[n]; /* must have COLON */ while(*p != ENDOFSTR) { if(*p == ':') { pointcnt++; q = p; } else if (!isdigit(*p) && (*p != '.')) { pointcnt = -1; break; } p++; } if(pointcnt != 1) { switch(pointcnt) { case(-1): fprintf(stdout, "ERROR: Invalid character (%c) in bar:beat value '%s' in item %d\n",*p,strings[n],n+1); break; case(0): fprintf(stdout, "ERROR: Invalid bar:beat value '%s' at item %d. (No colon found)\n",strings[n],n+1); break; default: fprintf(stdout, "ERROR: Invalid bar:beat value '%s' at item %d : %d colons found (should be only 1)\n", strings[n],n+1,pointcnt); break; } fflush(stdout); exit(1); } *q = ENDOFSTR; if(sscanf(strings[n],"%d",&bar)<1) { /* SAFETY (redundant) */ fprintf(stdout, "ERROR: Invalid bar:beat value at item %d. Failed to read bar count.\n",n+1); fflush(stdout); exit(1); } if(bar < 1) { fprintf(stdout, "ERROR: Invalid bar:beat value at item %d. Bar count less than 1.\n",n+1); fflush(stdout); exit(1); } bar--; start = q+1; if(*start==ENDOFSTR) { fprintf(stdout, "ERROR: Invalid bar:beat value at item %d. No beatcount.\n",n+1); fflush(stdout); exit(1); } if(sscanf(start,"%lf",&beat)<1) { /* SAFETY (redundant) */ fprintf(stdout, "ERROR: Invalid bar:beat value at item %d. Failed to read beatcount.\n",n+1); fflush(stdout); exit(1); } if(beat < 1.0) { fprintf(stdout, "ERROR: Invalid bar:beat value at item %d. Beat count less than 1.\n",n+1); fflush(stdout); exit(1); } else if(beat >= (double)(barlen + 1)) { fprintf(stdout, "ERROR: Invalid bar:beat value at item %d. Beat count beyond bar end.\n",n+1); fflush(stdout); exit(1); } beat -= 1.0; beat += (bar * (double)barlen); return beat; } /****************************** SCALE_FROM ***********************************/ void scale_from(void) { double interval, pivot = number[cnt]; double scaler = number[cnt+1]; int n; for(n = 0;n 0.0) { interval *= scaler; fprintf(stdout,"INFO: %lf\n",pivot + interval); } else fprintf(stdout,"INFO: %lf\n",number[n]); } fflush(stdout); } /****************************** SCALE_BELOW ***********************************/ void scale_below(void) { double interval, pivot = number[cnt]; double scaler = number[cnt+1]; int n; for(n = 0;n cnt) { fprintf(stdout,"ERROR: There are no numbers at or beyond position %d\n",start); fflush(stdout); exit(1); } else if(start < 1) { fprintf(stdout,"ERROR: There are no numbers at or before position %d\n",start); fflush(stdout); exit(1); } start--; if(abs(step = (int)round(number[steppos])) < 1) { fprintf(stdout,"ERROR: Step between values cannot be zero.\n"); fflush(stdout); exit(1); } if(c != 's') { if(step < 0) { fprintf(stdout,"ERROR: Step between values cannot be negative.\n"); fflush(stdout); exit(1); } item = number[cnt]; } switch(k) { case('s'): if(step > 0) { for(n = start;n=0;n+=step) fprintf(stdout,"INFO: %lf\n",number[n]); } break; case('a'): case('m'): n = 0; while(n < start) fprintf(stdout,"INFO: %lf\n",number[n++]); for(m = 0;n factor) { fprintf(stdout,"ERROR: Numbers already run beyond %lf\n",factor); fflush(stdout); exit(1); } if(number[0] <= 0.0) zero_exists = 1; if(number[cnt-1] >= factor) top_exists = 1; if(zero_exists) { if(top_exists) { fprintf(stdout,"ERROR: Numbers already begin at zero and end at %lf\n",factor); fflush(stdout); exit(1); } else { fprintf(stdout,"WARNING: Numbers already start at zero\n"); fflush(stdout); } } if(top_exists) { fprintf(stdout,"WARNING: Numbers already end at %lf\n",factor); fflush(stdout); } if(!zero_exists) fprintf(stdout,"INFO: %lf\n",0.0); for(n=0;n 1) { fprintf(stdout, "ERROR: Invalid tempo value.\n"); fflush(stdout); return(-1.0); } if(sscanf(str,"%lf",&tempo)!=1) { fprintf(stdout, "ERROR: Invalid tempo value.\n"); fflush(stdout); return(-1.0); } if(tempo <= 0.0) { fprintf(stdout, "ERROR: Zero or negative tempo: impossible.\n"); fflush(stdout); return(-1.0); } else if(tempo > MAX_TEMPO) { fprintf(stdout, "ERROR: Invalid tempo value. Beats shorter than 1 millisecond (!!).\n"); fflush(stdout); return(-1.0); } else if(tempo < MIN_TEMPO) { fprintf(stdout, "ERROR: Invalid tempo value. Beats longer than 1 hour (!!).\n"); fflush(stdout); return(-1.0); } return tempo; } /************************** GENERATE_RANDOMISED_VALS ********************************/ void generate_randomised_vals(void) { double scatter = number[2], span = number[0], sum = 0.0, mean, range, *temp = NULL, d; int cnt = (int)round(number[1]), n, m, j, subcnt; int bigscat = 0; if(scatter > 1.0) bigscat = (int)round(scatter); if(bigscat) { if((temp = (double *)malloc(bigscat * sizeof(double)))==NULL) { fprintf(stdout,"Out of memory.\n"); fflush(stdout); exit(1); } } if((number = (double *)realloc((char *)number,(cnt+1) * sizeof(double)))==NULL) { fprintf(stdout,"Out of memory.\n"); fflush(stdout); exit(1); } mean = span/(double)cnt; number[0] = 0.0; number[cnt] = span; if(bigscat) { for(n=1;n < cnt;n+= bigscat) { if((subcnt = n + bigscat) > cnt) /* find position of last number in this pass */ subcnt = cnt; /* set end position of pass */ subcnt--; /* allow for item already written at 1 */ if((subcnt %= bigscat) == 0) /* set size of pass */ subcnt = bigscat; range = mean * subcnt; /* set range of pass */ for(m = 0; m < subcnt; m++) temp[m] = sum + (drand48() * range); /* generate values within this range */ for(m=0;m < subcnt - 1; m++) { for(j=1;j < subcnt; j++) { if(temp[m] > temp[j]) { /* sort */ d = temp[j]; temp[j] = temp[m]; temp[m] = d; } } } for(m=0;m MIDIMAX) { fprintf(stdout,"MIDI value %d (%lf) is out of range.\n", n+1,number[n]); fflush(stdout); exit(1); } number[n] = miditohz(number[n]); } else if(number[n] < FLTERR || number[n] > 24000.0) { fprintf(stdout,"Frequency value %d (%lf) is out or range.\n",n+1,number[n]); fflush(stdout); exit(1); } number[n] = 1000.0/number[n]; } for(n=0;n MIDIMAXFRQ) { fprintf(stdout,"delay value %d (%lf) is out of range for conversion to MIDI.\n", n+1,number[n]); fflush(stdout); exit(1); } number[n] = hztomidi(number[n]); } else if(number[n] < FLTERR || number[n] > 24000) { fprintf(stdout,"Delay value %d (%lf) is out or range for conversion to frq.\n",n+1,number[n]); fflush(stdout); exit(1); } } for(n=0;n factor) isgreater = 1; for(m=2,n=3;n factor) { ratio = (factor - number[n-2])/(number[n] - number[n-2]); time[k++] = ((number[m] - number[m-2]) * ratio) + number[m-2]; isgreater = 1; } break; case(1): if(number[n] <= factor) { ratio = (factor - number[n-2])/(number[n] - number[n-2]); time[k++] = ((number[m] - number[m-2]) * ratio) + number[m-2]; isgreater = 0; } break; } } if(k == 0) { fprintf(stdout,"ERROR: The values do not cross the threshold.\n"); free(time); return; } for(n=0;n hibnd) { z = lobnd; lobnd = hibnd; hibnd = z; } if(number[1] >= lobnd && number[1] <= hibnd) bandpos = 0; else if(number[1] < lobnd) bandpos = -1; else bandpos = 1; for(m=2,n=3;n hibnd) { /* crosses out upwards */ ratio = (hibnd - number[n-2])/(number[n] - number[n-2]); time[k++] = ((number[m] - number[m-2]) * ratio) + number[m-2]; bandpos = 1; } break; case(1): if(number[n] <= hibnd) { /* crosses in from above */ ratio = (hibnd - number[n-2])/(number[n] - number[n-2]); time[k++] = ((number[m] - number[m-2]) * ratio) + number[m-2]; bandpos = 0; } if(number[n] < lobnd) { /* then possibly out below */ ratio = (lobnd - number[n-2])/(number[n] - number[n-2]); time[k++] = ((number[m] - number[m-2]) * ratio) + number[m-2]; bandpos = -1; } break; case(-1): if(number[n] >= lobnd) { /* crosses in from below */ ratio = (lobnd - number[n-2])/(number[n] - number[n-2]); time[k++] = ((number[m] - number[m-2]) * ratio) + number[m-2]; bandpos = 0; } if(number[n] > hibnd) { /* then possibly out above */ ratio = (hibnd - number[n-2])/(number[n] - number[n-2]); time[k++] = ((number[m] - number[m-2]) * ratio) + number[m-2]; bandpos = 1; } break; } } if(k == 0) { fprintf(stdout,"ERROR: The values in the 2nd column do not cross into or out of the specified band.\n"); free(time); return; } for(n=0;n 0) && number[n-2] >= number[n-1]) { fprintf(stdout,"WARNING: numbers %d (%lf) and %d (%lf) failed to be separated.\n", n,number[n-1],n+1,number[n]); fflush(stdout); return; } number[n] = z1 + FLTERR; if((n+1 < cnt) && number[n+1] <= number[n]) { fprintf(stdout,"WARNING: numbers %d (%lf) and %d (%lf) failed to be separated.\n", n+1,number[n],n+2,number[n+1]); fflush(stdout); return; } } } for(n=0;n lowlimit * 20.0) { diffstep = diffrange/20.0; thisdiff = mindiff; for(m=0;m<=20;m++) { error[m] = 0; thisgrid = number[0]; for(n=1;n error[m]) { minerror = error[m]; besterror = m; } } mindiff = mindiff + (besterror * diffstep); lastmindiff = mindiff; maxdiff = mindiff + diffstep; mindiff -= diffstep; } thisgrid = number[0]; for(n=0;n -FLTERR) thisdiff = 0.0; fprintf(stdout,"INFO: %lf\n",thisdiff); thisgrid += lastmindiff; } fflush(stdout); } /****************************** SINUSOID ******************************/ void sinusoid(void) { double maxval = number[0], minval = number[1]; double range = maxval - minval; double phase = (fmod(number[2],360.0)/360.0) * TWOPI; double periods = number[3]; double valdens = number[4]; int n, valcnt = (int)floor((periods * valdens) + 1.0); double val, phasestep = TWOPI/valdens; for(n = 0; n < valcnt; n++) { val = (sin(phase) + 1.0)/2.0; val *= range; val += minval; fprintf(stdout,"INFO: %lf\n",val); phase = phase + phasestep; /* should be fmod by TWOPI, but seems to work without this */ } fflush(stdout); } /****************************** RAND_INTS_WITH_FIXED_ENDS ****************************/ void rand_ints_with_fixed_ends(void) { int z, n, m, i, k, j, j1, j2, repets, fullperms, partperm, startval, finval; int range, rangbot, arrsiz, endcnt, endval, allowed, checkpart, done = 0; int *arr, *arr2, *perm; repets = round(number[5]); startval = round(number[3]); finval = round(number[4]); j1 = round(number[1]); j2 = round(number[2]); range = abs(j2 - j1) + 1; rangbot = (int)min(j1,j2); arrsiz = range * repets; ifactor = round(number[0]) - 2; fullperms = ifactor / arrsiz; partperm = ifactor - (fullperms * arrsiz); if(partperm == 0) { fullperms--; /* The last set of vals has to be calculated separately */ partperm = arrsiz; /* as, unlike others, it will have to be compared with the finval */ } if((arr = (int *)malloc(arrsiz * sizeof(int)))==NULL) { fprintf(stdout,"ERROR: Out of memory.\n"); fflush(stdout); exit(1); } if((perm = (int *)malloc(arrsiz * sizeof(int)))==NULL) { fprintf(stdout,"ERROR: Out of memory.\n"); fflush(stdout); exit(1); } if((arr2 = (int *)malloc(repets * sizeof(int)))==NULL) { fprintf(stdout,"ERROR: Out of memory.\n"); fflush(stdout); exit(1); } n = 0; for(j=0;j= checkpart) /* save last checkable stretch of perm */ arr2[j++] = k; } fflush(stdout); j--; endval = arr2[j--]; /* note the val at end of perm */ endcnt = 1; /* and count it */ for(k = j; k>= 0; k--) { if(arr2[k] == endval) /* check adjacent vals, for repetition of value: count */ endcnt++; else /* if no more repetitions, finish counting */ break; } allowed = repets - endcnt; /* get number of permissible repets at start of next perm */ n++; } k = partperm - 1; /* index of last item of next perm which will actually be outputted */ j = repets - 1; /* How many items at end of partperm, other than item k, which need to be checked for value-repetition */ while(!done) { do_repet_restricted_perm(arr,perm,arrsiz,allowed,endval); for(n=k;n>=k - j;n--) { if(arr[perm[n]] == finval) { /* Check end vals of the-set-of-values-in-the-final-perm-which-will-actually-be-outputted */ if(allowed == 0) /* against 'finval', to avoid too many value-repetitions at end of output */ break; else allowed--; } else { done = 1; break; } } } for(m = 0;m (int)max(j1,j2)) { fprintf(stdout,"ERROR: Final value specified does not lie within the range of values specified.\n"); fflush(stdout); exit(1); } arrsiz = range; if((arr = (int *)malloc(arrsiz * sizeof(int)))==NULL) { fprintf(stdout,"ERROR: Out of memory.\n"); fflush(stdout); exit(1); } if((perm = (int *)malloc(arrsiz * sizeof(int)))==NULL) { fprintf(stdout,"ERROR: Out of memory.\n"); fflush(stdout); exit(1); } k = rangbot; /* this set can be permd AS A WHOLE, as repet adjacent copies of any val */ for(n=0;n= outvals) { lastval = k; done = 1; break; } k++; } } else if(lastval > arr[perm[n]]) { k = lastval - 1; while(k > arr[perm[n]]) { fprintf(stdout,"INFO: %d\n",k); if(++j >= outvals) { lastval = k; done = 1; break; } k--; } } else { /* next perm val can only be equal to previous at join of two different perms */ break; /* in this case, get a different perm */ } if(done) { break; } lastval = arr[perm[n]]; fprintf(stdout,"INFO: %d\n",lastval); j++; } } if(lastval < finval) { lastval++; while(lastval <= finval) { fprintf(stdout,"INFO: %d\n",lastval); lastval++; } } else if(lastval > finval) { lastval--; while(lastval >= finval) { fprintf(stdout,"INFO: %d\n",lastval); lastval--; } } fflush(stdout); } /************************** ELIMINATE_DUPLTEXT *************************/ void eliminate_dupltext(void) { int m,n,k; for(n=0;n= arraysize) { arraysize += BIGARRAY; if((number2=(float *)malloc(arraysize*sizeof(float)))==NULL) { sprintf(errstr,"Out of memory for more warp values at %d numbers\n",cnt); do_error(); } memcpy((void *)number2,(void *)warpvals,cnt * sizeof(float)); warpvals = number2; } } } fclose(fp); if(wcnt ==0 || (wcnt & 1)) { sprintf(errstr,"Invalid or missing warp data.\n"); do_error(); } lastsum = number[0]; do_valout(lastsum); for(n=1;n