envprepro.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887
  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 <osbind.h>
  34. static int create_initial_envelope_params(double infiledur,dataptr dz);
  35. static int reallocate_initial_envelope_params(dataptr dz);
  36. static int allocate_initial_envelope_params(dataptr dz);
  37. static int find_and_test_attack_peak(dataptr dz);
  38. static int find_attack_point(float *buf,int *attack_point_found,int *attack_point,dataptr dz);
  39. static int find_attack_point_using_gate(float *buf,int *attack_point_found,int *attack_point,dataptr dz);
  40. static int attack_point_definitively_found(int *n,float *buf,/*int*/double *attack_level,int *attack_point,
  41. int previous_total_samps_read,dataptr dz);
  42. static int level_is_too_high(float *buf,int abs_samppos,dataptr dz);
  43. static int level_is_too_high_in_thisbuf(float *buf, double *gain, double tail_gainstep,int chans,
  44. int n,int *too_high,dataptr dz);
  45. static int go_to_search_start(dataptr dz);
  46. static int go_to_max_sample(float *buf,int *attack_point_found,int *attack_point,dataptr dz);
  47. static int find_local_maximum(float *buf,int *attack_point_found,int *attack_point,dataptr dz);
  48. static int level_is_too_high_in_thisbuf2(float *buf, double *gain, double tail_gainstep,double maxgain,
  49. int chans,int n,int *sampcnt,int abs_onset_len,int *too_high,dataptr dz);
  50. static int level_is_too_high_in_onset(float *buf,int abs_samppos,double tail_gainstep,dataptr dz);
  51. static int restore_buffers_and_file_to_original_condition(float *buf,int abs_samppos,dataptr dz);
  52. static int level_is_too_high_in_tail(float *buf,int abs_samppos,double tail_gainstep,dataptr dz);
  53. static int create_tremol_sintable(dataptr dz);
  54. static void convert_tremol_frq_to_log10(dataptr dz);
  55. /***************************** ENVEL_PREPROCESS ******************************/
  56. int envel_preprocess(dataptr dz)
  57. {
  58. int exit_status;
  59. int filestsmplen;
  60. //TW UPDATES
  61. double *d;
  62. double maxsplen, minwidth;
  63. int n;
  64. double sec = (double)(ENV_FSECSIZE)/(double)(dz->infile->channels * dz->infile->srate);
  65. switch(dz->process) {
  66. case(ENV_WARPING):
  67. case(ENV_RESHAPING):
  68. case(ENV_REPLOTTING):
  69. switch(dz->mode) {
  70. case(ENV_NORMALISE): case(ENV_REVERSE): case(ENV_CEILING):
  71. case(ENV_EXAGGERATING): case(ENV_ATTENUATING): case(ENV_FLATTENING):
  72. case(ENV_TSTRETCHING): case(ENV_CORRUGATING): case(ENV_PEAKCNT):
  73. case(ENV_LIFTING): case(ENV_GATING):
  74. case(ENV_DUCKED): case(ENV_TRIGGERING):
  75. break;
  76. case(ENV_LIMITING):
  77. if(!first_param_not_less_than_second(ENV_LIMIT,ENV_THRESHOLD,dz))
  78. return(DATA_ERROR);
  79. break;
  80. case(ENV_INVERTING):
  81. if(!first_param_greater_than_second(ENV_MIRROR,ENV_GATE,dz))
  82. return(DATA_ERROR);
  83. break;
  84. case(ENV_EXPANDING):
  85. if(!first_param_not_less_than_second(ENV_THRESHOLD,ENV_GATE,dz))
  86. return(DATA_ERROR);
  87. break;
  88. default:
  89. sprintf(errstr,"Unknown case: envwarp,reshape or replot: envelope_preprocess()\n");
  90. return(PROGRAM_ERROR);
  91. }
  92. break;
  93. case(ENV_CURTAILING):
  94. switch(dz->mode) {
  95. case(ENV_START_AND_END):
  96. case(ENV_START_AND_DUR):
  97. switch(dz->iparam[ENV_TIMETYPE]) {
  98. case(ENV_TIMETYPE_SMPS):
  99. dz->param[ENV_STARTTIME] = (double)(round(dz->param[ENV_STARTTIME])/dz->infile->channels);
  100. dz->param[ENV_ENDTIME] = (double)(round(dz->param[ENV_ENDTIME])/dz->infile->channels);
  101. /* fall thro */
  102. case(ENV_TIMETYPE_STSMPS):
  103. dz->param[ENV_STARTTIME] = dz->param[ENV_STARTTIME]/(double)dz->infile->srate;
  104. dz->param[ENV_ENDTIME] = dz->param[ENV_ENDTIME]/(double)dz->infile->srate;
  105. break;
  106. case(ENV_TIMETYPE_SECS):
  107. break;
  108. default:
  109. sprintf(errstr,"Unknown case: ENV_CURTAILING: envelope_preprocess()\n");
  110. return(PROGRAM_ERROR);
  111. }
  112. if(dz->param[ENV_STARTTIME] < 0.0 || dz->param[ENV_STARTTIME] >= dz->duration) {
  113. sprintf(errstr,"Start of fade time : out of range.\n");
  114. return(USER_ERROR);
  115. }
  116. if(dz->mode==ENV_START_AND_DUR) { /* "ENDTIME" is actually FADE DURATION */
  117. if(dz->param[ENV_ENDTIME] < FLTERR) {
  118. sprintf(errstr,"Negative or zero fade duration : impossible.\n");
  119. return(USER_ERROR);
  120. }
  121. dz->param[ENV_ENDTIME] = dz->param[ENV_STARTTIME] + dz->param[ENV_ENDTIME];
  122. if(dz->param[ENV_ENDTIME] > dz->duration + FLTERR) {
  123. fprintf(stdout,"WARNING: Fade duration goes beyond file end: curtailing to file end.\n");
  124. fflush(stdout);
  125. }
  126. if(dz->param[ENV_ENDTIME] > dz->duration-FLTERR) {
  127. dz->param[ENV_ENDTIME] = dz->duration;
  128. }
  129. } else {
  130. if(dz->param[ENV_STARTTIME] + sec >= dz->param[ENV_ENDTIME]) {
  131. sprintf(errstr,"Fade times too close or reversed.\n");
  132. return(USER_ERROR);
  133. }
  134. if(dz->param[ENV_ENDTIME] < 0.0) {
  135. sprintf(errstr,"End-of-fade time : out of range.\n");
  136. return(USER_ERROR);
  137. } else if(dz->param[ENV_ENDTIME] > dz->duration) {
  138. dz->param[ENV_ENDTIME] = dz->duration;
  139. fprintf(stdout,"WARNING: End-of-fade beyond file end: defaulting to end of file.\n");
  140. fflush(stdout);
  141. }
  142. }
  143. break;
  144. case(ENV_START_ONLY):
  145. switch(dz->iparam[ENV_TIMETYPE]) {
  146. case(ENV_TIMETYPE_SMPS):
  147. dz->param[ENV_STARTTIME] = (double)(round(dz->param[ENV_STARTTIME])/dz->infile->channels);
  148. /* fall thro */
  149. case(ENV_TIMETYPE_STSMPS):
  150. dz->param[ENV_STARTTIME] = dz->param[ENV_STARTTIME]/(double)dz->infile->srate;
  151. break;
  152. case(ENV_TIMETYPE_SECS):
  153. break;
  154. default:
  155. sprintf(errstr,"Unknown case: ENV_CURTAILING: envelope_preprocess()\n");
  156. return(PROGRAM_ERROR);
  157. }
  158. dz->param[ENV_ENDTIME] = dz->duration;
  159. }
  160. dz->itemcnt = 3;
  161. if((exit_status = create_initial_envelope_params(dz->duration,dz))<0)
  162. return(exit_status);
  163. if((exit_status = establish_additional_brktable(dz))<0)
  164. return(exit_status);
  165. break;
  166. case(ENV_DOVETAILING):
  167. filestsmplen = dz->insams[0]/dz->infile->channels;
  168. switch(dz->iparam[ENV_TIMETYPE]) {
  169. case(ENV_TIMETYPE_SMPS):
  170. dz->param[ENV_STARTTRIM] =
  171. (double)round(dz->param[ENV_STARTTRIM])/(double)(dz->infile->channels * dz->infile->srate);
  172. dz->param[ENV_ENDTRIM] =
  173. (double)round(dz->param[ENV_ENDTRIM])/(double)(dz->infile->channels * dz->infile->srate);
  174. dz->param[ENV_ENDTRIM] = dz->duration - dz->param[ENV_ENDTRIM];
  175. break;
  176. case(ENV_TIMETYPE_STSMPS):
  177. dz->param[ENV_STARTTRIM] = (double)round(dz->param[ENV_STARTTRIM])/(double)dz->infile->srate;
  178. dz->iparam[ENV_ENDTRIM] = (int)round(dz->param[ENV_ENDTRIM]);
  179. dz->iparam[ENV_ENDTRIM] = (int)(filestsmplen - dz->iparam[ENV_ENDTRIM]);
  180. dz->param[ENV_ENDTRIM] = (double)dz->iparam[ENV_ENDTRIM]/(double)dz->infile->srate;
  181. break;
  182. case(ENV_TIMETYPE_SECS):
  183. dz->param[ENV_ENDTRIM] = dz->duration - dz->param[ENV_ENDTRIM];
  184. break;
  185. default:
  186. sprintf(errstr,"Unknown case: ENV_DOVETAILING: envelope_preprocess()\n");
  187. return(PROGRAM_ERROR);
  188. }
  189. if(dz->param[ENV_ENDTRIM] < 0.0) {
  190. sprintf(errstr,"End Trim is too large.\n");
  191. return(USER_ERROR);
  192. }
  193. if(dz->param[ENV_STARTTRIM] > dz->duration) {
  194. sprintf(errstr,"Start Trim is too large.\n");
  195. return(USER_ERROR);
  196. }
  197. if(dz->param[ENV_ENDTRIM] < dz->param[ENV_STARTTRIM]) {
  198. sprintf(errstr,"Start and End Trims overlap: cannot proceed.\n");
  199. return(USER_ERROR);
  200. }
  201. if(flteq(dz->param[ENV_ENDTRIM],dz->duration) && flteq(dz->param[ENV_STARTTRIM],0.0)) {
  202. sprintf(errstr,"Start and End Trims are zero: no change in file.\n");
  203. return(USER_ERROR);
  204. }
  205. if(flteq(dz->param[ENV_ENDTRIM],dz->duration) || flteq(dz->param[ENV_STARTTRIM],0.0))
  206. dz->itemcnt = 3;
  207. else
  208. dz->itemcnt = 4;
  209. if((exit_status = create_initial_envelope_params(dz->duration,dz))<0)
  210. return(exit_status);
  211. if((exit_status = establish_additional_brktable(dz))<0)
  212. return(exit_status);
  213. break;
  214. case(ENV_SWELL):
  215. dz->itemcnt = 3;
  216. if((exit_status = create_initial_envelope_params(dz->duration,dz))<0)
  217. return(exit_status);
  218. if((exit_status = establish_additional_brktable(dz))<0)
  219. return(exit_status);
  220. break;
  221. case(ENV_ATTACK):
  222. dz->param[ENV_ATK_GATE] *= (double)F_MAXSAMP; /* RWD actually redundant, but do it anyway */
  223. if((exit_status = find_and_test_attack_peak(dz))<0)
  224. return(exit_status);
  225. dz->param[ENV_ATK_ONSET] *= MS_TO_SECS;
  226. dz->param[ENV_ATK_TAIL] *= MS_TO_SECS;
  227. if(dz->iparam[ENV_ATK_ENVTYPE] == ENVTYPE_EXP)
  228. dz->iparam[ENV_ATK_ENVTYPE] = ENVTYPE_STEEP;
  229. dz->itemcnt = 5;
  230. if((exit_status = create_initial_envelope_params(dz->duration,dz))<0)
  231. return(exit_status);
  232. if((exit_status = establish_additional_brktable(dz))<0)
  233. return(exit_status);
  234. break;
  235. case(ENV_CREATE):
  236. if(dz->mode==ENV_ENVFILE_OUT) {
  237. if(dz->extrabrkno>=0) { /* If a brktable passed in from framework */
  238. if(dz->brk == NULL || dz->brk[dz->extrabrkno] == NULL) { /* clear it */
  239. sprintf(errstr,"Problem freeing inbrkfile-table: ENV_CREATE: envelope_preprocess()\n");
  240. return(PROGRAM_ERROR);
  241. }
  242. free(dz->brk[dz->extrabrkno]);
  243. } /* allocate temporary brkpnt array */
  244. if((exit_status = establish_additional_brktable(dz))<0)
  245. return(exit_status);
  246. }
  247. break;
  248. case(ENV_EXTRACT): case(ENV_IMPOSE): case(ENV_REPLACE):
  249. case(ENV_ENVTOBRK): case(ENV_ENVTODBBRK): case(ENV_BRKTOENV):
  250. case(ENV_DBBRKTOENV):case(ENV_DBBRKTOBRK): case(ENV_BRKTODBBRK):
  251. //TW NEW CASE
  252. case(ENV_PROPOR):
  253. break;
  254. case(ENV_PLUCK):
  255. if(dz->infile->channels!=MONO) {
  256. sprintf(errstr,"This process only works with MONO files\n");
  257. return(USER_ERROR);
  258. }
  259. initrand48();
  260. break;
  261. case(ENV_TREMOL):
  262. if(dz->brksize[ENV_TREM_FRQ] && dz->mode==ENV_TREM_LOG)
  263. convert_tremol_frq_to_log10(dz);
  264. return create_tremol_sintable(dz);
  265. break;
  266. case(TIME_GRID):
  267. dz->tempsize = dz->insams[0] * dz->iparam[GRID_COUNT];
  268. if(dz->brksize[GRID_SPLEN] > 0) {
  269. d = dz->brk[GRID_SPLEN] + 1;
  270. for(n= 0;n < dz->brksize[GRID_SPLEN];n++) {
  271. *d *= MS_TO_SECS;
  272. d += 2;
  273. }
  274. } else
  275. dz->param[GRID_SPLEN] *= MS_TO_SECS;
  276. if(dz->brksize[GRID_WIDTH]) {
  277. if((exit_status = get_minvalue_in_brktable(&minwidth,GRID_WIDTH,dz))<0)
  278. return(exit_status);
  279. } else
  280. minwidth = dz->param[GRID_WIDTH];
  281. if((exit_status = get_maxvalue(GRID_SPLEN,&maxsplen,dz))<0)
  282. return(exit_status);
  283. if(maxsplen >= minwidth) {
  284. sprintf(errstr,"Maximum splicelen too large for minimum grid-width\n");
  285. return(DATA_ERROR);
  286. }
  287. break;
  288. default:
  289. sprintf(errstr,"Unknown case: envelope_preprocess()\n");
  290. return(PROGRAM_ERROR);
  291. }
  292. return(FINISHED);
  293. }
  294. /***************************** CREATE_INITIAL_ENVELOPE_PARAMS ******************************/
  295. int create_initial_envelope_params(double infiledur,dataptr dz)
  296. {
  297. int exit_status, n, in_itemcnt;
  298. double attack_start, attack_end;
  299. if((exit_status = allocate_initial_envelope_params(dz))<0)
  300. return(exit_status);
  301. switch(dz->process) {
  302. case(ENV_CURTAILING):
  303. dz->parray[ENV_CREATE_INTIME][0] = 0.0;
  304. dz->parray[ENV_CREATE_INLEVEL][0] = 1.0;
  305. dz->iparray[ENV_SLOPETYPE][0] = ENVTYPE_LIN;
  306. dz->parray[ENV_CREATE_INTIME][1] = dz->param[ENV_STARTTIME];
  307. dz->parray[ENV_CREATE_INLEVEL][1] = 1.0;
  308. dz->iparray[ENV_SLOPETYPE][1] = ENVTYPE_LIN;
  309. dz->parray[ENV_CREATE_INTIME][2] = dz->param[ENV_ENDTIME];
  310. dz->parray[ENV_CREATE_INLEVEL][2] = 0.0;
  311. switch(dz->mode) {
  312. case(ENV_START_AND_END):
  313. case(ENV_START_AND_DUR):
  314. case(ENV_START_ONLY):
  315. dz->iparray[ENV_SLOPETYPE][2] = dz->iparam[ENV_ENVTYPE];
  316. break;
  317. default:
  318. dz->iparray[ENV_SLOPETYPE][2] = ENVTYPE_DBL;
  319. break;
  320. }
  321. break;
  322. case(ENV_DOVETAILING):
  323. n = 0;
  324. if(flteq(dz->param[ENV_STARTTRIM],0.0)) {
  325. dz->parray[ENV_CREATE_INTIME][n] = 0.0;
  326. dz->parray[ENV_CREATE_INLEVEL][n] = 1.0;
  327. dz->iparray[ENV_SLOPETYPE][n] = ENVTYPE_LIN;
  328. n++;
  329. } else {
  330. dz->parray[ENV_CREATE_INTIME][n] = 0.0;
  331. dz->parray[ENV_CREATE_INLEVEL][n] = 0.0;
  332. dz->iparray[ENV_SLOPETYPE][n] = ENVTYPE_LIN;
  333. n++;
  334. dz->parray[ENV_CREATE_INTIME][n] = dz->param[ENV_STARTTRIM];
  335. dz->parray[ENV_CREATE_INLEVEL][n] = 1.0;
  336. if(dz->mode==DOVE)
  337. dz->iparray[ENV_SLOPETYPE][n] = dz->iparam[ENV_STARTTYPE];
  338. else
  339. dz->iparray[ENV_SLOPETYPE][n] = ENVTYPE_DBL;
  340. n++;
  341. }
  342. if(flteq(dz->param[ENV_ENDTRIM],infiledur)) {
  343. dz->parray[ENV_CREATE_INTIME][n] = infiledur;
  344. dz->parray[ENV_CREATE_INLEVEL][n] = 1.0;
  345. dz->iparray[ENV_SLOPETYPE][n] = ENVTYPE_LIN;
  346. } else {
  347. dz->parray[ENV_CREATE_INTIME][n] = dz->param[ENV_ENDTRIM];
  348. dz->parray[ENV_CREATE_INLEVEL][n] = 1.0;
  349. dz->iparray[ENV_SLOPETYPE][n] = ENVTYPE_LIN;
  350. n++;
  351. dz->parray[ENV_CREATE_INTIME][n] = infiledur;
  352. dz->parray[ENV_CREATE_INLEVEL][n] = 0.0;
  353. if(dz->mode==DOVE)
  354. dz->iparray[ENV_SLOPETYPE][n] = dz->iparam[ENV_ENDTYPE];
  355. else
  356. dz->iparray[ENV_SLOPETYPE][n] = ENVTYPE_DBL;
  357. }
  358. break;
  359. case(ENV_SWELL):
  360. dz->parray[ENV_CREATE_INTIME][0] = 0.0;
  361. dz->parray[ENV_CREATE_INLEVEL][0] = 0.0;
  362. dz->iparray[ENV_SLOPETYPE][0] = ENVTYPE_LIN;
  363. dz->parray[ENV_CREATE_INTIME][1] = dz->param[ENV_PEAKTIME];
  364. dz->parray[ENV_CREATE_INLEVEL][1] = 1.0;
  365. dz->iparray[ENV_SLOPETYPE][1] = dz->iparam[ENV_ENVTYPE];
  366. dz->parray[ENV_CREATE_INTIME][2] = infiledur;
  367. dz->parray[ENV_CREATE_INLEVEL][2] = 0.0;
  368. dz->iparray[ENV_SLOPETYPE][2] = dz->iparam[ENV_ENVTYPE];
  369. break;
  370. case(ENV_ATTACK):
  371. in_itemcnt = dz->itemcnt;
  372. n = 0;
  373. attack_start = max(0.0,dz->param[ENV_ATK_TIME] - dz->param[ENV_ATK_ONSET]);
  374. attack_end = min(infiledur,dz->param[ENV_ATK_TIME] + dz->param[ENV_ATK_TAIL]);
  375. if(dz->param[ENV_ATK_TIME] > 0.0) {
  376. dz->parray[ENV_CREATE_INTIME][n] = 0.0;
  377. dz->parray[ENV_CREATE_INLEVEL][n] = 1.0;
  378. dz->iparray[ENV_SLOPETYPE][n] = ENVTYPE_LIN;
  379. n++;
  380. if(attack_start > 0.0) {
  381. dz->parray[ENV_CREATE_INTIME][n] = attack_start;
  382. dz->parray[ENV_CREATE_INLEVEL][n] = 1.0;
  383. dz->iparray[ENV_SLOPETYPE][n] = ENVTYPE_LIN;
  384. n++;
  385. }
  386. dz->parray[ENV_CREATE_INTIME][n] = dz->param[ENV_ATK_TIME];
  387. dz->parray[ENV_CREATE_INLEVEL][n] = dz->param[ENV_ATK_GAIN];
  388. dz->iparray[ENV_SLOPETYPE][n] = dz->iparam[ENV_ATK_ENVTYPE];
  389. n++;
  390. } else {
  391. dz->parray[ENV_CREATE_INTIME][n] = 0.0;
  392. dz->parray[ENV_CREATE_INLEVEL][n] = dz->param[ENV_ATK_GAIN];
  393. dz->iparray[ENV_SLOPETYPE][n] = ENVTYPE_LIN;
  394. n++;
  395. }
  396. if(attack_end < infiledur) {
  397. dz->parray[ENV_CREATE_INTIME][n] = attack_end;
  398. dz->parray[ENV_CREATE_INLEVEL][n] = 1.0;
  399. dz->iparray[ENV_SLOPETYPE][n] = dz->iparam[ENV_ATK_ENVTYPE];
  400. n++;
  401. dz->parray[ENV_CREATE_INTIME][n] = infiledur;
  402. dz->parray[ENV_CREATE_INLEVEL][n] = 1.0;
  403. dz->iparray[ENV_SLOPETYPE][n] = ENVTYPE_LIN;
  404. n++;
  405. } else {
  406. dz->parray[ENV_CREATE_INTIME][3] = infiledur;
  407. dz->parray[ENV_CREATE_INLEVEL][3] = 1.0;
  408. dz->iparray[ENV_SLOPETYPE][3] = dz->iparam[ENV_ATK_ENVTYPE];
  409. }
  410. dz->itemcnt = n;
  411. if((dz->itemcnt != in_itemcnt) && (exit_status = reallocate_initial_envelope_params(dz))<0)
  412. return(exit_status);
  413. break;
  414. default:
  415. sprintf(errstr,"Unknown case in create_initial_envelope_params()\n");
  416. return(PROGRAM_ERROR);
  417. }
  418. return(FINISHED);
  419. }
  420. /***************************** REALLOCATE_INITIAL_ENVELOPE_PARAMS ******************************/
  421. int reallocate_initial_envelope_params(dataptr dz)
  422. {
  423. if((dz->parray[ENV_CREATE_INLEVEL] = (double *)realloc
  424. (dz->parray[ENV_CREATE_INLEVEL],dz->itemcnt * sizeof(double)))==NULL) {
  425. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate input level array.\n");
  426. return(MEMORY_ERROR);
  427. }
  428. if((dz->parray[ENV_CREATE_INTIME] = (double *)realloc
  429. (dz->parray[ENV_CREATE_INTIME],dz->itemcnt * sizeof(double)))==NULL) {
  430. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate input time array.\n");
  431. return(MEMORY_ERROR);
  432. }
  433. if((dz->iparray[ENV_SLOPETYPE] = (int *)realloc
  434. (dz->iparray[ENV_SLOPETYPE],dz->itemcnt * sizeof(int)))==NULL) {
  435. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate input slopetype array.\n");
  436. return(MEMORY_ERROR);
  437. }
  438. return(FINISHED);
  439. }
  440. /***************************** ALLOCATE_INITIAL_ENVELOPE_PARAMS ******************************/
  441. int allocate_initial_envelope_params(dataptr dz)
  442. {
  443. if((dz->parray[ENV_CREATE_INLEVEL] = (double *)malloc(dz->itemcnt * sizeof(double)))==NULL) {
  444. sprintf(errstr,"INSUFFICIENT MEMORY for input level array.\n");
  445. return(MEMORY_ERROR);
  446. }
  447. if((dz->parray[ENV_CREATE_INTIME] = (double *)malloc(dz->itemcnt * sizeof(double)))==NULL) {
  448. sprintf(errstr,"INSUFFICIENT MEMORY for input time array.\n");
  449. return(MEMORY_ERROR);
  450. }
  451. if((dz->iparray[ENV_SLOPETYPE] = (int *)malloc(dz->itemcnt * sizeof(int)))==NULL) {
  452. sprintf(errstr,"INSUFFICIENT MEMORY for input slopetype array.\n");
  453. return(MEMORY_ERROR);
  454. }
  455. return(FINISHED);
  456. }
  457. /****************************** FIND_AND_TEST_ATTACK_PEAK *******************************/
  458. int find_and_test_attack_peak(dataptr dz)
  459. {
  460. int exit_status;
  461. int chans = dz->infile->channels;
  462. int attack_point_found = FALSE;
  463. int attack_point=0, abs_samppos;
  464. float *buf = dz->sampbuf[0];
  465. if((exit_status = find_attack_point(buf,&attack_point_found,&attack_point,dz))<0)
  466. return(exit_status);
  467. if (!attack_point_found) {
  468. sprintf(errstr,"Gate amplitude not exceeded.\n");
  469. return(GOAL_FAILED);
  470. }
  471. if(dz->insams[0] - attack_point <
  472. round((ENV_MIN_ATK_ONSET * MS_TO_SECS) * (double)(dz->infile->srate * chans))) {
  473. sprintf(errstr,"Attack time too late in file to create a new attack.\n");
  474. return(GOAL_FAILED);
  475. }
  476. abs_samppos = (attack_point/chans) * chans;
  477. if((exit_status = restore_buffers_and_file_to_original_condition(buf,abs_samppos,dz))<0)
  478. return(exit_status);
  479. if(level_is_too_high(buf,abs_samppos,dz)) {
  480. sprintf(errstr,"The attack may distort with this gain level.\n");
  481. return(GOAL_FAILED);
  482. }
  483. if(dz->mode==ENV_ATK_XTIME)
  484. dz->param[ENV_ATK_TIME] = dz->param[ENV_ATK_ATTIME];
  485. else
  486. dz->param[ENV_ATK_TIME] = (double)(attack_point/chans)/(double)(dz->infile->srate);
  487. reset_filedata_counters(dz);
  488. if(sndseekEx(dz->ifd[0],0,0)<0) {
  489. sprintf(errstr,"sndseekEx failed: find_and_test_attack_peak()\n");
  490. return(SYSTEM_ERROR);
  491. }
  492. return(FINISHED);
  493. }
  494. /****************************** FIND_ATTACK_POINT *******************************/
  495. int find_attack_point(float *buf,int *attack_point_found,int *attack_point,dataptr dz)
  496. {
  497. int exit_status;
  498. // int definitely_found = FALSE;
  499. switch(dz->mode) {
  500. case(ENV_ATK_GATED):
  501. return find_attack_point_using_gate(buf,attack_point_found,attack_point,dz);
  502. case(ENV_ATK_TIMED):
  503. if((exit_status = go_to_search_start(dz))<0)
  504. return(exit_status);
  505. if((exit_status = find_local_maximum(buf,attack_point_found,attack_point,dz))<0)
  506. return(exit_status);
  507. break;
  508. case(ENV_ATK_XTIME):
  509. *attack_point = round(dz->param[ENV_ATK_ATTIME] * (double)dz->infile->srate) * dz->infile->channels;
  510. *attack_point_found = TRUE;
  511. break;
  512. case(ENV_ATK_ATMAX):
  513. return go_to_max_sample(buf,attack_point_found,attack_point,dz);
  514. default:
  515. sprintf(errstr,"Unknown case in find_attack_point()\n");
  516. return(PROGRAM_ERROR);
  517. }
  518. return(FINISHED);
  519. }
  520. /****************************** FIND_ATTACK_POINT_USING_GATE *******************************/
  521. int find_attack_point_using_gate(float *buf,int *attack_point_found,int *attack_point,dataptr dz)
  522. {
  523. int exit_status;
  524. int definitely_found = FALSE;
  525. /*int*/double attack_level=0.0;
  526. int previous_total_samps_read, n;
  527. while(!definitely_found && (dz->samps_left > 0)) {
  528. previous_total_samps_read = dz->total_samps_read;
  529. if((exit_status = read_samps(buf,dz))<0)
  530. return(exit_status);
  531. n = 0;
  532. while(n<dz->ssampsread) {
  533. if(!(*attack_point_found)) {
  534. /*RWD be a little efficient here... */
  535. double fabsamp = fabs(buf[n]);
  536. if(/*abs(buf[n])*/fabsamp > dz->param[ENV_ATK_GATE]) {
  537. attack_level = /* abs(buf[n])*/fabsamp;
  538. *attack_point = previous_total_samps_read + n;
  539. *attack_point_found = TRUE;
  540. }
  541. }
  542. if(*attack_point_found) {
  543. if((definitely_found =
  544. attack_point_definitively_found(&n,buf,&attack_level,attack_point,previous_total_samps_read,dz))==TRUE)
  545. break;
  546. } else
  547. n++;
  548. }
  549. }
  550. return(FINISHED);
  551. }
  552. /****************************** ATTACK_POINT_DEFINITIVELY_FOUND *******************************/
  553. int attack_point_definitively_found
  554. (int *n,float *buf,/*int*/double *attack_level,int *attack_point,int previous_total_samps_read,dataptr dz)
  555. {
  556. /*int*/double thislevel;
  557. while(*n < dz->ssampsread) {
  558. thislevel = fabs(buf[*n]);
  559. if(thislevel < *attack_level)
  560. return TRUE;
  561. else if(thislevel > *attack_level) {
  562. *attack_level = thislevel;
  563. *attack_point = previous_total_samps_read + *n;
  564. }
  565. (*n)++;
  566. }
  567. return(FALSE);
  568. }
  569. /****************************** LEVEL_IS_TOO_HIGH *******************************
  570. *
  571. * This is an overestimate of risk!!
  572. */
  573. int level_is_too_high(float *buf,int abs_samppos,dataptr dz)
  574. {
  575. int exit_status;
  576. // int chans = dz->infile->channels;
  577. int too_high = FALSE;
  578. double tail_gainstep = dz->param[ENV_ATK_GAIN] - 1.0;
  579. switch(dz->mode) {
  580. case(ENV_ATK_ATMAX):
  581. break;
  582. case(ENV_ATK_TIMED):
  583. case(ENV_ATK_XTIME):
  584. if((exit_status = level_is_too_high_in_onset(buf,abs_samppos,tail_gainstep,dz))<0)
  585. return(exit_status);
  586. if((too_high = exit_status)==TRUE)
  587. break;
  588. /* fall thro */
  589. case(ENV_ATK_GATED):
  590. if((exit_status = level_is_too_high_in_tail(buf,abs_samppos,tail_gainstep,dz))<0)
  591. return(exit_status);
  592. too_high = exit_status;
  593. break;
  594. default:
  595. sprintf(errstr,"Unknown case in level_is_too_high()\n");
  596. return(PROGRAM_ERROR);
  597. }
  598. return(too_high);
  599. }
  600. /****************************** LEVEL_IS_TOO_HIGH_IN_THISBUF *******************************/
  601. int level_is_too_high_in_thisbuf
  602. (float *buf, double *gain, double tail_gainstep,int chans,int n,int *too_high,dataptr dz)
  603. {
  604. int m;
  605. double thislevel;
  606. while(n < dz->ssampsread) {
  607. for(m=0;m<chans;m++) {
  608. if((thislevel = (double) fabs(buf[n+m]) * (*gain)) > F_MAXSAMP) {
  609. *too_high = TRUE;
  610. return(FINISHED);
  611. }
  612. }
  613. if((*gain -= tail_gainstep)<=1.0)
  614. return(FINISHED);
  615. n += chans;
  616. }
  617. return(CONTINUE);
  618. }
  619. /****************************** GO_TO_SEARCH_START *******************************/
  620. int go_to_search_start(dataptr dz)
  621. {
  622. int seccnt;
  623. int shsecsize = ENV_FSECSIZE;
  624. double starttime = max(0.0,dz->param[ENV_ATK_ATTIME] - (ENV_ATK_SRCH * MS_TO_SECS));
  625. int startsamp = round(starttime * (double)dz->infile->srate) * dz->infile->channels;
  626. if(startsamp >= dz->insams[0]) {
  627. sprintf(errstr,"Error in sample arithmetic: go_to_search_start()\n");
  628. return(PROGRAM_ERROR);
  629. }
  630. seccnt = startsamp/shsecsize; /* TRUNCATE */
  631. startsamp = seccnt * shsecsize;
  632. if(sndseekEx(dz->ifd[0],startsamp,0)<0) {
  633. sprintf(errstr,"sndseekEx failed: go_to_search_start()\n");
  634. return(SYSTEM_ERROR);
  635. }
  636. /*dz->total_bytes_read = startbyte;*/
  637. dz->total_samps_read = startsamp;
  638. dz->samps_left = dz->insams[0] - startsamp;
  639. return(FINISHED);
  640. }
  641. /****************************** GO_TO_MAX_SAMPLE *******************************/
  642. int go_to_max_sample(float *buf,int *attack_point_found,int *attack_point,dataptr dz)
  643. {
  644. int exit_status;
  645. int previous_total_samps_read = 0, n;
  646. /*int*/double thislevel;
  647. /*int*/double attack_level = -1.0;
  648. *attack_point_found = TRUE;
  649. while(dz->samps_left > 0) {
  650. previous_total_samps_read = dz->total_samps_read;
  651. if((exit_status = read_samps(dz->sampbuf[0],dz))<0)
  652. return(exit_status);
  653. n = 0;
  654. while(n<dz->ssampsread) {
  655. if((thislevel = fabs(buf[n])) > attack_level) {
  656. attack_level = thislevel;
  657. *attack_point = previous_total_samps_read + n;
  658. }
  659. n++;
  660. }
  661. }
  662. return(FINISHED);
  663. }
  664. /****************************** FIND_LOCAL_MAXIMUM *******************************/
  665. int find_local_maximum(float *buf,int *attack_point_found,int *attack_point,dataptr dz)
  666. {
  667. int exit_status;
  668. /*int*/double thislevel;
  669. int n, m = 0;
  670. /*int*/double attack_level = -1.0;
  671. int finished = FALSE;
  672. int previous_total_samps_read;
  673. int search_limit = round((ENV_ATK_SRCH * 2.0) * MS_TO_SECS * (double)dz->infile->srate);
  674. search_limit *= dz->infile->channels;
  675. if(dz->samps_left <=0) {
  676. sprintf(errstr,"Error in buffer arithmetic: find_local_maximum()\n");
  677. return(PROGRAM_ERROR);
  678. }
  679. while(!finished && (dz->samps_left > 0)) {
  680. previous_total_samps_read = dz->total_samps_read;
  681. if((exit_status = read_samps(dz->sampbuf[0],dz))<0)
  682. return(exit_status);
  683. n = 0;
  684. while(n<dz->ssampsread) {
  685. if((thislevel = fabs(buf[n])) > attack_level) {
  686. attack_level = thislevel;
  687. *attack_point = previous_total_samps_read + n;
  688. }
  689. n++;
  690. if(++m >= search_limit) {
  691. finished = TRUE;
  692. break;
  693. }
  694. }
  695. }
  696. *attack_point_found = TRUE;
  697. return(FINISHED);
  698. }
  699. /****************************** LEVEL_IS_TOO_HIGH_IN_THISBUF2 *******************************/
  700. int level_is_too_high_in_thisbuf2(float *buf, double *gain, double tail_gainstep,
  701. double maxgain,int chans,int n,int *sampcnt,int abs_onset_len,int *too_high,dataptr dz)
  702. {
  703. int m;
  704. double thislevel;
  705. while(!(*too_high) && (n < dz->ssampsread)) {
  706. for(m=0;m<chans;m++) {
  707. if((thislevel = (double) fabs(buf[n+m]) * (*gain)) > F_MAXSAMP) {
  708. *too_high = TRUE;
  709. break;
  710. }
  711. }
  712. if((*gain += tail_gainstep)>=maxgain)
  713. *gain = maxgain;
  714. if((*sampcnt += chans) >= abs_onset_len)
  715. return(FINISHED);
  716. n += chans;
  717. }
  718. return(CONTINUE);
  719. }
  720. /****************************** LEVEL_IS_TOO_HIGH_IN_ONSET *******************************/
  721. int level_is_too_high_in_onset(float *buf,int abs_samppos,double tail_gainstep,dataptr dz)
  722. {
  723. int exit_status;
  724. int too_high = FALSE;
  725. int chans = dz->infile->channels;
  726. double gain = 1.0;
  727. int this_bufpos;
  728. int sampcnt = 0;
  729. int go_back = round(dz->param[ENV_ATK_ONSET] * MS_TO_SECS * (double)dz->infile->srate) * chans;
  730. int bakpos = max(0,abs_samppos - go_back);
  731. int abs_onset_len = abs_samppos - bakpos;
  732. int onset_len = abs_onset_len/chans;
  733. int bakset = (bakpos/dz->buflen) * dz->buflen;
  734. if(sndseekEx(dz->ifd[0],bakset,0)<0) {
  735. sprintf(errstr,"sndseek failed in level_is_too_high_in_onset()\n");
  736. return(SYSTEM_ERROR);
  737. }
  738. this_bufpos = bakpos%dz->buflen;
  739. dz->total_samps_read = bakset;
  740. dz->samps_left = dz->insams[0] - dz->total_samps_read;
  741. tail_gainstep /= (double)onset_len;
  742. while(!too_high && (dz->samps_left > 0)) {
  743. if((exit_status = read_samps(buf,dz))<0)
  744. return(exit_status);
  745. if(dz->ssampsread <= 0) {
  746. sprintf(errstr,"read anomaly: level_is_too_high_in_onset()\n");
  747. return(PROGRAM_ERROR);
  748. }
  749. if((exit_status = level_is_too_high_in_thisbuf2(buf,&gain,tail_gainstep,
  750. dz->param[ENV_ATK_GAIN],chans,this_bufpos,&sampcnt,abs_onset_len,&too_high,dz))==FINISHED)
  751. break;
  752. this_bufpos = 0;
  753. }
  754. if((exit_status = restore_buffers_and_file_to_original_condition(buf,abs_samppos,dz))<0)
  755. return(exit_status);
  756. return(too_high);
  757. }
  758. /****************************** RESTORE_BUFFERS_AND_FILE_TO_ORIGINAL_CONDITION *******************************/
  759. int restore_buffers_and_file_to_original_condition(float *buf,int abs_samppos,dataptr dz)
  760. {
  761. int exit_status;
  762. int reset = (abs_samppos/dz->buflen) * dz->buflen;
  763. if(sndseekEx(dz->ifd[0],reset,0)<0) {
  764. sprintf(errstr,"sndseek failed in restore_buffers_and_file_to_original_condition()\n");
  765. return(SYSTEM_ERROR);
  766. }
  767. if((exit_status = read_samps(buf,dz))<0)
  768. return(exit_status);
  769. if(dz->ssampsread <= 0) {
  770. sprintf(errstr,"read anomaly: restore_buffers_and_file_to_original_condition()\n");
  771. return(PROGRAM_ERROR);
  772. }
  773. dz->total_samps_read = reset + dz->ssampsread;
  774. dz->samps_left = dz->insams[0] - dz->total_samps_read;
  775. return(FINISHED);
  776. }
  777. /****************************** LEVEL_IS_TOO_HIGH_IN_TAIL *******************************/
  778. int level_is_too_high_in_tail(float *buf,int abs_samppos,double tail_gainstep,dataptr dz)
  779. {
  780. int exit_status;
  781. int too_high = FALSE;
  782. int chans = dz->infile->channels;
  783. double gain = dz->param[ENV_ATK_GAIN];
  784. int tail_len = round((dz->param[ENV_ATK_TAIL] * MS_TO_SECS) * (double)dz->infile->srate);
  785. int buf_samppos = abs_samppos % dz->buflen;
  786. tail_gainstep /= (double)tail_len;
  787. if((exit_status = level_is_too_high_in_thisbuf
  788. (buf,&gain,tail_gainstep,chans,buf_samppos,&too_high,dz))==FINISHED)
  789. return(too_high);
  790. while(dz->samps_left > 0) {
  791. if((exit_status = read_samps(dz->sampbuf[0],dz))<0)
  792. return(exit_status);
  793. buf_samppos = 0;
  794. if((exit_status = level_is_too_high_in_thisbuf
  795. (buf,&gain,tail_gainstep,chans,buf_samppos,&too_high,dz))==FINISHED)
  796. break;
  797. }
  798. return(too_high);
  799. }
  800. /************************** CREATE_TREMOL_SINTABLE ******************/
  801. int create_tremol_sintable(dataptr dz)
  802. {
  803. int n;
  804. if((dz->parray[ENV_SINETAB] = (double *)malloc((ENV_TREM_TABSIZE + 1) * sizeof(double)))==NULL) {
  805. sprintf(errstr,"INSUFFICIENT MEMORY for sine table.\n");
  806. return(MEMORY_ERROR);
  807. }
  808. for(n=0;n<ENV_TREM_TABSIZE;n++) {
  809. dz->parray[ENV_SINETAB][n] = sin(PI * 2.0 * ((double)n/(double)ENV_TREM_TABSIZE));
  810. dz->parray[ENV_SINETAB][n] += 1.0;
  811. dz->parray[ENV_SINETAB][n] /= 2.0;
  812. }
  813. dz->parray[ENV_SINETAB][n] = 0.5; /* wrap around point */
  814. return(FINISHED);
  815. }
  816. /************************** CONVERT_TREMOL_FRQ_TO_LOG10 ******************/
  817. void convert_tremol_frq_to_log10(dataptr dz)
  818. {
  819. double *p, *pend;
  820. double infiledur = (double)dz->insams[0]/(double)dz->infile->srate;
  821. double effectively_zero = 1.0/infiledur;
  822. p = dz->brk[ENV_TREM_FRQ];
  823. pend = p + (dz->brksize[ENV_TREM_FRQ] * 2);
  824. p++;
  825. while(p < pend) {
  826. if(*p <= effectively_zero)
  827. *p = effectively_zero;
  828. *p = log10(*p);
  829. p += 2;
  830. }
  831. }