| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392 |
- /*
- * 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 <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <structures.h>
- #include <tkglobals.h>
- #include <globcon.h>
- #include <processno.h>
- #include <modeno.h>
- #include <arrays.h>
- #include <extend.h>
- #include <sfsys.h>
- #include <osbind.h>
- //#if defined unix
- #define round(x) lround((x))
- //#endif
- #define RANDSET (32) /* reduce no.of segs to small finite no, so start and end seg have chance to be chosen */
- #define FORWARDS (1)
- #define BACKWARDS (-1)
- static int setup_zigzag_splice(int paramno,dataptr dz);
- static int make_zigsplice(int paramno,dataptr dz);
- static int create_zigzag_splicebuffer(dataptr dz);
- static int generate_zigzag_table(dataptr dz);
- static int sort_zigs(dataptr dz);
- static int eliminate_n_steps(int *this_zigtime,int *next_zigtime,int **ziglistend,int *cnt,dataptr dz);
- static int eliminate_step(int *next_zigtime,int **ziglistend,int *cnt,dataptr dz);
- static int insert_extra_zig
- (int direction,int **this_zigtime,int **next_zigtime,int **ziglistend,int len,dataptr dz);
- static int split_up_steps_too_large_for_buffer(dataptr dz);
- static int update_and_check_ziglist_params(int **next_zigtime,int **this_zigtime,int *ziglistend,int direction);
- static int generate_loop_table(dataptr dz);
- static int sort_loops(dataptr dz);
- static int insert_extra_loop_element
- (int direction,int **this_zigtime,int **next_zigtime,int **ziglistend,int len,dataptr dz);
- static int generate_scramble_table(dataptr dz);
- static int scramble_rand(int arraysize,dataptr dz);
- static int preprocess_scramble_shred(dataptr dz);
- static int scramble_shred(int arraysize,dataptr dz);
- static int get_basis_lengths(int chunkcnt,int worklen,int *unit_len, int *endlen,
- int *scatgrpcnt, int *endscat, int *range, int *endrange, dataptr dz);
- static int normal_scat(int unit_len,int endlen,int chunkcnt_less_one,dataptr dz);
- static int heavy_scat(int scatgrpcnt,int range,int endscat,int endrange,dataptr dz);
- static void permute_chunks(int chunkcnt,dataptr dz);
- static void insert(int n,int t,int chunkcnt,dataptr dz);
- static void prefix(int n,int chunkcnt,dataptr dz);
- static void shuflup(int k,int chunkcnt,dataptr dz);
- static int ptr_sort(int end,dataptr dz);
- static int get_maxvalue_of_rand(double *maxrand,dataptr dz);
- static int get_maxvalue_of_pscat(double *maxpscat,dataptr dz);
- static int get_minvalue_of_delay(double *mindelay,dataptr dz);
- static void reverse_fadevals(dataptr dz);
- static void set_default_gain(int mindelay_samps,dataptr dz);
- static void set_default_delays(dataptr dz);
- static void setup_iter_process_type(int is_unity_gain,dataptr dz);
- static int make_drnk_splicetab(dataptr dz);
- static int convert_sec_steps_to_grain_steps(dataptr dz);
- /***************************** ZIGZAG_PREPROCESS ******************************/
- int zigzag_preprocess(dataptr dz)
- {
- int exit_status;
- int n = 0;
- if(dz->mode == ZIGZAG_SELF)
- initialise_random_sequence(IS_ZIG_RSEED,ZIGZAG_RSEED,dz);
- if((exit_status = setup_zigzag_splice(ZIGZAG_SPLEN,dz))<0)
- return(exit_status);
- if(dz->insams[0] <= dz->iparam[ZIG_SPLSAMPS] * dz->infile->channels * 2) {
- sprintf(errstr,"Infile too short for splices.\n");
- return(DATA_ERROR);
- }
- if(dz->mode == ZIGZAG_SELF) {
- if((exit_status = generate_zigzag_table(dz))<0)
- return(exit_status);
- }
- if((exit_status = sort_zigs(dz))<0)
- return(exit_status);
- if(sloom) {
- dz->tempsize = 0L;
- for(n=1;n<dz->itemcnt;n++)
- /*RWD treat tempszie as in samps */
- dz->tempsize += abs(dz->lparray[ZIGZAG_TIMES][n] - dz->lparray[ZIGZAG_TIMES][n-1]);
- }
- return(FINISHED);
- }
- /*********************** SETUP_ZIGZAG_SPLICE ***************************/
- int setup_zigzag_splice(int paramno,dataptr dz)
- {
- int exit_status;
- if((exit_status = make_zigsplice(paramno,dz))<0)
- return(exit_status);
- return create_zigzag_splicebuffer(dz);
- }
- /*********************** MAKE_ZIGSPLICE ***************************/
- int make_zigsplice(int paramno,dataptr dz)
- {
- int n;
- int framesize = dz->infile->channels;
-
- dz->iparam[ZIG_SPLICECNT] = (int)round(dz->param[paramno] * MS_TO_SECS * dz->infile->srate);
- dz->iparam[ZIG_SPLSAMPS] = dz->iparam[ZIG_SPLICECNT] * framesize;
- if(dz->iparam[ZIG_SPLSAMPS] >= dz->buflen) {
- sprintf(errstr,"Splicelength too long for available memory.\n");
- return(GOAL_FAILED);
- }
- if((dz->parray[ZIGZAG_SPLICE] = (double *)malloc(dz->iparam[ZIG_SPLICECNT] * sizeof(double)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to make splicer buffer.\n");
- return(MEMORY_ERROR);
- }
- for(n=0;n<dz->iparam[ZIG_SPLICECNT];n++)
- dz->parray[ZIGZAG_SPLICE][n] = (double)n/(double)dz->iparam[ZIG_SPLICECNT];
- return(FINISHED);
- }
- /*********************** CREATE_ZIGZAG_SPLICEBUFFER ***************************/
- int create_zigzag_splicebuffer(dataptr dz)
- {
- if(dz->extrabuf == (float **)0) {
- sprintf(errstr,"extrabuf has not been created: create_zigzag_splicebuffer()\n");
- return(PROGRAM_ERROR);
- }
- if((dz->extrabuf[ZIGZAG_SPLBUF] = (float *)malloc(sizeof(float) * dz->iparam[ZIG_SPLSAMPS]))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to make splicing buffer.\n");
- return(MEMORY_ERROR);
- }
- memset((char *)dz->extrabuf[ZIGZAG_SPLBUF],0,sizeof(float) * dz->iparam[ZIG_SPLSAMPS]);
- return(FINISHED);
- }
- /***************************** GENERATE_ZIGZAG_TABLE ***************************/
- int generate_zigzag_table(dataptr dz)
- {
- int OK;
- int arraysize = BIGARRAY;
- double infiledur = (double)(dz->insams[0]/dz->infile->channels)/(double)(dz->infile->srate);
- double totaltime = dz->param[ZIGZAG_START];
- double goaltime = dz->param[ZIGZAG_DUR] - (infiledur - dz->param[ZIGZAG_END]);
- double diff, randlen = 0.0, here = dz->param[ZIGZAG_START];
- int direction = FORWARDS;
- if((dz->lparray[ZIGZAG_TIMES] = (int *)malloc(arraysize * sizeof(int)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to store times.\n");
- return(MEMORY_ERROR);
- }
- dz->lparray[ZIGZAG_TIMES][0] = 0;
- dz->itemcnt = 1;
- do {
- OK = TRUE;
- switch(direction) {
- case(FORWARDS):
- diff = min(dz->param[ZIGZAG_MAX],dz->param[ZIGZAG_END] - here);
- if(diff<=dz->param[ZIGZAG_MIN])
- OK = FALSE;
- else {
- randlen = drand48(); /* generate segment length at random */
- randlen *= (diff - dz->param[ZIGZAG_MIN]); /* scale it to range required */
- randlen += dz->param[ZIGZAG_MIN]; /* and add mindur */
- here = (here + randlen);
- }
- break;
- case(BACKWARDS):
- diff = min(dz->param[ZIGZAG_MAX],here - dz->param[ZIGZAG_START]);
- if(diff<=dz->param[ZIGZAG_MIN])
- OK = FALSE;
- else {
- randlen = drand48(); /* generate segment length at random */
- randlen *= (diff - dz->param[ZIGZAG_MIN]); /* scale it to range required */
- randlen += dz->param[ZIGZAG_MIN]; /* and add mindur */
- here = (here - randlen);
- }
- break;
- }
- direction = -direction; /* invert time-direction */
- if(!OK)
- continue;
- totaltime += randlen;
- dz->lparray[ZIGZAG_TIMES][dz->itemcnt] = round(here * (double)dz->infile->srate) * dz->infile->channels;
- if(++dz->itemcnt >= arraysize) {
- arraysize += BIGARRAY;
- if((dz->lparray[ZIGZAG_TIMES] =
- (int *)realloc((char *)dz->lparray[ZIGZAG_TIMES],arraysize*sizeof(int)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to reallocate times store.\n");
- return(MEMORY_ERROR);
- }
- }
- } while(totaltime<goaltime);
- dz->lparray[ZIGZAG_TIMES][dz->itemcnt] = dz->insams[0];
- dz->itemcnt++;
- if(dz->itemcnt < arraysize) {
- if((dz->lparray[ZIGZAG_TIMES] =
- (int *)realloc((char *)dz->lparray[ZIGZAG_TIMES],dz->itemcnt*sizeof(int)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to reallocate times store.\n");
- return(MEMORY_ERROR);
- }
- }
- return(FINISHED);
- }
- /****************************** SORT_ZIGS ************************************/
- int sort_zigs(dataptr dz)
- {
- int exit_status;
- int zigsize;
- int safety = round(ZIG_MIN_UNSPLICED * MS_TO_SECS * (double)dz->infile->srate) * dz->infile->channels;
- int cnt = 0, firstime = TRUE, direction, previous_direction = FORWARDS;
- int *this_zigtime = dz->lparray[ZIGZAG_TIMES];
- int *next_zigtime = dz->lparray[ZIGZAG_TIMES] + 1;
- int *ziglistend = dz->lparray[ZIGZAG_TIMES] + dz->itemcnt;
- int minzig = (dz->iparam[ZIG_SPLSAMPS] * 2) + safety;
- int file_samplen = dz->insams[0];
- double convert_to_time = 1.0/(double)dz->infile->channels/(double)dz->infile->srate;
- if(minzig > (dz->buflen/2)-1) {
- sprintf(errstr,"splicelen too long to work with available memory\n"
- "Longest splicelen available %ld msecs.\n",
- round((double)(((((dz->buflen/2)-1) - safety)/2)/(double)dz->infile->channels/(double)dz->infile->srate) * SECS_TO_MS)-1);
- return(GOAL_FAILED);
- }
- if(*this_zigtime < 0 || *this_zigtime > file_samplen) {
- sprintf(errstr,"Invalid 1st zigtime %lf\n",(*this_zigtime) * convert_to_time);
- return(DATA_ERROR);
- }
- if(*(ziglistend-1) >= file_samplen) {
- *(ziglistend-1) = file_samplen;
- dz->iparam[ZIG_RUNSTOEND] = 1;
- } else
- dz->iparam[ZIG_RUNSTOEND] = 0;
- while(next_zigtime < ziglistend - dz->iparam[ZIG_RUNSTOEND]) {
- if(*next_zigtime < 0 || *next_zigtime > file_samplen) {
- sprintf(errstr,"Invalid zigtime %lf\n",(*next_zigtime) * convert_to_time);
- return(DATA_ERROR);
- }
- while((zigsize = abs(*next_zigtime - *this_zigtime)) < minzig) {
- if(++next_zigtime == ziglistend - dz->iparam[ZIG_RUNSTOEND])
- break;
- }
- if(next_zigtime - this_zigtime > 1) {
- if(dz->mode == ZIGZAG_USER) {
- sprintf(errstr,"Some zigs too short to use with specified splicelen.\n");
- return(DATA_ERROR);
- }
- eliminate_n_steps(this_zigtime,next_zigtime,&ziglistend,&cnt,dz);
- next_zigtime = this_zigtime + 1;
- }
- if(*next_zigtime > *this_zigtime)
- direction = FORWARDS;
- else
- direction = BACKWARDS;
- if(!firstime && (direction == previous_direction)) {
- if((exit_status = eliminate_step(next_zigtime,&ziglistend,&cnt,dz))<0)
- return(exit_status);
- continue;
- }
- previous_direction = direction;
- firstime = FALSE;
- this_zigtime++;
- next_zigtime++;
- }
- if(cnt>0) {
- fprintf(stdout,"WARNING: %d steps eliminated (too small relative to spliclength\n",cnt);
- //TW : CAN'T SPLIT LINES SENT TO SLOOM - 'WARNING' is a flag to SLOOM - possibly my error, since updated
- fprintf(stdout,"WARNING: or moving in same direction as previous step)\n");
- fflush(stdout);
- if((dz->lparray[ZIGZAG_TIMES] =
- (int *)realloc((char *)dz->lparray[ZIGZAG_TIMES],dz->itemcnt * sizeof(int)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to reallocate times store.\n");
- return(MEMORY_ERROR);
- }
- }
- if(dz->iparam[ZIG_RUNSTOEND]) {
- if(*(ziglistend-1) - *(ziglistend-2) < dz->iparam[ZIG_SPLSAMPS] + safety) {
- sprintf(errstr,"Final zig too short for splicelen.\n");
- return(GOAL_FAILED);
- }
- }
- return split_up_steps_too_large_for_buffer(dz);
- }
- /**************************** ELIMINATE_N_STEPS ***************************/
- int eliminate_n_steps(int *this_zigtime,int *next_zigtime,int **ziglistend,int *cnt,dataptr dz)
- {
- int *here = this_zigtime + 1;
- int *there = next_zigtime;
- int elimination_cnt = (int)( next_zigtime - this_zigtime - 1);
- while(there < *ziglistend) {
- *here = *there;
- here++;
- there++;
- }
- if((dz->itemcnt -= elimination_cnt) < 2) {
- sprintf(errstr,"All zigsteps either too small for splices: or moving in same direction.\n");
- return(DATA_ERROR);
- }
- *ziglistend -= elimination_cnt;
- (*cnt) += elimination_cnt;
- return(FINISHED);
- }
- /***************************** ELIMINATE_STEP ***************************/
- int eliminate_step(int *next_zigtime,int **ziglistend,int *cnt,dataptr dz)
- {
- int *here = next_zigtime;
- while(here < *ziglistend) {
- *(here-1) = *here;
- here++;
- }
- if(--dz->itemcnt < 2) {
- sprintf(errstr,"All zigsteps either too small for splices: or moving in same direction.\n");
- return(DATA_ERROR);
- }
- (*ziglistend)--;
- (*cnt)++;
- return(FINISHED);
- }
- /***************************** INSERT_EXTRA_ZIG ***************************/
- int insert_extra_zig(int direction,int **this_zigtime,int **next_zigtime,int **ziglistend,int len,dataptr dz)
- {
- int *here;
- int zthis = *this_zigtime - dz->lparray[ZIGZAG_TIMES];
- int znext = *next_zigtime - dz->lparray[ZIGZAG_TIMES];
- dz->itemcnt++;
- if((dz->lparray[ZIGZAG_TIMES] =
- (int *)realloc((char *)dz->lparray[ZIGZAG_TIMES],dz->itemcnt * sizeof(int)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to reallocate times store.\n");
- return(MEMORY_ERROR);
- }
- *this_zigtime = dz->lparray[ZIGZAG_TIMES] + zthis;
- *next_zigtime = dz->lparray[ZIGZAG_TIMES] + znext;
- *ziglistend = dz->lparray[ZIGZAG_TIMES] + dz->itemcnt;
- here = *ziglistend - 1;
- while(here > *next_zigtime) {
- *here = *(here-1);
- here--;
- }
- switch(direction) {
- case(FORWARDS):
- *here = **this_zigtime + len;
- break;
- case(BACKWARDS):
- *here = **this_zigtime - len;
- break;
- }
- if(*here < 0.0 || (int)*here > dz->insams[0]) {
- sprintf(errstr,"Error in logic of sample arithmetic: insert_extra_zig()\n");
- return(PROGRAM_ERROR);
- }
- return(FINISHED);
- }
- /**************************** SPLIT_UP_STEPS_TOO_LARGE_FOR_BUFFER ***************************/
- int split_up_steps_too_large_for_buffer(dataptr dz)
- {
- int zigsize;
- int direction, n, longbufs, shortbufs;
- int safety = round(ZIG_MIN_UNSPLICED * MS_TO_SECS * (double)dz->infile->srate) * dz->infile->channels;
- int minzig = (dz->iparam[ZIG_SPLSAMPS] * 2) + safety;
- int *this_zigtime = dz->lparray[ZIGZAG_TIMES];
- int *next_zigtime = this_zigtime + 1;
- int *ziglistend = dz->lparray[ZIGZAG_TIMES] + dz->itemcnt;
- int max_effective_length = dz->buflen - F_SECSIZE;
- int pre_endbuflen, endbuflen;
- while(next_zigtime < ziglistend) {
- zigsize = *next_zigtime - *this_zigtime;
- if(zigsize > 0.0)
- direction = FORWARDS;
- else
- direction = BACKWARDS;
- zigsize = abs(zigsize);
- if((longbufs = zigsize/max_effective_length) > 0) { /* TRUNCATE */
- shortbufs = -1;
- pre_endbuflen = 0;
- while((endbuflen = zigsize%max_effective_length) > 0 && endbuflen < minzig) {
- longbufs--;
- if(longbufs<0) {
- sprintf(errstr,"splicelen is too long for available memory.\n");
- return(GOAL_FAILED);
- }
- shortbufs++;
- pre_endbuflen = max_effective_length + endbuflen - minzig;
- if(pre_endbuflen > minzig)
- break;
- zigsize -= minzig;
- }
- for(n = 0; n < longbufs;n++) {
- insert_extra_zig(direction,&this_zigtime,&next_zigtime,&ziglistend,max_effective_length,dz);
- update_and_check_ziglist_params(&next_zigtime,&this_zigtime,ziglistend,direction);
- }
- if(pre_endbuflen > 0) {
- insert_extra_zig(direction,&this_zigtime,&next_zigtime,&ziglistend,pre_endbuflen,dz);
- update_and_check_ziglist_params(&next_zigtime,&this_zigtime,ziglistend,direction);
- }
- if(shortbufs > 0) {
- for(n = 0; n < shortbufs; n++) {
- insert_extra_zig(direction,&this_zigtime,&next_zigtime,&ziglistend,minzig,dz);
- update_and_check_ziglist_params(&next_zigtime,&this_zigtime,ziglistend,direction);
- }
- }
- }
- next_zigtime++;
- this_zigtime++;
- }
- return(FINISHED);
- }
- /***************************** UPDATE_AND_CHECK_ZIGLIST_PARAMS ***************************/
- int update_and_check_ziglist_params(int **next_zigtime,int **this_zigtime,int *ziglistend,int direction)
- {
- int zigsize;
- (*next_zigtime)++;
- (*this_zigtime)++;
- if(*this_zigtime >= ziglistend - 1) {
- sprintf(errstr,"Error in counting logic: update_and_check_ziglist_params()\n");
- return(PROGRAM_ERROR);
- }
- zigsize = **next_zigtime - **this_zigtime;
- if((zigsize > 0.0 && direction != FORWARDS)
- || (zigsize < 0.0 && direction != BACKWARDS)) {
- sprintf(errstr,"Error in counting logic(2): update_and_check_ziglist_params()\n");
- return(PROGRAM_ERROR);
- }
- return(FINISHED);
- }
- /*********************** LOOP_PREPROCESS ***************************/
- int loop_preprocess(dataptr dz)
- {
- int exit_status;
- initrand48();
- if(dz->param[LOOP_LEN] <= dz->param[LOOP_SPLEN] * 2) {
- sprintf(errstr,"Loop length too short for splices.\n");
- return(DATA_ERROR);
- }
- if((exit_status = setup_zigzag_splice(LOOP_SPLEN,dz))<0)
- return(exit_status);
- if(dz->insams[0] <= dz->iparam[ZIG_SPLSAMPS] * 2) {
- sprintf(errstr,"Infile too short for splices.\n");
- return(DATA_ERROR);
- }
- if((exit_status = generate_loop_table(dz))<0)
- return(exit_status);
- return sort_loops(dz);
- }
- /***************************** GENERATE_LOOP_TABLE ***************************/
- int generate_loop_table(dataptr dz)
- {
- int searchsamps, tmpstart;
- unsigned int file_endsamp = dz->insams[0];
- int i, arraysize = BIGARRAY;
- int startsamp = dz->infile->channels * (int) (dz->infile->srate * dz->param[LOOP_START]);
- int looplen = dz->infile->channels * (int) (dz->infile->srate * dz->param[LOOP_LEN] * MS_TO_SECS);
- int stepsamps = dz->infile->channels * (int) (dz->infile->srate * dz->param[LOOP_STEP] * MS_TO_SECS);
- int lsfield = dz->infile->channels * (int) (dz->infile->srate * dz->param[LOOP_SRCHF] * MS_TO_SECS);
- int samplen, excess, totallen, endsamp, n;
- /* NEW APR 16 --> */
- looplen += dz->iparam[ZIG_SPLSAMPS]; /* allow for splice overlaps in calcs */
- dz->itemcnt = 0;
- if((dz->lparray[ZIGZAG_TIMES] = (int *)malloc(arraysize * sizeof(int)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to store times.\n");
- return(MEMORY_ERROR);
- }
- if((dz->iparray[ZIGZAG_PLAY] = (int *)malloc(arraysize * sizeof(int )))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to store section markers.\n");
- return(MEMORY_ERROR);
- }
- searchsamps = 0;
- tmpstart = startsamp;
- for(i = 0; i < dz->iparam[LOOP_REPETS] ;i++) {
- if(dz->itemcnt + 2 > arraysize) {
- arraysize += BIGARRAY;
- if((dz->lparray[ZIGZAG_TIMES] = (int *)realloc(dz->lparray[ZIGZAG_TIMES],arraysize * sizeof(int)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to reallocate times.\n");
- return(MEMORY_ERROR);
- }
- if((dz->iparray[ZIGZAG_PLAY] = (int *)realloc(dz->iparray[ZIGZAG_PLAY],arraysize * sizeof(int)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to reallocate markers.\n");
- return(MEMORY_ERROR);
- }
- }
- dz->iparray[ZIGZAG_PLAY][dz->itemcnt] = TRUE;
- if(i==0 && dz->vflag[IS_KEEP_START])
- dz->lparray[ZIGZAG_TIMES][dz->itemcnt] = 0;
- else
- dz->lparray[ZIGZAG_TIMES][dz->itemcnt] = tmpstart;
- dz->itemcnt++;
- dz->iparray[ZIGZAG_PLAY][dz->itemcnt] = FALSE;
- if((unsigned int)(dz->lparray[ZIGZAG_TIMES][dz->itemcnt] = tmpstart + looplen) >= file_endsamp) {
- dz->iparam[ZIG_RUNSTOEND] = TRUE;
- dz->itemcnt++;
- break;
- }
- dz->itemcnt++;
- startsamp += stepsamps;
- if(lsfield)
- searchsamps = round((double) lsfield * drand48());
- tmpstart = (startsamp + searchsamps);
- }
- if(dz->iparam[ZIG_RUNSTOEND])
- dz->lparray[ZIGZAG_TIMES][dz->itemcnt-1] = file_endsamp; /* Force read to end */
- else if(dz->mode==LOOP_OUTLEN) {
- samplen = dz->infile->channels * round(dz->infile->srate * dz->param[LOOP_OUTDUR]);
- totallen = 0; /* Force to correct outlen */
- for(n=1;n<dz->itemcnt;n+=2)
- totallen += dz->lparray[ZIGZAG_TIMES][n] - dz->lparray[ZIGZAG_TIMES][n-1] - dz->iparam[ZIG_SPLSAMPS];
- if((excess = samplen - totallen) > 0) {
- endsamp = min(dz->lparray[ZIGZAG_TIMES][dz->itemcnt-1] + excess,(int)file_endsamp);
- dz->lparray[ZIGZAG_TIMES][dz->itemcnt-1] = endsamp;
- if(endsamp == (int)file_endsamp)
- dz->iparam[ZIG_RUNSTOEND] = TRUE;
- }
- }
- if((dz->lparray[ZIGZAG_TIMES] = (int *)realloc(dz->lparray[ZIGZAG_TIMES],dz->itemcnt * sizeof(int)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to reallocate times.\n");
- return(MEMORY_ERROR);
- }
- if((dz->iparray[ZIGZAG_PLAY] = (int *)realloc(dz->iparray[ZIGZAG_PLAY], dz->itemcnt * sizeof(int )))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to reallocate markers.\n");
- return(MEMORY_ERROR);
- }
- return(FINISHED);
- }
- /****************************** SORT_LOOPS ************************************/
- int sort_loops(dataptr dz)
- {
- int zigsize;
- int direction, n, longbufs, shortbufs;
- int safety = round(ZIG_MIN_UNSPLICED * MS_TO_SECS * (double)dz->infile->srate) * dz->infile->channels;
- int minzig = (dz->iparam[ZIG_SPLSAMPS] * 2) + safety;
- int *this_zigtime = dz->lparray[ZIGZAG_TIMES];
- int *next_zigtime = this_zigtime + 1;
- int *ziglistend = dz->lparray[ZIGZAG_TIMES] + dz->itemcnt;
- int max_effective_length = dz->buflen - F_SECSIZE;
- int pre_endbuflen, endbuflen;
- int m = 0;
- while(next_zigtime < ziglistend) {
- zigsize = *next_zigtime - *this_zigtime;
- if(zigsize > 0.0)
- direction = FORWARDS;
- else
- direction = BACKWARDS;
- zigsize = abs(zigsize);
- if((longbufs = zigsize/max_effective_length) > 0) { /* TRUNCATE */
- shortbufs = -1;
- pre_endbuflen = 0;
- while((endbuflen = zigsize%max_effective_length) > 0 && endbuflen < minzig) {
- longbufs--;
- if(longbufs<0) {
- sprintf(errstr,"splicelen is too long for available memory.\n");
- return(GOAL_FAILED);
- }
- shortbufs++;
- pre_endbuflen = max_effective_length + endbuflen - minzig;
- if(pre_endbuflen > minzig)
- break;
- zigsize -= minzig;
- }
- for(n = 0; n < longbufs;n++) {
- insert_extra_loop_element(direction,&this_zigtime,&next_zigtime,&ziglistend,max_effective_length,dz);
- update_and_check_ziglist_params(&next_zigtime,&this_zigtime,ziglistend,direction);
- }
- if(pre_endbuflen > 0) {
- insert_extra_loop_element(direction,&this_zigtime,&next_zigtime,&ziglistend,pre_endbuflen,dz);
- update_and_check_ziglist_params(&next_zigtime,&this_zigtime,ziglistend,direction);
- }
- if(shortbufs > 0) {
- for(n = 0; n < shortbufs; n++) {
- insert_extra_loop_element(direction,&this_zigtime,&next_zigtime,&ziglistend,minzig,dz);
- update_and_check_ziglist_params(&next_zigtime,&this_zigtime,ziglistend,direction);
- }
- }
- }
- next_zigtime++;
- this_zigtime++;
- }
- if(sloom) {
- dz->tempsize = 0L;
- for(n=0,m=1;m<dz->itemcnt;n++,m++) {
- if(dz->iparray[ZIGZAG_PLAY][n])
- dz->tempsize += abs(dz->lparray[ZIGZAG_TIMES][m] - dz->lparray[ZIGZAG_TIMES][n]);
- } /* abs for SAFETY: should be unnecessary as all plays should be forwards!! */
- }
- return(FINISHED);
- }
- /***************************** INSERT_EXTRA_LOOP_ELEMENT ***************************/
- int insert_extra_loop_element(int direction,int **this_zigtime,int **next_zigtime,int **ziglistend,int len,dataptr dz)
- {
- int *here;
- int *there, *playlistend, *nextplaytime;
- int zthis = *this_zigtime - dz->lparray[ZIGZAG_TIMES];
- int znext = *next_zigtime - dz->lparray[ZIGZAG_TIMES];
- dz->itemcnt++;
- if((dz->lparray[ZIGZAG_TIMES] =
- (int *)realloc(dz->lparray[ZIGZAG_TIMES],dz->itemcnt * sizeof(int)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to insert extra loop time.\n");
- return(MEMORY_ERROR);
- }
- if((dz->iparray[ZIGZAG_PLAY] =
- (int *)realloc(dz->iparray[ZIGZAG_PLAY], dz->itemcnt * sizeof(int )))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to insert extra loopmarker.\n");
- return(MEMORY_ERROR);
- }
- *this_zigtime = dz->lparray[ZIGZAG_TIMES] + zthis;
- *next_zigtime = dz->lparray[ZIGZAG_TIMES] + znext;
- *ziglistend = dz->lparray[ZIGZAG_TIMES] + dz->itemcnt;
- here = *ziglistend - 1;
- while(here > *next_zigtime) {
- *here = *(here-1);
- here--;
- }
- nextplaytime = dz->iparray[ZIGZAG_PLAY] + (*next_zigtime - dz->lparray[ZIGZAG_TIMES]);
- playlistend = dz->iparray[ZIGZAG_PLAY] + dz->itemcnt;
- there = playlistend - 1;
- while(there > nextplaytime) {
- *there = *(there-1);
- there--;
- }
- switch(dz->process) {
- case(LOOP): /* COMMENT: this old LOOPcode may be unnecessary, as SCRAMBLE version may be OK for both */
- switch(direction) {
- case(FORWARDS): *here = **this_zigtime + len; *there = TRUE; break;
- case(BACKWARDS): *here = **this_zigtime - len; *there = FALSE; break;
- }
- break;
- case(SCRAMBLE):
- switch(direction) {
- case(FORWARDS): *here = **this_zigtime + len; break;
- case(BACKWARDS): *here = **this_zigtime - len; break;
- }
- *there = *(there-1);
- break;
- }
- // if(*here < 0.0 || (unsigned int)*here > dz->insams[0]) {
- if(*here < 0.0 || (int)*here > dz->insams[0]) {
- sprintf(errstr,"Error in logic of sample arithmetic: insert_extra_loop_element()\n");
- return(PROGRAM_ERROR);
- }
- return(FINISHED);
- }
- /***************************** SCRAMBLE_PREPROCESS ***************************/
- int scramble_preprocess(dataptr dz)
- {
- int exit_status;
- initialise_random_sequence(IS_SCRAMBLE_RSEED,SCRAMBLE_SEED,dz);
- if((exit_status = setup_zigzag_splice(SCRAMBLE_SPLEN,dz))<0)
- return(exit_status);
- if(dz->insams[0] <= dz->iparam[ZIG_SPLSAMPS] * dz->infile->channels * 2) {
- sprintf(errstr,"Infile too short for splices.\n");
- return(DATA_ERROR);
- }
- if((exit_status = generate_scramble_table(dz))<0)
- return(exit_status);
- return sort_loops(dz);
- }
- /***************************** GENERATE_SCRAMBLE_TABLE **************************/
- int generate_scramble_table(dataptr dz)
- {
- int exit_status;
- int arraysize = BIGARRAY;
- if((dz->lparray[ZIGZAG_TIMES] = (int *)malloc(arraysize*sizeof(int)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY for times store.\n");
- return(MEMORY_ERROR);
- }
- if((dz->iparray[ZIGZAG_PLAY] = (int *)malloc(arraysize * sizeof(int )))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY for markers store.\n");
- return(MEMORY_ERROR);
- }
- switch(dz->mode) {
- case(SCRAMBLE_RAND):
- exit_status = scramble_rand(arraysize,dz);
- break;
- case(SCRAMBLE_SHRED):
- if((exit_status = preprocess_scramble_shred(dz))<0)
- return(exit_status);
- exit_status = scramble_shred(arraysize,dz);
- break;
- default:
- sprintf(errstr,"Unknown mode in generate_scramble_table()\n");
- return(PROGRAM_ERROR);
- }
- if(dz->vflag[IS_SCR_KEEP_START])
- dz->lparray[ZIGZAG_TIMES][0] = 0;
- if(dz->vflag[IS_SCR_KEEP_END])
- dz->lparray[ZIGZAG_TIMES][dz->itemcnt-1] = dz->insams[0];
- return(exit_status);
- }
- /***************************** SCRAMBLE_RAND **************************/
- int scramble_rand(int arraysize,dataptr dz)
- {
- int lenrange = round((dz->param[SCRAMBLE_MAX] - dz->param[SCRAMBLE_MIN]) * dz->infile->srate);
- int minlen = round(dz->param[SCRAMBLE_MIN] * dz->infile->srate);
- int infilelen = dz->insams[0];
- int thislen, outlen = 0, effective_range, thispos;
- int finished = 0, zz;
- double thisfrac;
- dz->iparam[SCRAMBLE_OUTLEN] = round(dz->param[SCRAMBLE_DUR] * dz->infile->srate) * dz->infile->channels;
- dz->itemcnt = 0;
- while(!finished) {
- if(dz->itemcnt + 2 >= arraysize) {
- arraysize += BIGARRAY;
- if((dz->lparray[ZIGZAG_TIMES] =(int *)realloc(dz->lparray[ZIGZAG_TIMES],arraysize*sizeof(int)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to reallocate times store.\n");
- return(MEMORY_ERROR);
- }
- if((dz->iparray[ZIGZAG_PLAY] = (int *)realloc(dz->iparray[ZIGZAG_PLAY], arraysize*sizeof(int )))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to reallocate markers store.\n");
- return(MEMORY_ERROR);
- }
- }
- thislen = (round(drand48() * lenrange) + minlen) * dz->infile->channels;
- effective_range = infilelen - dz->iparam[ZIG_SPLSAMPS] - thislen;
- zz = round(drand48() * RANDSET);
- thisfrac = (double)zz/(double)RANDSET;
- thispos = round(thisfrac * effective_range);
- if(ODD(thispos))
- thispos--;
- dz->lparray[ZIGZAG_TIMES][dz->itemcnt] = thispos;
- dz->iparray[ZIGZAG_PLAY][dz->itemcnt++] = TRUE;
- dz->lparray[ZIGZAG_TIMES][dz->itemcnt] = thispos + thislen + dz->iparam[ZIG_SPLSAMPS];
- dz->iparray[ZIGZAG_PLAY][dz->itemcnt++] = FALSE;
- if((outlen += thislen) >= dz->iparam[SCRAMBLE_OUTLEN])
- finished = 1;
- }
- if((dz->lparray[ZIGZAG_TIMES] = (int *)realloc(dz->lparray[ZIGZAG_TIMES],dz->itemcnt * sizeof(int)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to reallocate times store.\n");
- return(MEMORY_ERROR);
- }
- if((dz->iparray[ZIGZAG_PLAY] = (int *)realloc(dz->iparray[ZIGZAG_PLAY], dz->itemcnt * sizeof(int )))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to reallocate markers store.\n");
- return(MEMORY_ERROR);
- }
- return(FINISHED);
- }
- /***************************** PREPROCESS_SCRAMBLE_SHRED **************************/
- int preprocess_scramble_shred(dataptr dz)
- {
- // double infiledur;
- int chunksamps;
- //infiledur = (double)(dz->insams[0]/dz->infile->channels)/(double)(dz->infile->srate);
- chunksamps = round(dz->param[SCRAMBLE_LEN] * dz->infile->srate) * dz->infile->channels;
- dz->iparam[SCRAMBLE_CHCNT] = dz->insams[0]/chunksamps; /* truncate */
- if(dz->iparam[SCRAMBLE_CHCNT]<2) {
- sprintf(errstr,"Too long chunklen not trapped earlier.\n");
- return(PROGRAM_ERROR);
- }
- dz->iparam[SCRAMBLE_OUTLEN] = round(dz->param[SCRAMBLE_DUR] * dz->infile->srate) * dz->infile->channels;
- if((dz->lparray[SCRAMBLE_CHUNKPTR] = (int *)malloc(dz->iparam[SCRAMBLE_CHCNT] * sizeof(int)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to store scramble chunk pointers.\n");
- return(MEMORY_ERROR);
- }
- if((dz->lparray[SCRAMBLE_CHUNKLEN] = (int *)malloc(dz->iparam[SCRAMBLE_CHCNT] * sizeof(int)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to store scramble chunk lengths.\n");
- return(MEMORY_ERROR);
- }
- if((dz->iparray[SCRAMBLE_PERM] = (int *)malloc(dz->iparam[SCRAMBLE_CHCNT] * sizeof(int )))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to store scramble permutation.\n");
- return(MEMORY_ERROR);
- }
- return(FINISHED);
- }
- /******************************* SCRAMBLE_SHRED ***************************/
- int scramble_shred(int arraysize,dataptr dz)
- {
- int n, exit_status;
- int finished = 0;
- int chunkcnt = dz->iparam[SCRAMBLE_CHCNT];
- int worklen = dz->insams[0];
- int total_len = 0;
- int chunkcnt_less_one = chunkcnt - 1;
- int unit_len, endlen, scatgrpcnt=0, endscat=0, range=0, endrange=0;
- int *perm = dz->iparray[SCRAMBLE_PERM];
- dz->itemcnt = 0;
- if((exit_status = get_basis_lengths(chunkcnt,worklen,&unit_len,&endlen,&scatgrpcnt,&endscat,&range,&endrange,dz))<0)
- return(exit_status);
- while(!finished) {
- if(dz->iparam[SCRAMBLE_SCAT]) {
- if((exit_status = heavy_scat(scatgrpcnt,range,endscat,endrange,dz))<0)
- return(exit_status);
- } else {
- if((exit_status = normal_scat(unit_len,endlen,chunkcnt_less_one,dz))<0)
- return(exit_status);
- }
- for(n=0;n<chunkcnt_less_one;n++) /* 2 */
- dz->lparray[SCRAMBLE_CHUNKLEN][n] = dz->lparray[SCRAMBLE_CHUNKPTR][n+1] - dz->lparray[SCRAMBLE_CHUNKPTR][n];
- dz->lparray[SCRAMBLE_CHUNKLEN][n] = worklen - dz->lparray[SCRAMBLE_CHUNKPTR][n]; /* 2A */
- permute_chunks(chunkcnt,dz); /* 3 */
- for(n=0;n < chunkcnt; n++) {
- if(dz->itemcnt + 2 >= arraysize) {
- arraysize += BIGARRAY;
- if((dz->lparray[ZIGZAG_TIMES] =(int *)realloc(dz->lparray[ZIGZAG_TIMES],arraysize*sizeof(int)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to reallocate times store.\n");
- return(MEMORY_ERROR);
- }
- if((dz->iparray[ZIGZAG_PLAY] = (int *)realloc(dz->iparray[ZIGZAG_PLAY], arraysize*sizeof(int )))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to reallocate markers store.\n");
- return(MEMORY_ERROR);
- }
- }
- dz->lparray[ZIGZAG_TIMES][dz->itemcnt] = dz->lparray[SCRAMBLE_CHUNKPTR][perm[n]];
- dz->iparray[ZIGZAG_PLAY][dz->itemcnt] = TRUE;
- dz->lparray[ZIGZAG_TIMES][dz->itemcnt+1] = dz->lparray[ZIGZAG_TIMES][dz->itemcnt] + dz->lparray[SCRAMBLE_CHUNKLEN][perm[n]];
- /* APR 1998 */
- dz->lparray[ZIGZAG_TIMES][dz->itemcnt+1] += dz->iparam[ZIG_SPLSAMPS];
- if(dz->lparray[ZIGZAG_TIMES][dz->itemcnt+1] > worklen) {
- dz->lparray[ZIGZAG_TIMES][dz->itemcnt+1] = worklen;
- dz->lparray[ZIGZAG_TIMES][dz->itemcnt] = worklen - dz->lparray[SCRAMBLE_CHUNKLEN][perm[n]];
- }
- /* APR 1998 */
- dz->iparray[ZIGZAG_PLAY][dz->itemcnt+1] = FALSE;
- if((total_len += dz->lparray[SCRAMBLE_CHUNKLEN][perm[n]]) > dz->iparam[SCRAMBLE_OUTLEN]) {
- finished = 1;
- break;
- }
- dz->itemcnt += 2;
- }
- }
- if((dz->lparray[ZIGZAG_TIMES] = (int *)realloc(dz->lparray[ZIGZAG_TIMES],dz->itemcnt * sizeof(int)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to reallocate times store.\n");
- return(MEMORY_ERROR);
- }
- if((dz->iparray[ZIGZAG_PLAY] = (int *)realloc(dz->iparray[ZIGZAG_PLAY], dz->itemcnt * sizeof(int )))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to reallocate markers store.\n");
- return(MEMORY_ERROR);
- }
- return(FINISHED);
- }
- /*********************** GET_BASIS_LENGTHS ***********************/
- int get_basis_lengths(int chunkcnt,int worklen,int *unit_len, int *endlen,
- int *scatgrpcnt, int *endscat, int *range, int *endrange, dataptr dz)
- {
- int excess;
- *unit_len = (int)round(worklen/chunkcnt);
- if(ODD(*unit_len))
- (*unit_len)--; /* Allow for stereo case */
- excess = worklen - ((*unit_len) * chunkcnt);
- if(ODD(excess) && dz->infile->channels==2) {
- sprintf(errstr,"Problem in buffer accounting: get_basis_lengths()\n");
- return(PROGRAM_ERROR);
- }
- *endlen = *unit_len + excess;
- if(dz->param[SCRAMBLE_SCAT] >= 1.0) {
- dz->iparam[SCRAMBLE_SCAT] = round(dz->param[SCRAMBLE_SCAT]);
- *scatgrpcnt = (int)(chunkcnt/dz->iparam[SCRAMBLE_SCAT]);
- *endscat = (int)(chunkcnt - ((*scatgrpcnt) * dz->iparam[SCRAMBLE_SCAT]));
- *range = (*unit_len) * dz->iparam[SCRAMBLE_SCAT];
- *endrange = ((*endscat - 1) * (*unit_len)) + *endlen;
- } else {
- dz->iparam[SCRAMBLE_SCAT] = 0;
- }
- return(FINISHED);
- }
- /************************** NORMAL_SCAT *******************************/
- int normal_scat(int unit_len,int endlen,int chunkcnt_less_one,dataptr dz)
- {
- double this_scatter;
- int n;
- int new_chunklen, total_len = unit_len;
- for(n=1;n<chunkcnt_less_one;n++) {
- this_scatter = (drand48() - 0.5) * dz->param[SCRAMBLE_SCAT]; /* range +- .5 reduced by *scatter */
- new_chunklen = (int)(this_scatter * (double)unit_len);
- if(ODD(new_chunklen))
- new_chunklen--; /* in case stereo?? */
- dz->lparray[SCRAMBLE_CHUNKPTR][n] = total_len + new_chunklen; /* position chunk-pointer */
- total_len += unit_len; /* step to next BASE position */
- }
- this_scatter = (drand48() - 0.5) * dz->param[SCRAMBLE_SCAT]; /* as final chunk may be unique length */
- if(this_scatter<0.0) { /* if scatter is -ve, scatter is frac of penultimate length */
- new_chunklen = (int)(this_scatter * (double)unit_len);
- if(ODD(new_chunklen))
- new_chunklen--;
- dz->lparray[SCRAMBLE_CHUNKPTR][n] = total_len - new_chunklen;
- } else { /* else, scatter is frac of final length */
- new_chunklen = (int)(this_scatter * (double)endlen);
- if(ODD(new_chunklen))
- new_chunklen--;
- dz->lparray[SCRAMBLE_CHUNKPTR][n] = total_len + new_chunklen;
- }
- return(FINISHED);
- }
- /*********************** HEAVY_SCAT ***************************
- *
- * (1) Start at the chunk (this=1) AFTER the first (which can't be moved).
- * (2) STARTPTR marks the start of the chunk GROUP (and will be advanced
- * by RANGE, which is length of chunk-group).
- * (3) The loop will generate a set of positions for the chunks in
- * a chunk-group. In the first chunkgroup the position of the
- * first chunk (start of file) can't be moved, so loop starts at
- * (first=) 1. Subsequemt loop passes start at 0.
- * (4) For eveery chunk-group.
- * (5) Set the index of the first chunk in this group (start) to the
- * current index (this).
- * (6) For every member of this chunk-group.
- * (7) Generate a random-position within the chunk-grp's range
- * and check it is not too close ( < SPLICELEN) to the others.
- * Set a checking flag (OK).
- * (8) Generate a position within the range, and after the startptr.
- * (9) Compare it with all previously generated positions in this
- * chunk-grp AND with last position of previous chunk-group!!
- * If it's closer than SPLICELEN, set OK = 0, drop out of
- checking loop and generate another position instead.
- * (10) If the position is OK, drop out of position generating loop..
- * (11) Advance to next chunk in this group.
- * (12) Once all this group is done, advance the group startpoint by RANGE.
- * (13) After FIRST grp, all positions can by varied, so set the initial
- * loop counter to (first=)0.
- * (14) If there are chunks left over (endscat!=0)..
- * Follow the same procedure for chunks in end group, using the
- * alternative variables, endscat and endrange.
- */
- int heavy_scat(int scatgrpcnt,int range,int endscat,int endrange,dataptr dz)
- {
- int thiss = 0, that, start, n, m, OK; /* 1 */
- int startptr = 0; /* 2 */
- int minlen = (dz->iparam[ZIG_SPLSAMPS] * 2);
- int filend = dz->insams[0];
- int first = 1; /* 3 */
- /* TW OCT 1997 */
- int latest_ptr = 0;
- dz->lparray[SCRAMBLE_CHUNKPTR][thiss++] = 0;
- /* TW OCT 1997 */
- for(n=0;n<scatgrpcnt;n++) { /* 4 */
- start = thiss; /* 5 */
- for(m=first;m<dz->iparam[SCRAMBLE_SCAT];m++) { /* 6 */
- do { /* 7 */
- OK = 1;
- dz->lparray[SCRAMBLE_CHUNKPTR][thiss] = (int)(drand48()*range); /* TRUNCATE */
- dz->lparray[SCRAMBLE_CHUNKPTR][thiss] += startptr; /* 8 */
- if(ODD(dz->lparray[SCRAMBLE_CHUNKPTR][thiss]))
- dz->lparray[SCRAMBLE_CHUNKPTR][thiss]--;
- /* TW OCT 1997 -->*/
- if(abs(dz->lparray[SCRAMBLE_CHUNKPTR][thiss] - latest_ptr)< minlen) {
- OK = 0;
- continue;
- }
- for(that=start; that<thiss; that++) {
- if(abs(dz->lparray[SCRAMBLE_CHUNKPTR][thiss] - dz->lparray[SCRAMBLE_CHUNKPTR][that])<minlen
- || abs(filend - abs(dz->lparray[SCRAMBLE_CHUNKPTR][thiss]))< minlen) {
- /* TW OCT 1997 */
- OK = 0; /* 9 */
- break;
- }
- }
- } while(!OK); /* 10 */
- thiss++; /* 11 */
- }
- /* TW OCT 1997 --> */
- for(m=0;m<thiss;m++) {
- if(dz->lparray[SCRAMBLE_CHUNKPTR][m] > latest_ptr)
- latest_ptr = dz->lparray[SCRAMBLE_CHUNKPTR][m];
- }
- /* TW OCT 1997 */
- startptr += range; /* 12 */
- first = 0; /* 13 */
- }
- if(endscat) { /* 14 */
- start = thiss;
- for(m=0;m<endscat;m++) {
- do {
- OK = 1;
- dz->lparray[SCRAMBLE_CHUNKPTR][thiss] = (int)(drand48() * endrange); /* TRUNCATE */
- dz->lparray[SCRAMBLE_CHUNKPTR][thiss] += startptr;
- if(ODD(dz->lparray[SCRAMBLE_CHUNKPTR][thiss]))
- dz->lparray[SCRAMBLE_CHUNKPTR][thiss]--;
- /* TW OCT 1997 */
- if(abs(dz->lparray[SCRAMBLE_CHUNKPTR][thiss] - latest_ptr)< minlen) {
- OK = 0;
- continue;
- }
- /* TW OCT 1997 */
- for(that=start; that<thiss; that++) {
- if(abs(dz->lparray[SCRAMBLE_CHUNKPTR][thiss] - dz->lparray[SCRAMBLE_CHUNKPTR][that])< minlen
- /* TW OCT 1997 */
- || abs(filend - abs(dz->lparray[SCRAMBLE_CHUNKPTR][thiss]))< minlen) {
- /* TW OCT 1997 */
- OK = 0;
- break;
- }
- }
- } while(!OK);
- thiss++;
- }
- }
- return ptr_sort(thiss,dz);
- }
- /*************************** PERMUTE_CHUNKS ***************************/
- void permute_chunks(int chunkcnt,dataptr dz)
- {
- int n, t;
- for(n=0;n<chunkcnt;n++) {
- t = (int)(drand48() * (double)(n+1)); /* TRUNCATE */
- if(t==n)
- prefix(n,chunkcnt,dz);
- else
- insert(n,t,chunkcnt,dz);
- }
- }
- /****************************** INSERT ****************************/
- void insert(int n,int t,int chunkcnt,dataptr dz)
- {
- shuflup(t+1,chunkcnt,dz);
- dz->iparray[SCRAMBLE_PERM][t+1] = n;
- }
- /****************************** PREFIX ****************************/
- void prefix(int n,int chunkcnt,dataptr dz)
- {
- shuflup(0,chunkcnt,dz);
- dz->iparray[SCRAMBLE_PERM][0] = n;
- }
- /****************************** SHUFLUP ****************************/
- void shuflup(int k,int chunkcnt,dataptr dz)
- {
- int n;
- int *i;
- int z = chunkcnt-1;
- i = &(dz->iparray[SCRAMBLE_PERM][z]);
- for(n = z; n > k; n--) {
- *i = *(i-1);
- i--;
- }
- }
- /************************** PTR_SORT ***************************/
- int ptr_sort(int end,dataptr dz)
- {
- int i,j;
- int a;
- for(j=1;j<end;j++) {
- a = dz->lparray[SCRAMBLE_CHUNKPTR][j];
- i = j-1;
- while(i >= 0 && dz->lparray[SCRAMBLE_CHUNKPTR][i] > a) {
- dz->lparray[SCRAMBLE_CHUNKPTR][i+1]=dz->lparray[SCRAMBLE_CHUNKPTR][i];
- i--;
- }
- dz->lparray[SCRAMBLE_CHUNKPTR][i+1] = a;
- }
- return(FINISHED);
- }
- /**************************** ITERATE_PREPROCESS ******************************/
- int iterate_preprocess(dataptr dz)
- {
- int exit_status;
- double maxrand, maxpscat, mindelay, temp;
- int is_unity_gain = FALSE;
- int mindelay_samps;
- if(dz->process == ITERATE_EXTEND) {
- if(dz->iparam[ITER_RRSEED] > 0)
- srand((int)dz->iparam[ITER_RRSEED]);
- else
- initrand48();
- } else {
- if(dz->iparam[ITER_RSEED] > 0)
- srand((int)dz->iparam[ITER_RSEED]);
- else
- initrand48();
- }
- if((exit_status = get_maxvalue_of_rand(&maxrand,dz))<0)
- return(exit_status);
- if((exit_status = get_maxvalue_of_pscat(&maxpscat,dz))<0)
- return(exit_status);
- if((exit_status = get_minvalue_of_delay(&mindelay,dz))<0)
- return(exit_status);
- mindelay_samps = round(mindelay * (double)dz->infile->srate);
- if(dz->process == ITERATE_EXTEND) {
- dz->iparam[CHUNKSTART] = (int)round(dz->param[CHUNKSTART] * dz->infile->srate) * dz->infile->channels;
- dz->iparam[CHUNKEND] = (int)round(dz->param[CHUNKEND] * dz->infile->srate) * dz->infile->channels;
- if(dz->param[CHUNKSTART] > dz->param[CHUNKEND]) {
- temp = dz->param[CHUNKSTART];
- dz->param[CHUNKSTART] = dz->param[CHUNKEND];
- dz->param[CHUNKEND] = temp;
- }
- if(dz->iparam[CHUNKEND] - dz->iparam[CHUNKSTART] <= ITX_SPLICELEN * dz->infile->channels * 2) {
- sprintf(errstr,"FROZEN SEGMENT (%d samples) TOO SHORT FOR SPLICING (needs %d samples)\n",
- dz->iparam[CHUNKEND] - dz->iparam[CHUNKSTART],ITX_SPLICELEN * dz->infile->channels * 2);
- return(DATA_ERROR);
- }
- if(dz->iparam[CHUNKEND] - dz->iparam[CHUNKSTART] < mindelay_samps * dz->infile->channels) {
- sprintf(errstr,"FROZEN SEGMENT (%d samples) TOO SHORT FOR (MINIMUM) DELAY TIME SPECIFIED (%d samples)\n",
- dz->iparam[CHUNKEND] - dz->iparam[CHUNKSTART],mindelay_samps * dz->infile->channels);
- return(DATA_ERROR);
- }
- }
- if((dz->process != ITERATE_EXTEND) && (dz->param[ITER_GAIN]==DEFAULT_ITER_GAIN))
- set_default_gain(mindelay_samps,dz);
- set_default_delays(dz);
- if (dz->process == ITERATE_EXTEND) {
- dz->param[ITER_SSTEP] = 1.0; /* 1st sound is exact copy of orig */
- } else {
- reverse_fadevals(dz);
- dz->param[ITER_STEP] = 1.0; /* 1st sound is exact copy of orig */
- }
- if((dz->process != ITERATE_EXTEND) && flteq(dz->param[ITER_GAIN],1.0))
- is_unity_gain = TRUE;
- setup_iter_process_type(is_unity_gain,dz);
- return create_iterbufs(maxpscat,dz);
- }
- /*************************** GET_MAXVALUE_OF_RAND ****************************/
- int get_maxvalue_of_rand(double *maxrand,dataptr dz)
- {
- int exit_status;
- if(dz->brksize[ITER_RANDOM]) {
- if((exit_status = get_maxvalue_in_brktable(maxrand,ITER_RANDOM,dz))<0)
- return(exit_status);
- } else
- *maxrand = dz->param[ITER_RANDOM];
- return(FINISHED);
- }
- /************************* GET_MAXVALUE_OF_PSCAT ****************************/
- int get_maxvalue_of_pscat(double *maxpscat,dataptr dz)
- {
- int exit_status;
- if(dz->brksize[ITER_PSCAT]) {
- if((exit_status = get_maxvalue_in_brktable(maxpscat,ITER_PSCAT,dz))<0)
- return(exit_status);
- } else
- *maxpscat = dz->param[ITER_PSCAT];
- return(FINISHED);
- }
- /************************* GET_MINVALUE_OF_DELAY ****************************/
- int get_minvalue_of_delay(double *mindelay,dataptr dz)
- {
- int exit_status;
- if(dz->brksize[ITER_DELAY]) {
- if((exit_status = get_minvalue_in_brktable(mindelay,ITER_DELAY,dz))<0)
- return(exit_status);
- } else
- *mindelay = dz->param[ITER_DELAY];
- return(FINISHED);
- }
- /************************* REVERSE_FADEVALS ****************************/
- void reverse_fadevals(dataptr dz)
- {
- double *p, *pend;
- if(dz->brksize[ITER_FADE]==0)
- dz->param[ITER_FADE] = 1.0 - dz->param[ITER_FADE];
- else {
- p = dz->brk[ITER_FADE] + 1;
- pend = dz->brk[ITER_FADE] + (dz->brksize[ITER_FADE] * 2);
- while(p < pend) {
- *p = 1.0 - *p;
- p += 2;
- }
- }
- }
- /************************** SET_DEFAULT_GAIN ****************************/
- void set_default_gain(int mindelay_samps,dataptr dz)
- {
- int inmsampsize;
- int maxoverlay_cnt;
- inmsampsize = dz->insams[0]/dz->infile->channels;
- maxoverlay_cnt = round(((double)inmsampsize/(double)mindelay_samps)+1.0);
- if(dz->vflag[IS_ITER_RAND])
- maxoverlay_cnt++;
- dz->param[ITER_GAIN] = 1.0/(double)maxoverlay_cnt;
- }
- /*********************** SET_DEFAULT_DELAYS ****************************/
- void set_default_delays(dataptr dz)
- {
- if(dz->process==ITERATE_EXTEND) {
- if(!dz->brksize[ITER_DELAY])
- dz->iparam[ITER_MSAMPDEL] = round(dz->param[ITER_DELAY] * (double)dz->infile->srate);
- return;
- }
- if(dz->vflag[IS_ITER_DELAY]) {
- if(!dz->brksize[ITER_DELAY])
- dz->iparam[ITER_MSAMPDEL] = round(dz->param[ITER_DELAY] * (double)dz->infile->srate);
- } else
- dz->iparam[ITER_MSAMPDEL] = dz->insams[0]/dz->infile->channels; /* default */
- }
- /********************* SETUP_ITER_PROCESS_TYPE ********************************/
- void setup_iter_process_type(int is_unity_gain,dataptr dz)
- {
- if(dz->process==ITERATE_EXTEND) {
- if(dz->param[ITER_PSCAT] > 0.0) {
- if(dz->infile->channels>1)
- dz->iparam[ITER_PROCESS] = ST_INTP_SHIFT;
- else
- dz->iparam[ITER_PROCESS] = MN_INTP_SHIFT;
- } else {
- if(dz->infile->channels>1)
- dz->iparam[ITER_PROCESS] = STEREO;
- else
- dz->iparam[ITER_PROCESS] = MONO;
- }
- if(flteq(dz->param[ITER_ASCAT],0.0)) {
- dz->iparam[ITER_PROCESS] += FIXED_AMP;
- }
- return;
- }
- dz->iparam[ITER_DO_SCALE] = TRUE;
- if(dz->vflag[IS_ITER_PSCAT]) {
- if(dz->infile->channels>1)
- dz->iparam[ITER_PROCESS] = ST_INTP_SHIFT;
- else
- dz->iparam[ITER_PROCESS] = MN_INTP_SHIFT;
- } else {
- if(dz->infile->channels>1)
- dz->iparam[ITER_PROCESS] = STEREO;
- else
- dz->iparam[ITER_PROCESS] = MONO;
- }
- if(!dz->vflag[IS_ITER_ASCAT]) {
- if(is_unity_gain)
- dz->iparam[ITER_DO_SCALE] = FALSE;
- dz->iparam[ITER_PROCESS] += FIXED_AMP;
- }
- }
- /***************************** DRUNK_PREPROCESS *************************
- *
- * Splicelen & cloktiks have been converted to SAMPLES in pconsistency.c
- */
- int drunk_preprocess(dataptr dz)
- {
- int exit_status;
- dz->iparam[DRNK_LAST_LOCUS] = -1;
- initialise_random_sequence(IS_DRNK_RSEED,DRNK_RSEED,dz);
- if((exit_status = create_drunk_buffers(dz))<0) /* 1 */
- return(exit_status);
- if((exit_status = make_drnk_splicetab(dz))<0)
- return(exit_status);
- if(dz->insams[0] <= dz->iparam[DRNK_SPLICELEN] * dz->infile->channels * 2) {
- sprintf(errstr,"Infile too short for splices.\n");
- return(DATA_ERROR);
- }
- dz->iparam[DRNK_LGRAIN] = round((double)dz->infile->srate * DRNK_GRAIN);
- dz->iparam[DRNK_TOTALDUR] = round(dz->param[DRNK_TOTALDUR] * (double)(dz->infile->srate * dz->infile->channels));
- if((exit_status = convert_time_and_vals_to_samplecnts(DRNK_LOCUS,dz))<0)
- return(exit_status);
- if((exit_status = convert_time_and_vals_to_samplecnts(DRNK_AMBITUS,dz))<0)
- return(exit_status);
- if((exit_status = convert_time_to_samplecnts(DRNK_CLOKRND,dz))<0)
- return(exit_status);
- if((exit_status = convert_time_to_samplecnts(DRNK_OVERLAP,dz))<0)
- return(exit_status);
- if((exit_status = get_maxvalue(DRNK_OVERLAP,&dz->param[DRNK_MAX_OVLAP],dz))<0)
- return(exit_status);
- if((exit_status = convert_time_to_samplecnts(DRNK_GSTEP,dz))<0)
- return(exit_status);
- if((exit_status = convert_sec_steps_to_grain_steps(dz))<0)
- return(exit_status);
- if(dz->mode==HAS_SOBER_MOMENTS) {
- if((exit_status = convert_time_and_vals_to_samplecnts(DRNK_MIN_PAUS,dz))<0)
- return(exit_status);
- if((exit_status = convert_time_and_vals_to_samplecnts(DRNK_MAX_PAUS,dz))<0)
- return(exit_status);
- if((exit_status = convert_time_to_samplecnts(DRNK_MIN_DRNKTIK,dz))<0)
- return(exit_status);
- if((exit_status = convert_time_to_samplecnts(DRNK_MAX_DRNKTIK,dz))<0)
- return(exit_status);
- }
- return(FINISHED);
- }
- /********************** MAKE_DRNK_SPLICETAB *********************/
- int make_drnk_splicetab(dataptr dz)
- {
- int n;
- if((dz->parray[DRNK_SPLICETAB] = (double *)malloc(dz->iparam[DRNK_SPLICELEN] * sizeof(double)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to make splicetable.\n");
- return(MEMORY_ERROR);
- }
- for(n=0;n<dz->iparam[DRNK_SPLICELEN];n++)
- dz->parray[DRNK_SPLICETAB][n] = (double)n/(double)dz->iparam[DRNK_SPLICELEN];
- return(FINISHED);
- }
- /************************* CONVERT_SEC_STEPS_TO_GRAIN_STEPS *********************/
- int convert_sec_steps_to_grain_steps(dataptr dz)
- {
- double *p, *pend;
- int lval;
- if(dz->iparam[DRNK_LGRAIN]<=0) {
- sprintf(errstr,"Invalid DRNK_LGRAIN val: convert_sec_steps_to_grain_steps()\n");
- return(PROGRAM_ERROR);
- }
- if(dz->brksize[DRNK_GSTEP]) {
- p = dz->brk[DRNK_GSTEP] + 1;
- pend = dz->brk[DRNK_GSTEP] + (dz->brksize[DRNK_GSTEP] * 2);
- while(p < pend) {
- lval = round(*p * (double)dz->infile->srate);
- lval = (lval+(dz->iparam[DRNK_LGRAIN]/2))/dz->iparam[DRNK_LGRAIN];
- *p = (double)lval;
- p += 2;
- }
- } else {
- dz->iparam[DRNK_GSTEP] = round(dz->param[DRNK_GSTEP] * (double)dz->infile->srate);
- dz->iparam[DRNK_GSTEP] = (dz->iparam[DRNK_GSTEP]+(dz->iparam[DRNK_LGRAIN]/2))/dz->iparam[DRNK_LGRAIN];
- dz->param[DRNK_GSTEP] = (double)dz->iparam[DRNK_GSTEP];
- }
- return(FINISHED);
- }
|