| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696 |
- /*
- * 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
- *
- */
- /* floatsam version */
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- #include <float.h>
- #include <string.h>
- #include <structures.h>
- #include <tkglobals.h>
- #include <globcon.h>
- #include <processno.h>
- #include <modeno.h>
- #include <arrays.h>
- #include <envel.h>
- #include <cdpmain.h>
- #include <sfsys.h>
- //#ifdef unix
- #define round(x) lround((x))
- //#endif
- #define MARGIN (16)
- #define IS_CLICK (1.0/(3.0 * MS_TO_SECS)) /* from zero to full amplitude in 3ms */
- /* anything faster is a 'click'!! */
- #define MINSPAN (16) /* spanning points for creating exponential env */
- #define ATTEN (3.33333333) /* Attenuation for creating exponential env */
- #define ATTENATOR (1.7) /* Attenuation for creating exponential env */
- #define STEEP_ATTEN (2.0) /* For ATTACK */
- static int realloc_envcreate_tables(int tabsize,dataptr dz);
- static int envnorm(float *env,float *envend);
- static int envceiling(float *env,float *envend);
- static int envduck(float *env,float *envend,dataptr dz);
- static int envrevers(float *env,float *envend);
- static int envexagg(float *env,float *envend,dataptr dz);
- static int envatten(float *env,float *envend,dataptr dz);
- static int envlift(float *env,float *envend,dataptr dz);
- static int envtstretch(float **env,float **envend,dataptr dz);
- static int envflatn(float *env,float *envend,dataptr dz);
- static int envgate(float *env,float *envend,dataptr dz);
- static int envinvert(float *env,float *envend,dataptr dz);
- static int envexpand(float *env,float *envend,dataptr dz);
- static int envlimit(float *env,float *envend,dataptr dz);
- static int envkorrug(float *env,float *envend,dataptr dz);
- static int envpeakcnt(float *env,float *envend,dataptr dz);
- static int envtrig(float **env,float **envend,dataptr dz);
- static int envshortn(float **env,float **envend,double timestretch);
- static int envlenthn(float **env,float **envend,double timestretch);
- static float envintpl(double here,double winbase,double base,double next);
- static void brkdeglitch(double *,double **);
- static int gen_trigger_envelope(double **brk, double **brkend,dataptr dz);
- static int gen_reapplied_trigger_envelope(double **brk, double **brkend,dataptr dz);
- static int gatefilt(float *p,float *envend,double gate,int smoothing);
- static int do_simple_gating(float *env,float *envend,dataptr dz);
- static int do_smoothed_gating(float *env,float *envend,int smoothing,dataptr dz);
- static void do_env_invert(float *p,double upratio,double dnratio,dataptr dz);
- static void do_expanding(float *p,float *envend,int *gating,double squeeze,int smoothing,dataptr dz);
- static void digout_trough(float *env,float *envend,float *shadowenv,int del,float *q);
- static int ispeak(float *env,float *envend,float *q,int width);
- static int istrough(float *env,float *envend,float *q,int width);
- static int enlarge_brktable(double **brk,double **brkend, double **q,int *arraysize);
- static void convert_to_on_triggers(double now,double timestep,double rise,int *triggered,double **q);
- static int round_off_brktable(double *q,double **brk,double **brkend,double envlen);
- static int locate_and_size_triggers(float *env,float *envend,double **brk,double **brkend,dataptr dz);
- static int convert_other_brktable_to_envtable(double *brk,double *brkend,float **env,float **envend,dataptr dz);
- static float read_a_val_from_brktable(double *brk,double *brkend,double thistime);
- /*************************** ENVELOPE_WARP ************************/
-
- int envelope_warp(float **env,float **envend,dataptr dz)
- {
- int exit_status;
- if(flteq((double)dz->outfile->window_size,0.0)) {
- sprintf(errstr,"dz->outfile->wsize not set: envelope_warp()\n");
- return(PROGRAM_ERROR);
- }
- if(dz->process!=ENV_WARPING && dz->process!=ENV_REPLOTTING && dz->process!=ENV_RESHAPING) {
- sprintf(errstr,"this function not valid with this process: envelope_warp()\n");
- return(PROGRAM_ERROR);
- }
- switch(dz->mode) {
- case(ENV_NORMALISE): exit_status = envnorm(*env,*envend); break;
- case(ENV_REVERSE): exit_status = envrevers(*env,*envend); break;
- case(ENV_EXAGGERATING): exit_status = envexagg(*env,*envend,dz); break;
- case(ENV_ATTENUATING): exit_status = envatten(*env,*envend,dz); break;
- case(ENV_LIFTING): exit_status = envlift(*env,*envend,dz); break;
- case(ENV_TSTRETCHING): exit_status = envtstretch(env,envend,dz); break;
- case(ENV_FLATTENING): exit_status = envflatn(*env,*envend,dz); break;
- case(ENV_GATING): exit_status = envgate(*env,*envend,dz); break;
- case(ENV_INVERTING): exit_status = envinvert(*env,*envend,dz); break;
- case(ENV_EXPANDING): exit_status = envexpand(*env,*envend,dz); break;
- case(ENV_LIMITING): exit_status = envlimit(*env,*envend,dz); break;
- case(ENV_CORRUGATING): exit_status = envkorrug(*env,*envend,dz); break;
- case(ENV_TRIGGERING): exit_status = envtrig(env,envend,dz); break;
- case(ENV_CEILING): exit_status = envceiling(*env,*envend); break;
- case(ENV_DUCKED): exit_status = envduck(*env,*envend,dz); break;
- case(ENV_PEAKCNT): exit_status = envpeakcnt(*env,*envend,dz); break;
- default:
- sprintf(errstr,"Unknown case in envelope_warp()\n");
- return(PROGRAM_ERROR);
- }
- return(exit_status);
- }
- /*************************** ENVNORM ************************/
-
- int envnorm(float *env,float *envend)
- {
- float *p = env;
- double convertor, maxval = 0.0;
- while(p < envend) {
- maxval = max(*p,maxval);
- p++;
- }
- if(flteq(maxval,0.0)) {
- sprintf(errstr,"Envelope level is effectively zero: cannot normalise.\n");
- return(DATA_ERROR);
- }
- p = env;
- convertor = 1.0/maxval;
- while(p < envend) {
- *p = (float)((*p) * convertor);
- *p = (float)min(*p,1.0); /* SAFETY */
- p++;
- }
- return(FINISHED);
- }
- /*************************** ENVCEILING ************************/
-
- int envceiling(float *env,float *envend)
- {
- float *p = env;
- double maxval = 0.0;
- while(p < envend) {
- maxval = max(*p,maxval);
- p++;
- }
- p = env;
- while(p < envend) {
- *p = (float)maxval;
- p++;
- }
- return(FINISHED);
- }
- /*************************** ENVDUCK ************************/
-
- int envduck(float *env,float *envend,dataptr dz)
- {
- int exit_status;
- float *p = env;
- double thistime = 0.0;
- double timestep = dz->outfile->window_size * MS_TO_SECS;
- switch(dz->process) {
- case(ENV_WARPING):
- while(p < envend) {
- if((exit_status = read_values_from_all_existing_brktables(thistime,dz))<0)
- return(exit_status);
- if(*p > dz->param[ENV_THRESHOLD])
- *p = (float)dz->param[ENV_GATE];
- thistime += timestep;
- p++;
- }
- break;
- case(ENV_RESHAPING):
- case(ENV_REPLOTTING):
- while(p < envend) {
- if((exit_status = read_values_from_all_existing_brktables(thistime,dz))<0)
- return(exit_status);
- if(*p > dz->param[ENV_THRESHOLD])
- *p = (float)dz->param[ENV_GATE];
- else
- *p = 1.0f;
- thistime += timestep;
- p++;
- }
- break;
- default:
- sprintf(errstr,"Unknown case in envduck()\n");
- return(PROGRAM_ERROR);
- }
- return(FINISHED);
- }
- /*************************** ENVREVERS ************************/
-
- int envrevers(float *env,float *envend)
- {
- float *p = env, *q = envend - 1;
- float temp;
- while(q > p) {
- temp = *p;
- *p = *q;
- *q = temp;
- p++;
- q--;
- }
- return(FINISHED);
- }
- /*************************** ENVEXAGG ************************/
- int envexagg(float *env,float *envend,dataptr dz)
- {
- int exit_status;
- float *p = env;
- double thistime = 0.0;
- double timestep = dz->outfile->window_size * MS_TO_SECS;
- if(dz->brk[ENV_EXAG]) {
- while(p<envend) {
- if((exit_status = read_value_from_brktable(thistime,ENV_EXAG,dz))<0)
- return(exit_status);
- *p = (float)pow((double)*p,dz->param[ENV_EXAG]);
- p++;
- thistime += timestep;
- }
- } else {
- while(p<envend) {
- *p = (float)pow((double)*p,dz->param[ENV_EXAG]);
- p++;
- }
- }
- return(FINISHED);
- }
- /*************************** ENVATTEN *************************/
- int envatten(float *env,float *envend,dataptr dz)
- {
- int exit_status;
- float *p = env;
- double thistime = 0.0;
- double timestep = dz->outfile->window_size * MS_TO_SECS;
- if(dz->brk[ENV_ATTEN]) {
- while(p<envend) {
- if((exit_status = read_value_from_brktable(thistime,ENV_ATTEN,dz))<0)
- return(exit_status);
- *p = (float)(*p * dz->param[ENV_ATTEN]);
- p++;
- thistime += timestep;
- }
- } else {
- while(p<envend) {
- *p = (float)(*p * dz->param[ENV_ATTEN]);
- p++;
- }
- }
- return(FINISHED);
- }
- /*************************** ENVLIFT ************************/
- int envlift(float *env,float *envend,dataptr dz)
- {
- int exit_status;
- float *p = env;
- int saturated = 0;
- double thistime = 0.0;
- double timestep = dz->outfile->window_size * MS_TO_SECS;
- if(dz->brk[ENV_ATTEN]) {
- while(p<envend) {
- if((exit_status = read_value_from_brktable(thistime,ENV_LIFT,dz))<0)
- return(exit_status);
- if((*p = (float)(*p + dz->param[ENV_LIFT]))> 1.0) {
- *p = 1.0f;
- saturated++;
- }
- p++;
- thistime += timestep;
- }
- } else {
- while(p<envend) {
- if((*p = (float)(*p + dz->param[ENV_LIFT]))> 1.0) {
- *p = 1.0f;
- saturated++;
- }
- p++;
- }
- }
- if(saturated) {
- fprintf(stdout,"WARNING: Envelope was clipped, but will not distort sounds.\n");
- fflush(stdout);
- }
- return(FINISHED);
- }
- /**************************** ENVTSTRETCH **************************/
- int envtstretch(float **env,float **envend,dataptr dz)
- {
- int exit_status;
- double timestretch = dz->param[ENV_TSTRETCH];
- if(dz->brksize[ENV_TSTRETCH]) {
- sprintf(errstr,"Invalid use of brktable: envtstretch()\n");
- return(PROGRAM_ERROR);
- }
- if(timestretch>1.0) {
- if((exit_status = envlenthn(env,envend,timestretch))<0)
- return(exit_status);
- }
- if(timestretch<1.0) {
- if((exit_status = envshortn(env,envend,timestretch))<0)
- return(exit_status);
- }
- return(FINISHED);
- }
- /**************************** ENVSHORTN **************************/
- int envshortn(float **env,float **envend,double timestretch)
- {
- int oldenvlen, newenvlen;
- int n, m = 0;
- float *nuenv, *p;
- double here, skip, base, winbase, next;
- skip = 1.0/timestretch;
- oldenvlen = *envend - *env;
- newenvlen = (int)(((double)oldenvlen * timestretch) + 1.0); /* rescale & round up */
- newenvlen += MARGIN;
- if((nuenv = (float *)malloc(newenvlen*sizeof(float)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to create new envelope array.\n");
- return(MEMORY_ERROR);
- }
- p = nuenv;
- *p++ = **env;
- for(;;) {
- if(++m > newenvlen) {
- sprintf(errstr,"New envelope array bound exceeded in envshortn()\n");
- return(PROGRAM_ERROR);
- }
- here = skip * (double)(m);
- if(here>=(double)(oldenvlen-1)) {
- *p = *(p-1);
- newenvlen = p - nuenv;
- free(*env);
- if((*env = (float *)realloc(nuenv,newenvlen*sizeof(float)))==NULL) {
- sprintf(errstr,"envshortn(): 2\n");
- return(MEMORY_ERROR);
- }
- *envend = *env + newenvlen;
- break;
- }
- winbase = floor(here);
- n = round(winbase);
- base = (double)*((*env) + n);
- if(n > oldenvlen-1)
- next = base;
- else
- next = (double)*((*env) + n + 1);
- *p++ = envintpl(here,winbase,base,next);
- }
- return(FINISHED);
- }
- /**************************** ENVLENTHN ***************************/
- int envlenthn(float **env,float **envend,double timestretch)
- {
- int oldenvlen, newenvlen;
- int n = 0, m = 0;
- double here = 0.0, skip;
- float *nuenv, *p;
- double base, winbase, next;
- skip = 1.0/timestretch;
- oldenvlen = *envend - *env;
- newenvlen = (int)(((double)oldenvlen * timestretch) + 1.0);
- newenvlen += MARGIN;
- if((nuenv = (float *)malloc(newenvlen * sizeof(float)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to create new envelope array.\n");
- return(MEMORY_ERROR);
- }
- p = nuenv;
- next = (double)**env;
- for(;;) {
- base = next;
- winbase = (double)n;
- if(++n > oldenvlen-1) {
- if(!m) {
- sprintf(errstr,"Anomaly in envlenthn()\n");
- return(PROGRAM_ERROR);
- }
- newenvlen = p - nuenv;
- free(*env);
- if((*env = (float *)realloc(nuenv,newenvlen*sizeof(float)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to reallocate new envelope array.\n");
- return(MEMORY_ERROR);
- }
- *envend = *env + newenvlen;
- break;
- }
- next = (double)*((*env) + n);
- while(here <= (double)n) {
- *p++ = envintpl(here,winbase,base,next);
- here = skip * (double)(++m);
- if(m >= newenvlen) {
- sprintf(errstr,"envlenthn(): New array bounds exceeded\n");
- return(PROGRAM_ERROR);
- }
- }
- }
- return(FINISHED);
- }
- /*************************** ENVINTPL ****************************/
- float envintpl(double here,double winbase,double base,double next)
- {
- double tratio = here - winbase;
- double valdif = next - base;
- double val = base + (tratio * valdif);
- return((float)val);
- }
- /*************************** ENVFLATN *************************/
- int envflatn(float *env, float *envend, dataptr dz)
- {
- int exit_status;
- float *p, *q, *z, *nuenv;
- int envlen = envend - env, ppos, qpos;
- int backovflow, fowdovflow, thisback, n;
- double thistime = 0.0;
- double d, sum;
- double timestep = dz->outfile->window_size * MS_TO_SECS;
- int maxflatn;
- if(dz->brksize[ENV_FLATN]) {
- if((exit_status = get_maxvalue_in_brktable(&d,ENV_FLATN,dz))<0)
- return(exit_status);
- maxflatn = round(d);
- } else
- maxflatn = dz->iparam[ENV_FLATN];
- if(maxflatn >= envlen) {
- sprintf(errstr,"Flattening param too large for infile.\n");
- return(DATA_ERROR);
- }
- if((nuenv=(float *)malloc((envlen + maxflatn)*sizeof(float)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to create new envelope array.\n");
- return(MEMORY_ERROR);
- }
- backovflow = maxflatn/2;
- fowdovflow = maxflatn - backovflow - 1;
- p = env;
- q = nuenv;
- for(n=0;n<backovflow;n++)
- *q++ = *p;
- while(p < envend)
- *q++ = *p++;
- p--;
- for(n=0;n<fowdovflow;n++)
- *q++ = *p;
- p = env;
- q = nuenv;
- if(dz->brksize[ENV_FLATN]) {
- while(p < envend) {
- if((exit_status = read_value_from_brktable(thistime,ENV_EXAG,dz))<0)
- return(exit_status);
- thisback = dz->iparam[ENV_FLATN]/2;
- ppos = p - env;
- qpos = ppos + backovflow - thisback;
- z = nuenv + qpos;
- sum = 0.0;
- for(n=0;n<dz->iparam[ENV_FLATN];n++)
- sum += *z++;
- sum /= (double)dz->iparam[ENV_FLATN];
- *p++ = (float)sum;
- thistime += timestep;
- }
- } else {
- while(p < envend) {
- z = q++;
- sum = 0.0;
- for(n=0;n<dz->iparam[ENV_FLATN];n++)
- sum += *z++;
- sum /= (double)dz->iparam[ENV_FLATN];
- *p++ = (float)sum;
- }
- }
- free(nuenv);
- return(FINISHED);
- }
- /********************************* ENVGATE ****************************/
- int envgate(float *env,float *envend,dataptr dz)
- {
- int exit_status;
- int smoothing = dz->iparam[ENV_SMOOTH];
- if(smoothing==0)
- exit_status = do_simple_gating(env,envend,dz);
- else
- exit_status = do_smoothed_gating(env,envend,smoothing,dz);
- return(exit_status);
- }
- /********************************* DO_SIMPLE_GATING ****************************/
- int do_simple_gating(float *env,float *envend,dataptr dz)
- {
- int exit_status;
- double thistime = 0.0;
- float *p = env;
- double timestep = dz->outfile->window_size * MS_TO_SECS;
- if(dz->brksize[ENV_GATE]) {
- while(p<envend) {
- if((exit_status = read_value_from_brktable(thistime,ENV_GATE,dz))<0)
- return(exit_status);
- if(*p < dz->param[ENV_GATE])
- *p = 0.0f;
- p++;
- thistime += timestep;
- }
- } else {
- while(p<envend) {
- if(*p < dz->param[ENV_GATE])
- *p = 0.0f;
- p++;
- }
- }
- return(FINISHED);
- }
- /********************************* DO_SMOOTHED_GATING ****************************/
- int do_smoothed_gating(float *env,float *envend,int smoothing,dataptr dz)
- {
- int exit_status;
- double thistime = 0.0;
- int gating = TRUE;
- float *p = env;
- double timestep = dz->outfile->window_size * MS_TO_SECS;
- if(dz->brksize[ENV_GATE]) {
- while(p<envend) {
- if((exit_status = read_value_from_brktable(thistime,ENV_GATE,dz))<0)
- return(exit_status);
- if((*p >= dz->param[ENV_GATE]) /* 1 */
- && (!gating || (gating && !gatefilt(p,envend,dz->param[ENV_GATE],smoothing)))) {
- gating = FALSE;
- } else {
- *p = 0.0f; /* 2 */
- gating = TRUE;
- }
- p++;
- thistime += timestep;
- }
- } else {
- while(p<envend) {
- if((*p >= dz->param[ENV_GATE]) /* 1 */
- && (!gating || (gating && !gatefilt(p,envend,dz->param[ENV_GATE],smoothing)))) {
- gating = FALSE;
- } else {
- *p = 0.0f; /* 2 */
- gating = TRUE;
- }
- p++;
- }
- }
- return(FINISHED);
- }
- /****************************** GATEFILT *************************/
-
- int gatefilt(float *p,float *envend,double gate,int smoothing)
- {
- int this_smoothfactor, windows_remain;
- int n;
- double average = 0.0;
- float *q;
- if((windows_remain = envend - p) >= smoothing)
- this_smoothfactor = smoothing;
- else
- this_smoothfactor = windows_remain;
- q = p;
- for(n=0;n<this_smoothfactor;n++)
- average += *q++;
- average /= (double)this_smoothfactor;
- if(average<=gate)
- return(TRUE);
- return(FALSE);
- }
- /*************************** ENVINVERT *************************/
- int envinvert(float *env,float *envend,dataptr dz)
- {
- #define NO_BRK (0)
- #define G_BRK (1)
- #define M_BRK (2)
- #define G_AND_M_BRK (3)
- int exit_status;
- float *p;
- double hirange = 0.0, lorange = 0.0, upratio = 0.0, dnratio = 0.0;
- double thistime = 0.0;
- int thistype;
- double timestep = dz->outfile->window_size * MS_TO_SECS;
- if(dz->brksize[ENV_GATE]) {
- if(dz->brksize[ENV_MIRROR])
- thistype = G_AND_M_BRK;
- else {
- thistype = G_BRK;
- hirange = 1.0 - dz->param[ENV_MIRROR];
- }
- } else {
- if(dz->brksize[ENV_MIRROR])
- thistype = M_BRK;
- else {
- thistype = NO_BRK;
- hirange = 1.0 - dz->param[ENV_MIRROR];
- lorange = dz->param[ENV_MIRROR] - dz->param[ENV_GATE];
- upratio = hirange/lorange;
- dnratio = lorange/hirange;
- }
- }
- p = env;
- if(thistype == NO_BRK) {
- while(p<envend) {
- do_env_invert(p,upratio,dnratio,dz);
- p++;
- }
- } else {
- while(p<envend) {
- switch(thistype) {
- case(G_BRK):
- if((exit_status = read_value_from_brktable(thistime,ENV_GATE,dz))<0)
- return(exit_status);
- lorange = dz->param[ENV_MIRROR] - dz->param[ENV_GATE];
- break;
- case(M_BRK):
- if((exit_status = read_value_from_brktable(thistime,ENV_MIRROR,dz))<0)
- return(exit_status);
- hirange = 1.0 - dz->param[ENV_MIRROR];
- lorange = dz->param[ENV_MIRROR] - dz->param[ENV_GATE];
- break;
- case(G_AND_M_BRK):
- if((exit_status = read_value_from_brktable(thistime,ENV_GATE,dz))<0)
- return(exit_status);
- if((exit_status = read_value_from_brktable(thistime,ENV_MIRROR,dz))<0)
- return(exit_status);
- hirange = 1.0 - dz->param[ENV_MIRROR];
- lorange = dz->param[ENV_MIRROR] - dz->param[ENV_GATE];
- break;
- }
- upratio = hirange/lorange;
- dnratio = lorange/hirange;
- do_env_invert(p,upratio,dnratio,dz);
- thistime += timestep;
- p++;
- }
- }
- return(FINISHED);
- }
- /*************************** DO_ENV_INVERT *************************/
- void do_env_invert(float *p,double upratio,double dnratio,dataptr dz)
- {
- if(*p<dz->param[ENV_GATE]) {
- *p = 0.0f;
- } else {
- if(*p<=dz->param[ENV_THRESHOLD])
- *p = (float)(((dz->param[ENV_THRESHOLD] - *p) * upratio) + dz->param[ENV_THRESHOLD]);
- else
- *p = (float)(dz->param[ENV_THRESHOLD] - ((*p - dz->param[ENV_THRESHOLD]) * dnratio));
- }
- }
- /**************************** ENVFEXPAND ******************************/
- int envexpand(float *env,float *envend,dataptr dz)
- {
- #define NO_BRK (0)
- #define G_BRK (1)
- #define T_BRK (2)
- #define G_AND_T_BRK (3)
- int exit_status;
- float *p;
- double toprange = 0.0, newrange = 0.0, squeeze = 0.0;
- double thistime = 0.0;
- int gating = TRUE;
- int smoothing = dz->iparam[ENV_SMOOTH];
- int thistype;
- double timestep = dz->outfile->window_size * MS_TO_SECS;
- if(dz->brksize[ENV_GATE]) {
- if(dz->brksize[ENV_THRESHOLD])
- thistype = G_AND_T_BRK;
- else {
- thistype = G_BRK;
- newrange = 1.0 - dz->param[ENV_THRESHOLD];
- }
- } else {
- toprange = 1.0 - dz->param[ENV_GATE];
- if(dz->brksize[ENV_THRESHOLD])
- thistype = T_BRK;
- else {
- thistype = NO_BRK;
- newrange = 1.0 - dz->param[ENV_THRESHOLD];
- squeeze = newrange/toprange;
- }
- }
- p = env;
- if(thistype == NO_BRK) {
- while(p<envend) {
- do_expanding(p,envend,&gating,squeeze,smoothing,dz);
- p++;
- }
- } else {
- while(p<envend) {
- switch(thistype) {
- case(G_AND_T_BRK):
- if((exit_status = read_value_from_brktable(thistime,ENV_GATE,dz))<0)
- return(exit_status);
- toprange = 1.0 - dz->param[ENV_GATE];
- /* fall thro */
- case(T_BRK):
- if((exit_status = read_value_from_brktable(thistime,ENV_THRESHOLD,dz))<0)
- return(exit_status);
- newrange = 1.0 - dz->param[ENV_THRESHOLD];
- break;
- case(G_BRK):
- if((exit_status = read_value_from_brktable(thistime,ENV_GATE,dz))<0)
- return(exit_status);
- toprange = 1.0 - dz->param[ENV_GATE];
- break;
- }
- squeeze = newrange/toprange;
- do_expanding(p,envend,&gating,squeeze,smoothing,dz);
- thistime += timestep;
- p++;
- }
- }
- return(FINISHED);
- }
- /**************************** DO_EXPANDING ****************************/
- void do_expanding(float *p,float *envend,int *gating,double squeeze,int smoothing,dataptr dz)
- {
- if(smoothing) {
- if((*p > dz->param[ENV_GATE])
- && (*gating==FALSE || ((*gating==TRUE) && !gatefilt(p,envend,dz->param[ENV_GATE],smoothing)))) {
- *p = (float)(1.0 - ((1.0 - *p) * squeeze));
- *gating = FALSE;
- } else {
- *p = 0.0f;
- *gating = TRUE;
- }
- } else {
- if(*p > dz->param[ENV_GATE])
- *p = (float)(1.0 - ((1.0 - *p) * squeeze));
- else
- *p = 0.0f;
- }
- }
- /**************************** ENVLIMIT ******************************/
- int envlimit(float *env,float *envend,dataptr dz)
- {
- #define NO_BRK (0)
- #define TH_BRK (1)
- #define L_BRK (2)
- #define T_AND_L_BRK (3)
- int exit_status;
- float *p;
- double x, toprange = 0.0, newrange, squeeze = 0.0;
- double thistime = 0.0;
- int thistype;
- double timestep = dz->outfile->window_size * MS_TO_SECS;
- if(dz->brksize[ENV_THRESHOLD]) {
- if(dz->brksize[ENV_LIMIT])
- thistype = T_AND_L_BRK;
- else
- thistype = TH_BRK;
- } else {
- toprange = 1.0 - dz->param[ENV_THRESHOLD];
- if(dz->brksize[ENV_LIMIT])
- thistype = L_BRK;
- else {
- thistype = NO_BRK;
- newrange = dz->param[ENV_LIMIT] - dz->param[ENV_THRESHOLD];
- squeeze = newrange/toprange;
- }
- }
- p = env;
- if(thistype == NO_BRK) {
- while(p<envend) {
- if(*p > dz->param[ENV_THRESHOLD]) {
- x = (*p - dz->param[ENV_THRESHOLD]) * squeeze;
- *p = (float)(dz->param[ENV_THRESHOLD] + x);
- }
- p++;
- }
- } else {
- while(p<envend) {
- switch(thistype) {
- case(L_BRK):
- if((exit_status = read_value_from_brktable(thistime,ENV_LIMIT,dz))<0)
- return(exit_status);
- newrange = dz->param[ENV_LIMIT] - dz->param[ENV_THRESHOLD];
- squeeze = newrange/toprange;
- break;
- case(T_AND_L_BRK):
- if((exit_status = read_value_from_brktable(thistime,ENV_LIMIT,dz))<0)
- return(exit_status);
- /* fall thro */
- case(TH_BRK):
- if((exit_status = read_value_from_brktable(thistime,ENV_THRESHOLD,dz))<0)
- return(exit_status);
- toprange = 1.0 - dz->param[ENV_THRESHOLD];
- newrange = dz->param[ENV_LIMIT] - dz->param[ENV_THRESHOLD];
- squeeze = newrange/toprange;
- break;
- }
- if(*p > dz->param[ENV_THRESHOLD]) {
- x = (*p - dz->param[ENV_THRESHOLD]) * squeeze;
- *p = (float)(dz->param[ENV_THRESHOLD] + x);
- }
- thistime += timestep;
- p++;
- }
- }
- return(FINISHED);
- }
- /*************************** ENVKORRUG *************************/
-
- int envkorrug(float *env,float *envend,dataptr dz)
- {
- int exit_status;
- int upwards;
- double thistime = 0.0;
- float *p, *q;
- double timestep = dz->outfile->window_size * MS_TO_SECS;
- float *shadowenv;
- size_t bytelen = (envend - env) * sizeof(float);
- if((shadowenv = (float *)malloc(bytelen))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to create shadow envelope array.\n");
- return(MEMORY_ERROR);
- }
- memset((char *)shadowenv,0,(size_t)bytelen);
- p = env+1;
- q = env;
- if (*p > *q)
- upwards = TRUE;
- else
- upwards = FALSE;
- while(p < envend) {
- if((exit_status = read_values_from_all_existing_brktables(thistime,dz))<0)
- return(exit_status);
- if(upwards) {
- if(*p <= *q) {
- if(ispeak(env,envend,q,(int)dz->iparam[ENV_PKSRCHWIDTH]))
- *(shadowenv + (q - env)) = 1.0f;
- upwards = FALSE;
- }
- } else {
- if(*p > *q)
- upwards = TRUE;
- }
- thistime += timestep;
- p++;
- q++;
- }
- thistime = 0.0;
- p = env+1;
- q = env;
- while(p < envend) {
- if((exit_status = read_values_from_all_existing_brktables(thistime,dz))<0)
- return(exit_status);
- if(upwards) {
- if(*p <= *q) {
- upwards = FALSE;
- }
- } else {
- if(*p > *q) {
- if(istrough(env,envend,q,(int)dz->iparam[ENV_PKSRCHWIDTH]))
- digout_trough(env,envend,shadowenv,(int)dz->iparam[ENV_TROFDEL],q);
- upwards = TRUE;
- }
- }
- thistime += timestep;
- p++;
- q++;
- }
- if(dz->process==ENV_WARPING) {
- p = env;
- while(p < envend) {
- if(*p>0.0)
- *p = 1.0f; /* NB: NB: Therefore don't use REPLACE with corrugation, when WARPING !! */
- p++;
- }
- }
- free(shadowenv);
- return(FINISHED);
- }
-
- /*************************** ISTROUGH **********************************/
-
- int istrough(float *env,float *envend,float *q,int width)
- {
- int up, down;
- float *upq, *downq, *r;
- if(width<2)
- return(1);
- down = up = width/2;
- if(EVEN(width))
- down = up - 1; /* set search p[arams above and below q */
- downq = q - down;
- upq = q + up;
- upq = min(envend-1,upq); /* allow for ends of envelope table */
- downq = max(env,downq);
- for(r = downq; r<=upq; r++) {
- if(*q > *r)
- return(FALSE);
- }
- return(TRUE); /* if r is minimum of all in trough, return 1 */
- }
-
- /*************************** ISPEAK **********************************/
-
- int ispeak(float *env,float *envend,float *q,int width)
- {
- int up, down;
- float *upq, *downq, *r;
- if(width<2)
- return(TRUE);
- down = up = width/2;
- if(EVEN(width))
- down = up - 1; /* set search params above and below q */
- downq = q - down;
- upq = q + up;
- upq = min(envend-1,upq); /* allow for ends of envelope table */
- downq = max(env,downq);
- for(r = downq; r<=upq; r++) {
- if(*q < *r)
- return(FALSE);
- }
- return(TRUE); /* if r is maximum of all in peak, return 1 */
- }
-
- /***************************** DIGOUT_TROUGH *********************************/
-
- void digout_trough(float *env,float *envend,float *shadowenv,int del,float *q)
- {
- float *r, *upq, *downq;
- int down, up, herepos, lopos, hipos, thispos;
- if(del<2) {
- *q = 0.0f; /* set single-sector trough to 0.0 */
- return;
- }
- down = up = del/2;
- if(EVEN(del))
- down = up - 1; /* set trof_delete limits above and below q */
- downq = q - down;
- upq = q + up;
- upq = min(envend-1,upq); /* allow for ends of envelope table */
- downq = max(env,downq);
- herepos = q-env;
- lopos = downq - env; /* find relative positions in env-table */
- hipos = upq - env;
- /* search downwards for peaks set in shadow table */
- for(r = shadowenv + herepos; r>= shadowenv + lopos; r--) {
- if(*r>FLTERR) {
- thispos = (r+1) - shadowenv;
- downq = env + thispos;/* & adjust downward delete-limit accordingly */
- break; /* to avoid deleting peaks */
- }
- } /* search upwards for peaks set in shadow table */
- for(r = shadowenv + herepos; r<=shadowenv + hipos; r++) {
- if(*r>FLTERR) {
- thispos = (r-1) - shadowenv;
- upq = env + thispos; /* and adjust upward delete-limit accordingly */
- break; /* to avoid deleting peaks */
- }
- }
- for(r = downq; r<=upq; r++) /* delete the defined trough */
- *r = 0.0f;
- }
- /**************************** ENVTRIG *********************************/
- int envtrig(float **env,float **envend,dataptr dz) /* NOTE THIS USES POINTERS TO env AND envend */
- {
- int exit_status;
- double *brk, *brkend;
- if((exit_status = locate_and_size_triggers(*env,*envend,&brk,&brkend,dz))<0)
- return(exit_status);
- switch(dz->process) {
- case(ENV_REPLOTTING):
- case(ENV_RESHAPING):
- exit_status = gen_trigger_envelope(&brk,&brkend,dz);
- break;
- case(ENV_WARPING):
- exit_status = gen_reapplied_trigger_envelope(&brk,&brkend,dz);
- break;
- }
- if(exit_status < 0)
- return(exit_status);
- return convert_other_brktable_to_envtable(brk,brkend,env,envend,dz);
- }
- /**************************** LOCATE_AND_SIZE_TRIGGERS *******************************/
- int locate_and_size_triggers(float *env,float *envend,double **brk,double **brkend,dataptr dz)
- {
- int exit_status;
- float *p = env, *end;
- double *q, rise, mean, now;
- double timestep = dz->outfile->window_size * MS_TO_SECS;
- double envdur;
- int n, scan, arraysize = BIGARRAY;
- int triggered = FALSE, k;
- double maxrise, thistime = 0.0;
- int look_ahead = 4;
- if((*brk = (double *)malloc(arraysize * sizeof(double)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to create trigger brktable.\n");
- return(MEMORY_ERROR);
- }
- q = *brk;
- *brkend = *brk + arraysize;
- if((scan = (int)(dz->param[ENV_TRIGDUR]/timestep))<=0) {
- sprintf(errstr,"scansize too small for envelope windows.\n");
- return(GOAL_FAILED);
- }
- end = envend - scan - 1;
- *q++ = 0.0;
- *q++ = 0.0; /*Store an initial brkpnt value of zero */
- n = scan;
- while(p<end) {
- if((exit_status = read_values_from_all_existing_brktables(thistime,dz))<0)
- return(exit_status);
- maxrise = -DBL_MAX;
- for(k=1;k<=scan;k++) {
- rise = *(p+k) - *p; /* deduce max and min rise[fall] of envelope across scantime */
- maxrise = max(rise,maxrise);
- }
- rise = maxrise;
- mean = *p + (rise/2.0); /* calc mean level of rising portion */
- if(mean>dz->param[ENV_GATE] /* deduce mean rate of rise[fall] and compare with triggering rate */
- && fabs(rise)>=dz->param[ENV_TRIGRISE]) {/* if triggering criteria met */
- if(q+look_ahead >= *brkend) {
- if((exit_status = enlarge_brktable(brk,brkend,&q,&arraysize))<0)
- return(exit_status);
- }
- now = n * timestep;
- convert_to_on_triggers(now,timestep,rise,&triggered,&q);
- p += scan;
- n += scan;
- thistime += timestep * scan;
- } else {
- triggered = FALSE;
- p++;
- n++;
- thistime += timestep;
- }
- }
- envdur = (envend - env) * timestep; /* if end of new brktable not at orig end of envel.. extend */
- if((exit_status = round_off_brktable(q,brk,brkend,envdur))<0)
- return(exit_status);
- return(FINISHED);
- }
- /******************************* GEN_TRIGGER_ENVELOPE ******************************/
- int gen_trigger_envelope(double **brk, double **brkend,dataptr dz)
- {
- int exit_status;
- int n, brklen;
- double next_trigtime, this_trigtime, nuhere, last_outval = 0.0, trigval;
- double *q, *nubrkptr, *nubrk, *nubrkend;
- double *trigptr, *trigbrk, *trigbrkend;
- int arraysize = BIGARRAY;
- trigptr = trigbrk = *brk;
- trigbrkend = *brkend;
- if((nubrk = (double *)malloc(arraysize * sizeof(double)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to create new envelope array.\n");
- return(MEMORY_ERROR);
- }
- nubrkend = nubrk + arraysize;
- nubrkptr = nubrk;
- while(trigptr < trigbrkend) {
- this_trigtime = *trigptr++;
- trigval = *trigptr++;
- if(trigptr < trigbrkend)
- next_trigtime = *trigptr;
- else
- next_trigtime = DBL_MAX;
- if(flteq(trigval,0.0)) { /* if the trigger table value is 0.0 put Zero in new table */
- *nubrkptr++ = this_trigtime;
- *nubrkptr++ = 0.0;
- } else { /* else */
- if(trigval < last_outval) /* If the new trigger value is less than current value held, */
- trigval = last_outval; /* set trig val to held value, (else, keep the new value). */
- q = dz->rampbrk; /* start copying values from ramp table into new brkpnt table, */
- n = 0; /* until ramptable ends, OR we reach next brkpnt in trigger table */
- while(n < dz->rampbrksize && (nuhere = this_trigtime + *q++)<next_trigtime) {
- *nubrkptr++ = nuhere;
- last_outval = trigval * (*q++); /* Each rampval is scaled by size of current trigger */
- *nubrkptr++ = last_outval;
- n++;
- }
- }
- if(nubrkptr>=(nubrkend-2)) {
- if((exit_status = enlarge_brktable(&nubrk,&nubrkend,&nubrkptr,&arraysize))<0)
- return(exit_status);
- }
- }
- brkdeglitch(nubrk,&nubrkptr); /* get rid of too fast amp rises or falls */
- brklen = nubrkptr - nubrk;
- free((char *)(*brk));
- if((*brk=(double *)realloc((char *)nubrk,brklen * sizeof(double)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to reallocate new envelope array.\n");
- return(MEMORY_ERROR);
- }
- if((brklen/2) * 2 != brklen) {
- sprintf(errstr,"Anomalous breaktable size in gen_trigger_envelope()\n");
- return(PROGRAM_ERROR);
- }
- *brkend = *brk + brklen;
- return(FINISHED);
- }
- /**************************** BRKDEGLITCH ****************************
- * Check a breakpoint table for sudden glitches, and smooth them.
- *
- * (1) If the brktable has very sudden rise or fall, current time-point is moved forward a little.
- * (2) If, as a result last time-points moved beyond original endtime, readjust to orig duration.
- */
- void brkdeglitch(double *brk,double **brkend)
- {
- double *p = brk, *here, *next;
- double rise, risetime, slope, newtime;
- double thistime, thisval, timeshift, timeratio;
- double lasttime = *p++;
- double lastval = *p++;
- double endtime = *((*brkend)-2);
- double timediff, valdiff, valstep;
- double click = IS_CLICK;
- // int cnt = 0;
- while(p < *brkend) {
- thistime = *p++;
- thisval = *p++;
- rise =fabs(thisval-lastval);
- if((slope = rise/(thistime-lasttime))>click) { /* If the brktable has very sudden rise or fall */
- risetime = rise/click;
- here = p-2;
- next = p;
- newtime = lasttime + risetime; /* current time-point is moved forward a little */
- timeshift = newtime - thistime;
- while(next < *brkend) {
- *here += timeshift;
- if(*here >= *next) {
- here += 2;
- next += 2;
- } else
- break;
- }
- if(next >= *brkend)
- *here += timeshift;
- thistime = newtime;
- }
- lasttime = thistime;
- lastval = thisval;
- }
- p = *brkend - 2;
- if(flteq((double)*p,endtime)) {
- *p = endtime;
- *brkend = p + 2;
- } else {
- while(*p > endtime + FLTERR) /* if, as as a result of deglitches, endtime of table is moved forward */
- p -= 2; /* Find the last point prior to the true endtime */
- if(flteq((double)*p,endtime)) { /* and establish the correct time .. */
- *p = endtime;
- *brkend = p + 2;
- } else { /* ... or the correct value, for that true endtime */
- lasttime = *p;
- lastval = *(p+1);
- thistime = *(p+2);
- thisval = *(p+3);
- timediff = thistime - lasttime;
- valdiff = thisval - lastval;
- timeratio= (endtime - lasttime)/timediff;
- valstep = valdiff * timeratio;
- thisval = lastval + valstep;
- p += 2;
- *p++ = endtime;
- *p++ = thisval;
- *brkend = p;
- }
- }
- return;
- }
-
- /********************************* ENVREPLACE *************************
- *
- * NEEDED FOR all WARP, except KORRUGATION and TRIGGER
- */
- int envreplace(float *env,float **envend,float *origenv,float *origend)
- {
- float *p, *q;
- double gate = MIN_FRACTION_OF_LEVEL; /* minimum non-zero value of envelope */
- double maxval = 0.0;
- p = origenv;
- q = env;
- if((origend - origenv) < (*envend - env)) {
- while(p<origend) {
- if(*p <= gate) { /* if original envelope touches zero */
- if(*q <=gate || q==env) /* if new envelope touches zero */
- *q = 0.0f; /* OR start_of_file, set to zero */
- else /* else, retain previous value of envelope */
- *q = *(q-1);
- } else
- *q = (float)((*q)/(*p));
- maxval = max(*q,maxval);
- q++;
- p++;
- }
- } else {
- while(q<*envend) {
- if(*p <= gate) { /* if original envelope touches zero */
- if(*q <=gate || q==env) /* if new envelope touches zero */
- *q = 0.0f; /* OR start_of_file, set to zero */
- else /* else, retain previous value of envelope */
- *q = *(q-1);
- } else
- *q = (float)((*q)/(*p));
- maxval = max(*q,maxval);
- q++;
- p++;
- }
- }
- *envend = q;
- if(maxval<=gate) {
- sprintf(errstr,"new envelope is effectively zero.\n");
- return(GOAL_FAILED);
- }
- return(FINISHED);
- }
- /****************************** CONVERT_OTHER_BRKTABLE_TO_ENVTABLE *********************************/
- int convert_other_brktable_to_envtable(double *brk,double *brkend,float **env,float **envend,dataptr dz)
- {
- int n, envlen;
- float *q;
- double here;
- double timestep = dz->outfile->window_size * MS_TO_SECS;
- // double inc = timestep;
- double duration = *(brkend-2);
- if(timestep <= 0.0) {
- sprintf(errstr,"No window_size set: convert_other_brktable_to_envtable()\n");
- return(PROGRAM_ERROR);
- }
- if(timestep < ENV_MIN_WSIZE * MS_TO_SECS) {
- sprintf(errstr,"Invalid window_size: convert_other_brktable_to_envtable()\n");
- return(PROGRAM_ERROR);
- }
- if(duration < timestep) {
- sprintf(errstr,"Brktable duration less than window_size: Cannot proceed.\n");
- return(DATA_ERROR);
- }
- envlen = (int)((duration/timestep) + 1.0); /* round up */
- envlen += MARGIN; /* allow for errors in float-calculation */
- if(brk==NULL) {
- sprintf(errstr,"No existing brkpnt table. convert_brktable_to_envtable()\n");
- return(PROGRAM_ERROR);
- }
- if(*env != NULL)
- free(*env);
- if((*env = (float *)malloc(envlen * sizeof(float)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to create new envelope array.\n");
- return(MEMORY_ERROR);
- }
- q = *env;
- n = 0;
- while(n<envlen) {
- if((here = (double)n * timestep)>(duration+FLTERR))
- break;
- *q = read_a_val_from_brktable(brk,brkend,here);
- q++;
- n++;
- }
- envlen = n;
- if((*env = (float *)realloc(*env,envlen * sizeof(float)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to reallocate new envelope array.\n");
- return(MEMORY_ERROR);
- }
- *envend = *env + envlen;
- return(FINISHED);
- }
- /**************************** READ_A_VAL_FROM_BRKTABLE *****************************/
- float read_a_val_from_brktable(double *brk,double *brkend,double thistime)
- {
- float thisval;
- double *p = brk, val;
- double hival, loval, hiind, loind;
- double firstval = *(brk+1);
- double lastval = *(brkend-1);
- double lasttime = *(brkend-2);
- if(thistime <= 0.0)
- thisval = (float)firstval;
- else if(thistime >= lasttime)
- thisval = (float)lastval;
- else {
- while(*(p)<thistime)
- p += 2;
- hival = *(p+1);
- hiind = *p;
- loval = *(p-1);
- loind = *(p-2);
- val = (thistime - loind)/(hiind - loind);
- val *= (hival - loval);
- val += loval;
- thisval = (float)val;
- }
- return(thisval);
- }
- /**************************** ENLARGE_BRKTABLE *****************************/
- int enlarge_brktable(double **brk,double **brkend, double **q,int *arraysize)
- {
- int offset = *q - *brk;
- *arraysize += BIGARRAY;
- if((*brk = (double *)realloc((*brk),(*arraysize) * sizeof(double)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to enlarge brktable.\n");
- return(MEMORY_ERROR);
- }
- *brkend = *brk + *arraysize;
- *q = *brk + offset;
- return(FINISHED);
- }
- /**************************** ROUND_OFF_BRKTABLE *****************************/
- int round_off_brktable(double *q,double **brk,double **brkend,double envdur)
- {
- int brksize;
- int vals_written = q - *brk;
- double *endadr;
- double *startadr = *brk;
- double *nextadr = *brk + 2;
- double starttime = *startadr, nexttime = *nextadr;
- (brksize = vals_written/2);
- if((brksize = vals_written/2) * 2 != vals_written) {
- sprintf(errstr,"Data pairing anomaly in round_off_brktable()\n");
- return(PROGRAM_ERROR);
- }
- if(brksize > 1) {
- if(flteq(nexttime,starttime)) { /* Junk any redundant initial zero */
- memmove((char *)startadr,(char *)nextadr,(brksize-1)*2*sizeof(double));
- brksize--;
- }
- }
- endadr = *brk + (brksize * 2);
- if(*(endadr - 2) != envdur) { /* IF lasttime != length of envelope */
- if(flteq(*(endadr - 2),envdur)) /* If approx equal, reset to equal */
- *(endadr - 2) = envdur;
- else { /* Else generate an endtime time-val pair */
- brksize++;
- if((*brk=(double *)realloc(*brk,(brksize*2)*sizeof(double)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to reallocate brktable.\n");
- return(MEMORY_ERROR);
- }
- endadr = *brk + (brksize * 2);
- *(endadr-2) = envdur; /* true end time gets */
- *(endadr-1) = 0.0; /* 0 endvalue */
- }
- }
- if((*brk=(double *)realloc(*brk,(brksize*2)*sizeof(double)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to reallocate brktable.\n");
- return(MEMORY_ERROR);
- }
- *brkend = *brk + (brksize * 2);
- return(FINISHED);
- }
- /**************************** CONVERT_TO_ON_TRIGGERS *****************************/
- void convert_to_on_triggers(double now,double timestep,double rise,int *triggered,double **q)
- {
- double *p = *q;
- if(*triggered==FALSE) { /* If not already RISING-triggered */
- if(!flteq(*(p-2),now-timestep)) { /* If previous time-value was not too close to this one */
- *p++ = now - timestep; /* Write pre-time and 0.0 for start of rise */
- *p++ = 0.0;
- }
- *p++ = now; /* Write time and rise-value for end of rise */
- *p++ = rise;
- *triggered = TRUE; /* Flag trigrise */
- } else { /* If already RISING-triggered */
- *(p-4) = now - timestep; /* readjust start-time of existing rise, from current time */
- *(p-2) = now; /* readjust end-time of existing rise, from current time */
- *(p-1) += rise; /* readjust total rise value */
- }
- *q = p;
- }
- /******************************* GEN_REAPPLIED_TRIGGER_ENVELOPE ******************************/
- int gen_reapplied_trigger_envelope(double **brk, double **brkend,dataptr dz)
- {
- int exit_status;
- int n, brklen;
- // double next_trigtime, this_trigtime, nuhere, last_outval = 0.0, trigval;
- double next_trigtime, this_trigtime, nuhere, trigval;
- double *q, *nubrkptr, *nubrk, *nubrkend;
- double *trigptr, *trigbrk, *trigbrkend;
- int arraysize = BIGARRAY;
- trigptr = trigbrk = *brk;
- trigbrkend = *brkend;
- if((nubrk = (double *)malloc(arraysize * sizeof(double)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to create new envelope table.\n");
- return(MEMORY_ERROR);
- }
- nubrkend = nubrk + arraysize;
- nubrkptr = nubrk;
- while(trigptr < trigbrkend) {
- this_trigtime = *trigptr++;
- trigval = *trigptr++;
- if(trigptr < trigbrkend)
- next_trigtime = *trigptr;
- else
- next_trigtime = DBL_MAX;
- if(flteq(trigval,0.0)) { /* if the trigger table value is 0.0 put Zero in new table */
- *nubrkptr++ = this_trigtime;
- *nubrkptr++ = 0.0;
- } else { /* else */
- q = dz->rampbrk; /* start copying values from ramp table into new brkpnt table, */
- n = 0; /* until ramptable ends, OR we reach next brkpnt in trigger table */
- while(n < dz->rampbrksize && (nuhere = this_trigtime + *q++)<next_trigtime) {
- *nubrkptr++ = nuhere;
- *nubrkptr++ = *q++;
- n++;
- }
- }
- if(nubrkptr>=(nubrkend-2)) {
- if((exit_status = enlarge_brktable(&nubrk,&nubrkend,&nubrkptr,&arraysize))<0)
- return(exit_status);
- }
- }
- brkdeglitch(nubrk,&nubrkptr); /* get rid of too fast amp rises or falls */
- brklen = nubrkptr - nubrk;
- free((char *)(*brk));
- if((*brk=(double *)realloc((char *)nubrk,brklen * sizeof(double)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to reallocate new envelope table.\n");
- return(MEMORY_ERROR);
- }
- if((brklen/2) * 2 != brklen) {
- sprintf(errstr,"Anomalous breaktable size in gen_reapplied_trigger_envelope()\n");
- return(PROGRAM_ERROR);
- }
- *brkend = *brk + brklen;
- return(FINISHED);
- }
- /***************************** REALLOC_ENVCREATE_TABLES ****************************/
- int realloc_envcreate_tables(int tabsize,dataptr dz)
- {
- if((dz->parray[ENV_CREATE_TIME] =
- (double *)realloc(dz->parray[ENV_CREATE_TIME],tabsize * sizeof(double)))==NULL
- || (dz->parray[ENV_CREATE_LEVL] =
- (double *)realloc(dz->parray[ENV_CREATE_LEVL],tabsize * sizeof(double)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to reallocate level array.\n");
- return(MEMORY_ERROR);
- }
- return(FINISHED);
- }
- /***************************** CREATE_ENVELOPE ****************************
- *
- * (1) time_quantum has a minimum value, as this function can create a
- * brktable for conversion to an envfile.
- * 1a) Except in the case of ENV_ATTACK, which has very acute risetime!!
- */
- int create_envelope(int *cnt,dataptr dz)
- {
- int exit_status;
- int falling = FALSE;
- int n,m, k, base, newcnt;
- double time_quantum, timestep, levelstep, attenator = 0.0;
- double thisduration, ratio;
- // double atten = 1.0/ATTEN;
- if((dz->parray[ENV_CREATE_TIME] = (double *)malloc(sizeof(double)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to create times array.\n");
- return(MEMORY_ERROR);
- }
- if((dz->parray[ENV_CREATE_LEVL] = (double *)malloc(sizeof(double)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to create levels array.\n");
- return(MEMORY_ERROR);
- }
- dz->parray[ENV_CREATE_TIME][0] = dz->parray[ENV_CREATE_INTIME][0];
- dz->parray[ENV_CREATE_LEVL][0] = dz->parray[ENV_CREATE_INLEVEL][0];
- *cnt = 1;
- for(n=1;n<dz->itemcnt;n++) {
- thisduration = dz->parray[ENV_CREATE_INTIME][n] - dz->parray[ENV_CREATE_INTIME][n-1];
- //TW UPDATE
- if(dz->process == ENV_ATTACK || dz->process == ENV_DOVETAILING || dz->process == ENV_CURTAILING)
- time_quantum = max(thisduration/(double)MINSPAN,2.0/dz->infile->srate); /* 1a */
- else
- time_quantum = max(thisduration/(double)MINSPAN,ENV_MIN_WSIZE * MS_TO_SECS); /* 1 */
- if((levelstep = dz->parray[ENV_CREATE_INLEVEL][n] - dz->parray[ENV_CREATE_INLEVEL][n-1]) <= 0.0)
- falling = TRUE;
- else
- falling = FALSE;
- switch(dz->iparray[ENV_SLOPETYPE][n]) {
- case(ENVTYPE_LIN):
- (*cnt)++;
- if((exit_status = realloc_envcreate_tables(*cnt,dz))<0)
- return(exit_status);
- dz->parray[ENV_CREATE_TIME][*cnt - 1] = dz->parray[ENV_CREATE_INTIME][n];
- dz->parray[ENV_CREATE_LEVL][*cnt - 1] = dz->parray[ENV_CREATE_INLEVEL][n];
- break;
- case(ENVTYPE_STEEP):
- case(ENVTYPE_EXP):
- case(ENVTYPE_DBL):
- switch(dz->iparray[ENV_SLOPETYPE][n]) {
- case(ENVTYPE_STEEP): attenator = STEEP_ATTEN; break;
- case(ENVTYPE_EXP): attenator = ATTENATOR; break;
- case(ENVTYPE_DBL): attenator = ATTENATOR * 2; break;
- }
- base = *cnt;
- newcnt = (int)(thisduration/time_quantum); /* TRUNCATE */
- /* RWD 4:2002 NB: div/zero bug here when newcnt resolves to zero */
- /* should this be flagged as a user error? */
- if(newcnt==0)
- newcnt = 1;
-
- timestep = thisduration/(double)newcnt;
- *cnt += newcnt;
- if((exit_status = realloc_envcreate_tables(*cnt,dz))<0)
- return(exit_status);
- for(m = 1,k = base;k < *cnt;k++,m++) {
- dz->parray[ENV_CREATE_TIME][k] = dz->parray[ENV_CREATE_INTIME][n-1] + (m * timestep);
- if(falling) {
- ratio = 1.0 - ((m * timestep)/thisduration);
- ratio = max(ratio,0.0);
- ratio = pow(ratio,attenator);
- dz->parray[ENV_CREATE_LEVL][k] = fabs(levelstep) * ratio;
- dz->parray[ENV_CREATE_LEVL][k] += dz->parray[ENV_CREATE_INLEVEL][n];
- }
- else {
- ratio = (m * timestep)/thisduration;
- ratio = pow(ratio,attenator);
- ratio = min(ratio,1.0);
- dz->parray[ENV_CREATE_LEVL][k] = fabs(levelstep) * ratio;
- dz->parray[ENV_CREATE_LEVL][k] += dz->parray[ENV_CREATE_INLEVEL][n-1];
- }
- }
- dz->parray[ENV_CREATE_TIME][*cnt-1] = dz->parray[ENV_CREATE_INTIME][n];
- break;
- default:
- sprintf(errstr,"Unknown case in create_envelope()\n");
- return(PROGRAM_ERROR);
- }
- }
- return(FINISHED);
- }
- /******************************** ENVELOPE_TREMOL **********************************/
- int envelope_tremol(dataptr dz)
- {
- int exit_status;
- int m;
- int n, k, st_sampsread, st_samps_processed;
- double thistime, losin, hisin, frac, val;
- double fsinpos = 0.0;
- int sinpos;
- int chans = dz->infile->channels;
- double inverse_srate = 1.0/(double)dz->infile->srate;
- double tabsize_over_srate = (double)ENV_TREM_TABSIZE/(double)dz->infile->srate;
- float *buf = dz->sampbuf[0];
- double *sintab = dz->parray[ENV_SINETAB];
- while(dz->samps_left > 0) {
- st_samps_processed = dz->total_samps_read/chans;
- if((exit_status = read_samps(buf,dz))<0)
- return(exit_status);
- st_sampsread = dz->ssampsread/chans;
- for(n=0; n < st_sampsread; n++) {
- k = n * chans;
- thistime = (double)st_samps_processed * inverse_srate;
- if((exit_status = read_values_from_all_existing_brktables(thistime,dz))<0)
- return(exit_status);
- if(dz->brksize[ENV_TREM_FRQ] && dz->mode==ENV_TREM_LOG)
- dz->param[ENV_TREM_FRQ] = pow(10,dz->param[ENV_TREM_FRQ]);
- sinpos = (int)fsinpos; /* TRUNCATE */
- frac = fsinpos - (double)sinpos;
- losin = sintab[sinpos];
- hisin = sintab[sinpos+1];
- val = losin + ((hisin - losin) * frac); /* interpd (normalised) sintable value */
- val *= dz->param[ENV_TREM_DEPTH]; /* adjusted for tremolo depth */
- val += (1.0 - dz->param[ENV_TREM_DEPTH]); /* subtract from max: tremol superimposed on existing level */
- val *= dz->param[ENV_TREM_AMP]; /* multiply by overall signal gain (<= 1.0) */
- fsinpos += (dz->param[ENV_TREM_FRQ] * tabsize_over_srate); /* advance sintable float-pointer */
- fsinpos = fmod(fsinpos,(double)ENV_TREM_TABSIZE); /* wrap at table-size */
- for(m=0;m<chans;m++)
- buf[k+m] = (float)/*round*/(buf[k+m] * val);
- st_samps_processed++;
- }
- if(dz->ssampsread > 0) {
- if((exit_status = write_samps(buf,dz->ssampsread,dz))<0)
- return(exit_status);
- }
- }
- return(FINISHED);
- }
- /*************************** ENVPEAKCNT *************************/
-
- int envpeakcnt(float *env,float *envend,dataptr dz)
- {
- int exit_status;
- int upwards, peakkcnt = 0;
- double thistime = 0.0;
- float *p, *q;
- double timestep = dz->outfile->window_size * MS_TO_SECS;
- float *shadowenv;
- size_t bytelen = (envend - env) * sizeof(float);
- if((shadowenv = (float *)malloc(bytelen))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY to create shadow envelope array.\n");
- return(MEMORY_ERROR);
- }
- memset((char *)shadowenv,0,(size_t)bytelen);
- p = env+1;
- q = env;
- if (*p > *q)
- upwards = TRUE;
- else
- upwards = FALSE;
- while(p < envend) {
- if((exit_status = read_values_from_all_existing_brktables(thistime,dz))<0)
- return(exit_status);
- if(upwards) {
- if(*p <= *q) {
- if(ispeak(env,envend,q,(int)dz->iparam[ENV_PKSRCHWIDTH]))
- peakkcnt++;
- upwards = FALSE;
- }
- } else {
- if(*p > *q)
- upwards = TRUE;
- }
- thistime += timestep;
- p++;
- q++;
- }
- fprintf(stdout,"INFO: Number of peaks = %d\n",peakkcnt);
- fflush(stdout);
- return(FINISHED);
- }
-
|