pan.c 47 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220
  1. /*
  2. * Copyright (c) 1983-2023 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 <string.h> /*RWD Nov 2003 */
  25. #include <structures.h>
  26. #include <tkglobals.h>
  27. #include <globcon.h>
  28. #include <modify.h>
  29. #include <cdpmain.h>
  30. #include <modeno.h>
  31. #include <arrays.h>
  32. #include <filetype.h>
  33. #include <sfsys.h>
  34. //TW UPDATE
  35. #include <osbind.h>
  36. //#ifdef unix
  37. #define round(x) lround((x))
  38. //#endif
  39. //TW UPDATES
  40. #define SMALLARRAY 20
  41. #define ONE_dB 1.22018
  42. #define BSIZE (128)
  43. #define ROOT2 (1.4142136)
  44. #define SIGNAL_TO_LEFT (0)
  45. #define SIGNAL_TO_RIGHT (1)
  46. #define NARROW_IT (1)
  47. #define MONO_IT (0)
  48. #define MIRROR_IT (-1)
  49. static int newpar(int *brkindex,double *par,double *parincr,int *total_sams,dataptr dz);
  50. static void pancalc(double position,double *leftgain,double *rightgain);
  51. static void do_mirror(float *buffer,dataptr dz);
  52. static void do_narrow(double narrow,double one_less_narrow,dataptr dz);
  53. static void do_mono(dataptr dz);
  54. static int more_space(int size_step,int *arraysize,double **brk);
  55. static int get_sinval(double *f0,double *a0,double time,double *phase,double phase_quantum,double **p,dataptr dz);
  56. //TW UPDATE: NEW FUNCTIONS
  57. static int insert_point_in_envelope(int *last_postk,double basetime,int thisenv,int *cnt,
  58. double *last_posttime,double *last_postlevel,int *last_insertk,double *last_inserttime,double *last_insertlevel,
  59. double envtime,double envlevel,dataptr dz);
  60. /* SHUDDER */
  61. static int apply_brkpnt_envelope(dataptr dz);
  62. static int init_brkpnts
  63. (int *sampno,double *starttime,double *gain,double **endbrk,double **nextbrk,
  64. double *nextgain,double *gain_step,double *gain_incr,int *nextbrk_sampno,int paramno,int brksize,dataptr dz);
  65. static int advance_brkpnts
  66. (double starttime,double *gain,double *endbrk,double **nextbrk,double *nextgain,
  67. double *gain_step,double *gain_incr,int *nextbrk_sampno,dataptr dz);
  68. static int simple_envel_processing
  69. (int *samps_left_to_process,double starttime,double *endbrk,double **nextbrk,double *nextgain,
  70. int *sampno,double *gain,double *gain_step,double *gain_incr,int *nextbrk_sampno,int chan,float *maxobuf,dataptr dz);
  71. static int do_mono_envelope
  72. (int samp_cnt,double starttime,double *endbrk,double **nextbrk,double *nextgain,
  73. int *sampno,double *gain,double *gain_step,double *gain_incr,int *nextbrk_sampno,float *maxobuf,dataptr dz);
  74. static int read_ssamps(int samps_to_read,int *samps_left_to_process,int chan,dataptr dz);
  75. static int do_simple_read(int *samps_left_to_process,int buflen,int chan,dataptr dz);
  76. static int other_read_samps(int samps_to_read,int fileid,int bufno,dataptr dz);
  77. static void unlink_temp_files(int type,int ofd0, int ofd1,dataptr dz);
  78. /************************************ MODSPACE_PCONSISTENCY *******************************/
  79. int modspace_pconsistency(dataptr dz)
  80. {
  81. switch(dz->mode) {
  82. case(MOD_PAN):
  83. if(dz->infile->channels!=MONO) {
  84. sprintf(errstr,"ERROR: PAN only works with MONO input files.\n");
  85. return(DATA_ERROR);
  86. }
  87. break;
  88. case(MOD_MIRROR):
  89. if(dz->infile->channels!=STEREO) {
  90. sprintf(errstr,"ERROR: MIRROR only works with STEREO input files.\n");
  91. return(DATA_ERROR);
  92. }
  93. break;
  94. case(MOD_MIRRORPAN):
  95. if(dz->infile->filetype!=UNRANGED_BRKFILE) {
  96. sprintf(errstr,"ERROR: MIRROR PAN only works with PAN textdata files.\n");
  97. return(DATA_ERROR);
  98. }
  99. if(dz->brksize[dz->extrabrkno] < 2) {
  100. sprintf(errstr,"ERROR: MIRROR PAN table too short [%d pairs < 2].\n",dz->brksize[dz->extrabrkno]);
  101. return(DATA_ERROR);
  102. }
  103. break;
  104. case(MOD_NARROW):
  105. if(dz->infile->channels!=STEREO) {
  106. sprintf(errstr,"ERROR: NARROW only works with STEREO input files.\n");
  107. return(DATA_ERROR);
  108. }
  109. break;
  110. }
  111. return(FINISHED);
  112. }
  113. /************************************ MODSPACE_PREPROCESS *******************************/
  114. int modspace_preprocess(dataptr dz)
  115. {
  116. int exit_status;
  117. if(dz->mode == MOD_PAN && dz->brksize[PAN_PAN]) {
  118. if((exit_status = force_value_at_zero_time(PAN_PAN,dz))<0)
  119. return(exit_status);
  120. }
  121. if(dz->mode==MOD_PAN){
  122. /* create stereo outfile here! */
  123. /* RWD 4:2002 now we can open outfile with corect params! */
  124. dz->infile->channels = STEREO; /* ARRGH! */
  125. if((exit_status = create_sized_outfile(dz->outfilename,dz))<0)
  126. return(exit_status);
  127. }
  128. return(FINISHED);
  129. }
  130. /************************************ DOPAN *******************************/
  131. int dopan(dataptr dz)
  132. {
  133. int exit_status;
  134. int i;
  135. int brkindex = 1;
  136. int block = 0, sams = 0, total_sams = 0;
  137. float *inbuf = dz->sampbuf[0], *bufptr;
  138. double leftgain,rightgain;
  139. double lcoef = 0.0, rcoef = 0.0;
  140. double par = 0.0, parincr = 0.0;
  141. /* double fdist = 1.0;*/ /* fdist is for listener distance: not used yet */
  142. if(!dz->brksize[PAN_PAN]) {
  143. pancalc(dz->param[PAN_PAN],&leftgain,&rightgain);
  144. lcoef = leftgain * dz->param[PAN_PRESCALE];
  145. rcoef = rightgain * dz->param[PAN_PRESCALE];
  146. }
  147. display_virtual_time(0L,dz);
  148. dz->infile->channels = STEREO; /* affects output only */
  149. do {
  150. if((exit_status = read_samps(inbuf,dz))<0) {
  151. sprintf(errstr,"Failed to read data from sndfile.\n");
  152. return(DATA_ERROR);
  153. }
  154. bufptr = dz->sampbuf[1]; /* reset output buffer pointer */
  155. for (i = 0 ; i < dz->ssampsread; i++ ) {
  156. if(dz->brksize[PAN_PAN]) {
  157. if(sams-- <= 0)
  158. sams = newpar(&brkindex,&par,&parincr,&total_sams,dz);
  159. if(block-- <= 0) {
  160. pancalc(par,&leftgain,&rightgain);
  161. lcoef = leftgain * dz->param[PAN_PRESCALE];
  162. rcoef = rightgain * dz->param[PAN_PRESCALE];
  163. block += BSIZE;
  164. par += parincr;
  165. }
  166. }
  167. *bufptr++ = (float) /*round*/(lcoef * inbuf[i]);
  168. *bufptr++ = (float) /*round*/(rcoef * inbuf[i]);
  169. }
  170. if(dz->ssampsread > 0) {
  171. if((exit_status = write_samps(dz->sampbuf[1],dz->ssampsread * STEREO,dz))<0)
  172. return(exit_status);
  173. }
  174. } while(dz->samps_left > 0);
  175. return(FINISHED);
  176. }
  177. /************************************ MIRRORING *******************************/
  178. int mirroring(dataptr dz)
  179. {
  180. int exit_status;
  181. float *inbuf = dz->sampbuf[0];
  182. do {
  183. if((exit_status = read_samps(inbuf,dz))<0) {
  184. sprintf(errstr,"Failed to read data from sndfile.\n");
  185. return(DATA_ERROR);
  186. }
  187. do_mirror(inbuf,dz);
  188. if(dz->ssampsread > 0) {
  189. if((exit_status = write_exact_samps(dz->sampbuf[0],dz->ssampsread,dz))<0)
  190. return(exit_status);
  191. }
  192. } while(dz->samps_left > 0);
  193. return(FINISHED);
  194. }
  195. /******************************** MIRROR_PANFILE ********************************/
  196. void mirror_panfile(dataptr dz)
  197. {
  198. int panbrk = dz->extrabrkno;
  199. int n;
  200. double *panbrktab = dz->brk[panbrk];
  201. int panbrksize = dz->brksize[panbrk];
  202. double *p = panbrktab + 1;
  203. for(n=0;n<panbrksize;n++) {
  204. *p = -(*p);
  205. p += 2;
  206. }
  207. p = panbrktab;
  208. for(n=0;n<panbrksize;n++) {
  209. fprintf(dz->fp,"%lf\t%lf\n",*p,*(p+1));
  210. p += 2;
  211. }
  212. return;
  213. }
  214. /***************************** NARROW_SOUND ***************************/
  215. int narrow_sound(dataptr dz)
  216. {
  217. int exit_status;
  218. int narrowing = NARROW_IT;
  219. double narrow = dz->param[NARROW], one_less_narrow;
  220. float *buffer = dz->sampbuf[0];
  221. display_virtual_time(0L,dz);
  222. if(flteq(narrow,1.0)) {
  223. sprintf(errstr, "WARNING: Narrowing of 1.0 has no effect on input file.\n");
  224. return(DATA_ERROR);
  225. }
  226. if(flteq(narrow,-1.0)) narrowing = MIRROR_IT;
  227. else if(flteq(narrow,0.0)) narrowing = MONO_IT;
  228. narrow = dz->param[NARROW] + 1.0;
  229. narrow /= 2.0;
  230. one_less_narrow = narrow;
  231. narrow = 1.0 - narrow;
  232. while(dz->samps_left != 0) {
  233. if((exit_status = read_samps(buffer,dz))<0) {
  234. sprintf(errstr,"Failed to read data from sndfile.\n");
  235. return(PROGRAM_ERROR);
  236. }
  237. switch(narrowing) {
  238. case(NARROW_IT): do_narrow(narrow,one_less_narrow,dz); break;
  239. case(MIRROR_IT): do_mirror(buffer,dz); break;
  240. case(MONO_IT): do_mono(dz); break;
  241. }
  242. if(dz->ssampsread > 0) {
  243. if((exit_status= write_exact_samps(buffer,dz->ssampsread,dz))<0)
  244. return(exit_status);
  245. }
  246. }
  247. return(FINISHED);
  248. }
  249. /************************************ NEWPAR *******************************/
  250. int newpar(int *brkindex,double *par,double *parincr,int *total_sams,dataptr dz)
  251. {
  252. double diff, steps, nextval;
  253. double *thisbrk = dz->brk[PAN_PAN];
  254. int here;
  255. int sams;
  256. if(*brkindex < dz->brksize[PAN_PAN]) {
  257. here = (*brkindex) * 2;
  258. sams = round(thisbrk[here] * dz->infile->srate) - *total_sams;
  259. *par = thisbrk[here-1];
  260. nextval = thisbrk[++here];
  261. diff = nextval - (*par);
  262. steps = (double)sams/(double)BSIZE;
  263. *parincr = diff/steps;
  264. (*brkindex)++;
  265. } else {
  266. *parincr = 0.0;
  267. sams = dz->insams[0] - *total_sams;
  268. }
  269. *total_sams += sams;
  270. return(sams);
  271. }
  272. /************************************ PANCALC *******************************/
  273. void pancalc(double position,double *leftgain,double *rightgain)
  274. {
  275. int dirflag;
  276. double temp;
  277. double relpos;
  278. double reldist, invsquare;
  279. if(position < 0.0)
  280. dirflag = SIGNAL_TO_LEFT; /* signal on left */
  281. else
  282. dirflag = SIGNAL_TO_RIGHT;
  283. if(position < 0)
  284. relpos = -position;
  285. else
  286. relpos = position;
  287. if(relpos <= 1.0){ /* between the speakers */
  288. temp = 1.0 + (relpos * relpos);
  289. reldist = ROOT2 / sqrt(temp);
  290. temp = (position + 1.0) / 2.0;
  291. *rightgain = temp * reldist;
  292. *leftgain = (1.0 - temp ) * reldist;
  293. } else { /* outside the speakers */
  294. temp = (relpos * relpos) + 1.0;
  295. reldist = sqrt(temp) / ROOT2; /* relative distance to source */
  296. invsquare = 1.0 / (reldist * reldist);
  297. if(dirflag == SIGNAL_TO_LEFT){
  298. *leftgain = invsquare;
  299. *rightgain = 0.0;
  300. } else { /* SIGNAL_TO_RIGHT */
  301. *rightgain = invsquare;
  302. *leftgain = 0;
  303. }
  304. }
  305. }
  306. /************************************ DO_MIRROR *******************************/
  307. void do_mirror(float *buffer,dataptr dz)
  308. {
  309. register int i;
  310. float store;
  311. for(i = 0; i < dz->ssampsread; i += 2) {
  312. store = buffer[i];
  313. buffer[i] = buffer[i+1];
  314. buffer[i+1] = store;
  315. }
  316. }
  317. /******************************* DO_NARROW *************************/
  318. void do_narrow(double narrow,double one_less_narrow,dataptr dz)
  319. {
  320. register int i;
  321. double new_l, new_r, add_to_l, add_to_r;
  322. float *buffer = dz->sampbuf[0];
  323. for(i = 0; i < dz->ssampsread; i+=2) {
  324. //TW CHANGED (casts removed)
  325. add_to_r = buffer[i] * narrow;
  326. add_to_l = buffer[i+1] * narrow;
  327. new_l = buffer[i] * one_less_narrow;
  328. new_r = buffer[i+1] * one_less_narrow;
  329. new_l += add_to_l;
  330. new_r += add_to_r;
  331. buffer[i] = (float) /*round*/(new_l);
  332. buffer[i+1] = (float) /*round*/(new_r);
  333. }
  334. }
  335. /******************************* DO_MONO *************************/
  336. void do_mono(dataptr dz)
  337. {
  338. register int i, j;
  339. register double temp;
  340. float *buffer =dz->sampbuf[0];
  341. for(i = 0; i < dz->ssampsread; i+=2) {
  342. j = i+1;
  343. temp = (buffer[i] + buffer[j]) /*/2.0*/ * 0.5;
  344. buffer[i] = (float)/*round*/(temp);
  345. buffer[j] = (float)/*round*/(temp);
  346. }
  347. }
  348. /****************************** GENERATE_SINTABLE *******************************/
  349. int generate_sintable(dataptr dz)
  350. {
  351. int exit_status;
  352. double *p, f0, a0, phase_quantum, time, phase;
  353. int arraysize = BIGARRAY, cnt;
  354. if((dz->parray[SIN_TABLE] = (double *)malloc(arraysize * sizeof(double)))==NULL) {
  355. sprintf(errstr,"Out of memory for breakpoint table.\n");
  356. return(MEMORY_ERROR);
  357. }
  358. p = dz->parray[SIN_TABLE];
  359. phase = (dz->param[SIN_PHASE]/360.0) * TWOPI;
  360. //TW UPDATE
  361. // *p++ = 0.0;
  362. // *p++ = phase;
  363. // cnt = 2;
  364. time = 0.0;
  365. if(dz->brksize[SIN_FRQ]) {
  366. if((exit_status = read_value_from_brktable(time,SIN_FRQ,dz))<0)
  367. return(exit_status);
  368. }
  369. //TW UPDATE
  370. dz->param[SIN_FRQ] = 1.0/dz->param[SIN_FRQ];
  371. if(dz->brksize[SIN_AMP]) {
  372. if((exit_status = read_value_from_brktable(time,SIN_AMP,dz))<0)
  373. return(exit_status);
  374. }
  375. f0 = dz->param[SIN_FRQ];
  376. a0 = dz->param[SIN_AMP];
  377. phase_quantum = dz->param[SIN_QUANT] * TWOPI;
  378. //TW UPDATES
  379. if((exit_status = get_sinval(&f0,&a0,time,&phase,phase_quantum,&p,dz))<0)
  380. return exit_status;
  381. cnt = 2;
  382. for(time = dz->param[SIN_QUANT]; time <= dz->param[SIN_DUR]; time += dz->param[SIN_QUANT]) {
  383. if((cnt += 2) > arraysize) {
  384. if((exit_status = more_space(BIGARRAY,&arraysize,&(dz->parray[SIN_TABLE])))<0)
  385. return(exit_status);
  386. p = dz->parray[SIN_TABLE] + cnt - 2;
  387. }
  388. if((exit_status = get_sinval(&f0,&a0,time,&phase,phase_quantum,&p,dz))<0)
  389. return exit_status;
  390. }
  391. if(!flteq(*(p-2),dz->param[SIN_DUR])) {
  392. if((cnt += 2) > arraysize) {
  393. arraysize = cnt;
  394. if((exit_status = more_space(2,&arraysize,&(dz->parray[SIN_TABLE])))<0)
  395. return(exit_status);
  396. p = dz->parray[SIN_TABLE] + cnt - 2;
  397. }
  398. if((exit_status = get_sinval(&f0,&a0,dz->param[SIN_DUR],&phase,phase_quantum,&p,dz))<0)
  399. return exit_status;
  400. } else {
  401. *(p-2) = dz->param[SIN_DUR];
  402. }
  403. if(cnt < arraysize) {
  404. if((dz->parray[SIN_TABLE] = (double *)realloc((char *)(dz->parray[SIN_TABLE]),cnt * sizeof(double)))==NULL) {
  405. sprintf(errstr,"Memory error on shrinking breaktable to size.\n");
  406. return(MEMORY_ERROR);
  407. }
  408. }
  409. cnt /= 2;
  410. if((exit_status = write_brkfile(dz->fp,cnt,SIN_TABLE,dz))<0)
  411. return(exit_status);
  412. return(FINISHED);
  413. }
  414. /****************************** GET_SINVAL *******************************/
  415. int get_sinval(double *f0,double *a0,double time,double *phase,double phase_quantum,double **p,dataptr dz)
  416. {
  417. int exit_status;
  418. double frq, amp, val;
  419. if(dz->brksize[SIN_FRQ]) {
  420. if((exit_status = read_value_from_brktable(time,SIN_FRQ,dz))<0)
  421. return(exit_status);
  422. //TW UPDATE
  423. dz->param[SIN_FRQ] = 1.0/dz->param[SIN_FRQ];
  424. frq = (dz->param[SIN_FRQ] + *f0) /*/2.0 */ * 0.5;
  425. } else {
  426. frq = *f0;
  427. }
  428. if(dz->brksize[SIN_AMP]) {
  429. if((exit_status = read_value_from_brktable(time,SIN_AMP,dz))<0)
  430. return(exit_status);
  431. amp = (dz->param[SIN_AMP] + *a0) /* /2.0*/ * 0.5;
  432. } else {
  433. amp = *a0;
  434. }
  435. //TW UPDATE (moved line)
  436. val = sin(*phase) * amp;
  437. *phase += frq * phase_quantum;
  438. *phase = fmod(*phase,TWOPI);
  439. **p = time;
  440. (*p)++;
  441. **p = val;
  442. (*p)++;
  443. *f0 = dz->param[SIN_FRQ];
  444. *a0 = dz->param[SIN_AMP];
  445. return(FINISHED);
  446. }
  447. /****************************** MORE_SPACE *******************************/
  448. int more_space(int size_step,int *arraysize,double **brk)
  449. {
  450. *arraysize += size_step;
  451. if((*brk = (double *)realloc((char *)(*brk),(*arraysize) * sizeof(double)))==NULL) {
  452. sprintf(errstr,"Out of memory for breakpoint table.\n");
  453. return(MEMORY_ERROR);
  454. }
  455. return(FINISHED);
  456. }
  457. //TW NEW FUNCTIONS (updated for flotsams)
  458. /************************************ SCALEDPAN_PREPROCESS *******************************/
  459. int scaledpan_preprocess(dataptr dz)
  460. {
  461. int exit_status, n, len;
  462. double endtime, scaling;
  463. double *thisbrk;
  464. if((len = (dz->brksize[PAN_PAN] * 2)) <= 0) {
  465. fprintf(stdout,"WARNING: Scaled pan is no different to ordinary panning, if you do not use a brkpoint file.\n");
  466. fflush(stdout);
  467. return(FINISHED);
  468. }
  469. if((exit_status = force_value_at_zero_time(PAN_PAN,dz))<0)
  470. return(exit_status);
  471. thisbrk = dz->brk[PAN_PAN];
  472. endtime = thisbrk[len - 2];
  473. scaling = dz->duration/endtime;
  474. for(n=0;n<len;n+=2)
  475. thisbrk[n] *= scaling;
  476. /* create stereo outfile here! */
  477. dz->infile->channels = STEREO; /* ARRGH! */
  478. return create_sized_outfile(dz->outfilename,dz);
  479. }
  480. /************************************* DO_SHUDDER ***********************************/
  481. int do_shudder(dataptr dz)
  482. {
  483. int left, exit_status;
  484. int cnt = 0, cnt2 = 0, timecnt, n, m, j, levelcnt;
  485. int cnt0, cnt1;
  486. int arraysz[2] = {SMALLARRAY,SMALLARRAY};
  487. double time, nexttime, lasttime, pos, leftgain, rightgain, depth, maxlevel, width, lastrealtime = -1.0;
  488. double envtime, envlevel, lgain, rgain, scat, realtime, levell, levelr, one_minus_depth, safety = 1.0/ROOT2;
  489. double last_posttime[2], last_postlevel[2], last_inserttime[2], last_insertlevel[2], basetime[2];
  490. int last_insertk[2], last_postk[2];
  491. double ee[] = {-7,-5, -3, -1, 1, 3, 5, 7};
  492. double ff[] = {0, 0.2,0.8,1.0,0.8,0.2,0.1,0};
  493. dz->tempsize = dz->insams[0] * 2;
  494. initrand48();
  495. for(n=0;n<8;n++)
  496. ee[n] *= 1.0/14.0;
  497. if((dz->parray[SHUD_TIMES] = (double *) malloc(arraysz[0] * sizeof(double)))==NULL) {
  498. sprintf(errstr,"Out of Memory While calculating Shudder Times\n");
  499. return(MEMORY_ERROR);
  500. }
  501. if((dz->parray[SHUD_LEVEL] = (double *) malloc(arraysz[1] * sizeof(double)))==NULL) {
  502. sprintf(errstr,"Out of Memory While calculating Shudder Levels\n");
  503. return(MEMORY_ERROR);
  504. }
  505. if((dz->parray[SHUD_WIDTH] = (double *) malloc(arraysz[0] * sizeof(double)))==NULL) {
  506. sprintf(errstr,"Out of Memory While calculating Shudder Widths\n");
  507. return(MEMORY_ERROR);
  508. }
  509. if((dz->parray[SHUD_DEPTH] = (double *) malloc(arraysz[0] * sizeof(double)))==NULL) {
  510. sprintf(errstr,"Out of Memory While calculating Shudder Widths\n");
  511. return(MEMORY_ERROR);
  512. }
  513. if((drand48() * 2.0) - 1.0 <= 0.0)
  514. left = 1;
  515. else
  516. left = -1;
  517. /* Get TIME, and WIDTH of initial shudder */
  518. time = dz->param[SHUD_STARTTIME];
  519. if((exit_status = read_values_from_all_existing_brktables(time,dz))<0)
  520. return(exit_status);
  521. width = ((dz->param[SHUD_MAXWIDTH] - dz->param[SHUD_MINWIDTH]) * drand48()) + dz->param[SHUD_MINWIDTH];
  522. dz->parray[SHUD_WIDTH][cnt] = width;
  523. time = max(time,width/2.0);
  524. dz->parray[SHUD_TIMES][cnt] = time;
  525. /* From STEREO-POSITION and DEPTH, calculate L and R levels */
  526. pos = dz->param[SHUD_SPREAD] * drand48() * left;
  527. pancalc(pos,&leftgain,&rightgain);
  528. depth = ((dz->param[SHUD_MAXDEPTH] - dz->param[SHUD_MINDEPTH]) * drand48()) + dz->param[SHUD_MINDEPTH];
  529. /* SHUDDER is added to existing level */
  530. /*... and will be automatically scaled by existing level when imposed on sound */
  531. dz->parray[SHUD_DEPTH][cnt] = 1.0 - depth;
  532. lgain = depth * leftgain;
  533. rgain = depth * rightgain;
  534. maxlevel = max(lgain,rgain);
  535. dz->parray[SHUD_LEVEL][cnt2++] = lgain;
  536. dz->parray[SHUD_LEVEL][cnt2++] = rgain;
  537. left = -left;
  538. cnt++;
  539. /* get, time , width and L & R level for all shudders */
  540. while(time < dz->duration) {
  541. lasttime = time;
  542. time = time + (1/dz->param[SHUD_FRQ]); /* use frq from previous time, to calculate where next time is */
  543. if((exit_status = read_values_from_all_existing_brktables(time,dz))<0)
  544. return(exit_status);
  545. nexttime = time + (1/dz->param[SHUD_FRQ]);
  546. scat = ((drand48() * 2.0) - 1.0) * dz->param[SHUD_SCAT];
  547. if(scat >= 0)
  548. realtime = ((nexttime - time) * scat) + time;
  549. else
  550. realtime = time - ((time - lasttime) * scat);
  551. width = ((dz->param[SHUD_MAXWIDTH] - dz->param[SHUD_MINWIDTH]) * drand48()) + dz->param[SHUD_MINWIDTH];
  552. if((realtime <= (width/2.0) + FLTERR) || (realtime <= lastrealtime))
  553. continue;
  554. lastrealtime = realtime;
  555. dz->parray[SHUD_TIMES][cnt] = realtime;
  556. pos = dz->param[SHUD_SPREAD] * drand48() * left;
  557. left = -left;
  558. pancalc(pos,&leftgain,&rightgain);
  559. depth = ((dz->param[SHUD_MAXDEPTH] - dz->param[SHUD_MINDEPTH]) * drand48()) + dz->param[SHUD_MINDEPTH];
  560. dz->parray[SHUD_DEPTH][cnt] = 1.0 - depth;
  561. lgain = depth * leftgain;
  562. rgain = depth * rightgain;
  563. maxlevel = max(maxlevel,lgain);
  564. maxlevel = max(maxlevel,rgain);
  565. dz->parray[SHUD_LEVEL][cnt2++] = lgain;
  566. dz->parray[SHUD_LEVEL][cnt2++] = rgain;
  567. dz->parray[SHUD_WIDTH][cnt] = width;
  568. if (++cnt >= arraysz[0]) {
  569. arraysz[0] += SMALLARRAY;
  570. if((dz->parray[SHUD_TIMES] = (double *)realloc((char *)dz->parray[SHUD_TIMES],arraysz[0] * sizeof(double)))==NULL) {
  571. sprintf(errstr,"Out of Memory While calculating Shudder Times\n");
  572. return(MEMORY_ERROR);
  573. }
  574. if((dz->parray[SHUD_WIDTH] = (double *)realloc((char *)dz->parray[SHUD_WIDTH],arraysz[0] * sizeof(double)))==NULL) {
  575. sprintf(errstr,"Out of Memory While calculating Shudder Widths\n");
  576. return(MEMORY_ERROR);
  577. }
  578. if((dz->parray[SHUD_DEPTH] = (double *)realloc((char *)dz->parray[SHUD_DEPTH],arraysz[0] * sizeof(double)))==NULL) {
  579. sprintf(errstr,"Out of Memory While calculating Shudder Widths\n");
  580. return(MEMORY_ERROR);
  581. }
  582. }
  583. if (cnt2 >= arraysz[1]) {
  584. arraysz[1] += SMALLARRAY;
  585. if((dz->parray[SHUD_LEVEL] = (double *)realloc((char *)dz->parray[SHUD_LEVEL],arraysz[1] * sizeof(double)))==NULL) {
  586. sprintf(errstr,"Out of Memory While calculating Shudder Levels\n");
  587. return(MEMORY_ERROR);
  588. }
  589. }
  590. }
  591. if((dz->parray[SHUD_TIMES] = (double *)realloc((char *)dz->parray[SHUD_TIMES],cnt * sizeof(double)))==NULL) {
  592. sprintf(errstr,"Out of Memory While calculating Shudder Times\n");
  593. return(MEMORY_ERROR);
  594. }
  595. if((dz->parray[SHUD_WIDTH] = (double *)realloc((char *)dz->parray[SHUD_WIDTH],cnt * sizeof(double)))==NULL) {
  596. sprintf(errstr,"Out of Memory While calculating Shudder Widths\n");
  597. return(MEMORY_ERROR);
  598. }
  599. if((dz->parray[SHUD_DEPTH] = (double *)realloc((char *)dz->parray[SHUD_DEPTH],cnt * sizeof(double)))==NULL) {
  600. sprintf(errstr,"Out of Memory While calculating Shudder Widths\n");
  601. return(MEMORY_ERROR);
  602. }
  603. if((dz->parray[SHUD_LEVEL] = (double *)realloc((char *)dz->parray[SHUD_LEVEL],cnt2 * sizeof(double)))==NULL) {
  604. sprintf(errstr,"Out of Memory While calculating Shudder Levels\n");
  605. return(MEMORY_ERROR);
  606. }
  607. /* NORMALISE LEVELS */
  608. for(m=0;m<cnt2;m++)
  609. dz->parray[SHUD_LEVEL][m] /= maxlevel;
  610. if((dz->parray[SHUD_ENV0] = (double *)malloc(((cnt * 16) + 4) * sizeof(double)))==NULL) {
  611. sprintf(errstr,"Out of Memory While calculating Shudder Envelopes\n");
  612. return(MEMORY_ERROR);
  613. }
  614. if((dz->parray[SHUD_ENV1] = (double *)malloc(((cnt * 16) + 4) * sizeof(double)))==NULL) {
  615. sprintf(errstr,"Out of Memory While calculating Shudder Envelopes\n");
  616. return(MEMORY_ERROR);
  617. }
  618. timecnt = 0;
  619. levelcnt = 0;
  620. cnt0 = 0;
  621. cnt1 = 0;
  622. basetime[0] = -1.0;
  623. basetime[1] = -1.0;
  624. arraysz[0] = SMALLARRAY;
  625. arraysz[1] = SMALLARRAY;
  626. while(timecnt< cnt) {
  627. time = dz->parray[SHUD_TIMES][timecnt];
  628. width = dz->parray[SHUD_WIDTH][timecnt];
  629. one_minus_depth = dz->parray[SHUD_DEPTH][timecnt];
  630. levell = dz->parray[SHUD_LEVEL][levelcnt];
  631. levelr = dz->parray[SHUD_LEVEL][levelcnt+1];
  632. last_postk[0] = -1;
  633. last_postk[1] = -1;
  634. for(j=0;j<8;j++) {
  635. envtime = time + (ee[j] * width);
  636. envlevel = ((levell * ff[j]) + one_minus_depth) * safety;
  637. /* safety compensates for centre boost given by pan-calculation */
  638. insert_point_in_envelope(&(last_postk[0]),basetime[0],SHUD_ENV0,&cnt0,&(last_posttime[0]),&(last_postlevel[0]),
  639. &(last_insertk[0]),&(last_inserttime[0]),&(last_insertlevel[0]),envtime,envlevel,dz);
  640. envlevel = (levelr * ff[j]) + one_minus_depth;
  641. insert_point_in_envelope(&(last_postk[1]),basetime[1],SHUD_ENV1,&cnt1,&(last_posttime[1]),&(last_postlevel[1]),
  642. &(last_insertk[1]),&(last_inserttime[1]),&(last_insertlevel[1]),envtime,envlevel,dz);
  643. }
  644. basetime[0] = dz->parray[SHUD_ENV0][cnt0-2]; /* last envelope time in array */
  645. basetime[1] = dz->parray[SHUD_ENV1][cnt1-2]; /* last envelope time in array */
  646. timecnt++;
  647. levelcnt+=2;
  648. }
  649. if(dz->parray[SHUD_ENV0][0] <= FLTERR) { /* Force points at ZERO and at DURATION+ */
  650. dz->parray[SHUD_ENV0][0] = 0.0;
  651. dz->parray[SHUD_ENV1][0] = 0.0;
  652. } else {
  653. for(n=cnt0-1;n>=0;n--)
  654. dz->parray[SHUD_ENV0][n+2] = dz->parray[SHUD_ENV0][n];
  655. for(n=cnt1-1;n>=0;n--)
  656. dz->parray[SHUD_ENV1][n+2] = dz->parray[SHUD_ENV1][n];
  657. dz->parray[SHUD_ENV0][0] = 0.0;
  658. dz->parray[SHUD_ENV0][1] = dz->parray[SHUD_ENV0][3];
  659. dz->parray[SHUD_ENV1][0] = 0.0;
  660. dz->parray[SHUD_ENV1][1] = dz->parray[SHUD_ENV1][3];
  661. cnt0 += 2;
  662. cnt1 += 2;
  663. }
  664. if(dz->parray[SHUD_ENV0][cnt0 - 2] < dz->duration - FLTERR) {
  665. dz->parray[SHUD_ENV0][cnt0] = dz->duration + FLTERR;
  666. dz->parray[SHUD_ENV0][cnt0 + 1] = dz->parray[SHUD_ENV0][cnt0 - 1];
  667. dz->parray[SHUD_ENV1][cnt1] = dz->duration + FLTERR;
  668. dz->parray[SHUD_ENV1][cnt1 + 1] = dz->parray[SHUD_ENV1][cnt1 - 1];
  669. cnt0 += 2;
  670. cnt1 += 2;
  671. }
  672. if((dz->parray[SHUD_ENV0] = (double *)realloc((char *)dz->parray[SHUD_ENV0],cnt0 * sizeof(double)))==NULL) {
  673. sprintf(errstr,"Out of Memory While calculating Shudder Envelopes\n");
  674. return(MEMORY_ERROR);
  675. }
  676. if((dz->parray[SHUD_ENV1] = (double *)realloc((char *)dz->parray[SHUD_ENV1],cnt1 * sizeof(double)))==NULL) {
  677. sprintf(errstr,"Out of Memory While calculating Shudder Envelopes\n");
  678. return(MEMORY_ERROR);
  679. }
  680. dz->itemcnt = cnt0; /* used to store counts */
  681. dz->extrabrkno = cnt1; /* used to store counts */
  682. if((exit_status = apply_brkpnt_envelope(dz))<0)
  683. return(exit_status);
  684. return(FINISHED);
  685. }
  686. /************************************* INSERT_POINT_IN_ENVELOPE ***********************************/
  687. int insert_point_in_envelope(int *last_postk,double basetime,int thisenv,int *cnt,
  688. double *last_posttime,double *last_postlevel,int *last_insertk,double *last_inserttime,double *last_insertlevel,
  689. double envtime,double envlevel,dataptr dz)
  690. {
  691. int k, j, last_pk;
  692. double pretime, posttime, prelevel, postlevel, timestep, frac, levelhere, last_ptime, last_plevel;
  693. if(envtime <= basetime) {
  694. k = *cnt - 2;
  695. while (dz->parray[thisenv][k] > envtime)
  696. k -= 2;
  697. pretime = dz->parray[thisenv][k];
  698. prelevel = dz->parray[thisenv][k+1];
  699. k += 2;
  700. posttime = dz->parray[thisenv][k];
  701. postlevel = dz->parray[thisenv][k+1];
  702. timestep = posttime - pretime;
  703. frac = (envtime - pretime)/timestep;
  704. levelhere = ((postlevel - prelevel) * frac) + prelevel;
  705. if(envlevel > levelhere) {
  706. for(j = *cnt-1;j >= k; j--) /* SHUFFLUP DATA ABOVE */
  707. dz->parray[thisenv][j+2] = dz->parray[thisenv][j];
  708. dz->parray[thisenv][k] = envtime; /* INSERT NEW POINT */
  709. dz->parray[thisenv][k+1] = envlevel;
  710. *cnt += 2;
  711. if(*last_postk >= 0) { /* IF POINTS HAVE ALREADY BEEN INSERTED */
  712. timestep = dz->parray[thisenv][k] - dz->parray[thisenv][*last_insertk];
  713. last_pk = *last_postk;
  714. last_ptime = *last_posttime; /* CHECK POINTS INTERVENING BETWEEN THIS AND LAST INSERT */
  715. last_plevel = *last_postlevel;
  716. while(envtime > last_ptime) {
  717. frac = (last_ptime - *last_inserttime)/timestep;
  718. levelhere = ((envlevel - *last_insertlevel) * frac) + *last_insertlevel;
  719. if(levelhere > last_plevel)
  720. dz->parray[thisenv][last_pk+1] = levelhere;
  721. last_pk += 2;
  722. last_ptime = dz->parray[thisenv][last_pk];
  723. last_plevel = dz->parray[thisenv][last_pk+1];
  724. }
  725. }
  726. *last_insertk = k; /* REMEMBER TIMES AND LEVELS OF LAST INSERT, AND POST-INSERT */
  727. *last_inserttime = dz->parray[thisenv][k];
  728. *last_insertlevel = dz->parray[thisenv][k+1];
  729. k +=2;
  730. *last_postk = k;
  731. *last_posttime = dz->parray[thisenv][k];
  732. *last_postlevel = dz->parray[thisenv][k+1];
  733. } else {
  734. *last_postk = -1;
  735. }
  736. } else {
  737. dz->parray[thisenv][(*cnt)++] = envtime;
  738. dz->parray[thisenv][(*cnt)++] = envlevel;
  739. *last_postk = -1;
  740. }
  741. return(FINISHED);
  742. }
  743. /******************************* APPLY_BRKPNT_ENVELOPE *******************************/
  744. int apply_brkpnt_envelope(dataptr dz)
  745. {
  746. int exit_status, ofd0, ofd1;
  747. int samps_left_to_process = dz->insams[0], sampout_cnt;
  748. int sampno, nextbrk_sampno;
  749. double starttime, gain, nextgain, gain_step, gain_incr, multiplier0 = 0.0, multiplier1 = 0.0;
  750. double *endbrk, *nextbrk;
  751. int total_samps_to_read, n, j, k,samps_to_read_here;
  752. int chan;
  753. float maxobuf0, maxobuf1;
  754. char *outfilename;
  755. if(sloom) {
  756. if((outfilename = (char *)malloc((strlen(dz->wordstor[0])+1) * sizeof(char)))==NULL) {
  757. sprintf(errstr,"INSUFFICIENT MEMORY for outfilename.\n");
  758. return(MEMORY_ERROR);
  759. }
  760. } else {
  761. if((outfilename = (char *)malloc((strlen(dz->outfilename)+1) * sizeof(char)))==NULL) {
  762. sprintf(errstr,"INSUFFICIENT MEMORY for outfilename.\n");
  763. return(MEMORY_ERROR);
  764. }
  765. }
  766. /* ENVELOPE CHANNEL 1 */
  767. chan = 0;
  768. maxobuf0 = 0.0f;
  769. if((exit_status = do_simple_read(&samps_left_to_process,dz->buflen,chan,dz))<0)
  770. return(exit_status); /* setup simple buffering option */
  771. if((exit_status = init_brkpnts
  772. (&sampno,&starttime,&gain,&endbrk,&nextbrk,&nextgain,&gain_step,&gain_incr,&nextbrk_sampno,SHUD_ENV0,dz->itemcnt,dz))<0)
  773. return(exit_status);
  774. if((exit_status = simple_envel_processing(&samps_left_to_process,starttime,endbrk,&nextbrk,&nextgain,
  775. &sampno,&gain,&gain_step,&gain_incr,&nextbrk_sampno,chan,&maxobuf0,dz))<0)
  776. return(exit_status);
  777. /* STORE CHANNEL 1 OUTFILE */
  778. ofd0 = dz->ofd;
  779. /* CREATE CHANNEL 2 OUTFILE */
  780. if(sloom) {
  781. strcpy(outfilename,dz->wordstor[0]);
  782. insert_new_number_at_filename_end(outfilename,2,1);
  783. } else {
  784. strcpy(outfilename,dz->outfilename);
  785. insert_new_number_at_filename_end(outfilename,2,1);
  786. }
  787. sampout_cnt = dz->total_samps_written;
  788. if((exit_status = create_sized_outfile(outfilename,dz))<0) {
  789. dz->ofd = ofd0;
  790. return(SYSTEM_ERROR);
  791. }
  792. dz->total_samps_written = sampout_cnt;
  793. /* RESET INFILE TO START */
  794. sndseekEx(dz->ifd[0],0,0);
  795. samps_left_to_process = dz->insams[0];
  796. /* ENVELOPE CHANNEL 2 */
  797. chan = 1;
  798. maxobuf1 = 0.0f;
  799. if((exit_status = do_simple_read(&samps_left_to_process,dz->buflen,chan,dz))<0)
  800. return(exit_status); /* setup simple buffering option */
  801. if((exit_status = init_brkpnts
  802. (&sampno,&starttime,&gain,&endbrk,&nextbrk,&nextgain,&gain_step,&gain_incr,&nextbrk_sampno,SHUD_ENV1,dz->extrabrkno,dz))<0)
  803. return(exit_status);
  804. if((exit_status = simple_envel_processing(&samps_left_to_process,starttime,endbrk,&nextbrk,&nextgain,
  805. &sampno,&gain,&gain_step,&gain_incr,&nextbrk_sampno,chan,&maxobuf1,dz))<0)
  806. return(exit_status);
  807. /* STORE CHANNEL 2 OUTFILE */
  808. ofd1 = dz->ofd;
  809. /* CREATE STEREO OUTFILE */
  810. strcpy(outfilename,dz->wordstor[0]);
  811. if(sloom)
  812. insert_new_number_at_filename_end(outfilename,0,1);
  813. else
  814. outfilename[strlen(outfilename) -9] = ENDOFSTR;
  815. sampout_cnt = dz->total_samps_written;
  816. if((exit_status = create_sized_outfile(outfilename,dz))<0) {
  817. unlink_temp_files(1,ofd0,ofd1,dz);
  818. return(SYSTEM_ERROR);
  819. }
  820. if((exit_status = reset_peak_finder(dz))<0)
  821. return(exit_status);
  822. dz->total_samps_written = sampout_cnt;
  823. /* RESET BOTH CHANNEL-FILES TO START */
  824. sndseekEx(ofd0,0,0);
  825. sndseekEx(ofd1,0,0);
  826. total_samps_to_read = dz->insams[0]/2;
  827. /* MERGE SEPARATE CHANNELS BACK INTO STEREO */
  828. if(dz->vflag[SHUD_BALANCE]) {
  829. if(((maxobuf0 > maxobuf1) && (maxobuf0/maxobuf1 < ONE_dB))
  830. || (maxobuf1/maxobuf0 < ONE_dB))
  831. dz->vflag[0] = 0;
  832. else if(maxobuf0 > maxobuf1) {
  833. multiplier1 = maxobuf0/maxobuf1;
  834. } else {
  835. multiplier1 = -1.0;
  836. multiplier0 = maxobuf1/maxobuf0;
  837. }
  838. }
  839. while(total_samps_to_read > 0) {
  840. samps_to_read_here = min(total_samps_to_read,dz->buflen);
  841. if((exit_status = other_read_samps(samps_to_read_here,ofd0,0,dz))<0) {
  842. unlink_temp_files(2,ofd0,ofd1,dz);
  843. return(exit_status);
  844. }
  845. if((exit_status = other_read_samps(samps_to_read_here,ofd1,1,dz))<0) {
  846. unlink_temp_files(2,ofd0,ofd1,dz);
  847. return(exit_status);
  848. }
  849. if(dz->vflag[SHUD_BALANCE]) {
  850. if(multiplier1 > 0.0) {
  851. for(n=0,j=0,k=1;n<dz->ssampsread;n++,j+=2,k+=2) {
  852. dz->sampbuf[2][j] = dz->sampbuf[0][n];
  853. dz->sampbuf[2][k] = (float)(dz->sampbuf[1][n] * multiplier1);
  854. }
  855. } else {
  856. for(n=0,j=0,k=1;n<dz->ssampsread;n++,j+=2,k+=2) {
  857. dz->sampbuf[2][j] = (float)(dz->sampbuf[0][n] * multiplier0);
  858. dz->sampbuf[2][k] = dz->sampbuf[1][n];
  859. }
  860. }
  861. } else {
  862. for(n=0,j=0,k=1;n<dz->ssampsread;n++,j+=2,k+=2) {
  863. dz->sampbuf[2][j] = dz->sampbuf[0][n];
  864. dz->sampbuf[2][k] = dz->sampbuf[1][n];
  865. }
  866. }
  867. if(dz->ssampsread > 0) {
  868. if((exit_status = write_samps(dz->sampbuf[2],dz->ssampsread * 2,dz))<0) {
  869. unlink_temp_files(2,ofd0,ofd1,dz);
  870. return(exit_status);
  871. }
  872. }
  873. total_samps_to_read -= dz->ssampsread;
  874. }
  875. /* DELETE TEMPORARY OUTFILES */
  876. unlink_temp_files(2,ofd0,ofd1,dz);
  877. return FINISHED;
  878. }
  879. /**************************** INIT_BRKPNTS ********************************/
  880. int init_brkpnts(int *sampno,double *starttime,double *gain,double **endbrk,double **nextbrk,
  881. double *nextgain,double *gain_step,double *gain_incr,int *nextbrk_sampno,int paramno,int brksize,dataptr dz)
  882. {
  883. double nexttime, time_from_start;
  884. *endbrk = dz->parray[paramno] + ((brksize-1) * 2);
  885. *sampno = 0;
  886. *starttime = dz->parray[paramno][0];
  887. *gain = dz->parray[paramno][1];
  888. *nextbrk = dz->parray[paramno] + 2;
  889. nexttime = **nextbrk;
  890. *nextgain = *((*nextbrk) + 1);
  891. *gain_step = *nextgain - *gain;
  892. time_from_start = nexttime - *starttime;
  893. if((*nextbrk_sampno = (int)round(time_from_start * (double)dz->infile->srate))<0) {
  894. sprintf(errstr,"Impossible brkpoint time: (%.2lf secs)\n",time_from_start);
  895. return(PROGRAM_ERROR);
  896. }
  897. *gain_incr = (*gain_step)/(double)(*nextbrk_sampno);
  898. return(FINISHED);
  899. }
  900. /**************************** ADVANCE_BRKPNTS ******************************/
  901. int advance_brkpnts(double starttime,double *gain,double *endbrk,double **nextbrk,
  902. double *nextgain,double *gain_step,double *gain_incr,int *nextbrk_sampno,dataptr dz)
  903. {
  904. double nexttime, time_from_start;
  905. int lastbrk_sampno, sampdist;
  906. if(*nextbrk!=endbrk) {
  907. *nextbrk += 2;
  908. *gain = *nextgain;
  909. nexttime = **nextbrk;
  910. *nextgain = *((*nextbrk) + 1);
  911. *gain_step = *nextgain - *gain;
  912. lastbrk_sampno = *nextbrk_sampno;
  913. time_from_start = nexttime - starttime;
  914. if((*nextbrk_sampno = (int)round(time_from_start * dz->infile->srate))<0) {
  915. sprintf(errstr,"Impossible brkpoint time: (%.2lf secs)\n",time_from_start);
  916. return(PROGRAM_ERROR);
  917. }
  918. sampdist = *nextbrk_sampno - lastbrk_sampno;
  919. *gain_incr = (*gain_step)/(double)sampdist;
  920. }
  921. return(FINISHED);
  922. }
  923. /*********************** SIMPLE_ENVEL_PROCESSING *********************************/
  924. int simple_envel_processing
  925. (int *samps_left_to_process,double starttime,double *endbrk,double **nextbrk,double *nextgain,
  926. int *sampno,double *gain,double *gain_step,double *gain_incr,int *nextbrk_sampno,int chan,float *maxobuf,dataptr dz)
  927. {
  928. int exit_status;
  929. while(*samps_left_to_process > 0) {
  930. if((exit_status = do_mono_envelope
  931. (dz->buflen,starttime,endbrk,nextbrk,nextgain,sampno,gain,gain_step,gain_incr,nextbrk_sampno,maxobuf,dz))<0)
  932. return(exit_status);
  933. if((exit_status = write_samps(dz->sampbuf[1],dz->buflen,dz))<0)
  934. return(exit_status);
  935. if((exit_status = do_simple_read(samps_left_to_process,dz->buflen,chan,dz))<0)
  936. return(exit_status);
  937. }
  938. if((exit_status = do_mono_envelope
  939. (dz->ssampsread,starttime,endbrk,nextbrk,nextgain,sampno,gain,gain_step,gain_incr,nextbrk_sampno,maxobuf,dz))<0)
  940. return(exit_status);
  941. if(dz->ssampsread > 0)
  942. return write_samps(dz->sampbuf[1],dz->ssampsread,dz);
  943. return FINISHED;
  944. }
  945. /************************* DO_MONO_ENVELOPE *********************************/
  946. int do_mono_envelope
  947. (int sampcnt,double starttime,double *endbrk,double **nextbrk,double *nextgain,
  948. int *sampno,double *gain,double *gain_step,double *gain_incr,int *nextbrk_sampno,float *maxobuf,dataptr dz)
  949. {
  950. int exit_status;
  951. int n;
  952. int endsampno, this_endsamp, this_sampcnt;
  953. float *ibuf = dz->sampbuf[0];
  954. float *obuf = dz->sampbuf[1];
  955. float *obufend = obuf + dz->buflen;
  956. int quit = FALSE, change;
  957. double this_gain = *gain;
  958. double this_gain_incr = *gain_incr;
  959. double this_gain_step = *gain_step;
  960. endsampno = *sampno + sampcnt; /* 1 */
  961. if(sampcnt > dz->buflen) {
  962. sprintf(errstr,"Buffering anomaly: do_mono_envelope()\n");
  963. return(PROGRAM_ERROR);
  964. }
  965. while(quit==FALSE) {
  966. if(*nextbrk_sampno <= endsampno) { /* 2 */
  967. change = TRUE;
  968. this_endsamp = *nextbrk_sampno; /* 3 */
  969. if(*nextbrk_sampno==endsampno)
  970. quit = TRUE; /* 4 */
  971. } else {
  972. change = FALSE; /* 5 */
  973. this_endsamp = endsampno;
  974. quit = TRUE;
  975. }
  976. this_sampcnt = this_endsamp - *sampno; /* 6 */
  977. if(obuf + this_sampcnt > obufend) {
  978. sprintf(errstr,"array overrun: do_mono_envelope()\n");
  979. return(PROGRAM_ERROR);
  980. }
  981. if(flteq(this_gain,1.0) && flteq(this_gain_step,0.0)) {
  982. obuf += this_sampcnt;
  983. ibuf += this_sampcnt; /* no modification of sound */
  984. }
  985. else {
  986. for(n=0;n<this_sampcnt;n++) { /* 7 */
  987. this_gain += this_gain_incr;
  988. *obuf = (float)(*ibuf * this_gain);
  989. *maxobuf = max(*maxobuf,*obuf);
  990. obuf++;
  991. ibuf++;
  992. }
  993. }
  994. *sampno += this_sampcnt; /* 8 */
  995. if(change) { /* 9 */
  996. if((exit_status = advance_brkpnts
  997. (starttime,gain,endbrk,nextbrk,nextgain,gain_step,gain_incr,nextbrk_sampno,dz))<0)
  998. return(exit_status);
  999. this_gain = *gain;
  1000. this_gain_incr = *gain_incr;
  1001. this_gain_step = *gain_step;
  1002. }
  1003. }
  1004. *gain = this_gain; /* 10 */
  1005. return(FINISHED);
  1006. }
  1007. /************************* READ_SSAMPS ******************************/
  1008. int read_ssamps(int samps_to_read,int *samps_left_to_process,int chan,dataptr dz)
  1009. {
  1010. int n, m;
  1011. if((dz->ssampsread = fgetfbufEx(dz->sampbuf[2],samps_to_read,dz->ifd[0],0))<0) {
  1012. sprintf(errstr,"Can't read samps from input soundfile: read_ssamps()\n");
  1013. return(SYSTEM_ERROR);
  1014. }
  1015. if(dz->ssampsread!=samps_to_read) {
  1016. sprintf(errstr,"Error in buffering arithmetic: read_ssamps()\n");
  1017. return(PROGRAM_ERROR);
  1018. }
  1019. *samps_left_to_process -= dz->ssampsread;
  1020. dz->ssampsread /= 2;
  1021. for(n=0,m=chan;n<dz->ssampsread;n++,m+=2)
  1022. dz->sampbuf[0][n] = dz->sampbuf[2][m];
  1023. return(FINISHED);
  1024. }
  1025. /******************************** DO_SIMPLE_READ **********************************/
  1026. int do_simple_read(int *samps_left_to_process,int buflen,int chan,dataptr dz)
  1027. {
  1028. int exit_status;
  1029. if(*samps_left_to_process < buflen * 2)
  1030. exit_status = read_ssamps(*samps_left_to_process,samps_left_to_process,chan,dz);
  1031. else
  1032. exit_status = read_ssamps(buflen * 2,samps_left_to_process,chan,dz);
  1033. return(exit_status);
  1034. }
  1035. /**************************** OTHER_READ_SAMPS *****************************/
  1036. int other_read_samps(int samps_to_read,int fileid,int bufno,dataptr dz)
  1037. {
  1038. if((dz->ssampsread = fgetfbufEx(dz->sampbuf[bufno],samps_to_read,fileid,0)) < 0) {
  1039. sprintf(errstr,"Can't read samps from input soundfile: other_read_samps()\n");
  1040. return(SYSTEM_ERROR);
  1041. }
  1042. if(dz->ssampsread < samps_to_read) {
  1043. sprintf(errstr,"Error in buffering arithmetic: other_read_samps()\n");
  1044. return(PROGRAM_ERROR);
  1045. }
  1046. return(FINISHED);
  1047. }
  1048. /**************************** UNLINK_TEMP_FILES *****************************/
  1049. void unlink_temp_files(int type,int ofd0, int ofd1,dataptr dz)
  1050. {
  1051. switch(type) {
  1052. case(1):
  1053. if(sndunlink(ofd1) < 0)
  1054. fprintf(stdout, "ERROR: Can't set temporary output soundfile for deletion.\n");
  1055. if(sndcloseEx(ofd1) < 0)
  1056. fprintf(stdout, "WARNING: Can't close temporary output soundfile.\n");
  1057. else
  1058. ofd1 = -1;
  1059. dz->ofd = ofd0; /* closed at finish() */
  1060. break;
  1061. case(2):
  1062. if(sndunlink(ofd0) < 0)
  1063. fprintf(stdout, "ERROR: Can't set 1st temporary output soundfile for deletion.\n");
  1064. if(sndcloseEx(ofd0) < 0)
  1065. fprintf(stdout, "WARNING: Can't close 1st temporary output soundfile.\n");
  1066. else
  1067. ofd0 = -1;
  1068. if(sndunlink(ofd1) < 0)
  1069. fprintf(stdout, "ERROR: Can't set 2nd temporary output soundfile for deletion.\n");
  1070. if(sndcloseEx(ofd1) < 0)
  1071. fprintf(stdout, "WARNING: Can't close 2nd temporary output soundfile.\n");
  1072. else
  1073. ofd1 = -1;
  1074. break;
  1075. }
  1076. }
  1077. /************************************ FINDPAN *******************************/
  1078. int findpan(dataptr dz)
  1079. {
  1080. int exit_status;
  1081. int n, m, k, samppos, secpos;
  1082. double panpos;
  1083. float *inbuf = dz->sampbuf[0];
  1084. float maxL = 0.0, maxR = 0.0;
  1085. if(dz->param[PAN_PAN] > 0.0) { /* Assesses One Sector at given time */
  1086. samppos = round(dz->param[PAN_PAN] * dz->infile->srate) * dz->infile->channels;
  1087. secpos = samppos;
  1088. if (secpos >= dz->insams[0]) {
  1089. if((secpos -= F_SECSIZE) < 0)
  1090. secpos = 0;
  1091. }
  1092. secpos = (secpos/F_SECSIZE) * F_SECSIZE;
  1093. sndseekEx(dz->ifd[0],secpos,0);
  1094. if((exit_status = read_samps(inbuf,dz))<0) {
  1095. sprintf(errstr,"Failed to read data from sndfile.\n");
  1096. return(DATA_ERROR);
  1097. }
  1098. k = min(dz->ssampsread,F_SECSIZE);
  1099. for(n=0,m=1;n<k;n+=2,m+=2) {
  1100. maxL = (float)max(fabs(inbuf[n]),maxL);
  1101. maxR = (float)max(fabs(inbuf[m]),maxR);
  1102. }
  1103. } else { /* Assesses whole file */
  1104. do {
  1105. if((exit_status = read_samps(inbuf,dz))<0) {
  1106. sprintf(errstr,"Failed to read data from sndfile.\n");
  1107. return(DATA_ERROR);
  1108. }
  1109. for(n=0,m=1;n<dz->ssampsread;n+=2,m+=2) {
  1110. maxL = (float)max(fabs(inbuf[n]),maxL);
  1111. maxR = (float)max(fabs(inbuf[m]),maxR);
  1112. }
  1113. } while(dz->samps_left > 0);
  1114. }
  1115. if(maxL < SMP_FLTERR && maxR < SMP_FLTERR)
  1116. fprintf(stdout,"INFO: levels are ZERO\n");
  1117. else {
  1118. panpos = maxR/(maxR + maxL);
  1119. panpos = (panpos * 2.0) - 1.0;
  1120. fprintf(stdout,"INFO: levels LEFT %.3lf RIGHT %.3lf : Panning position is %.2lf\n",maxL,maxR,panpos);
  1121. }
  1122. fflush(stdout);
  1123. return(FINISHED);
  1124. }