syncatt.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603
  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. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <string.h>
  24. #include <structures.h>
  25. #include <tkglobals.h>
  26. #include <globcon.h>
  27. #include <processno.h>
  28. #include <modeno.h>
  29. #include <filetype.h>
  30. #include <arrays.h>
  31. #include <mix.h>
  32. #include <cdpmain.h>
  33. #include <sfsys.h>
  34. //#ifdef unix
  35. #define round(x) lround((x))
  36. //#endif
  37. static int getenvpeak(int n,int samps_per_second,
  38. int windows_per_sector,int sectors_per_window,int window_size,dataptr dz);
  39. static int gettime_of_maxsamp(int k, /*int*/float *env,/*int*/float *envend,int *envpos,int *peak_sampno,int window_size);
  40. static int create_envelope_arrays(int n,int numsects,int windows_per_sector,int sectors_per_window,
  41. int **envpos,/*int*/float **env,dataptr dz);
  42. static int count_sectors_to_scan(int *numsects,int lineno,int *skipsamps,int samps_per_second,dataptr dz);
  43. static int get_envelope(int skipsamps,int **envpos,/*int*/float **env,int nbuff,int nsec, int window_size,dataptr dz);
  44. static void readenv_in_buffer(float *buf,int samps_to_process,int window_size,int **envpos,/*int*/float **env,int powflag);
  45. static void getmaxsamp_in_window(float *buf,int startsamp,int sample_cnt,int *envpos, /*int*/float *env,int powflag);
  46. static int rescale_the_lines(double atten,dataptr dz);
  47. static int attenuate_line(int total_words,double atten,int wordcnt,dataptr dz);
  48. static int output_a_new_syncatt_file(double *timestor,double gain,dataptr dz);
  49. static int output_a_syncatt_file(double *timestor,double gain,dataptr dz);
  50. static int sum_maximum_samples(int n,double *total_maxval,dataptr dz);
  51. static int get_filesearch_data(dataptr dz);
  52. static int check_syncatt_window_factor(dataptr dz);
  53. /******************************** SYNCHRONISE_MIX_ATTACK ******************************/
  54. /* RWD crude hack to avoid SECSIZE abusage! */
  55. /* NB dz->lparray relaced with dz->lfarray for MSY_ENVEL amp stuff*/
  56. //TW WINSECSIZE replaced by global F_SECSIZE
  57. int synchronise_mix_attack(dataptr dz)
  58. {
  59. int exit_status;
  60. double total_maxval = 0.0, attenuation = 1.0, *timestor;
  61. int sectors_per_window, n, max_atk_time = 0, sampblok, window_size;
  62. int windows_per_sector, typefactor, inchans;
  63. int total_words = 0, srate =0, samps_per_second;
  64. int textfile_filetype = dz->infile->filetype;
  65. for(n=0;n<dz->linecnt;n++) {
  66. windows_per_sector = 0;
  67. if((exit_status = open_file_retrieve_props_open(n,dz->wordstor[total_words],&srate,dz))<0)
  68. return(exit_status);
  69. inchans = dz->iparray[MSY_CHANS][n];
  70. samps_per_second = srate * inchans;
  71. typefactor = dz->iparam[MSY_SRFAC] * inchans;
  72. sampblok = (F_SECSIZE * typefactor)/dz->iparam[MSY_WFAC];
  73. if((sectors_per_window = sampblok/F_SECSIZE)<=0)
  74. windows_per_sector = F_SECSIZE/sampblok;
  75. window_size = sampblok;
  76. if((exit_status = getenvpeak(n,samps_per_second,windows_per_sector,sectors_per_window,window_size,dz))<0)
  77. return(exit_status);
  78. if((exit_status = sum_maximum_samples(n,&total_maxval,dz))<0) /* read maxsample and add to running sum */
  79. return(exit_status);
  80. dz->lparray[MSY_PEAKSAMP][n] /= inchans; /* convert to 'stereo'-sample count: TRUNCATES */
  81. max_atk_time = max(max_atk_time,dz->lparray[MSY_PEAKSAMP][n]); /* find attack time which is latest */
  82. total_words += dz->wordcnt[n];
  83. if(sndcloseEx(dz->ifd[0])<0) {
  84. sprintf(errstr, "Failed to close input file %s: line %d: synchronise_mix_attack()\n",
  85. dz->wordstor[total_words],n+1);
  86. return(SYSTEM_ERROR);
  87. }
  88. dz->ifd[0] = -1;
  89. }
  90. if(total_maxval > (double)F_MAXSAMP) /* calculate required attenuation */
  91. attenuation = (double)F_MAXSAMP/total_maxval;
  92. if((dz->parray[MSY_TIMESTOR] = (double *)malloc(dz->linecnt * sizeof(double)))==NULL) {
  93. sprintf(errstr,"INSUFFICIENT MEMORY to store times.\n");
  94. return(MEMORY_ERROR);
  95. }
  96. timestor = dz->parray[MSY_TIMESTOR];
  97. for(n=0;n<dz->linecnt;n++) /* calculate sndfile offsets */
  98. timestor[n] = (double)(max_atk_time - dz->lparray[MSY_PEAKSAMP][n])/(double)srate;
  99. dz->infile->filetype = textfile_filetype;
  100. switch(dz->infile->filetype) {
  101. case(SNDLIST):
  102. case(SYNCLIST):
  103. return output_a_new_syncatt_file(timestor,attenuation,dz);
  104. case(MIXFILE):
  105. return output_a_syncatt_file(timestor,attenuation,dz);
  106. default:
  107. sprintf(errstr,"Unknown case in synchronise_mix_attack()\n");
  108. return(PROGRAM_ERROR);
  109. }
  110. return(FINISHED); /* NOTREACHED */
  111. }
  112. /* RWD NB window_size is in samps */
  113. /* dz->lparray etc now floats */
  114. /******************************** GETENVPEAK ******************************/
  115. int getenvpeak(int lineno,int samps_per_second,int windows_per_sector,int sectors_per_window,int window_size,dataptr dz)
  116. {
  117. int exit_status;
  118. int peak_sampno;
  119. int skipsamps, numsects, searchsize, nbuff, nsec;
  120. int *envpos;
  121. /*int*/float *env, *envend;
  122. if((exit_status = count_sectors_to_scan(&numsects,lineno,&skipsamps,samps_per_second,dz))<0)
  123. return(exit_status);
  124. if((exit_status = create_envelope_arrays(lineno,numsects,windows_per_sector,sectors_per_window,&envpos,&env,dz))<0)
  125. return(exit_status);
  126. searchsize = numsects * F_SECSIZE;
  127. nbuff = searchsize/dz->buflen; /* no. of whole buffs to srch */
  128. nsec = (searchsize % dz->buflen)/F_SECSIZE; /* no. of further secs to srch */
  129. if((exit_status = get_envelope(skipsamps,&envpos,&env,nbuff,nsec,window_size,dz))<0)
  130. return(exit_status);
  131. envend = env;
  132. env = dz->lfarray[MSY_ENVEL];
  133. envpos = dz->iparray[MSY_ENVPOS];
  134. if((exit_status = gettime_of_maxsamp(lineno,env,envend,envpos,&peak_sampno,window_size))<0)
  135. return(exit_status);
  136. dz->lparray[MSY_PEAKSAMP][lineno] = peak_sampno + skipsamps;
  137. return(FINISHED);
  138. }
  139. /***************************** GETTIME_OF_MAXSAMP ***********************************/
  140. int gettime_of_maxsamp(int lineno, /*int*/float *env,/*int*/float *envend,int *envpos,int *peak_sampno,int window_size)
  141. {
  142. float peak = 0.0f, *thismax = env, *loudest_place = NULL;
  143. int blokno;
  144. while(thismax < envend) {
  145. if(*thismax > peak) {
  146. peak = *thismax;
  147. loudest_place = thismax;
  148. }
  149. thismax++;
  150. }
  151. if(loudest_place==NULL) {
  152. fprintf(stdout,"WARNING: No peak found in file %d: Syncing to file start.\n",lineno+1);
  153. fflush(stdout);
  154. *peak_sampno = 0;
  155. return(FINISHED);
  156. }
  157. blokno = loudest_place - env; /* to nearest shrtblok */
  158. *peak_sampno = (blokno * window_size) + envpos[blokno]; /* to nearest sample */
  159. return(FINISHED);
  160. }
  161. /********************** CREATE_ENVELOPE_ARRAYS ***********************/
  162. int create_envelope_arrays
  163. (int lineno,int numsects,int windows_per_sector,int sectors_per_window,int **envpos,/*int*/float **env,dataptr dz)
  164. {
  165. int arraysize;
  166. if(windows_per_sector > 0) {
  167. arraysize = numsects * windows_per_sector;
  168. arraysize += windows_per_sector; /* Allow for a short buf at end */
  169. } else {
  170. arraysize = numsects/sectors_per_window;
  171. arraysize++; /* round up + allow ditto */
  172. }
  173. if(lineno==0) {
  174. if((dz->iparray[MSY_ENVPOS] = (int *)malloc(arraysize * sizeof(int)))==NULL) {
  175. sprintf(errstr,"INSUFFICIENT MEMORY to store envelope positions.\n");
  176. return(MEMORY_ERROR);
  177. }
  178. if((dz->lfarray[MSY_ENVEL] = (/*int*/float *)malloc(arraysize * sizeof(/*int*/float)))==NULL) {
  179. sprintf(errstr,"INSUFFICIENT MEMORY to store envelope.\n");
  180. return(MEMORY_ERROR);
  181. }
  182. } else {
  183. free(dz->iparray[MSY_ENVPOS]);
  184. free(dz->lparray[MSY_ENVEL]);
  185. dz->iparray[MSY_ENVPOS] = NULL;
  186. dz->lparray[MSY_ENVEL] = NULL;
  187. if((dz->iparray[MSY_ENVPOS] = (int *)realloc(dz->iparray[MSY_ENVPOS],arraysize * sizeof(int)))==NULL) {
  188. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate envelope positions.\n");
  189. return(MEMORY_ERROR);
  190. }
  191. if((dz->lfarray[MSY_ENVEL] = (/*int*/float *)realloc(dz->lfarray[MSY_ENVEL],arraysize * sizeof(/*int*/float)))==NULL) {
  192. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate envelope.\n");
  193. return(MEMORY_ERROR);
  194. }
  195. }
  196. *envpos = dz->iparray[MSY_ENVPOS];
  197. *env = dz->lfarray[MSY_ENVEL];
  198. return(FINISHED);
  199. }
  200. /****************************** COUNT_SECTORS_TO_SCAN *******************************/
  201. int count_sectors_to_scan(int *numsects,int lineno,int *skipsamps,int samps_per_second,dataptr dz)
  202. {
  203. int endsamps, endsecs, skipsecs;
  204. double *start = dz->parray[MSY_STARTSRCH];
  205. double *end = dz->parray[MSY_ENDSRCH];
  206. int shsecsize = F_SECSIZE;
  207. skipsecs = 0;
  208. /* RWD what is this doing? */
  209. *skipsamps = round(start[lineno] * (double)samps_per_second);
  210. //TW SAFETY for the moment: matches up with secsize rounding below
  211. // and secsize rounding in envelope-windowing and search
  212. skipsecs = *skipsamps/shsecsize; /* TRUNCATE */
  213. *skipsamps = skipsecs * shsecsize;
  214. if(end[lineno] < 0.0) /* -1.0 flags ENDOFSNDFILE */
  215. endsamps = dz->lparray[MSY_SAMPSIZE][lineno];
  216. else
  217. endsamps = round(end[lineno] * samps_per_second);
  218. endsecs = endsamps/shsecsize;
  219. if(endsecs * shsecsize < endsamps) /* CEILING */
  220. endsecs++;
  221. *numsects = max((int)1,endsecs - skipsecs);
  222. return(FINISHED);
  223. }
  224. /************************** GET_ENVELOPE ***************************/
  225. int get_envelope(int skipsamps,int **envpos,/*int*/float **env,int nbuff,int nsec, int window_size,dataptr dz)
  226. {
  227. int exit_status;
  228. int n, shrtstoget;
  229. int shsecsize = F_SECSIZE;
  230. float *buf = dz->sampbuf[0];
  231. int powflag = dz->vflag[MSY_POWMETHOD];
  232. if(sndseekEx(dz->ifd[0],skipsamps,0)<0) {
  233. sprintf(errstr,"seek() failed in get_envelope()\n");
  234. return(SYSTEM_ERROR);
  235. }
  236. if(nbuff > 0) {
  237. for(n = 0; n < nbuff-1; n++) { /* 1ST PASS : WHOLE BUFFERS */
  238. if((exit_status = read_samps(dz->bigbuf,dz))<0)
  239. return(exit_status);
  240. if(dz->ssampsread < dz->buflen) {
  241. sprintf(errstr,"Error in buffer accounting: get_envelope()\n");
  242. return(PROGRAM_ERROR);
  243. }
  244. readenv_in_buffer(buf,dz->buflen,window_size,envpos,env,powflag);
  245. }
  246. /* 2ND PASS : LAST WHOLE BUFFERS */
  247. if((exit_status = read_samps(dz->bigbuf,dz))<0)
  248. return(exit_status);
  249. if(nsec > 0 && dz->ssampsread < dz->buflen) {
  250. sprintf(errstr,"Error in buffer accounting: get_envelope()\n");
  251. return(PROGRAM_ERROR);
  252. }
  253. readenv_in_buffer(buf,min(dz->ssampsread,dz->buflen),window_size,envpos,env,powflag);
  254. }
  255. if(nsec) { /* 3RD PASS : REMAINING SECTORS */
  256. shrtstoget = nsec * shsecsize;
  257. if((exit_status = read_samps(dz->bigbuf,dz))<0)
  258. return(exit_status);
  259. readenv_in_buffer(buf,min(shrtstoget,dz->ssampsread),window_size,envpos,env,powflag);
  260. }
  261. return(FINISHED);
  262. }
  263. /************************* READENV_IN_BUFFER ******************************/
  264. void readenv_in_buffer(float *buf,int samps_to_process,int window_size,int **envpos,/*int*/float **env,int powflag)
  265. {
  266. int startsamp = 0;
  267. int *epos;
  268. float *ev;
  269. epos = *envpos;
  270. ev = *env;
  271. while(samps_to_process >= window_size) {
  272. getmaxsamp_in_window(buf,startsamp,window_size,epos,ev,powflag);
  273. epos++;
  274. ev++;
  275. startsamp += window_size;
  276. samps_to_process -= window_size;
  277. }
  278. if(samps_to_process) { /* Handle any final short buffer */
  279. getmaxsamp_in_window(buf,startsamp,samps_to_process,epos,ev,powflag);
  280. epos++;
  281. ev++;
  282. }
  283. *envpos = epos;
  284. *env = ev;
  285. }
  286. /*************************** GETMAXSAMP_IN_WINDOW ********************************/
  287. void getmaxsamp_in_window(float *buf,int startsamp,int sample_cnt,int *envpos, /*int*/float *env,int powflag)
  288. {
  289. int i, endsamp = startsamp + sample_cnt, maxpos = startsamp;
  290. double rms_power = 0.0;
  291. double maxval = 0, val;
  292. switch(powflag) {
  293. case(TRUE):
  294. for(i = startsamp; i<endsamp; i++) {
  295. val = fabs(buf[i]);
  296. rms_power += (double)(val * val);
  297. if(val > maxval) {
  298. maxval = val;
  299. maxpos = i;
  300. }
  301. }
  302. rms_power /= (double)sample_cnt;
  303. rms_power = sqrt(rms_power);
  304. *env = (float) rms_power;
  305. break;
  306. case(FALSE):
  307. for(i = startsamp; i<endsamp; i++) {
  308. val = fabs(buf[i]);
  309. if(val > maxval) {
  310. maxval = val;
  311. maxpos = i;
  312. }
  313. }
  314. *env = (float)maxval;
  315. break;
  316. }
  317. *envpos = (int)(maxpos - startsamp);
  318. }
  319. /*************************** RESCALE_THE_LINES ***************************/
  320. int rescale_the_lines(double atten,dataptr dz)
  321. {
  322. int exit_status;
  323. int lineno;
  324. int total_words = 0;
  325. for(lineno=0;lineno<dz->linecnt;lineno++) {
  326. if((exit_status = attenuate_line(total_words,atten,dz->wordcnt[lineno],dz))<0)
  327. return(exit_status);
  328. total_words += dz->wordcnt[lineno];
  329. }
  330. return(FINISHED);
  331. }
  332. /************************** ATTENUATE_LINE ***************************/
  333. int attenuate_line(int total_words,double atten,int wordcnt,dataptr dz)
  334. {
  335. int exit_status;
  336. int wordno, newlen;
  337. double level;
  338. wordno = total_words + MIX_LEVELPOS;
  339. if((exit_status = get_level(dz->wordstor[wordno],&level))<0)
  340. return(exit_status);
  341. sprintf(errstr,"%.5lf",level * atten);
  342. if((newlen = (int)strlen(errstr)) > (int)strlen(dz->wordstor[wordno])) {
  343. if((dz->wordstor[wordno] = (char *)realloc(dz->wordstor[wordno],(newlen+1) * sizeof(char)))==NULL) {
  344. sprintf(errstr,"INSUFFICIENT MEMORY for wordstore %d\n",wordno+1);
  345. return(MEMORY_ERROR);
  346. }
  347. }
  348. strcpy(dz->wordstor[wordno],errstr);
  349. if(wordcnt <= MIX_MIDLINE)
  350. return(FINISHED);
  351. wordno = total_words + MIX_RLEVELPOS;
  352. if((exit_status = get_level(dz->wordstor[wordno],&level))<0)
  353. return(exit_status);
  354. sprintf(errstr,"%.5lf",level * atten);
  355. if((newlen = (int)strlen(errstr)) > (int)strlen(dz->wordstor[wordno])) {
  356. if((dz->wordstor[wordno] = (char *)realloc(dz->wordstor[wordno],(newlen+1) * sizeof(char)))==NULL) {
  357. sprintf(errstr,"INSUFFICIENT MEMORY for wordstore %d\n",wordno+1);
  358. return(MEMORY_ERROR);
  359. }
  360. }
  361. strcpy(dz->wordstor[wordno],errstr);
  362. return(FINISHED);
  363. }
  364. /************************** OUTPUT_A_NEW_SYNCATT_FILE ***************************/
  365. int output_a_new_syncatt_file(double *timestor,double gain,dataptr dz)
  366. {
  367. int exit_status;
  368. int max_timeword = 0;
  369. int max_namelen = 0;
  370. int total_words = 0, n;
  371. for(n=0;n<dz->linecnt;n++) {
  372. max_namelen = max(max_namelen,(int)strlen(dz->wordstor[total_words]));
  373. sprintf(errstr,"%.5lf",timestor[n]);
  374. max_timeword = max(max_timeword,(int)strlen(errstr));
  375. total_words += dz->wordcnt[n];
  376. }
  377. total_words = 0;
  378. for(n=0;n<dz->linecnt;n++) {
  379. if((exit_status = sync_and_output_mixfile_line
  380. (n,dz->wordstor[total_words],max_namelen,max_timeword,timestor[n],gain,dz))<0)
  381. return(exit_status);
  382. total_words += dz->wordcnt[n];
  383. }
  384. return(FINISHED);
  385. }
  386. /************************** OUTPUT_A_SYNCATT_FILE ***************************/
  387. int output_a_syncatt_file(double *timestor,double gain,dataptr dz)
  388. {
  389. int exit_status;
  390. int *maxwordsize;
  391. int postdec = DEFAULT_DECIMAL_REPRESENTATION;
  392. if((exit_status = retime_the_lines(timestor,postdec,dz))<0)
  393. return(exit_status);
  394. if(gain < 1.0) {
  395. if((exit_status = rescale_the_lines(gain,dz))<0)
  396. return(exit_status);
  397. }
  398. if((exit_status = timesort_mixfile(timestor,dz))<0)
  399. return(exit_status);
  400. if((exit_status = get_maxwordsize(&maxwordsize,dz))<0)
  401. return(exit_status);
  402. if((exit_status = output_mixfile_lines(maxwordsize,dz))<0)
  403. return(exit_status);
  404. free(maxwordsize);
  405. return(FINISHED);
  406. }
  407. /************************** SUM_MAXIMUM_SAMPLES ***************************/
  408. /* RWD: IS THIS ROUNDING FOR SFSEEK, OR ROUNDING FOR WINDOW SECTORS????? */
  409. int sum_maximum_samples(int n,double *total_maxval,dataptr dz)
  410. {
  411. int exit_status;
  412. float *buf = dz->sampbuf[0];
  413. int shsecsize = F_SECSIZE;
  414. int peak_sampno = dz->lparray[MSY_PEAKSAMP][n];
  415. int sectorstart_of_maxsamp, sampstep;
  416. sectorstart_of_maxsamp = (peak_sampno/shsecsize) * shsecsize; /* TRUNCATE */
  417. sampstep = peak_sampno - sectorstart_of_maxsamp;
  418. if(sndseekEx(dz->ifd[0],sectorstart_of_maxsamp,0)<0) {
  419. sprintf(errstr,"soundfile seek failed in sum_maximum_samples()\n");
  420. return(SYSTEM_ERROR);
  421. }
  422. if((exit_status = read_samps(buf,dz))<0)
  423. return(exit_status);
  424. if(sampstep >= dz->ssampsread) {
  425. sprintf(errstr,"Buffer accounting anomaly: sum_maximum_samples()\n");
  426. return(PROGRAM_ERROR);
  427. }
  428. *total_maxval += fabs(buf[sampstep]);
  429. return(FINISHED);
  430. }
  431. /************************* GET_FILESEARCH_DATA ************************/
  432. int get_filesearch_data(dataptr dz)
  433. {
  434. int exit_status;
  435. int srate = 0, total_words, n;
  436. int *inchans;
  437. int shsecsize = F_SECSIZE, *samplen;
  438. double filedur;
  439. double minsyncscan;
  440. double *start, *end;
  441. int textfile_filetype = dz->infile->filetype;
  442. if(dz->linecnt > SF_MAXFILES) {
  443. sprintf(errstr,"Maximum number of sndfiles [%d] exceeded.\n",SF_MAXFILES);
  444. return(USER_ERROR);
  445. } else if(dz->linecnt <= 0) {
  446. sprintf(errstr,"No data in sync file.\n");
  447. return(USER_ERROR);
  448. }
  449. if((dz->parray[MSY_STARTSRCH] = (double *)malloc(dz->linecnt * sizeof(double)))==NULL) {
  450. sprintf(errstr,"INSUFFICIENT MEMORY to store startsearch array.\n");
  451. return(MEMORY_ERROR);
  452. }
  453. start = dz->parray[MSY_STARTSRCH];
  454. if((dz->parray[MSY_ENDSRCH] = (double *)malloc(dz->linecnt * sizeof(double)))==NULL) {
  455. sprintf(errstr,"INSUFFICIENT MEMORY to store endsearch array.\n");
  456. return(MEMORY_ERROR);
  457. }
  458. end = dz->parray[MSY_ENDSRCH];
  459. if((dz->lparray[MSY_SAMPSIZE] = (int *)malloc(dz->linecnt * sizeof(int)))==NULL) {
  460. sprintf(errstr,"gINSUFFICIENT MEMORY to store sizes in samples.\n");
  461. return(MEMORY_ERROR);
  462. }
  463. samplen = dz->lparray[MSY_SAMPSIZE];
  464. if((dz->iparray[MSY_CHANS] = (int *)malloc(dz->linecnt * sizeof(int)))==NULL) {
  465. sprintf(errstr,"INSUFFICIENT MEMORY to store channel info.\n");
  466. return(MEMORY_ERROR);
  467. }
  468. inchans = dz->iparray[MSY_CHANS];
  469. if((dz->lparray[MSY_PEAKSAMP] = (int *)malloc(dz->linecnt * sizeof(int)))==NULL) {
  470. sprintf(errstr,"INSUFFICIENT MEMORY to store peak information.\n");
  471. return(MEMORY_ERROR);
  472. }
  473. if((exit_status = establish_file_data_storage_for_mix((int)1,dz))<0)
  474. return(exit_status);
  475. total_words = 0;
  476. for(n=0;n<dz->linecnt;n++) {
  477. if((exit_status = open_file_and_retrieve_props(n,dz->wordstor[total_words],&srate,dz))<0)
  478. return(exit_status);
  479. samplen[n] = dz->insams[0];
  480. inchans[n] = dz->infile->channels;
  481. //REVISION TW July, 2004
  482. // filedur = (double)(samplen[n]/inchans[n])/(double)srate;
  483. total_words += dz->wordcnt[n];
  484. }
  485. if(srate > SAMPLE_RATE_DIVIDE) dz->iparam[MSY_SRFAC]=2;
  486. else dz->iparam[MSY_SRFAC]=1;
  487. minsyncscan = (double)((shsecsize * dz->iparam[MSY_SRFAC])/MAX_WINFAC)/(double)srate;
  488. total_words = 0;
  489. for(n=0;n<dz->linecnt;n++) {
  490. switch(dz->wordcnt[n]) {
  491. case(3):
  492. if(dz->infile->filetype==MIXFILE) {
  493. sprintf(errstr,"Anomalous line length [%d] in mixfile\n",dz->wordcnt[n]);
  494. return(PROGRAM_ERROR);
  495. }
  496. if(sscanf(dz->wordstor[total_words+1],"%lf",&(start[n]))!=1) {
  497. sprintf(errstr,"Failed to read starttime: line %d: get_filesearch_data()\n",n+1);
  498. return(PROGRAM_ERROR);
  499. }
  500. if(sscanf(dz->wordstor[total_words+2],"%lf",&(end[n]))!=1) {
  501. sprintf(errstr,"Failed to read endtime: line %d: get_filesearch_data()\n",n+1);
  502. return(PROGRAM_ERROR);
  503. }
  504. if((start[n] < 0.0) || (end[n] < 0.0) || (start[n] + minsyncscan >= end[n])) {
  505. sprintf(errstr,"Impossible or incompatible searchtimes [%.5lf to %.5lf]: line %d.\n",
  506. start[n],end[n],n+1);
  507. return(USER_ERROR);
  508. }
  509. //REVISION TW July, 2004
  510. filedur = (double)(samplen[n]/inchans[n])/(double)srate;
  511. if(start[n] >= filedur - minsyncscan) {
  512. sprintf(errstr,"starttime on line %d is beyond effective file end.\n",n+1);
  513. return(DATA_ERROR);
  514. }
  515. if(end[n] >= filedur)
  516. end[n] = -1.0; /* flags END_OF_SNDFILE */
  517. break;
  518. default:
  519. start[n] = 0.0;
  520. end[n] = -1.0; /* flags END_OF_SNDFILE */
  521. break;
  522. }
  523. total_words += dz->wordcnt[n];
  524. }
  525. dz->infile->filetype = textfile_filetype;
  526. return(FINISHED);
  527. }
  528. /***************************** SYNCATT_PRESETS **************************/
  529. int syncatt_presets(dataptr dz)
  530. {
  531. int exit_status;
  532. if(!check_syncatt_window_factor(dz))
  533. return(USER_ERROR);
  534. if((exit_status= get_filesearch_data(dz))<0)
  535. return(exit_status);
  536. return(FINISHED);
  537. }
  538. /***************************** CHECK_SYNCATT_WINDOW_FACTOR **************************/
  539. int check_syncatt_window_factor(dataptr dz)
  540. {
  541. int valid_value = MIN_WINFAC;
  542. while(valid_value <= MAX_WINFAC) {
  543. if(dz->iparam[MSY_WFAC]==valid_value)
  544. return(TRUE);
  545. valid_value *= 2;
  546. }
  547. return(FALSE);
  548. }