envfuncs.c 52 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696
  1. /*
  2. * Copyright (c) 1983-2013 Trevor Wishart and Composers Desktop Project Ltd
  3. * http://www.trevorwishart.co.uk
  4. * http://www.composersdesktop.com
  5. *
  6. This file is part of the CDP System.
  7. The CDP System is free software; you can redistribute it
  8. and/or modify it under the terms of the GNU Lesser General Public
  9. License as published by the Free Software Foundation; either
  10. version 2.1 of the License, or (at your option) any later version.
  11. The CDP System is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. GNU Lesser General Public License for more details.
  15. You should have received a copy of the GNU Lesser General Public
  16. License along with the CDP System; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  18. 02111-1307 USA
  19. *
  20. */
  21. /* floatsam version */
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <math.h>
  25. #include <float.h>
  26. #include <string.h>
  27. #include <structures.h>
  28. #include <tkglobals.h>
  29. #include <globcon.h>
  30. #include <processno.h>
  31. #include <modeno.h>
  32. #include <arrays.h>
  33. #include <envel.h>
  34. #include <cdpmain.h>
  35. #include <sfsys.h>
  36. //#ifdef unix
  37. #define round(x) lround((x))
  38. //#endif
  39. #define MARGIN (16)
  40. #define IS_CLICK (1.0/(3.0 * MS_TO_SECS)) /* from zero to full amplitude in 3ms */
  41. /* anything faster is a 'click'!! */
  42. #define MINSPAN (16) /* spanning points for creating exponential env */
  43. #define ATTEN (3.33333333) /* Attenuation for creating exponential env */
  44. #define ATTENATOR (1.7) /* Attenuation for creating exponential env */
  45. #define STEEP_ATTEN (2.0) /* For ATTACK */
  46. static int realloc_envcreate_tables(int tabsize,dataptr dz);
  47. static int envnorm(float *env,float *envend);
  48. static int envceiling(float *env,float *envend);
  49. static int envduck(float *env,float *envend,dataptr dz);
  50. static int envrevers(float *env,float *envend);
  51. static int envexagg(float *env,float *envend,dataptr dz);
  52. static int envatten(float *env,float *envend,dataptr dz);
  53. static int envlift(float *env,float *envend,dataptr dz);
  54. static int envtstretch(float **env,float **envend,dataptr dz);
  55. static int envflatn(float *env,float *envend,dataptr dz);
  56. static int envgate(float *env,float *envend,dataptr dz);
  57. static int envinvert(float *env,float *envend,dataptr dz);
  58. static int envexpand(float *env,float *envend,dataptr dz);
  59. static int envlimit(float *env,float *envend,dataptr dz);
  60. static int envkorrug(float *env,float *envend,dataptr dz);
  61. static int envpeakcnt(float *env,float *envend,dataptr dz);
  62. static int envtrig(float **env,float **envend,dataptr dz);
  63. static int envshortn(float **env,float **envend,double timestretch);
  64. static int envlenthn(float **env,float **envend,double timestretch);
  65. static float envintpl(double here,double winbase,double base,double next);
  66. static void brkdeglitch(double *,double **);
  67. static int gen_trigger_envelope(double **brk, double **brkend,dataptr dz);
  68. static int gen_reapplied_trigger_envelope(double **brk, double **brkend,dataptr dz);
  69. static int gatefilt(float *p,float *envend,double gate,int smoothing);
  70. static int do_simple_gating(float *env,float *envend,dataptr dz);
  71. static int do_smoothed_gating(float *env,float *envend,int smoothing,dataptr dz);
  72. static void do_env_invert(float *p,double upratio,double dnratio,dataptr dz);
  73. static void do_expanding(float *p,float *envend,int *gating,double squeeze,int smoothing,dataptr dz);
  74. static void digout_trough(float *env,float *envend,float *shadowenv,int del,float *q);
  75. static int ispeak(float *env,float *envend,float *q,int width);
  76. static int istrough(float *env,float *envend,float *q,int width);
  77. static int enlarge_brktable(double **brk,double **brkend, double **q,int *arraysize);
  78. static void convert_to_on_triggers(double now,double timestep,double rise,int *triggered,double **q);
  79. static int round_off_brktable(double *q,double **brk,double **brkend,double envlen);
  80. static int locate_and_size_triggers(float *env,float *envend,double **brk,double **brkend,dataptr dz);
  81. static int convert_other_brktable_to_envtable(double *brk,double *brkend,float **env,float **envend,dataptr dz);
  82. static float read_a_val_from_brktable(double *brk,double *brkend,double thistime);
  83. /*************************** ENVELOPE_WARP ************************/
  84. int envelope_warp(float **env,float **envend,dataptr dz)
  85. {
  86. int exit_status;
  87. if(flteq((double)dz->outfile->window_size,0.0)) {
  88. sprintf(errstr,"dz->outfile->wsize not set: envelope_warp()\n");
  89. return(PROGRAM_ERROR);
  90. }
  91. if(dz->process!=ENV_WARPING && dz->process!=ENV_REPLOTTING && dz->process!=ENV_RESHAPING) {
  92. sprintf(errstr,"this function not valid with this process: envelope_warp()\n");
  93. return(PROGRAM_ERROR);
  94. }
  95. switch(dz->mode) {
  96. case(ENV_NORMALISE): exit_status = envnorm(*env,*envend); break;
  97. case(ENV_REVERSE): exit_status = envrevers(*env,*envend); break;
  98. case(ENV_EXAGGERATING): exit_status = envexagg(*env,*envend,dz); break;
  99. case(ENV_ATTENUATING): exit_status = envatten(*env,*envend,dz); break;
  100. case(ENV_LIFTING): exit_status = envlift(*env,*envend,dz); break;
  101. case(ENV_TSTRETCHING): exit_status = envtstretch(env,envend,dz); break;
  102. case(ENV_FLATTENING): exit_status = envflatn(*env,*envend,dz); break;
  103. case(ENV_GATING): exit_status = envgate(*env,*envend,dz); break;
  104. case(ENV_INVERTING): exit_status = envinvert(*env,*envend,dz); break;
  105. case(ENV_EXPANDING): exit_status = envexpand(*env,*envend,dz); break;
  106. case(ENV_LIMITING): exit_status = envlimit(*env,*envend,dz); break;
  107. case(ENV_CORRUGATING): exit_status = envkorrug(*env,*envend,dz); break;
  108. case(ENV_TRIGGERING): exit_status = envtrig(env,envend,dz); break;
  109. case(ENV_CEILING): exit_status = envceiling(*env,*envend); break;
  110. case(ENV_DUCKED): exit_status = envduck(*env,*envend,dz); break;
  111. case(ENV_PEAKCNT): exit_status = envpeakcnt(*env,*envend,dz); break;
  112. default:
  113. sprintf(errstr,"Unknown case in envelope_warp()\n");
  114. return(PROGRAM_ERROR);
  115. }
  116. return(exit_status);
  117. }
  118. /*************************** ENVNORM ************************/
  119. int envnorm(float *env,float *envend)
  120. {
  121. float *p = env;
  122. double convertor, maxval = 0.0;
  123. while(p < envend) {
  124. maxval = max(*p,maxval);
  125. p++;
  126. }
  127. if(flteq(maxval,0.0)) {
  128. sprintf(errstr,"Envelope level is effectively zero: cannot normalise.\n");
  129. return(DATA_ERROR);
  130. }
  131. p = env;
  132. convertor = 1.0/maxval;
  133. while(p < envend) {
  134. *p = (float)((*p) * convertor);
  135. *p = (float)min(*p,1.0); /* SAFETY */
  136. p++;
  137. }
  138. return(FINISHED);
  139. }
  140. /*************************** ENVCEILING ************************/
  141. int envceiling(float *env,float *envend)
  142. {
  143. float *p = env;
  144. double maxval = 0.0;
  145. while(p < envend) {
  146. maxval = max(*p,maxval);
  147. p++;
  148. }
  149. p = env;
  150. while(p < envend) {
  151. *p = (float)maxval;
  152. p++;
  153. }
  154. return(FINISHED);
  155. }
  156. /*************************** ENVDUCK ************************/
  157. int envduck(float *env,float *envend,dataptr dz)
  158. {
  159. int exit_status;
  160. float *p = env;
  161. double thistime = 0.0;
  162. double timestep = dz->outfile->window_size * MS_TO_SECS;
  163. switch(dz->process) {
  164. case(ENV_WARPING):
  165. while(p < envend) {
  166. if((exit_status = read_values_from_all_existing_brktables(thistime,dz))<0)
  167. return(exit_status);
  168. if(*p > dz->param[ENV_THRESHOLD])
  169. *p = (float)dz->param[ENV_GATE];
  170. thistime += timestep;
  171. p++;
  172. }
  173. break;
  174. case(ENV_RESHAPING):
  175. case(ENV_REPLOTTING):
  176. while(p < envend) {
  177. if((exit_status = read_values_from_all_existing_brktables(thistime,dz))<0)
  178. return(exit_status);
  179. if(*p > dz->param[ENV_THRESHOLD])
  180. *p = (float)dz->param[ENV_GATE];
  181. else
  182. *p = 1.0f;
  183. thistime += timestep;
  184. p++;
  185. }
  186. break;
  187. default:
  188. sprintf(errstr,"Unknown case in envduck()\n");
  189. return(PROGRAM_ERROR);
  190. }
  191. return(FINISHED);
  192. }
  193. /*************************** ENVREVERS ************************/
  194. int envrevers(float *env,float *envend)
  195. {
  196. float *p = env, *q = envend - 1;
  197. float temp;
  198. while(q > p) {
  199. temp = *p;
  200. *p = *q;
  201. *q = temp;
  202. p++;
  203. q--;
  204. }
  205. return(FINISHED);
  206. }
  207. /*************************** ENVEXAGG ************************/
  208. int envexagg(float *env,float *envend,dataptr dz)
  209. {
  210. int exit_status;
  211. float *p = env;
  212. double thistime = 0.0;
  213. double timestep = dz->outfile->window_size * MS_TO_SECS;
  214. if(dz->brk[ENV_EXAG]) {
  215. while(p<envend) {
  216. if((exit_status = read_value_from_brktable(thistime,ENV_EXAG,dz))<0)
  217. return(exit_status);
  218. *p = (float)pow((double)*p,dz->param[ENV_EXAG]);
  219. p++;
  220. thistime += timestep;
  221. }
  222. } else {
  223. while(p<envend) {
  224. *p = (float)pow((double)*p,dz->param[ENV_EXAG]);
  225. p++;
  226. }
  227. }
  228. return(FINISHED);
  229. }
  230. /*************************** ENVATTEN *************************/
  231. int envatten(float *env,float *envend,dataptr dz)
  232. {
  233. int exit_status;
  234. float *p = env;
  235. double thistime = 0.0;
  236. double timestep = dz->outfile->window_size * MS_TO_SECS;
  237. if(dz->brk[ENV_ATTEN]) {
  238. while(p<envend) {
  239. if((exit_status = read_value_from_brktable(thistime,ENV_ATTEN,dz))<0)
  240. return(exit_status);
  241. *p = (float)(*p * dz->param[ENV_ATTEN]);
  242. p++;
  243. thistime += timestep;
  244. }
  245. } else {
  246. while(p<envend) {
  247. *p = (float)(*p * dz->param[ENV_ATTEN]);
  248. p++;
  249. }
  250. }
  251. return(FINISHED);
  252. }
  253. /*************************** ENVLIFT ************************/
  254. int envlift(float *env,float *envend,dataptr dz)
  255. {
  256. int exit_status;
  257. float *p = env;
  258. int saturated = 0;
  259. double thistime = 0.0;
  260. double timestep = dz->outfile->window_size * MS_TO_SECS;
  261. if(dz->brk[ENV_ATTEN]) {
  262. while(p<envend) {
  263. if((exit_status = read_value_from_brktable(thistime,ENV_LIFT,dz))<0)
  264. return(exit_status);
  265. if((*p = (float)(*p + dz->param[ENV_LIFT]))> 1.0) {
  266. *p = 1.0f;
  267. saturated++;
  268. }
  269. p++;
  270. thistime += timestep;
  271. }
  272. } else {
  273. while(p<envend) {
  274. if((*p = (float)(*p + dz->param[ENV_LIFT]))> 1.0) {
  275. *p = 1.0f;
  276. saturated++;
  277. }
  278. p++;
  279. }
  280. }
  281. if(saturated) {
  282. fprintf(stdout,"WARNING: Envelope was clipped, but will not distort sounds.\n");
  283. fflush(stdout);
  284. }
  285. return(FINISHED);
  286. }
  287. /**************************** ENVTSTRETCH **************************/
  288. int envtstretch(float **env,float **envend,dataptr dz)
  289. {
  290. int exit_status;
  291. double timestretch = dz->param[ENV_TSTRETCH];
  292. if(dz->brksize[ENV_TSTRETCH]) {
  293. sprintf(errstr,"Invalid use of brktable: envtstretch()\n");
  294. return(PROGRAM_ERROR);
  295. }
  296. if(timestretch>1.0) {
  297. if((exit_status = envlenthn(env,envend,timestretch))<0)
  298. return(exit_status);
  299. }
  300. if(timestretch<1.0) {
  301. if((exit_status = envshortn(env,envend,timestretch))<0)
  302. return(exit_status);
  303. }
  304. return(FINISHED);
  305. }
  306. /**************************** ENVSHORTN **************************/
  307. int envshortn(float **env,float **envend,double timestretch)
  308. {
  309. int oldenvlen, newenvlen;
  310. int n, m = 0;
  311. float *nuenv, *p;
  312. double here, skip, base, winbase, next;
  313. skip = 1.0/timestretch;
  314. oldenvlen = *envend - *env;
  315. newenvlen = (int)(((double)oldenvlen * timestretch) + 1.0); /* rescale & round up */
  316. newenvlen += MARGIN;
  317. if((nuenv = (float *)malloc(newenvlen*sizeof(float)))==NULL) {
  318. sprintf(errstr,"INSUFFICIENT MEMORY to create new envelope array.\n");
  319. return(MEMORY_ERROR);
  320. }
  321. p = nuenv;
  322. *p++ = **env;
  323. for(;;) {
  324. if(++m > newenvlen) {
  325. sprintf(errstr,"New envelope array bound exceeded in envshortn()\n");
  326. return(PROGRAM_ERROR);
  327. }
  328. here = skip * (double)(m);
  329. if(here>=(double)(oldenvlen-1)) {
  330. *p = *(p-1);
  331. newenvlen = p - nuenv;
  332. free(*env);
  333. if((*env = (float *)realloc(nuenv,newenvlen*sizeof(float)))==NULL) {
  334. sprintf(errstr,"envshortn(): 2\n");
  335. return(MEMORY_ERROR);
  336. }
  337. *envend = *env + newenvlen;
  338. break;
  339. }
  340. winbase = floor(here);
  341. n = round(winbase);
  342. base = (double)*((*env) + n);
  343. if(n > oldenvlen-1)
  344. next = base;
  345. else
  346. next = (double)*((*env) + n + 1);
  347. *p++ = envintpl(here,winbase,base,next);
  348. }
  349. return(FINISHED);
  350. }
  351. /**************************** ENVLENTHN ***************************/
  352. int envlenthn(float **env,float **envend,double timestretch)
  353. {
  354. int oldenvlen, newenvlen;
  355. int n = 0, m = 0;
  356. double here = 0.0, skip;
  357. float *nuenv, *p;
  358. double base, winbase, next;
  359. skip = 1.0/timestretch;
  360. oldenvlen = *envend - *env;
  361. newenvlen = (int)(((double)oldenvlen * timestretch) + 1.0);
  362. newenvlen += MARGIN;
  363. if((nuenv = (float *)malloc(newenvlen * sizeof(float)))==NULL) {
  364. sprintf(errstr,"INSUFFICIENT MEMORY to create new envelope array.\n");
  365. return(MEMORY_ERROR);
  366. }
  367. p = nuenv;
  368. next = (double)**env;
  369. for(;;) {
  370. base = next;
  371. winbase = (double)n;
  372. if(++n > oldenvlen-1) {
  373. if(!m) {
  374. sprintf(errstr,"Anomaly in envlenthn()\n");
  375. return(PROGRAM_ERROR);
  376. }
  377. newenvlen = p - nuenv;
  378. free(*env);
  379. if((*env = (float *)realloc(nuenv,newenvlen*sizeof(float)))==NULL) {
  380. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate new envelope array.\n");
  381. return(MEMORY_ERROR);
  382. }
  383. *envend = *env + newenvlen;
  384. break;
  385. }
  386. next = (double)*((*env) + n);
  387. while(here <= (double)n) {
  388. *p++ = envintpl(here,winbase,base,next);
  389. here = skip * (double)(++m);
  390. if(m >= newenvlen) {
  391. sprintf(errstr,"envlenthn(): New array bounds exceeded\n");
  392. return(PROGRAM_ERROR);
  393. }
  394. }
  395. }
  396. return(FINISHED);
  397. }
  398. /*************************** ENVINTPL ****************************/
  399. float envintpl(double here,double winbase,double base,double next)
  400. {
  401. double tratio = here - winbase;
  402. double valdif = next - base;
  403. double val = base + (tratio * valdif);
  404. return((float)val);
  405. }
  406. /*************************** ENVFLATN *************************/
  407. int envflatn(float *env, float *envend, dataptr dz)
  408. {
  409. int exit_status;
  410. float *p, *q, *z, *nuenv;
  411. int envlen = envend - env, ppos, qpos;
  412. int backovflow, fowdovflow, thisback, n;
  413. double thistime = 0.0;
  414. double d, sum;
  415. double timestep = dz->outfile->window_size * MS_TO_SECS;
  416. int maxflatn;
  417. if(dz->brksize[ENV_FLATN]) {
  418. if((exit_status = get_maxvalue_in_brktable(&d,ENV_FLATN,dz))<0)
  419. return(exit_status);
  420. maxflatn = round(d);
  421. } else
  422. maxflatn = dz->iparam[ENV_FLATN];
  423. if(maxflatn >= envlen) {
  424. sprintf(errstr,"Flattening param too large for infile.\n");
  425. return(DATA_ERROR);
  426. }
  427. if((nuenv=(float *)malloc((envlen + maxflatn)*sizeof(float)))==NULL) {
  428. sprintf(errstr,"INSUFFICIENT MEMORY to create new envelope array.\n");
  429. return(MEMORY_ERROR);
  430. }
  431. backovflow = maxflatn/2;
  432. fowdovflow = maxflatn - backovflow - 1;
  433. p = env;
  434. q = nuenv;
  435. for(n=0;n<backovflow;n++)
  436. *q++ = *p;
  437. while(p < envend)
  438. *q++ = *p++;
  439. p--;
  440. for(n=0;n<fowdovflow;n++)
  441. *q++ = *p;
  442. p = env;
  443. q = nuenv;
  444. if(dz->brksize[ENV_FLATN]) {
  445. while(p < envend) {
  446. if((exit_status = read_value_from_brktable(thistime,ENV_EXAG,dz))<0)
  447. return(exit_status);
  448. thisback = dz->iparam[ENV_FLATN]/2;
  449. ppos = p - env;
  450. qpos = ppos + backovflow - thisback;
  451. z = nuenv + qpos;
  452. sum = 0.0;
  453. for(n=0;n<dz->iparam[ENV_FLATN];n++)
  454. sum += *z++;
  455. sum /= (double)dz->iparam[ENV_FLATN];
  456. *p++ = (float)sum;
  457. thistime += timestep;
  458. }
  459. } else {
  460. while(p < envend) {
  461. z = q++;
  462. sum = 0.0;
  463. for(n=0;n<dz->iparam[ENV_FLATN];n++)
  464. sum += *z++;
  465. sum /= (double)dz->iparam[ENV_FLATN];
  466. *p++ = (float)sum;
  467. }
  468. }
  469. free(nuenv);
  470. return(FINISHED);
  471. }
  472. /********************************* ENVGATE ****************************/
  473. int envgate(float *env,float *envend,dataptr dz)
  474. {
  475. int exit_status;
  476. int smoothing = dz->iparam[ENV_SMOOTH];
  477. if(smoothing==0)
  478. exit_status = do_simple_gating(env,envend,dz);
  479. else
  480. exit_status = do_smoothed_gating(env,envend,smoothing,dz);
  481. return(exit_status);
  482. }
  483. /********************************* DO_SIMPLE_GATING ****************************/
  484. int do_simple_gating(float *env,float *envend,dataptr dz)
  485. {
  486. int exit_status;
  487. double thistime = 0.0;
  488. float *p = env;
  489. double timestep = dz->outfile->window_size * MS_TO_SECS;
  490. if(dz->brksize[ENV_GATE]) {
  491. while(p<envend) {
  492. if((exit_status = read_value_from_brktable(thistime,ENV_GATE,dz))<0)
  493. return(exit_status);
  494. if(*p < dz->param[ENV_GATE])
  495. *p = 0.0f;
  496. p++;
  497. thistime += timestep;
  498. }
  499. } else {
  500. while(p<envend) {
  501. if(*p < dz->param[ENV_GATE])
  502. *p = 0.0f;
  503. p++;
  504. }
  505. }
  506. return(FINISHED);
  507. }
  508. /********************************* DO_SMOOTHED_GATING ****************************/
  509. int do_smoothed_gating(float *env,float *envend,int smoothing,dataptr dz)
  510. {
  511. int exit_status;
  512. double thistime = 0.0;
  513. int gating = TRUE;
  514. float *p = env;
  515. double timestep = dz->outfile->window_size * MS_TO_SECS;
  516. if(dz->brksize[ENV_GATE]) {
  517. while(p<envend) {
  518. if((exit_status = read_value_from_brktable(thistime,ENV_GATE,dz))<0)
  519. return(exit_status);
  520. if((*p >= dz->param[ENV_GATE]) /* 1 */
  521. && (!gating || (gating && !gatefilt(p,envend,dz->param[ENV_GATE],smoothing)))) {
  522. gating = FALSE;
  523. } else {
  524. *p = 0.0f; /* 2 */
  525. gating = TRUE;
  526. }
  527. p++;
  528. thistime += timestep;
  529. }
  530. } else {
  531. while(p<envend) {
  532. if((*p >= dz->param[ENV_GATE]) /* 1 */
  533. && (!gating || (gating && !gatefilt(p,envend,dz->param[ENV_GATE],smoothing)))) {
  534. gating = FALSE;
  535. } else {
  536. *p = 0.0f; /* 2 */
  537. gating = TRUE;
  538. }
  539. p++;
  540. }
  541. }
  542. return(FINISHED);
  543. }
  544. /****************************** GATEFILT *************************/
  545. int gatefilt(float *p,float *envend,double gate,int smoothing)
  546. {
  547. int this_smoothfactor, windows_remain;
  548. int n;
  549. double average = 0.0;
  550. float *q;
  551. if((windows_remain = envend - p) >= smoothing)
  552. this_smoothfactor = smoothing;
  553. else
  554. this_smoothfactor = windows_remain;
  555. q = p;
  556. for(n=0;n<this_smoothfactor;n++)
  557. average += *q++;
  558. average /= (double)this_smoothfactor;
  559. if(average<=gate)
  560. return(TRUE);
  561. return(FALSE);
  562. }
  563. /*************************** ENVINVERT *************************/
  564. int envinvert(float *env,float *envend,dataptr dz)
  565. {
  566. #define NO_BRK (0)
  567. #define G_BRK (1)
  568. #define M_BRK (2)
  569. #define G_AND_M_BRK (3)
  570. int exit_status;
  571. float *p;
  572. double hirange = 0.0, lorange = 0.0, upratio = 0.0, dnratio = 0.0;
  573. double thistime = 0.0;
  574. int thistype;
  575. double timestep = dz->outfile->window_size * MS_TO_SECS;
  576. if(dz->brksize[ENV_GATE]) {
  577. if(dz->brksize[ENV_MIRROR])
  578. thistype = G_AND_M_BRK;
  579. else {
  580. thistype = G_BRK;
  581. hirange = 1.0 - dz->param[ENV_MIRROR];
  582. }
  583. } else {
  584. if(dz->brksize[ENV_MIRROR])
  585. thistype = M_BRK;
  586. else {
  587. thistype = NO_BRK;
  588. hirange = 1.0 - dz->param[ENV_MIRROR];
  589. lorange = dz->param[ENV_MIRROR] - dz->param[ENV_GATE];
  590. upratio = hirange/lorange;
  591. dnratio = lorange/hirange;
  592. }
  593. }
  594. p = env;
  595. if(thistype == NO_BRK) {
  596. while(p<envend) {
  597. do_env_invert(p,upratio,dnratio,dz);
  598. p++;
  599. }
  600. } else {
  601. while(p<envend) {
  602. switch(thistype) {
  603. case(G_BRK):
  604. if((exit_status = read_value_from_brktable(thistime,ENV_GATE,dz))<0)
  605. return(exit_status);
  606. lorange = dz->param[ENV_MIRROR] - dz->param[ENV_GATE];
  607. break;
  608. case(M_BRK):
  609. if((exit_status = read_value_from_brktable(thistime,ENV_MIRROR,dz))<0)
  610. return(exit_status);
  611. hirange = 1.0 - dz->param[ENV_MIRROR];
  612. lorange = dz->param[ENV_MIRROR] - dz->param[ENV_GATE];
  613. break;
  614. case(G_AND_M_BRK):
  615. if((exit_status = read_value_from_brktable(thistime,ENV_GATE,dz))<0)
  616. return(exit_status);
  617. if((exit_status = read_value_from_brktable(thistime,ENV_MIRROR,dz))<0)
  618. return(exit_status);
  619. hirange = 1.0 - dz->param[ENV_MIRROR];
  620. lorange = dz->param[ENV_MIRROR] - dz->param[ENV_GATE];
  621. break;
  622. }
  623. upratio = hirange/lorange;
  624. dnratio = lorange/hirange;
  625. do_env_invert(p,upratio,dnratio,dz);
  626. thistime += timestep;
  627. p++;
  628. }
  629. }
  630. return(FINISHED);
  631. }
  632. /*************************** DO_ENV_INVERT *************************/
  633. void do_env_invert(float *p,double upratio,double dnratio,dataptr dz)
  634. {
  635. if(*p<dz->param[ENV_GATE]) {
  636. *p = 0.0f;
  637. } else {
  638. if(*p<=dz->param[ENV_THRESHOLD])
  639. *p = (float)(((dz->param[ENV_THRESHOLD] - *p) * upratio) + dz->param[ENV_THRESHOLD]);
  640. else
  641. *p = (float)(dz->param[ENV_THRESHOLD] - ((*p - dz->param[ENV_THRESHOLD]) * dnratio));
  642. }
  643. }
  644. /**************************** ENVFEXPAND ******************************/
  645. int envexpand(float *env,float *envend,dataptr dz)
  646. {
  647. #define NO_BRK (0)
  648. #define G_BRK (1)
  649. #define T_BRK (2)
  650. #define G_AND_T_BRK (3)
  651. int exit_status;
  652. float *p;
  653. double toprange = 0.0, newrange = 0.0, squeeze = 0.0;
  654. double thistime = 0.0;
  655. int gating = TRUE;
  656. int smoothing = dz->iparam[ENV_SMOOTH];
  657. int thistype;
  658. double timestep = dz->outfile->window_size * MS_TO_SECS;
  659. if(dz->brksize[ENV_GATE]) {
  660. if(dz->brksize[ENV_THRESHOLD])
  661. thistype = G_AND_T_BRK;
  662. else {
  663. thistype = G_BRK;
  664. newrange = 1.0 - dz->param[ENV_THRESHOLD];
  665. }
  666. } else {
  667. toprange = 1.0 - dz->param[ENV_GATE];
  668. if(dz->brksize[ENV_THRESHOLD])
  669. thistype = T_BRK;
  670. else {
  671. thistype = NO_BRK;
  672. newrange = 1.0 - dz->param[ENV_THRESHOLD];
  673. squeeze = newrange/toprange;
  674. }
  675. }
  676. p = env;
  677. if(thistype == NO_BRK) {
  678. while(p<envend) {
  679. do_expanding(p,envend,&gating,squeeze,smoothing,dz);
  680. p++;
  681. }
  682. } else {
  683. while(p<envend) {
  684. switch(thistype) {
  685. case(G_AND_T_BRK):
  686. if((exit_status = read_value_from_brktable(thistime,ENV_GATE,dz))<0)
  687. return(exit_status);
  688. toprange = 1.0 - dz->param[ENV_GATE];
  689. /* fall thro */
  690. case(T_BRK):
  691. if((exit_status = read_value_from_brktable(thistime,ENV_THRESHOLD,dz))<0)
  692. return(exit_status);
  693. newrange = 1.0 - dz->param[ENV_THRESHOLD];
  694. break;
  695. case(G_BRK):
  696. if((exit_status = read_value_from_brktable(thistime,ENV_GATE,dz))<0)
  697. return(exit_status);
  698. toprange = 1.0 - dz->param[ENV_GATE];
  699. break;
  700. }
  701. squeeze = newrange/toprange;
  702. do_expanding(p,envend,&gating,squeeze,smoothing,dz);
  703. thistime += timestep;
  704. p++;
  705. }
  706. }
  707. return(FINISHED);
  708. }
  709. /**************************** DO_EXPANDING ****************************/
  710. void do_expanding(float *p,float *envend,int *gating,double squeeze,int smoothing,dataptr dz)
  711. {
  712. if(smoothing) {
  713. if((*p > dz->param[ENV_GATE])
  714. && (*gating==FALSE || ((*gating==TRUE) && !gatefilt(p,envend,dz->param[ENV_GATE],smoothing)))) {
  715. *p = (float)(1.0 - ((1.0 - *p) * squeeze));
  716. *gating = FALSE;
  717. } else {
  718. *p = 0.0f;
  719. *gating = TRUE;
  720. }
  721. } else {
  722. if(*p > dz->param[ENV_GATE])
  723. *p = (float)(1.0 - ((1.0 - *p) * squeeze));
  724. else
  725. *p = 0.0f;
  726. }
  727. }
  728. /**************************** ENVLIMIT ******************************/
  729. int envlimit(float *env,float *envend,dataptr dz)
  730. {
  731. #define NO_BRK (0)
  732. #define TH_BRK (1)
  733. #define L_BRK (2)
  734. #define T_AND_L_BRK (3)
  735. int exit_status;
  736. float *p;
  737. double x, toprange = 0.0, newrange, squeeze = 0.0;
  738. double thistime = 0.0;
  739. int thistype;
  740. double timestep = dz->outfile->window_size * MS_TO_SECS;
  741. if(dz->brksize[ENV_THRESHOLD]) {
  742. if(dz->brksize[ENV_LIMIT])
  743. thistype = T_AND_L_BRK;
  744. else
  745. thistype = TH_BRK;
  746. } else {
  747. toprange = 1.0 - dz->param[ENV_THRESHOLD];
  748. if(dz->brksize[ENV_LIMIT])
  749. thistype = L_BRK;
  750. else {
  751. thistype = NO_BRK;
  752. newrange = dz->param[ENV_LIMIT] - dz->param[ENV_THRESHOLD];
  753. squeeze = newrange/toprange;
  754. }
  755. }
  756. p = env;
  757. if(thistype == NO_BRK) {
  758. while(p<envend) {
  759. if(*p > dz->param[ENV_THRESHOLD]) {
  760. x = (*p - dz->param[ENV_THRESHOLD]) * squeeze;
  761. *p = (float)(dz->param[ENV_THRESHOLD] + x);
  762. }
  763. p++;
  764. }
  765. } else {
  766. while(p<envend) {
  767. switch(thistype) {
  768. case(L_BRK):
  769. if((exit_status = read_value_from_brktable(thistime,ENV_LIMIT,dz))<0)
  770. return(exit_status);
  771. newrange = dz->param[ENV_LIMIT] - dz->param[ENV_THRESHOLD];
  772. squeeze = newrange/toprange;
  773. break;
  774. case(T_AND_L_BRK):
  775. if((exit_status = read_value_from_brktable(thistime,ENV_LIMIT,dz))<0)
  776. return(exit_status);
  777. /* fall thro */
  778. case(TH_BRK):
  779. if((exit_status = read_value_from_brktable(thistime,ENV_THRESHOLD,dz))<0)
  780. return(exit_status);
  781. toprange = 1.0 - dz->param[ENV_THRESHOLD];
  782. newrange = dz->param[ENV_LIMIT] - dz->param[ENV_THRESHOLD];
  783. squeeze = newrange/toprange;
  784. break;
  785. }
  786. if(*p > dz->param[ENV_THRESHOLD]) {
  787. x = (*p - dz->param[ENV_THRESHOLD]) * squeeze;
  788. *p = (float)(dz->param[ENV_THRESHOLD] + x);
  789. }
  790. thistime += timestep;
  791. p++;
  792. }
  793. }
  794. return(FINISHED);
  795. }
  796. /*************************** ENVKORRUG *************************/
  797. int envkorrug(float *env,float *envend,dataptr dz)
  798. {
  799. int exit_status;
  800. int upwards;
  801. double thistime = 0.0;
  802. float *p, *q;
  803. double timestep = dz->outfile->window_size * MS_TO_SECS;
  804. float *shadowenv;
  805. size_t bytelen = (envend - env) * sizeof(float);
  806. if((shadowenv = (float *)malloc(bytelen))==NULL) {
  807. sprintf(errstr,"INSUFFICIENT MEMORY to create shadow envelope array.\n");
  808. return(MEMORY_ERROR);
  809. }
  810. memset((char *)shadowenv,0,(size_t)bytelen);
  811. p = env+1;
  812. q = env;
  813. if (*p > *q)
  814. upwards = TRUE;
  815. else
  816. upwards = FALSE;
  817. while(p < envend) {
  818. if((exit_status = read_values_from_all_existing_brktables(thistime,dz))<0)
  819. return(exit_status);
  820. if(upwards) {
  821. if(*p <= *q) {
  822. if(ispeak(env,envend,q,(int)dz->iparam[ENV_PKSRCHWIDTH]))
  823. *(shadowenv + (q - env)) = 1.0f;
  824. upwards = FALSE;
  825. }
  826. } else {
  827. if(*p > *q)
  828. upwards = TRUE;
  829. }
  830. thistime += timestep;
  831. p++;
  832. q++;
  833. }
  834. thistime = 0.0;
  835. p = env+1;
  836. q = env;
  837. while(p < envend) {
  838. if((exit_status = read_values_from_all_existing_brktables(thistime,dz))<0)
  839. return(exit_status);
  840. if(upwards) {
  841. if(*p <= *q) {
  842. upwards = FALSE;
  843. }
  844. } else {
  845. if(*p > *q) {
  846. if(istrough(env,envend,q,(int)dz->iparam[ENV_PKSRCHWIDTH]))
  847. digout_trough(env,envend,shadowenv,(int)dz->iparam[ENV_TROFDEL],q);
  848. upwards = TRUE;
  849. }
  850. }
  851. thistime += timestep;
  852. p++;
  853. q++;
  854. }
  855. if(dz->process==ENV_WARPING) {
  856. p = env;
  857. while(p < envend) {
  858. if(*p>0.0)
  859. *p = 1.0f; /* NB: NB: Therefore don't use REPLACE with corrugation, when WARPING !! */
  860. p++;
  861. }
  862. }
  863. free(shadowenv);
  864. return(FINISHED);
  865. }
  866. /*************************** ISTROUGH **********************************/
  867. int istrough(float *env,float *envend,float *q,int width)
  868. {
  869. int up, down;
  870. float *upq, *downq, *r;
  871. if(width<2)
  872. return(1);
  873. down = up = width/2;
  874. if(EVEN(width))
  875. down = up - 1; /* set search p[arams above and below q */
  876. downq = q - down;
  877. upq = q + up;
  878. upq = min(envend-1,upq); /* allow for ends of envelope table */
  879. downq = max(env,downq);
  880. for(r = downq; r<=upq; r++) {
  881. if(*q > *r)
  882. return(FALSE);
  883. }
  884. return(TRUE); /* if r is minimum of all in trough, return 1 */
  885. }
  886. /*************************** ISPEAK **********************************/
  887. int ispeak(float *env,float *envend,float *q,int width)
  888. {
  889. int up, down;
  890. float *upq, *downq, *r;
  891. if(width<2)
  892. return(TRUE);
  893. down = up = width/2;
  894. if(EVEN(width))
  895. down = up - 1; /* set search params above and below q */
  896. downq = q - down;
  897. upq = q + up;
  898. upq = min(envend-1,upq); /* allow for ends of envelope table */
  899. downq = max(env,downq);
  900. for(r = downq; r<=upq; r++) {
  901. if(*q < *r)
  902. return(FALSE);
  903. }
  904. return(TRUE); /* if r is maximum of all in peak, return 1 */
  905. }
  906. /***************************** DIGOUT_TROUGH *********************************/
  907. void digout_trough(float *env,float *envend,float *shadowenv,int del,float *q)
  908. {
  909. float *r, *upq, *downq;
  910. int down, up, herepos, lopos, hipos, thispos;
  911. if(del<2) {
  912. *q = 0.0f; /* set single-sector trough to 0.0 */
  913. return;
  914. }
  915. down = up = del/2;
  916. if(EVEN(del))
  917. down = up - 1; /* set trof_delete limits above and below q */
  918. downq = q - down;
  919. upq = q + up;
  920. upq = min(envend-1,upq); /* allow for ends of envelope table */
  921. downq = max(env,downq);
  922. herepos = q-env;
  923. lopos = downq - env; /* find relative positions in env-table */
  924. hipos = upq - env;
  925. /* search downwards for peaks set in shadow table */
  926. for(r = shadowenv + herepos; r>= shadowenv + lopos; r--) {
  927. if(*r>FLTERR) {
  928. thispos = (r+1) - shadowenv;
  929. downq = env + thispos;/* & adjust downward delete-limit accordingly */
  930. break; /* to avoid deleting peaks */
  931. }
  932. } /* search upwards for peaks set in shadow table */
  933. for(r = shadowenv + herepos; r<=shadowenv + hipos; r++) {
  934. if(*r>FLTERR) {
  935. thispos = (r-1) - shadowenv;
  936. upq = env + thispos; /* and adjust upward delete-limit accordingly */
  937. break; /* to avoid deleting peaks */
  938. }
  939. }
  940. for(r = downq; r<=upq; r++) /* delete the defined trough */
  941. *r = 0.0f;
  942. }
  943. /**************************** ENVTRIG *********************************/
  944. int envtrig(float **env,float **envend,dataptr dz) /* NOTE THIS USES POINTERS TO env AND envend */
  945. {
  946. int exit_status;
  947. double *brk, *brkend;
  948. if((exit_status = locate_and_size_triggers(*env,*envend,&brk,&brkend,dz))<0)
  949. return(exit_status);
  950. switch(dz->process) {
  951. case(ENV_REPLOTTING):
  952. case(ENV_RESHAPING):
  953. exit_status = gen_trigger_envelope(&brk,&brkend,dz);
  954. break;
  955. case(ENV_WARPING):
  956. exit_status = gen_reapplied_trigger_envelope(&brk,&brkend,dz);
  957. break;
  958. }
  959. if(exit_status < 0)
  960. return(exit_status);
  961. return convert_other_brktable_to_envtable(brk,brkend,env,envend,dz);
  962. }
  963. /**************************** LOCATE_AND_SIZE_TRIGGERS *******************************/
  964. int locate_and_size_triggers(float *env,float *envend,double **brk,double **brkend,dataptr dz)
  965. {
  966. int exit_status;
  967. float *p = env, *end;
  968. double *q, rise, mean, now;
  969. double timestep = dz->outfile->window_size * MS_TO_SECS;
  970. double envdur;
  971. int n, scan, arraysize = BIGARRAY;
  972. int triggered = FALSE, k;
  973. double maxrise, thistime = 0.0;
  974. int look_ahead = 4;
  975. if((*brk = (double *)malloc(arraysize * sizeof(double)))==NULL) {
  976. sprintf(errstr,"INSUFFICIENT MEMORY to create trigger brktable.\n");
  977. return(MEMORY_ERROR);
  978. }
  979. q = *brk;
  980. *brkend = *brk + arraysize;
  981. if((scan = (int)(dz->param[ENV_TRIGDUR]/timestep))<=0) {
  982. sprintf(errstr,"scansize too small for envelope windows.\n");
  983. return(GOAL_FAILED);
  984. }
  985. end = envend - scan - 1;
  986. *q++ = 0.0;
  987. *q++ = 0.0; /*Store an initial brkpnt value of zero */
  988. n = scan;
  989. while(p<end) {
  990. if((exit_status = read_values_from_all_existing_brktables(thistime,dz))<0)
  991. return(exit_status);
  992. maxrise = -DBL_MAX;
  993. for(k=1;k<=scan;k++) {
  994. rise = *(p+k) - *p; /* deduce max and min rise[fall] of envelope across scantime */
  995. maxrise = max(rise,maxrise);
  996. }
  997. rise = maxrise;
  998. mean = *p + (rise/2.0); /* calc mean level of rising portion */
  999. if(mean>dz->param[ENV_GATE] /* deduce mean rate of rise[fall] and compare with triggering rate */
  1000. && fabs(rise)>=dz->param[ENV_TRIGRISE]) {/* if triggering criteria met */
  1001. if(q+look_ahead >= *brkend) {
  1002. if((exit_status = enlarge_brktable(brk,brkend,&q,&arraysize))<0)
  1003. return(exit_status);
  1004. }
  1005. now = n * timestep;
  1006. convert_to_on_triggers(now,timestep,rise,&triggered,&q);
  1007. p += scan;
  1008. n += scan;
  1009. thistime += timestep * scan;
  1010. } else {
  1011. triggered = FALSE;
  1012. p++;
  1013. n++;
  1014. thistime += timestep;
  1015. }
  1016. }
  1017. envdur = (envend - env) * timestep; /* if end of new brktable not at orig end of envel.. extend */
  1018. if((exit_status = round_off_brktable(q,brk,brkend,envdur))<0)
  1019. return(exit_status);
  1020. return(FINISHED);
  1021. }
  1022. /******************************* GEN_TRIGGER_ENVELOPE ******************************/
  1023. int gen_trigger_envelope(double **brk, double **brkend,dataptr dz)
  1024. {
  1025. int exit_status;
  1026. int n, brklen;
  1027. double next_trigtime, this_trigtime, nuhere, last_outval = 0.0, trigval;
  1028. double *q, *nubrkptr, *nubrk, *nubrkend;
  1029. double *trigptr, *trigbrk, *trigbrkend;
  1030. int arraysize = BIGARRAY;
  1031. trigptr = trigbrk = *brk;
  1032. trigbrkend = *brkend;
  1033. if((nubrk = (double *)malloc(arraysize * sizeof(double)))==NULL) {
  1034. sprintf(errstr,"INSUFFICIENT MEMORY to create new envelope array.\n");
  1035. return(MEMORY_ERROR);
  1036. }
  1037. nubrkend = nubrk + arraysize;
  1038. nubrkptr = nubrk;
  1039. while(trigptr < trigbrkend) {
  1040. this_trigtime = *trigptr++;
  1041. trigval = *trigptr++;
  1042. if(trigptr < trigbrkend)
  1043. next_trigtime = *trigptr;
  1044. else
  1045. next_trigtime = DBL_MAX;
  1046. if(flteq(trigval,0.0)) { /* if the trigger table value is 0.0 put Zero in new table */
  1047. *nubrkptr++ = this_trigtime;
  1048. *nubrkptr++ = 0.0;
  1049. } else { /* else */
  1050. if(trigval < last_outval) /* If the new trigger value is less than current value held, */
  1051. trigval = last_outval; /* set trig val to held value, (else, keep the new value). */
  1052. q = dz->rampbrk; /* start copying values from ramp table into new brkpnt table, */
  1053. n = 0; /* until ramptable ends, OR we reach next brkpnt in trigger table */
  1054. while(n < dz->rampbrksize && (nuhere = this_trigtime + *q++)<next_trigtime) {
  1055. *nubrkptr++ = nuhere;
  1056. last_outval = trigval * (*q++); /* Each rampval is scaled by size of current trigger */
  1057. *nubrkptr++ = last_outval;
  1058. n++;
  1059. }
  1060. }
  1061. if(nubrkptr>=(nubrkend-2)) {
  1062. if((exit_status = enlarge_brktable(&nubrk,&nubrkend,&nubrkptr,&arraysize))<0)
  1063. return(exit_status);
  1064. }
  1065. }
  1066. brkdeglitch(nubrk,&nubrkptr); /* get rid of too fast amp rises or falls */
  1067. brklen = nubrkptr - nubrk;
  1068. free((char *)(*brk));
  1069. if((*brk=(double *)realloc((char *)nubrk,brklen * sizeof(double)))==NULL) {
  1070. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate new envelope array.\n");
  1071. return(MEMORY_ERROR);
  1072. }
  1073. if((brklen/2) * 2 != brklen) {
  1074. sprintf(errstr,"Anomalous breaktable size in gen_trigger_envelope()\n");
  1075. return(PROGRAM_ERROR);
  1076. }
  1077. *brkend = *brk + brklen;
  1078. return(FINISHED);
  1079. }
  1080. /**************************** BRKDEGLITCH ****************************
  1081. * Check a breakpoint table for sudden glitches, and smooth them.
  1082. *
  1083. * (1) If the brktable has very sudden rise or fall, current time-point is moved forward a little.
  1084. * (2) If, as a result last time-points moved beyond original endtime, readjust to orig duration.
  1085. */
  1086. void brkdeglitch(double *brk,double **brkend)
  1087. {
  1088. double *p = brk, *here, *next;
  1089. double rise, risetime, slope, newtime;
  1090. double thistime, thisval, timeshift, timeratio;
  1091. double lasttime = *p++;
  1092. double lastval = *p++;
  1093. double endtime = *((*brkend)-2);
  1094. double timediff, valdiff, valstep;
  1095. double click = IS_CLICK;
  1096. // int cnt = 0;
  1097. while(p < *brkend) {
  1098. thistime = *p++;
  1099. thisval = *p++;
  1100. rise =fabs(thisval-lastval);
  1101. if((slope = rise/(thistime-lasttime))>click) { /* If the brktable has very sudden rise or fall */
  1102. risetime = rise/click;
  1103. here = p-2;
  1104. next = p;
  1105. newtime = lasttime + risetime; /* current time-point is moved forward a little */
  1106. timeshift = newtime - thistime;
  1107. while(next < *brkend) {
  1108. *here += timeshift;
  1109. if(*here >= *next) {
  1110. here += 2;
  1111. next += 2;
  1112. } else
  1113. break;
  1114. }
  1115. if(next >= *brkend)
  1116. *here += timeshift;
  1117. thistime = newtime;
  1118. }
  1119. lasttime = thistime;
  1120. lastval = thisval;
  1121. }
  1122. p = *brkend - 2;
  1123. if(flteq((double)*p,endtime)) {
  1124. *p = endtime;
  1125. *brkend = p + 2;
  1126. } else {
  1127. while(*p > endtime + FLTERR) /* if, as as a result of deglitches, endtime of table is moved forward */
  1128. p -= 2; /* Find the last point prior to the true endtime */
  1129. if(flteq((double)*p,endtime)) { /* and establish the correct time .. */
  1130. *p = endtime;
  1131. *brkend = p + 2;
  1132. } else { /* ... or the correct value, for that true endtime */
  1133. lasttime = *p;
  1134. lastval = *(p+1);
  1135. thistime = *(p+2);
  1136. thisval = *(p+3);
  1137. timediff = thistime - lasttime;
  1138. valdiff = thisval - lastval;
  1139. timeratio= (endtime - lasttime)/timediff;
  1140. valstep = valdiff * timeratio;
  1141. thisval = lastval + valstep;
  1142. p += 2;
  1143. *p++ = endtime;
  1144. *p++ = thisval;
  1145. *brkend = p;
  1146. }
  1147. }
  1148. return;
  1149. }
  1150. /********************************* ENVREPLACE *************************
  1151. *
  1152. * NEEDED FOR all WARP, except KORRUGATION and TRIGGER
  1153. */
  1154. int envreplace(float *env,float **envend,float *origenv,float *origend)
  1155. {
  1156. float *p, *q;
  1157. double gate = MIN_FRACTION_OF_LEVEL; /* minimum non-zero value of envelope */
  1158. double maxval = 0.0;
  1159. p = origenv;
  1160. q = env;
  1161. if((origend - origenv) < (*envend - env)) {
  1162. while(p<origend) {
  1163. if(*p <= gate) { /* if original envelope touches zero */
  1164. if(*q <=gate || q==env) /* if new envelope touches zero */
  1165. *q = 0.0f; /* OR start_of_file, set to zero */
  1166. else /* else, retain previous value of envelope */
  1167. *q = *(q-1);
  1168. } else
  1169. *q = (float)((*q)/(*p));
  1170. maxval = max(*q,maxval);
  1171. q++;
  1172. p++;
  1173. }
  1174. } else {
  1175. while(q<*envend) {
  1176. if(*p <= gate) { /* if original envelope touches zero */
  1177. if(*q <=gate || q==env) /* if new envelope touches zero */
  1178. *q = 0.0f; /* OR start_of_file, set to zero */
  1179. else /* else, retain previous value of envelope */
  1180. *q = *(q-1);
  1181. } else
  1182. *q = (float)((*q)/(*p));
  1183. maxval = max(*q,maxval);
  1184. q++;
  1185. p++;
  1186. }
  1187. }
  1188. *envend = q;
  1189. if(maxval<=gate) {
  1190. sprintf(errstr,"new envelope is effectively zero.\n");
  1191. return(GOAL_FAILED);
  1192. }
  1193. return(FINISHED);
  1194. }
  1195. /****************************** CONVERT_OTHER_BRKTABLE_TO_ENVTABLE *********************************/
  1196. int convert_other_brktable_to_envtable(double *brk,double *brkend,float **env,float **envend,dataptr dz)
  1197. {
  1198. int n, envlen;
  1199. float *q;
  1200. double here;
  1201. double timestep = dz->outfile->window_size * MS_TO_SECS;
  1202. // double inc = timestep;
  1203. double duration = *(brkend-2);
  1204. if(timestep <= 0.0) {
  1205. sprintf(errstr,"No window_size set: convert_other_brktable_to_envtable()\n");
  1206. return(PROGRAM_ERROR);
  1207. }
  1208. if(timestep < ENV_MIN_WSIZE * MS_TO_SECS) {
  1209. sprintf(errstr,"Invalid window_size: convert_other_brktable_to_envtable()\n");
  1210. return(PROGRAM_ERROR);
  1211. }
  1212. if(duration < timestep) {
  1213. sprintf(errstr,"Brktable duration less than window_size: Cannot proceed.\n");
  1214. return(DATA_ERROR);
  1215. }
  1216. envlen = (int)((duration/timestep) + 1.0); /* round up */
  1217. envlen += MARGIN; /* allow for errors in float-calculation */
  1218. if(brk==NULL) {
  1219. sprintf(errstr,"No existing brkpnt table. convert_brktable_to_envtable()\n");
  1220. return(PROGRAM_ERROR);
  1221. }
  1222. if(*env != NULL)
  1223. free(*env);
  1224. if((*env = (float *)malloc(envlen * sizeof(float)))==NULL) {
  1225. sprintf(errstr,"INSUFFICIENT MEMORY to create new envelope array.\n");
  1226. return(MEMORY_ERROR);
  1227. }
  1228. q = *env;
  1229. n = 0;
  1230. while(n<envlen) {
  1231. if((here = (double)n * timestep)>(duration+FLTERR))
  1232. break;
  1233. *q = read_a_val_from_brktable(brk,brkend,here);
  1234. q++;
  1235. n++;
  1236. }
  1237. envlen = n;
  1238. if((*env = (float *)realloc(*env,envlen * sizeof(float)))==NULL) {
  1239. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate new envelope array.\n");
  1240. return(MEMORY_ERROR);
  1241. }
  1242. *envend = *env + envlen;
  1243. return(FINISHED);
  1244. }
  1245. /**************************** READ_A_VAL_FROM_BRKTABLE *****************************/
  1246. float read_a_val_from_brktable(double *brk,double *brkend,double thistime)
  1247. {
  1248. float thisval;
  1249. double *p = brk, val;
  1250. double hival, loval, hiind, loind;
  1251. double firstval = *(brk+1);
  1252. double lastval = *(brkend-1);
  1253. double lasttime = *(brkend-2);
  1254. if(thistime <= 0.0)
  1255. thisval = (float)firstval;
  1256. else if(thistime >= lasttime)
  1257. thisval = (float)lastval;
  1258. else {
  1259. while(*(p)<thistime)
  1260. p += 2;
  1261. hival = *(p+1);
  1262. hiind = *p;
  1263. loval = *(p-1);
  1264. loind = *(p-2);
  1265. val = (thistime - loind)/(hiind - loind);
  1266. val *= (hival - loval);
  1267. val += loval;
  1268. thisval = (float)val;
  1269. }
  1270. return(thisval);
  1271. }
  1272. /**************************** ENLARGE_BRKTABLE *****************************/
  1273. int enlarge_brktable(double **brk,double **brkend, double **q,int *arraysize)
  1274. {
  1275. int offset = *q - *brk;
  1276. *arraysize += BIGARRAY;
  1277. if((*brk = (double *)realloc((*brk),(*arraysize) * sizeof(double)))==NULL) {
  1278. sprintf(errstr,"INSUFFICIENT MEMORY to enlarge brktable.\n");
  1279. return(MEMORY_ERROR);
  1280. }
  1281. *brkend = *brk + *arraysize;
  1282. *q = *brk + offset;
  1283. return(FINISHED);
  1284. }
  1285. /**************************** ROUND_OFF_BRKTABLE *****************************/
  1286. int round_off_brktable(double *q,double **brk,double **brkend,double envdur)
  1287. {
  1288. int brksize;
  1289. int vals_written = q - *brk;
  1290. double *endadr;
  1291. double *startadr = *brk;
  1292. double *nextadr = *brk + 2;
  1293. double starttime = *startadr, nexttime = *nextadr;
  1294. (brksize = vals_written/2);
  1295. if((brksize = vals_written/2) * 2 != vals_written) {
  1296. sprintf(errstr,"Data pairing anomaly in round_off_brktable()\n");
  1297. return(PROGRAM_ERROR);
  1298. }
  1299. if(brksize > 1) {
  1300. if(flteq(nexttime,starttime)) { /* Junk any redundant initial zero */
  1301. memmove((char *)startadr,(char *)nextadr,(brksize-1)*2*sizeof(double));
  1302. brksize--;
  1303. }
  1304. }
  1305. endadr = *brk + (brksize * 2);
  1306. if(*(endadr - 2) != envdur) { /* IF lasttime != length of envelope */
  1307. if(flteq(*(endadr - 2),envdur)) /* If approx equal, reset to equal */
  1308. *(endadr - 2) = envdur;
  1309. else { /* Else generate an endtime time-val pair */
  1310. brksize++;
  1311. if((*brk=(double *)realloc(*brk,(brksize*2)*sizeof(double)))==NULL) {
  1312. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate brktable.\n");
  1313. return(MEMORY_ERROR);
  1314. }
  1315. endadr = *brk + (brksize * 2);
  1316. *(endadr-2) = envdur; /* true end time gets */
  1317. *(endadr-1) = 0.0; /* 0 endvalue */
  1318. }
  1319. }
  1320. if((*brk=(double *)realloc(*brk,(brksize*2)*sizeof(double)))==NULL) {
  1321. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate brktable.\n");
  1322. return(MEMORY_ERROR);
  1323. }
  1324. *brkend = *brk + (brksize * 2);
  1325. return(FINISHED);
  1326. }
  1327. /**************************** CONVERT_TO_ON_TRIGGERS *****************************/
  1328. void convert_to_on_triggers(double now,double timestep,double rise,int *triggered,double **q)
  1329. {
  1330. double *p = *q;
  1331. if(*triggered==FALSE) { /* If not already RISING-triggered */
  1332. if(!flteq(*(p-2),now-timestep)) { /* If previous time-value was not too close to this one */
  1333. *p++ = now - timestep; /* Write pre-time and 0.0 for start of rise */
  1334. *p++ = 0.0;
  1335. }
  1336. *p++ = now; /* Write time and rise-value for end of rise */
  1337. *p++ = rise;
  1338. *triggered = TRUE; /* Flag trigrise */
  1339. } else { /* If already RISING-triggered */
  1340. *(p-4) = now - timestep; /* readjust start-time of existing rise, from current time */
  1341. *(p-2) = now; /* readjust end-time of existing rise, from current time */
  1342. *(p-1) += rise; /* readjust total rise value */
  1343. }
  1344. *q = p;
  1345. }
  1346. /******************************* GEN_REAPPLIED_TRIGGER_ENVELOPE ******************************/
  1347. int gen_reapplied_trigger_envelope(double **brk, double **brkend,dataptr dz)
  1348. {
  1349. int exit_status;
  1350. int n, brklen;
  1351. // double next_trigtime, this_trigtime, nuhere, last_outval = 0.0, trigval;
  1352. double next_trigtime, this_trigtime, nuhere, trigval;
  1353. double *q, *nubrkptr, *nubrk, *nubrkend;
  1354. double *trigptr, *trigbrk, *trigbrkend;
  1355. int arraysize = BIGARRAY;
  1356. trigptr = trigbrk = *brk;
  1357. trigbrkend = *brkend;
  1358. if((nubrk = (double *)malloc(arraysize * sizeof(double)))==NULL) {
  1359. sprintf(errstr,"INSUFFICIENT MEMORY to create new envelope table.\n");
  1360. return(MEMORY_ERROR);
  1361. }
  1362. nubrkend = nubrk + arraysize;
  1363. nubrkptr = nubrk;
  1364. while(trigptr < trigbrkend) {
  1365. this_trigtime = *trigptr++;
  1366. trigval = *trigptr++;
  1367. if(trigptr < trigbrkend)
  1368. next_trigtime = *trigptr;
  1369. else
  1370. next_trigtime = DBL_MAX;
  1371. if(flteq(trigval,0.0)) { /* if the trigger table value is 0.0 put Zero in new table */
  1372. *nubrkptr++ = this_trigtime;
  1373. *nubrkptr++ = 0.0;
  1374. } else { /* else */
  1375. q = dz->rampbrk; /* start copying values from ramp table into new brkpnt table, */
  1376. n = 0; /* until ramptable ends, OR we reach next brkpnt in trigger table */
  1377. while(n < dz->rampbrksize && (nuhere = this_trigtime + *q++)<next_trigtime) {
  1378. *nubrkptr++ = nuhere;
  1379. *nubrkptr++ = *q++;
  1380. n++;
  1381. }
  1382. }
  1383. if(nubrkptr>=(nubrkend-2)) {
  1384. if((exit_status = enlarge_brktable(&nubrk,&nubrkend,&nubrkptr,&arraysize))<0)
  1385. return(exit_status);
  1386. }
  1387. }
  1388. brkdeglitch(nubrk,&nubrkptr); /* get rid of too fast amp rises or falls */
  1389. brklen = nubrkptr - nubrk;
  1390. free((char *)(*brk));
  1391. if((*brk=(double *)realloc((char *)nubrk,brklen * sizeof(double)))==NULL) {
  1392. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate new envelope table.\n");
  1393. return(MEMORY_ERROR);
  1394. }
  1395. if((brklen/2) * 2 != brklen) {
  1396. sprintf(errstr,"Anomalous breaktable size in gen_reapplied_trigger_envelope()\n");
  1397. return(PROGRAM_ERROR);
  1398. }
  1399. *brkend = *brk + brklen;
  1400. return(FINISHED);
  1401. }
  1402. /***************************** REALLOC_ENVCREATE_TABLES ****************************/
  1403. int realloc_envcreate_tables(int tabsize,dataptr dz)
  1404. {
  1405. if((dz->parray[ENV_CREATE_TIME] =
  1406. (double *)realloc(dz->parray[ENV_CREATE_TIME],tabsize * sizeof(double)))==NULL
  1407. || (dz->parray[ENV_CREATE_LEVL] =
  1408. (double *)realloc(dz->parray[ENV_CREATE_LEVL],tabsize * sizeof(double)))==NULL) {
  1409. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate level array.\n");
  1410. return(MEMORY_ERROR);
  1411. }
  1412. return(FINISHED);
  1413. }
  1414. /***************************** CREATE_ENVELOPE ****************************
  1415. *
  1416. * (1) time_quantum has a minimum value, as this function can create a
  1417. * brktable for conversion to an envfile.
  1418. * 1a) Except in the case of ENV_ATTACK, which has very acute risetime!!
  1419. */
  1420. int create_envelope(int *cnt,dataptr dz)
  1421. {
  1422. int exit_status;
  1423. int falling = FALSE;
  1424. int n,m, k, base, newcnt;
  1425. double time_quantum, timestep, levelstep, attenator = 0.0;
  1426. double thisduration, ratio;
  1427. // double atten = 1.0/ATTEN;
  1428. if((dz->parray[ENV_CREATE_TIME] = (double *)malloc(sizeof(double)))==NULL) {
  1429. sprintf(errstr,"INSUFFICIENT MEMORY to create times array.\n");
  1430. return(MEMORY_ERROR);
  1431. }
  1432. if((dz->parray[ENV_CREATE_LEVL] = (double *)malloc(sizeof(double)))==NULL) {
  1433. sprintf(errstr,"INSUFFICIENT MEMORY to create levels array.\n");
  1434. return(MEMORY_ERROR);
  1435. }
  1436. dz->parray[ENV_CREATE_TIME][0] = dz->parray[ENV_CREATE_INTIME][0];
  1437. dz->parray[ENV_CREATE_LEVL][0] = dz->parray[ENV_CREATE_INLEVEL][0];
  1438. *cnt = 1;
  1439. for(n=1;n<dz->itemcnt;n++) {
  1440. thisduration = dz->parray[ENV_CREATE_INTIME][n] - dz->parray[ENV_CREATE_INTIME][n-1];
  1441. //TW UPDATE
  1442. if(dz->process == ENV_ATTACK || dz->process == ENV_DOVETAILING || dz->process == ENV_CURTAILING)
  1443. time_quantum = max(thisduration/(double)MINSPAN,2.0/dz->infile->srate); /* 1a */
  1444. else
  1445. time_quantum = max(thisduration/(double)MINSPAN,ENV_MIN_WSIZE * MS_TO_SECS); /* 1 */
  1446. if((levelstep = dz->parray[ENV_CREATE_INLEVEL][n] - dz->parray[ENV_CREATE_INLEVEL][n-1]) <= 0.0)
  1447. falling = TRUE;
  1448. else
  1449. falling = FALSE;
  1450. switch(dz->iparray[ENV_SLOPETYPE][n]) {
  1451. case(ENVTYPE_LIN):
  1452. (*cnt)++;
  1453. if((exit_status = realloc_envcreate_tables(*cnt,dz))<0)
  1454. return(exit_status);
  1455. dz->parray[ENV_CREATE_TIME][*cnt - 1] = dz->parray[ENV_CREATE_INTIME][n];
  1456. dz->parray[ENV_CREATE_LEVL][*cnt - 1] = dz->parray[ENV_CREATE_INLEVEL][n];
  1457. break;
  1458. case(ENVTYPE_STEEP):
  1459. case(ENVTYPE_EXP):
  1460. case(ENVTYPE_DBL):
  1461. switch(dz->iparray[ENV_SLOPETYPE][n]) {
  1462. case(ENVTYPE_STEEP): attenator = STEEP_ATTEN; break;
  1463. case(ENVTYPE_EXP): attenator = ATTENATOR; break;
  1464. case(ENVTYPE_DBL): attenator = ATTENATOR * 2; break;
  1465. }
  1466. base = *cnt;
  1467. newcnt = (int)(thisduration/time_quantum); /* TRUNCATE */
  1468. /* RWD 4:2002 NB: div/zero bug here when newcnt resolves to zero */
  1469. /* should this be flagged as a user error? */
  1470. if(newcnt==0)
  1471. newcnt = 1;
  1472. timestep = thisduration/(double)newcnt;
  1473. *cnt += newcnt;
  1474. if((exit_status = realloc_envcreate_tables(*cnt,dz))<0)
  1475. return(exit_status);
  1476. for(m = 1,k = base;k < *cnt;k++,m++) {
  1477. dz->parray[ENV_CREATE_TIME][k] = dz->parray[ENV_CREATE_INTIME][n-1] + (m * timestep);
  1478. if(falling) {
  1479. ratio = 1.0 - ((m * timestep)/thisduration);
  1480. ratio = max(ratio,0.0);
  1481. ratio = pow(ratio,attenator);
  1482. dz->parray[ENV_CREATE_LEVL][k] = fabs(levelstep) * ratio;
  1483. dz->parray[ENV_CREATE_LEVL][k] += dz->parray[ENV_CREATE_INLEVEL][n];
  1484. }
  1485. else {
  1486. ratio = (m * timestep)/thisduration;
  1487. ratio = pow(ratio,attenator);
  1488. ratio = min(ratio,1.0);
  1489. dz->parray[ENV_CREATE_LEVL][k] = fabs(levelstep) * ratio;
  1490. dz->parray[ENV_CREATE_LEVL][k] += dz->parray[ENV_CREATE_INLEVEL][n-1];
  1491. }
  1492. }
  1493. dz->parray[ENV_CREATE_TIME][*cnt-1] = dz->parray[ENV_CREATE_INTIME][n];
  1494. break;
  1495. default:
  1496. sprintf(errstr,"Unknown case in create_envelope()\n");
  1497. return(PROGRAM_ERROR);
  1498. }
  1499. }
  1500. return(FINISHED);
  1501. }
  1502. /******************************** ENVELOPE_TREMOL **********************************/
  1503. int envelope_tremol(dataptr dz)
  1504. {
  1505. int exit_status;
  1506. int m;
  1507. int n, k, st_sampsread, st_samps_processed;
  1508. double thistime, losin, hisin, frac, val;
  1509. double fsinpos = 0.0;
  1510. int sinpos;
  1511. int chans = dz->infile->channels;
  1512. double inverse_srate = 1.0/(double)dz->infile->srate;
  1513. double tabsize_over_srate = (double)ENV_TREM_TABSIZE/(double)dz->infile->srate;
  1514. float *buf = dz->sampbuf[0];
  1515. double *sintab = dz->parray[ENV_SINETAB];
  1516. while(dz->samps_left > 0) {
  1517. st_samps_processed = dz->total_samps_read/chans;
  1518. if((exit_status = read_samps(buf,dz))<0)
  1519. return(exit_status);
  1520. st_sampsread = dz->ssampsread/chans;
  1521. for(n=0; n < st_sampsread; n++) {
  1522. k = n * chans;
  1523. thistime = (double)st_samps_processed * inverse_srate;
  1524. if((exit_status = read_values_from_all_existing_brktables(thistime,dz))<0)
  1525. return(exit_status);
  1526. if(dz->brksize[ENV_TREM_FRQ] && dz->mode==ENV_TREM_LOG)
  1527. dz->param[ENV_TREM_FRQ] = pow(10,dz->param[ENV_TREM_FRQ]);
  1528. sinpos = (int)fsinpos; /* TRUNCATE */
  1529. frac = fsinpos - (double)sinpos;
  1530. losin = sintab[sinpos];
  1531. hisin = sintab[sinpos+1];
  1532. val = losin + ((hisin - losin) * frac); /* interpd (normalised) sintable value */
  1533. val *= dz->param[ENV_TREM_DEPTH]; /* adjusted for tremolo depth */
  1534. val += (1.0 - dz->param[ENV_TREM_DEPTH]); /* subtract from max: tremol superimposed on existing level */
  1535. val *= dz->param[ENV_TREM_AMP]; /* multiply by overall signal gain (<= 1.0) */
  1536. fsinpos += (dz->param[ENV_TREM_FRQ] * tabsize_over_srate); /* advance sintable float-pointer */
  1537. fsinpos = fmod(fsinpos,(double)ENV_TREM_TABSIZE); /* wrap at table-size */
  1538. for(m=0;m<chans;m++)
  1539. buf[k+m] = (float)/*round*/(buf[k+m] * val);
  1540. st_samps_processed++;
  1541. }
  1542. if(dz->ssampsread > 0) {
  1543. if((exit_status = write_samps(buf,dz->ssampsread,dz))<0)
  1544. return(exit_status);
  1545. }
  1546. }
  1547. return(FINISHED);
  1548. }
  1549. /*************************** ENVPEAKCNT *************************/
  1550. int envpeakcnt(float *env,float *envend,dataptr dz)
  1551. {
  1552. int exit_status;
  1553. int upwards, peakkcnt = 0;
  1554. double thistime = 0.0;
  1555. float *p, *q;
  1556. double timestep = dz->outfile->window_size * MS_TO_SECS;
  1557. float *shadowenv;
  1558. size_t bytelen = (envend - env) * sizeof(float);
  1559. if((shadowenv = (float *)malloc(bytelen))==NULL) {
  1560. sprintf(errstr,"INSUFFICIENT MEMORY to create shadow envelope array.\n");
  1561. return(MEMORY_ERROR);
  1562. }
  1563. memset((char *)shadowenv,0,(size_t)bytelen);
  1564. p = env+1;
  1565. q = env;
  1566. if (*p > *q)
  1567. upwards = TRUE;
  1568. else
  1569. upwards = FALSE;
  1570. while(p < envend) {
  1571. if((exit_status = read_values_from_all_existing_brktables(thistime,dz))<0)
  1572. return(exit_status);
  1573. if(upwards) {
  1574. if(*p <= *q) {
  1575. if(ispeak(env,envend,q,(int)dz->iparam[ENV_PKSRCHWIDTH]))
  1576. peakkcnt++;
  1577. upwards = FALSE;
  1578. }
  1579. } else {
  1580. if(*p > *q)
  1581. upwards = TRUE;
  1582. }
  1583. thistime += timestep;
  1584. p++;
  1585. q++;
  1586. }
  1587. fprintf(stdout,"INFO: Number of peaks = %d\n",peakkcnt);
  1588. fflush(stdout);
  1589. return(FINISHED);
  1590. }