envprocess.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775
  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 <structures.h>
  25. #include <tkglobals.h>
  26. #include <globcon.h>
  27. #include <processno.h>
  28. #include <modeno.h>
  29. #include <arrays.h>
  30. #include <envel.h>
  31. #include <cdpmain.h>
  32. #include <sfsys.h>
  33. #include <envlcon.h>
  34. #define MARGIN (16)
  35. #define BASE_REDUCE ENV_DEFAULT_DATAREDUCE
  36. static int read_envel_from_envfile(float **env,float **envend,int fileno,dataptr dz);
  37. static int envcopy(float *envel1,float *envend1,float **envel2,float **envend2);
  38. static int convert_envelope_to_brkpnt_table(int envcnt,double window_size,double infiledur,dataptr dz);
  39. static int convert_brktable_to_envtable(double window_size,float **env,float **envend,dataptr dz);
  40. static int write_brkpnt_data_to_file(dataptr dz);
  41. static int write_envel_to_envfile(float *env,float *envend,dataptr dz);
  42. static double *datareduce(double *q,double datareduction,int *bcnt,int paramno,dataptr dz);
  43. static int rejig_buffering(dataptr dz);
  44. static int adjust_last_val_of_brk(double *brk,double *brkend,int *datacnt,double endtime);
  45. static int store_brkpnt_envelope(int cnt,dataptr dz);
  46. static int read_value_from_brktable_from_brkpntfile(double thistime,float *thisval,dataptr dz);
  47. static int convert_brkvals_db_to_gain(int paramno,dataptr dz);
  48. static int convert_brkvals_gain_to_dB(int paramno,dataptr dz);
  49. static int convert_normalised_gain_val_to_dB(double *val);
  50. /************************** PROCESS_ENVELOPE ************************/
  51. int process_envelope(dataptr dz)
  52. {
  53. int exit_status;
  54. int bufcnt, envcnt, cnt, other_envcnt;
  55. switch(dz->process) {
  56. case(ENV_CURTAILING):
  57. case(ENV_DOVETAILING):
  58. case(ENV_SWELL):
  59. case(ENV_ATTACK):
  60. if((exit_status = create_envelope(&cnt,dz))<0)
  61. return(exit_status);
  62. if((exit_status = store_brkpnt_envelope(cnt,dz))<0)
  63. return(exit_status);
  64. if((exit_status = apply_brkpnt_envelope(dz))<0)
  65. return(exit_status);
  66. break;
  67. case(ENV_CREATE):
  68. if((exit_status = create_envelope(&cnt,dz))<0)
  69. return(exit_status);
  70. if((exit_status = store_brkpnt_envelope(cnt,dz))<0)
  71. return(exit_status);
  72. switch(dz->mode) {
  73. case(ENV_ENVFILE_OUT):
  74. if((exit_status = convert_brktable_to_envtable(dz->param[ENV_WSIZE] * MS_TO_SECS,&dz->env,&dz->envend,dz))<0)
  75. return(exit_status);
  76. if((exit_status = write_envel_to_envfile(dz->env,dz->envend,dz))<0)
  77. return(exit_status);
  78. break;
  79. case(ENV_BRKFILE_OUT):
  80. if((exit_status = write_brkpnt_data_to_file(dz))<0)
  81. return(exit_status);
  82. break;
  83. default:
  84. sprintf(errstr,"Unknown case: ENV_CREATE in process_envelope()\n");
  85. return(PROGRAM_ERROR);
  86. }
  87. break;
  88. case(ENV_EXTRACT):
  89. if((exit_status = extract_env_from_sndfile(&bufcnt,&envcnt,&dz->env,&dz->envend,0,dz))<0)
  90. return(exit_status);
  91. switch(dz->mode) {
  92. case(ENV_ENVFILE_OUT):
  93. if((exit_status = write_envel_to_envfile(dz->env,dz->envend,dz))<0)
  94. return(exit_status);
  95. break;
  96. case(ENV_BRKFILE_OUT):
  97. if((exit_status = convert_envelope_to_brkpnt_table(envcnt,dz->outfile->window_size * MS_TO_SECS,dz->duration,dz))<0)
  98. return(exit_status);
  99. if((exit_status = write_brkpnt_data_to_file(dz))<0)
  100. return(exit_status);
  101. break;
  102. default:
  103. sprintf(errstr,"Unknown case: ENV_EXTRACT in process_envelope()\n");
  104. return(PROGRAM_ERROR);
  105. }
  106. break;
  107. case(ENV_ENVTOBRK):
  108. case(ENV_ENVTODBBRK):
  109. if((exit_status = read_envel_from_envfile(&dz->env,&dz->envend,0,dz))<0)
  110. return(exit_status);
  111. envcnt = dz->envend - dz->env;
  112. if((exit_status = convert_envelope_to_brkpnt_table(envcnt,dz->infile->window_size * MS_TO_SECS,dz->duration,dz))<0)
  113. return(exit_status);
  114. if(dz->process==ENV_ENVTODBBRK) {
  115. if((exit_status = convert_brkvals_gain_to_dB(dz->extrabrkno,dz))<0)
  116. return(exit_status);
  117. }
  118. if((exit_status = write_brkpnt_data_to_file(dz))<0)
  119. return(exit_status);
  120. break;
  121. case(ENV_BRKTODBBRK):
  122. if((exit_status = convert_brkvals_gain_to_dB(dz->extrabrkno,dz))<0)
  123. return(exit_status);
  124. if((exit_status = write_brkpnt_data_to_file(dz))<0)
  125. return(exit_status);
  126. break;
  127. case(ENV_DBBRKTOBRK):
  128. if((exit_status = convert_brkvals_db_to_gain(dz->extrabrkno,dz))<0)
  129. return(exit_status);
  130. if((exit_status = write_brkpnt_data_to_file(dz))<0)
  131. return(exit_status);
  132. break;
  133. case(ENV_DBBRKTOENV):
  134. if((exit_status = convert_brkvals_db_to_gain(dz->extrabrkno,dz))<0)
  135. return(exit_status);
  136. /* fall thro */
  137. case(ENV_BRKTOENV):
  138. if((exit_status = convert_brktable_to_envtable(dz->param[ENV_WSIZE] * MS_TO_SECS,&dz->env,&dz->envend,dz))<0)
  139. return(exit_status);
  140. if((exit_status = write_envel_to_envfile(dz->env,dz->envend,dz))<0)
  141. return(exit_status);
  142. break;
  143. case(ENV_WARPING):
  144. if(sloom) {
  145. fprintf(stdout,"INFO: Extracting envelope from input soundfile.\n");
  146. fflush(stdout);
  147. }
  148. if((exit_status = extract_env_from_sndfile(&bufcnt,&envcnt,&dz->origenv,&dz->origend,0,dz))<0)
  149. return(exit_status);
  150. if((exit_status = envcopy(dz->origenv,dz->origend,&dz->env,&dz->envend))<0)
  151. return(exit_status);
  152. if((exit_status = envelope_warp(&dz->env,&dz->envend,dz))<0)
  153. return(exit_status);
  154. switch(dz->mode) {
  155. case(ENV_CORRUGATING): /* generated envelope applied directly to source */
  156. case(ENV_TRIGGERING): /* generated envelope applied directly to source */
  157. case(ENV_PEAKCNT):
  158. break;
  159. default:
  160. if((exit_status = envreplace(dz->env,&dz->envend,dz->origenv,dz->origend))<0)
  161. return(exit_status);
  162. break;
  163. }
  164. if(dz->mode == ENV_PEAKCNT)
  165. return(FINISHED);
  166. if((exit_status = impose_envel_on_sndfile(dz->env,envcnt,bufcnt,0,dz))<0)
  167. return(exit_status);
  168. break;
  169. case(ENV_RESHAPING):
  170. if((exit_status = read_envel_from_envfile(&dz->env,&dz->envend,0,dz))<0)
  171. return(exit_status);
  172. if((exit_status = envelope_warp(&dz->env,&dz->envend,dz))<0)
  173. return(exit_status);
  174. if((exit_status = write_envel_to_envfile(dz->env,dz->envend,dz))<0)
  175. return(exit_status);
  176. break;
  177. case(ENV_REPLOTTING):
  178. if((exit_status = convert_brktable_to_envtable(dz->param[ENV_WSIZE] * MS_TO_SECS,&dz->env,&dz->envend,dz))<0)
  179. return(exit_status);
  180. if((exit_status = envelope_warp(&dz->env,&dz->envend,dz))<0)
  181. return(exit_status);
  182. envcnt = dz->envend - dz->env;
  183. if((exit_status = convert_envelope_to_brkpnt_table(envcnt,dz->param[ENV_WSIZE] * MS_TO_SECS,dz->duration,dz))<0)
  184. return(exit_status);
  185. if((exit_status = write_brkpnt_data_to_file(dz))<0)
  186. return(exit_status);
  187. break;
  188. //TW NEW CASE
  189. case(ENV_PROPOR):
  190. return apply_brkpnt_envelope(dz);
  191. case(ENV_IMPOSE):
  192. switch(dz->mode) {
  193. case(ENV_BRKFILE_IN):
  194. case(ENV_DB_BRKFILE_IN):
  195. return apply_brkpnt_envelope(dz);
  196. case(ENV_ENVFILE_IN):
  197. exit_status = read_envel_from_envfile(&dz->env,&dz->envend,1,dz);
  198. break;
  199. case(ENV_SNDFILE_IN):
  200. if(sloom) {
  201. fprintf(stdout,"INFO: Extracting envelope from input soundfile.\n");
  202. fflush(stdout);
  203. }
  204. if((exit_status = extract_env_from_sndfile(&bufcnt,&envcnt,&dz->env,&dz->envend,1,dz))<0)
  205. return(exit_status);
  206. exit_status = rejig_buffering(dz); /* deals with file2 having different srate or channels */
  207. reset_filedata_counters(dz);
  208. break;
  209. default:
  210. sprintf(errstr,"Unknown case for ENV_IMPOSE: in process_envelope()\n");
  211. return(PROGRAM_ERROR);
  212. }
  213. if(exit_status<0)
  214. return(exit_status);
  215. bufcnt = buffers_in_sndfile(/*dz->bigbufsize*/dz->buflen,0,dz);
  216. envcnt = dz->envend - dz->env;
  217. if((exit_status = impose_envel_on_sndfile(dz->env,envcnt,bufcnt,0,dz))<0)
  218. return(exit_status);
  219. break;
  220. case(ENV_REPLACE):
  221. switch(dz->mode) {
  222. case(ENV_ENVFILE_IN):
  223. exit_status = read_envel_from_envfile(&dz->env,&dz->envend,1,dz);
  224. if(sloom) {
  225. fprintf(stdout,"INFO: Extracting envelope from input soundfile.\n");
  226. fflush(stdout);
  227. }
  228. break;
  229. case(ENV_BRKFILE_IN):
  230. case(ENV_DB_BRKFILE_IN):
  231. // exit_status = convert_brktable_to_envtable(dz->param[ENV_WSIZE] * MS_TO_SECS,&dz->env,&dz->envend,dz);
  232. exit_status = convert_brktable_to_envtable
  233. ((double)(dz->iparam[ENV_SAMP_WSIZE]/dz->infile->channels)/(double)dz->infile->srate,&dz->env,&dz->envend,dz);
  234. if(sloom) {
  235. fprintf(stdout,"INFO: Extracting envelope from input soundfile.\n");
  236. fflush(stdout);
  237. }
  238. break;
  239. case(ENV_SNDFILE_IN):
  240. if(sloom) {
  241. fprintf(stdout,"INFO: Extracting envelope from 1st input soundfile.\n");
  242. fflush(stdout);
  243. }
  244. if((exit_status = extract_env_from_sndfile(&bufcnt,&envcnt,&dz->env,&dz->envend,1,dz))<0)
  245. return(exit_status);
  246. exit_status = rejig_buffering(dz); /* deals with file2 having different srate or channels */
  247. reset_filedata_counters(dz);
  248. break;
  249. default:
  250. sprintf(errstr,"Unknown case for ENV_REPLACE: in process_envelope()\n");
  251. return(PROGRAM_ERROR);
  252. }
  253. if(exit_status<0)
  254. return(exit_status);
  255. envcnt = dz->envend - dz->env;
  256. if(sloom) {
  257. fprintf(stdout,"INFO: Extracting envelope from 2nd input soundfile.\n");
  258. fflush(stdout);
  259. }
  260. if((exit_status = extract_env_from_sndfile(&bufcnt,&other_envcnt,&dz->origenv,&dz->origend,0,dz))<0)
  261. return(exit_status);
  262. if((exit_status = envreplace(dz->env,&dz->envend,dz->origenv,dz->origend))<0)
  263. return(exit_status);
  264. if((exit_status = impose_envel_on_sndfile(dz->env,envcnt,bufcnt,0,dz))<0)
  265. return(exit_status);
  266. break;
  267. case(ENV_PLUCK):
  268. if((exit_status = envelope_pluck(dz))<0)
  269. return(exit_status);
  270. break;
  271. case(ENV_TREMOL):
  272. if((exit_status = envelope_tremol(dz))<0)
  273. return(exit_status);
  274. break;
  275. default:
  276. sprintf(errstr,"Unknown case in process_envelope()\n");
  277. return(PROGRAM_ERROR);
  278. }
  279. return FINISHED;
  280. }
  281. /**************************** REJIG_BUFFERING ******************************
  282. *
  283. * recreates buffering to deal with 1ST file, once 2ND file has been dealt with!!
  284. */
  285. int rejig_buffering(dataptr dz)
  286. {
  287. int exit_status;
  288. if(dz->otherfile->srate != dz->infile->srate
  289. || dz->otherfile->channels != dz->infile->channels) {
  290. if((exit_status = generate_samp_windowsize(dz->infile,dz)) < 0)
  291. return(exit_status);
  292. free(dz->bigbuf);
  293. if((exit_status = create_sndbufs_for_envel(dz)) < 0)
  294. return(exit_status);
  295. }
  296. return(FINISHED);
  297. }
  298. /*************************** READ_ENVEL_FROM_ENVFILE **************************/
  299. int read_envel_from_envfile(float **env,float **envend,int fileno,dataptr dz)
  300. {
  301. int samps_read /*, samps_to_read, secs_to_read*/;
  302. int envlen = dz->insams[fileno];
  303. #ifdef NOTDEF
  304. if(((secs_to_read = dz->infilesize[fileno]/SECSIZE)*SECSIZE)!=dz->infilesize[fileno])
  305. secs_to_read++;
  306. bytes_to_read = secs_to_read * SECSIZE;
  307. #endif
  308. if((*env = (float *)malloc(/*bytes_to_read*/envlen * sizeof(float)))==NULL) {
  309. sprintf(errstr,"INSUFFICIENT MEMORY for envelope array.\n");
  310. return(MEMORY_ERROR);
  311. }
  312. if((samps_read = fgetfbufEx(*env, envlen,dz->ifd[fileno],0)) < 0) {
  313. sprintf(errstr,"Can't read samples from input envelfile\n");
  314. return(SYSTEM_ERROR);
  315. }
  316. #ifdef NOTDEF
  317. if((*env = (float *)realloc(*env,dz->insams[fileno]))==NULL) {
  318. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate envelope array.\n");
  319. return(MEMORY_ERROR);
  320. }
  321. #endif
  322. *envend = *env + envlen;
  323. return(FINISHED);
  324. }
  325. /*************************** ENVCOPY [ENVMOVE] *****************************
  326. * moves envelope from array env1 to array pointed to by env2.
  327. * returns the end+1 address of env2 array.
  328. */
  329. int envcopy(float *envel1,float *envend1,float **envel2,float **envend2)
  330. {
  331. float *p, *q;
  332. int tabsize = envend1 - envel1;
  333. if(*envel2 != NULL)
  334. free(*envel2);
  335. if((*envel2 = (float *)malloc(tabsize * sizeof(float)))==NULL) {
  336. sprintf(errstr,"INSUFFICIENT MEMORY to copy envelope array.\n");
  337. return(MEMORY_ERROR);
  338. }
  339. p = envel1;
  340. q = *envel2;
  341. while(p<envend1)
  342. *q++ = *p++;
  343. *envend2 = q;
  344. return(FINISHED);
  345. }
  346. /****************************** CONVERT_ENVELOPE_TO_BRKPNT_TABLE [ENVTOBRK]*********************************
  347. *
  348. * window_size is in seconds.
  349. */
  350. int convert_envelope_to_brkpnt_table(int envcnt,double window_size,double infiledur,dataptr dz)
  351. {
  352. int exit_status;
  353. double *q;
  354. float *p = dz->env;
  355. double inc = window_size, lasttime, thisreduce = BASE_REDUCE;
  356. int bcnt, n, final_size;
  357. int paramno = dz->extrabrkno;
  358. int add_last_val = FALSE;
  359. int orig_bcnt;
  360. if(window_size <= 0.0) {
  361. sprintf(errstr,"No window_size set: convert_envelope_to_brkpnt_table()\n");
  362. return(PROGRAM_ERROR);
  363. }
  364. if(paramno < 0) {
  365. sprintf(errstr,"extrabuf not set up: convert_envelope_to_brkpnt_table()\n");
  366. return(PROGRAM_ERROR);
  367. }
  368. if(dz->brk[paramno]!=NULL)
  369. free(dz->brk[paramno]);
  370. if((dz->brk[paramno] = (double *)malloc(envcnt * sizeof(double) * 2))==NULL) {
  371. sprintf(errstr,"INSUFFICIENT MEMORY to convert envelope to brkpnt table.\n");
  372. return(MEMORY_ERROR);
  373. }
  374. q = dz->brk[paramno];
  375. for(n=0;n<envcnt;n++) {
  376. *q++ = (double)n * inc;
  377. *q++ = (double)*p++;
  378. }
  379. bcnt = envcnt * 2;
  380. while(bcnt >= 6 && thisreduce < dz->param[ENV_DATAREDUCE]) { /* RWD improvement --> */
  381. q = dz->brk[paramno] + 4; /* incremental datareduction */
  382. orig_bcnt = bcnt;
  383. for(n=4;n<orig_bcnt;n+=2) {
  384. q += 2;
  385. q = datareduce(q,thisreduce,&bcnt,paramno,dz);
  386. }
  387. thisreduce += BASE_REDUCE;
  388. }
  389. if(bcnt >= 6) {
  390. q = dz->brk[paramno] + 4;
  391. orig_bcnt = bcnt;
  392. for(n=4;n<orig_bcnt;n+=2) {
  393. q += 2;
  394. q = datareduce(q,dz->param[ENV_DATAREDUCE],&bcnt,paramno,dz);
  395. }
  396. }
  397. n = bcnt;
  398. if(ODD(n)) {
  399. sprintf(errstr,"convert_envelope_to_brkpnt_table(): Problem of event pairing.\n");
  400. return(PROGRAM_ERROR);
  401. }
  402. lasttime = *(q-2);
  403. final_size = n;
  404. if(flteq(lasttime,infiledur)) {
  405. *(q-2) = infiledur;
  406. final_size = n;
  407. } else if(lasttime < infiledur) {
  408. final_size = n+2;
  409. add_last_val = TRUE;
  410. } else {
  411. if(q-4 >= dz->brk[paramno]) {
  412. if((exit_status = adjust_last_val_of_brk(dz->brk[paramno],q,&final_size,infiledur))<0)
  413. return(exit_status);
  414. }
  415. }
  416. if((dz->brk[paramno] = (double *)realloc(dz->brk[paramno],final_size * sizeof(double)))==NULL) {
  417. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate new brkpnt table.\n");
  418. return(MEMORY_ERROR);
  419. }
  420. if(add_last_val) {
  421. *(dz->brk[paramno] + final_size - 2) = infiledur;
  422. *(dz->brk[paramno] + final_size - 1) = *(dz->brk[paramno] + final_size - 3);
  423. }
  424. dz->brkptr[paramno] = dz->brk[paramno];
  425. dz->brksize[paramno] = final_size/2;
  426. return(FINISHED);
  427. }
  428. /***************************** DATAREDUCE **********************
  429. * Reduce data on passing from envelope to brkpnt representation.
  430. *
  431. * Take last 3 points, and if middle point has (approx) same value as
  432. * a point derived by interpolating between first and last points, then
  433. * ommit midpoint from brkpnt representation.
  434. */
  435. double *datareduce(double *q,double datareduction,int *bcnt,int paramno,dataptr dz)
  436. {
  437. double *p = q-6, *midpair = q-4, *endpair = q-2, *tabend;
  438. double startime = *p++;
  439. double startval = sqrt(*p++); /* RWD improvement: in power case, take sqrt */
  440. double midtime = *p++;
  441. double midval = sqrt(*p++);
  442. double endtime = *p++;
  443. double endval = sqrt(*p);
  444. double valrange = endval - startval;
  445. double midtimeratio = (midtime-startime)/(endtime-startime);
  446. double guessval = (valrange * midtimeratio) + startval;
  447. if(fabs(guessval - midval) < datareduction) {
  448. tabend = dz->brk[paramno] + (*bcnt);
  449. while (endpair < tabend) {
  450. *midpair++ = *endpair++;
  451. }
  452. (*bcnt) -= 2;
  453. q -= 2;
  454. }
  455. return(q);
  456. }
  457. /****************************** CONVERT_BRKTABLE_TO_ENVTABLE [BRKTOENV] *********************************
  458. * convert brkpnt table to envelope table
  459. *
  460. * Assume envelope space has already beem mallocd().
  461. *
  462. * window_size is in SECS.
  463. */
  464. int convert_brktable_to_envtable(double window_size,float **env,float **envend,dataptr dz)
  465. {
  466. int exit_status;
  467. int n, envlen;
  468. float *q;
  469. double here = 0.0;
  470. double inc = window_size;
  471. int paramno = dz->extrabrkno;
  472. double duration;
  473. if(paramno < 0) {
  474. sprintf(errstr,"extrabuf not set up: convert_brktable_to_envtable()\n");
  475. return(PROGRAM_ERROR);
  476. }
  477. duration = *(dz->brk[paramno] + ((dz->brksize[paramno]-1)*2));
  478. if(window_size <= 0.0) {
  479. sprintf(errstr,"No window_size set: convert_brktable_to_envtable()\n");
  480. return(PROGRAM_ERROR);
  481. }
  482. if(inc < ENV_MIN_WSIZE * MS_TO_SECS) {
  483. sprintf(errstr,"Invalid window_size: convert_brktable_to_envtable()\n");
  484. return(PROGRAM_ERROR);
  485. }
  486. if(duration < inc) {
  487. sprintf(errstr,"Brktable duration less than window_size: Cannot proceed.\n");
  488. return(DATA_ERROR);
  489. }
  490. envlen = (int)((duration/inc) + 1.0); /* round up */
  491. envlen += MARGIN; /* allow for errors in float-calculation */
  492. if(dz->brk[paramno]==NULL) {
  493. sprintf(errstr,"No existing brkpnt table. convert_brktable_to_envtable()\n");
  494. return(PROGRAM_ERROR);
  495. }
  496. if(dz->brksize[paramno]<2) {
  497. sprintf(errstr,"Brkpnt table length invalid: convert_brktable_to_envtable()\n");
  498. return(PROGRAM_ERROR);
  499. }
  500. if(*env != NULL)
  501. free(*env);
  502. if((*env = (float *)malloc(envlen * sizeof(float)))==NULL) {
  503. sprintf(errstr,"INSUFFICIENT MEMORY for envelope array.\n");
  504. return(MEMORY_ERROR);
  505. }
  506. q = *env;
  507. n = 0;
  508. while(n<envlen) {
  509. if((here = (double)n * inc)>(duration+FLTERR))
  510. break;
  511. if((exit_status = read_value_from_brktable_from_brkpntfile(here,q,dz))<0)
  512. return(exit_status);
  513. q++;
  514. n++;
  515. }
  516. if(here<duration) {
  517. sprintf(errstr,"Not all of brkpnt table transferred: convert_brktable_to_envtable()\n");
  518. return(PROGRAM_ERROR);
  519. }
  520. envlen = n;
  521. if((*env = (float *)realloc(*env,envlen * sizeof(float)))==NULL) {
  522. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate envelope array.\n");
  523. return(MEMORY_ERROR);
  524. }
  525. *envend = *env + envlen;
  526. return(FINISHED);
  527. }
  528. /*************************** WRITE_BRKPNT_DATA_TO_FILE [FPUT_BRK] *****************************/
  529. int write_brkpnt_data_to_file(dataptr dz)
  530. {
  531. double *p;
  532. int n, cnt;
  533. int paramno = dz->extrabrkno;
  534. if(paramno < 0) {
  535. sprintf(errstr,"extrabrkno not set: write_brkpnt_data_to_file()\n");
  536. return(PROGRAM_ERROR);
  537. }
  538. p = dz->brk[paramno];
  539. cnt = dz->brksize[paramno];
  540. for(n=0;n<cnt;n++) {
  541. if((fprintf(dz->fp,"%lf\t%lf\n",*p,*(p+1)))<2) {
  542. sprintf(errstr,"fput_brk(): Problem writing brkpnt data to file.\n");
  543. return(PROGRAM_ERROR);
  544. }
  545. p += 2;
  546. }
  547. /*
  548. if(fclose(dz->fp)<0) {
  549. fprintf(stdout,"WARNING: Failure to close brkpnt data output file.\n");
  550. fflush(stdout);
  551. }
  552. */
  553. return(FINISHED);
  554. }
  555. /*************************** WRITE_ENVEL_TO_ENVFILE ***************************/
  556. int write_envel_to_envfile(float *env,float *envend,dataptr dz)
  557. {
  558. int envlen = envend - env;
  559. int samps_to_write = envlen /* * sizeof(float)*/;
  560. int exit_status;
  561. #ifdef NOTDEF
  562. int pseudo_bytes_to_write;
  563. int secs_to_write = bytes_to_write/SECSIZE;
  564. int bytes_written;
  565. if((secs_to_write * SECSIZE)!=bytes_to_write)
  566. secs_to_write++;
  567. pseudo_bytes_to_write = secs_to_write * SECSIZE;
  568. #else
  569. int samps_written;
  570. #endif
  571. if(samps_to_write > 0) {
  572. if((exit_status = write_samps_no_report(env,samps_to_write,&samps_written,dz))<0)
  573. return(SYSTEM_ERROR);
  574. else if(samps_written == 0) {
  575. sprintf(errstr,"No data written to output envelfile.\n");
  576. return(SYSTEM_ERROR);
  577. }
  578. }
  579. return(FINISHED);
  580. }
  581. /*************************** ADJUST_LAST_VAL_OF_BRK ***************************/
  582. int adjust_last_val_of_brk(double *brk,double *brkend,int *datacnt,double endtime)
  583. {
  584. double *q = brkend - 4;
  585. double penulttime, penultval, lasttime, lastval, timeratio, valdiff;
  586. while(*q > endtime+FLTERR) {
  587. q -= 2;
  588. if(q < brk) {
  589. sprintf(errstr,"Cannot adjust last brkval: adjust_last_val_of_brk()\n");
  590. return(PROGRAM_ERROR);
  591. }
  592. }
  593. if(flteq(*q,endtime)) {
  594. *q = endtime;
  595. q += 2;
  596. *datacnt = (q - brk)/2;
  597. } else {
  598. penulttime = *(q);
  599. penultval = *(q+1);
  600. lasttime = *(q+2);
  601. lastval = *(q+3);
  602. timeratio = (endtime - penulttime)/(lasttime - penulttime);
  603. valdiff = timeratio * (lastval - penultval);
  604. *(q+2) = lasttime;
  605. *(q+3) = penultval + valdiff;
  606. q += 4;
  607. *datacnt = (q - brk)/2;
  608. }
  609. return(FINISHED);
  610. }
  611. /***************************** STORE_BRKPNT_ENVELOPE *****************************/
  612. int store_brkpnt_envelope(int cnt,dataptr dz)
  613. {
  614. int paramno = dz->extrabrkno;
  615. int n;
  616. double *p;
  617. if(paramno < 0) {
  618. sprintf(errstr,"extrabrkno not established: store_brkpnt_envelope()\n");
  619. return(PROGRAM_ERROR);
  620. }
  621. if(dz->brk[paramno]!=NULL) {
  622. sprintf(errstr,"extrabrktable already exists: store_brkpnt_envelope()\n");
  623. return(PROGRAM_ERROR);
  624. }
  625. if((dz->brk[paramno] = (double *)malloc(cnt * 2 * sizeof(double)))==NULL) {
  626. sprintf(errstr,"INSUFFICIENT MEMORY for brkpnt envelope array.\n");
  627. return(MEMORY_ERROR);
  628. }
  629. p = dz->brk[paramno];
  630. for(n=0;n<cnt;n++) {
  631. *p++ = dz->parray[ENV_CREATE_TIME][n];
  632. *p++ = dz->parray[ENV_CREATE_LEVL][n];
  633. }
  634. dz->brksize[paramno] = cnt;
  635. dz->brkptr[paramno] = dz->brk[paramno];
  636. free(dz->parray[ENV_CREATE_TIME]);
  637. free(dz->parray[ENV_CREATE_LEVL]);
  638. dz->parray[ENV_CREATE_TIME] = (double *)0;
  639. dz->parray[ENV_CREATE_LEVL] = (double *)0;
  640. return(FINISHED);
  641. }
  642. /**************************** READ_VALUE_FROM_BRKTABLE_FROM_BRKPNTFILE *****************************/
  643. int read_value_from_brktable_from_brkpntfile(double thistime,float *thisval,dataptr dz)
  644. {
  645. double *endpair, *p, val;
  646. double hival, loval, hiind, loind;
  647. int paramno = dz->extrabrkno;
  648. if(!dz->brkinit[paramno]) {
  649. dz->brkptr[paramno] = dz->brk[paramno];
  650. dz->firstval[paramno] = *(dz->brk[paramno]+1);
  651. endpair = dz->brk[paramno] + ((dz->brksize[paramno]-1)*2);
  652. dz->lastind[paramno] = *endpair;
  653. dz->lastval[paramno] = *(endpair+1);
  654. dz->brkinit[paramno] = 1;
  655. }
  656. p = dz->brkptr[paramno];
  657. if(thistime <= *(dz->brk[paramno])) {
  658. *thisval = (float)dz->firstval[paramno];
  659. return(FINISHED);
  660. } else if(thistime >= dz->lastind[paramno]) {
  661. *thisval = (float)dz->lastval[paramno];
  662. return(FINISHED);
  663. }
  664. if(thistime > *p) {
  665. while(*p < thistime)
  666. p += 2;
  667. } else {
  668. while(*p >= thistime)
  669. p -= 2;
  670. p += 2;
  671. }
  672. hival = *(p+1);
  673. hiind = *p;
  674. loval = *(p-1);
  675. loind = *(p-2);
  676. val = (thistime - loind)/(hiind - loind);
  677. val *= (hival - loval);
  678. val += loval;
  679. *thisval = (float)val;
  680. dz->brkptr[paramno] = p;
  681. return(FINISHED);
  682. }
  683. /******************************** CONVERT_BRKVALS_DB_TO_GAIN *************************/
  684. int convert_brkvals_db_to_gain(int paramno,dataptr dz)
  685. {
  686. int exit_status;
  687. double *p = dz->brk[paramno];
  688. double *pend = p + (dz->brksize[paramno] * 2);
  689. p++;
  690. while(p < pend) {
  691. if((exit_status = convert_dB_at_or_below_zero_to_gain(p))<0)
  692. return(exit_status);
  693. p += 2;
  694. }
  695. return(FINISHED);
  696. }
  697. /******************************** CONVERT_BRKVALS_GAIN_TO_DB *************************/
  698. int convert_brkvals_gain_to_dB(int paramno,dataptr dz)
  699. {
  700. int exit_status;
  701. double *p = dz->brk[paramno];
  702. double *pend = p + (dz->brksize[paramno] * 2);
  703. p++;
  704. while(p < pend) {
  705. if((exit_status = convert_normalised_gain_val_to_dB(p))<0)
  706. return(exit_status);
  707. p += 2;
  708. }
  709. return(FINISHED);
  710. }
  711. /**************************** CONVERT_NORMALISED_GAIN_VAL_TO_DB ********************************/
  712. int convert_normalised_gain_val_to_dB(double *val)
  713. {
  714. double thisval = *val;
  715. double mingain = 1.0/pow(10,(-MIN_DB_ON_16_BIT/20.0));
  716. if(thisval > 1.0 || thisval < 0.0) {
  717. sprintf(errstr,"convert_normalised_gain_vals_to_dB() received non-normalised gain\n");
  718. return(PROGRAM_ERROR);
  719. }
  720. if(thisval <= mingain)
  721. *val = MIN_DB_ON_16_BIT;
  722. else {
  723. thisval = 1.0/thisval;
  724. thisval = log10(thisval);
  725. thisval *= 20.0;
  726. thisval = -thisval;
  727. *val = thisval;
  728. }
  729. return(FINISHED);
  730. }