compare.c 55 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493
  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. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <structures.h>
  24. #include <tkglobals.h>
  25. #include <globcon.h>
  26. #include <cdpmain.h>
  27. #include <sndinfo.h>
  28. #include <processno.h>
  29. #include <modeno.h>
  30. #include <pnames.h>
  31. #include <filetype.h>
  32. #include <flags.h>
  33. #include <float.h>
  34. #include <time.h>
  35. #include <sfsys.h>
  36. #include <string.h>
  37. #include <math.h>
  38. #define round(x) lround((x))
  39. #define SPACECNT (32)
  40. static int try_header(int chans,double inverse_sr,dataptr dz);
  41. static void make_time_display(char temp[],char timestr[],double secs);
  42. static int get_and_set_float_maxmina(float *flbuf,dataptr dz);
  43. static int get_and_set_float_maxmin(float *buf,int chans, double inverse_sr,dataptr dz);
  44. static int compare_sndfile_properties(char temp[],dataptr dz);
  45. static int compare_analfile_properties(dataptr dz);
  46. static int read_both_the_files(int samesize,dataptr dz);
  47. static int read_samps_for_cdiff(dataptr dz);
  48. static void compare_samps(char temp[],int *badmatch,int *limitcnt,double threshold,dataptr dz);
  49. static void anal_file_time(char temp[],int n,dataptr dz);
  50. static void snd_file_time(char temp[],int n,dataptr dz);
  51. static int sfdiff_process(char temp[],int samesize,dataptr dz);
  52. static int compare_infile_sizes(int *same_size,dataptr dz);
  53. static int do_sfdiff(char temp[],dataptr dz);
  54. static int prntprops(SFPROPS *prop, dataptr dz);
  55. static int get_float_maxmin(float *buf,int chans, double inverse_sr,dataptr dz);
  56. /*RWD 6:2001 */
  57. static int getpeakdata(int ifd, float *peakval,SFPROPS *props);
  58. static int do_zcross_ratio(dataptr dz);
  59. /****************************** DO_SNDINFO ******************************/
  60. int do_sndinfo(dataptr dz)
  61. {
  62. int exit_status;
  63. float *flbuf;
  64. float *buf;
  65. double sr = (double)dz->infile->srate;
  66. int chans = dz->infile->channels, maxpos;
  67. double other_sr = (double)dz->otherfile->srate;
  68. int other_chans = dz->otherfile->channels;
  69. double inverse_sr = 1.0, secs;
  70. int thisspace, m;
  71. float *chanmax;
  72. int ftype = dz->infile->filetype;
  73. int is_a_text_file = FALSE;
  74. int n, k, j;
  75. fileptr fptr = dz->infile;
  76. char timestr[64];
  77. char temp[200];
  78. int holesize = 0, holesamp = 0;
  79. int maxholesize = 0;
  80. int maxholesamp = 0;
  81. double maxholelen, maxholetime;
  82. double threshold, level = 0.0;
  83. int orig_ifd0;
  84. SFPROPS props = {0};
  85. infileptr ifp;
  86. double maxamp, maxloc;
  87. int maxrep;
  88. int getmax = 0, getmaxinfo = 0;
  89. if(sr > 0.0)
  90. inverse_sr = 1.0/sr;
  91. switch(dz->process) {
  92. case(INFO_TIMESUM):
  93. secs = 0.0;
  94. for(n=0;n<dz->infilecnt;n++) {
  95. secs += (double)(dz->insams[n]/chans) * inverse_sr;
  96. secs -= dz->param[TIMESUM_SPLEN] * MS_TO_SECS;
  97. }
  98. sprintf(errstr,"TOTAL TIME ");
  99. make_time_display(temp,timestr,secs);
  100. strcat(errstr,timestr);
  101. strcat(errstr,"\n");
  102. print_outmessage(errstr);
  103. break;
  104. case(INFO_TIMELIST):
  105. if((ifp = (infileptr)malloc(sizeof(struct filedata)))==NULL) {
  106. sprintf(errstr,"INSUFFICIENT MEMORY to store data on file.\n");
  107. return(MEMORY_ERROR);
  108. }
  109. secs = (double)(dz->insams[0]/chans) * inverse_sr;
  110. sprintf(errstr,"%s",dz->wordstor[0]);
  111. thisspace = SPACECNT - strlen(dz->wordstor[0]);
  112. thisspace = max(thisspace,2);
  113. for(m=0;m<thisspace;m++)
  114. strcat(errstr,".");
  115. make_time_display(temp,timestr,secs);
  116. strcat(errstr,timestr);
  117. strcat(errstr,"\n");
  118. print_outmessage(errstr);
  119. //TW UPDATE
  120. if(sloom) {
  121. sprintf(errstr,"%lf\n",secs);
  122. if(fputs(errstr,dz->fp)<0) {
  123. sprintf(errstr,"Cannot output data to file\n");
  124. return(SYSTEM_ERROR);
  125. }
  126. }
  127. for(n=1;n<dz->infilecnt;n++) {
  128. if((exit_status = readhead(ifp,dz->ifd[n],dz->wordstor[n],&maxamp,&maxloc,&maxrep,getmax,getmaxinfo))<0) {
  129. sprintf(errstr,"Cannot re-read file %d header.\n",n+1);
  130. return(PROGRAM_ERROR);
  131. }
  132. copy_to_fileptr(ifp,dz->infile);
  133. secs = (double)(dz->insams[n]/dz->infile->channels)/(double)dz->infile->srate;
  134. sprintf(errstr,"%s",dz->wordstor[n]);
  135. thisspace = SPACECNT - strlen(dz->wordstor[n]);
  136. thisspace = max(thisspace,2);
  137. for(m=0;m<thisspace;m++)
  138. strcat(errstr,".");
  139. make_time_display(temp,timestr,secs);
  140. strcat(errstr,timestr);
  141. strcat(errstr,"\n");
  142. print_outmessage(errstr);
  143. //TW UPDATE
  144. if(sloom) {
  145. sprintf(errstr,"%lf\n",secs);
  146. if(fputs(errstr,dz->fp)<0) {
  147. sprintf(errstr,"Cannot output data to file\n");
  148. return(SYSTEM_ERROR);
  149. }
  150. }
  151. }
  152. break;
  153. case(INFO_LOUDLIST):
  154. orig_ifd0 = dz->ifd[0];
  155. for(m=0;m<dz->infilecnt;m++) {
  156. float fmaxamp = 0.0f; /*RWD 6:2001 */
  157. int gotpeak = 0;
  158. /*RWD 6:2001 try to read PEAK chunk too! */
  159. if(getpeakdata(dz->ifd[m],&fmaxamp,&props)){
  160. level = fmaxamp;
  161. gotpeak = 1;
  162. }
  163. else {
  164. /* RWD impossible to report int values without lot of hoohaa */
  165. /* just look as if its floatsam file, for now */
  166. if(sndgetprop(dz->ifd[m],"fmaxamp",(char *)&fmaxamp,sizeof(float)) < 0 ) {
  167. dz->samps_left = dz->insams[m];
  168. dz->ifd[0] = dz->ifd[m];
  169. while(dz->samps_left) {
  170. if((exit_status = read_samps(dz->bigbuf,dz))<0)
  171. return(exit_status);
  172. for(n=0;n<dz->ssampsread;n++)
  173. fmaxamp = (float)max(fmaxamp,fabs(dz->bigbuf[n]));
  174. }
  175. }
  176. }
  177. if(!gotpeak) /*RWD 6:2001 */
  178. level = (double)fmaxamp/F_MAXSAMP;
  179. sprintf(errstr,"%s\t",dz->wordstor[m]);
  180. sprintf(timestr,"%lf\n",level);
  181. strcat(errstr,timestr);
  182. print_outmessage(errstr);
  183. if(fputs(timestr,dz->fp)<0) {
  184. sprintf(errstr,"Cannot output data to file\n");
  185. return(SYSTEM_ERROR);
  186. }
  187. dz->ifd[0] = orig_ifd0;
  188. }
  189. break;
  190. case(INFO_TIMEDIFF):
  191. sprintf(errstr,"DIFFERENCE IS ");
  192. secs = (dz->insams[0]/chans) * inverse_sr;
  193. secs -= (dz->insams[1]/other_chans)/other_sr;
  194. secs = fabs(secs);
  195. make_time_display(temp,timestr,secs);
  196. strcat(errstr,timestr);
  197. strcat(errstr,"\n");
  198. print_outmessage(errstr);
  199. break;
  200. case(INFO_SFLEN):
  201. switch(dz->infile->filetype) {
  202. case(SNDFILE):
  203. print_outmessage("A soundfile\n");
  204. sprintf(errstr,"DURATION: ");
  205. secs = (double)(dz->insams[0]/dz->infile->channels) * inverse_sr;
  206. make_time_display(temp,timestr,secs);
  207. strcat(errstr,timestr);
  208. sprintf(temp,"samples %d\n",dz->insams[0]);
  209. strcat(errstr,temp);
  210. break;
  211. case(ANALFILE):
  212. print_outmessage("An analysis data file\n");
  213. sprintf(errstr,"DURATION: ");
  214. secs = (double)dz->wlength * dz->frametime;
  215. make_time_display(temp,timestr,secs);
  216. strcat(errstr,timestr);
  217. sprintf(temp,"windows %d : floats %d\n",dz->wlength,dz->insams[0]);
  218. strcat(errstr,temp);
  219. break;
  220. case(PITCHFILE):
  221. print_outmessage("A binary pitch data file\n");
  222. sprintf(errstr,"DURATION: ");
  223. secs = (double)dz->insams[0] * dz->frametime;
  224. make_time_display(temp,timestr,secs);
  225. strcat(errstr,timestr);
  226. sprintf(temp,"windows %d : floats %d\n",dz->insams[0],dz->insams[0]);
  227. strcat(errstr,temp);
  228. break;
  229. case(TRANSPOSFILE):
  230. print_outmessage("A binary transposition data file\n");
  231. sprintf(errstr,"DURATION: ");
  232. secs = (double)dz->insams[0] * dz->frametime;
  233. make_time_display(temp,timestr,secs);
  234. strcat(errstr,timestr);
  235. sprintf(temp,"windows %d : floats %d\n",dz->insams[0],dz->insams[0]);
  236. strcat(errstr,temp);
  237. break;
  238. case(ENVFILE):
  239. print_outmessage("A binary envelope file\n");
  240. sprintf(errstr,"DURATION: ");
  241. secs = (double)dz->insams[0] * dz->infile->window_size * MS_TO_SECS;
  242. make_time_display(temp,timestr,secs);
  243. strcat(errstr,timestr);
  244. sprintf(temp,"windows %d : floats %d\n",dz->wlength,dz->insams[0]);
  245. strcat(errstr,temp);
  246. break;
  247. case(FORMANTFILE):
  248. print_outmessage("A formant data file\n");
  249. sprintf(errstr,"DURATION: ");
  250. dz->wlength = (dz->insams[0]/dz->specenvcnt) - DESCRIPTOR_DATA_BLOKS;
  251. secs = (double)dz->wlength * dz->frametime;
  252. make_time_display(temp,timestr,secs);
  253. strcat(errstr,timestr);
  254. n = dz->insams[0] - (dz->specenvcnt * DESCRIPTOR_DATA_BLOKS);
  255. sprintf(temp,"windows %d : floats %d\n",dz->wlength,n);
  256. strcat(errstr,temp);
  257. break;
  258. default:
  259. sprintf(errstr,"This process only works with soundfiling-system files.\n");
  260. return(DATA_ERROR);
  261. }
  262. print_outmessage(errstr);
  263. break;
  264. case(INFO_LOUDCHAN):
  265. if(dz->infile->channels==MONO) {
  266. sprintf(errstr,"This program does not works with MONO files.\n");
  267. return(GOAL_FAILED);
  268. }
  269. if((chanmax = (float *)malloc(chans *sizeof(float)))==NULL) {
  270. sprintf(errstr,"INSUFFICIENT MEMORY to store channel maximi.\n");
  271. return(MEMORY_ERROR);
  272. }
  273. for(m=0;m<chans;m++)
  274. chanmax[m] = 0;
  275. while(dz->samps_left) {
  276. if((exit_status = read_samps(dz->bigbuf,dz))<0)
  277. return(exit_status);
  278. for(n=0;n<dz->ssampsread;n+=chans) {
  279. for(m=0;m<chans;m++)
  280. chanmax[m] = (float)max(chanmax[m],(float) fabs(dz->bigbuf[n+m]));
  281. }
  282. }
  283. maxpos = 0;
  284. for(m=1;m<chans;m++) {
  285. if(chanmax[m] > chanmax[maxpos])
  286. maxpos = m;
  287. }
  288. sprintf(errstr,"LOUDEST CHANNEL is %d\n",maxpos+1);
  289. print_outmessage(errstr);
  290. free(chanmax);
  291. break;
  292. case(INFO_SAMPTOTIME):
  293. if(!dz->vflag[CHAN_GROUPED])
  294. dz->iparam[INFO_SAMPS] /= chans;
  295. secs = dz->iparam[INFO_SAMPS] * inverse_sr;
  296. make_time_display(temp,timestr,secs);
  297. sprintf(errstr,"TIME %s",timestr);
  298. strcat(errstr,"\n");
  299. print_outmessage(errstr);
  300. break;
  301. case(INFO_TIMETOSAMP):
  302. n = round(dz->param[INFO_TIME] * sr);
  303. if(!dz->vflag[CHAN_GROUPED])
  304. n *= chans;
  305. sprintf(errstr,"SAMPLE %d\n",n);
  306. print_outmessage(errstr);
  307. break;
  308. case(INFO_PROPS):
  309. errstr[0] = ENDOFSTR;
  310. switch(ftype) {
  311. case(SNDFILE):
  312. sprintf(errstr,"A SOUND file.\n"); break;
  313. case(ANALFILE):
  314. sprintf(errstr,"An ANALYSIS file.\n"); break;
  315. case(PITCHFILE):
  316. sprintf(errstr,"A binary PITCH file.\n"); break;
  317. case(TRANSPOSFILE):
  318. sprintf(errstr,"A binary TRANSPOSITION file.\n"); break;
  319. case(FORMANTFILE):
  320. sprintf(errstr,"A FORMANT data file.\n"); break;
  321. case(ENVFILE):
  322. sprintf(errstr,"A binary ENVELOPE file.\n"); break;
  323. default:
  324. if(is_a_textfile_type(ftype)) {
  325. sprintf(errstr,"A TEXT data file.\n");
  326. is_a_text_file = TRUE;
  327. } else {
  328. print_outmessage("UNKNOWN input file type.\n");
  329. return(FINISHED);
  330. }
  331. break;
  332. }
  333. print_outmessage(errstr);
  334. if(is_a_text_file) {
  335. sprintf(errstr,"Contains %d LINES\n",dz->linecnt);
  336. print_outmessage(errstr);
  337. sprintf(errstr,"Contains %d WORDS\n",dz->all_words);
  338. print_outmessage(errstr);
  339. if(ftype==MIXFILE) {
  340. sprintf(errstr,"Could be a MIXFILE with output channel cnt %d\n",dz->out_chans);
  341. print_outmessage(errstr);
  342. } else if(ftype==SYNCLIST) {
  343. sprintf(errstr,"Could be a LIST OF SOUNDFILES TO SYNCHRONISE.\n");
  344. print_outmessage(errstr);
  345. } else if(ftype==SNDLIST) {
  346. sprintf(errstr,"Could be a LIST OF SOUNDFILES.\n");
  347. print_outmessage(errstr);
  348. }
  349. if(dz->tempsize >0 || (dz->extrabrkno >= 0 && dz->brksize[dz->extrabrkno] > 0)) {
  350. sprintf(errstr,"Could be a BREAKPOINT FILE:\n");
  351. print_outmessage(errstr);
  352. sprintf(errstr,"length %d minval %lf maxval %lf duration %lf\n",
  353. dz->numsize/2,dz->minbrk,dz->maxbrk,dz->duration);
  354. print_outmessage(errstr);
  355. }
  356. if(dz->numsize > 0) {
  357. sprintf(errstr,"Could be a NUMBER LIST:\n");
  358. print_outmessage(errstr);
  359. sprintf(errstr,"length %d minval %lf maxval %lf\n",dz->numsize,dz->minnum,dz->maxnum);
  360. print_outmessage(errstr);
  361. }
  362. } else {
  363. sprintf(errstr,"samples: ............ %d\n",dz->insams[0]);
  364. print_outmessage(errstr);
  365. if(ftype!=SNDFILE) {
  366. switch(ftype) {
  367. case(ANALFILE):
  368. sprintf(errstr,"file type: .......... ANALYSIS DATA\n"); break;
  369. case(PITCHFILE):
  370. sprintf(errstr,"file type: .......... PITCH DATA (binary)\n"); break;
  371. case(TRANSPOSFILE):
  372. sprintf(errstr,"file type: .......... TRANSPOSITION DATA (binary)\n"); break;
  373. case(FORMANTFILE):
  374. sprintf(errstr,"file type: .......... FORMANT DATA (binary)\n"); break;
  375. case(ENVFILE):
  376. sprintf(errstr,"file type: .......... ENVELOPE DATA (binary)\n"); break;
  377. }
  378. print_outmessage(errstr);
  379. //TW UPDATE: moved srate & chans, as ENVFILES have srate and channels
  380. sprintf(errstr,"sample rate: ........ %d\n",fptr->srate);
  381. print_outmessage(errstr);
  382. sprintf(errstr,"channels: ........... %d\n",fptr->channels);
  383. print_outmessage(errstr);
  384. if(fptr->filetype==ENVFILE) {
  385. sprintf(errstr,"window size: ........ %f ms\n",fptr->window_size);
  386. print_outmessage(errstr);
  387. return(FINISHED);
  388. }
  389. if(fptr->filetype==FORMANTFILE) {
  390. sprintf(errstr,"formant envelope cnt: %d\n",fptr->specenvcnt);
  391. print_outmessage(errstr);
  392. }
  393. /*RWD*/
  394. //TW NOW REDUNDANT: flagging changed
  395. // if(fptr->filetype!=SNDFILE){
  396. sprintf(errstr,"original sampsize: .. %d\n",fptr->origstype);
  397. print_outmessage(errstr);
  398. sprintf(errstr,"original sample rate: %d\n",fptr->origrate);
  399. print_outmessage(errstr);
  400. sprintf(errstr,"analysis rate: ...... %f\n",fptr->arate);
  401. print_outmessage(errstr);
  402. sprintf(errstr,"analysis window len: %d\n",fptr->Mlen);
  403. print_outmessage(errstr);
  404. sprintf(errstr,"decimation factor: .. %d\n",fptr->Dfac);
  405. print_outmessage(errstr);
  406. // }
  407. if(fptr->filetype==PITCHFILE || fptr->filetype==TRANSPOSFILE) {
  408. sprintf(errstr,"original channels: .. %d\n",fptr->origchans);
  409. print_outmessage(errstr);
  410. }
  411. } else {
  412. sprintf(errstr,"file type: ........... SOUND\n");
  413. print_outmessage(errstr);
  414. sprintf(errstr,"sample rate: ........ %d\n",fptr->srate);
  415. print_outmessage(errstr);
  416. sprintf(errstr,"channels: ........... %d\n",fptr->channels);
  417. print_outmessage(errstr);
  418. }
  419. if((exit_status = prntprops(&props,dz))<0)
  420. return(exit_status);
  421. }
  422. break;
  423. case(INFO_MAXSAMP):
  424. if(is_a_text_input_filetype(dz->infile->filetype)) {
  425. sprintf(errstr,"This is a text file.\n");
  426. return(GOAL_FAILED);
  427. }
  428. /* RWD 2022 this hangs if user supplies anal file */
  429. /* now fixed by TW 2022 (tlkib3.c) */
  430. //if(dz->infile->filetype == ANALFILE){
  431. // sprintf(errstr,"This is an anlysis file.\n");
  432. // return(GOAL_FAILED);
  433. //}
  434. flbuf = (float *)dz->bigbuf;
  435. buf = dz->bigbuf;
  436. if(!dz->vflag[FORCE_SCAN] && try_header(chans,inverse_sr,dz)==FINISHED)
  437. break;
  438. else {
  439. if(dz->infile->filetype != SNDFILE) {
  440. if((exit_status = get_and_set_float_maxmina(flbuf,dz))<0)
  441. return(exit_status);
  442. } else {
  443. if((exit_status = get_and_set_float_maxmin(buf,chans,inverse_sr,dz))<0)
  444. return(exit_status);
  445. }
  446. }
  447. break;
  448. case(INFO_MAXSAMP2):
  449. buf = dz->bigbuf;
  450. if((exit_status = get_float_maxmin(buf,chans,inverse_sr,dz))<0)
  451. return(exit_status);
  452. break;
  453. case(INFO_PRNTSND):
  454. dz->ssampsread = 0;
  455. dz->iparam[PRNT_START] = round(dz->param[PRNT_START] * sr) * chans;
  456. dz->iparam[PRNT_END] = round(dz->param[PRNT_END] * sr) * chans;
  457. if(dz->iparam[PRNT_START] >= dz->iparam[PRNT_END]) {
  458. sprintf(errstr,"Incompatible start and end times.\n");
  459. return(DATA_ERROR);
  460. }
  461. if(dz->iparam[PRNT_START] >= dz->insams[0]) {
  462. sprintf(errstr,"Start time is at end of file: can't proceed.\n");
  463. return(DATA_ERROR);
  464. }
  465. dz->total_samps_read = 0;
  466. for(;;) {
  467. if((exit_status = read_samps(dz->bigbuf,dz))<0)
  468. return(exit_status);
  469. if(dz->iparam[PRNT_START] > dz->ssampsread) {
  470. dz->iparam[PRNT_START] -= dz->ssampsread;
  471. dz->iparam[PRNT_END] -= dz->ssampsread;
  472. } else
  473. break;
  474. }
  475. k = 0;
  476. j = (dz->total_samps_read - dz->ssampsread + dz->iparam[PRNT_START])/chans;
  477. display_virtual_time(0L,dz);
  478. for(n=dz->iparam[PRNT_START];n<dz->iparam[PRNT_END];n+=chans,k+=chans,j++) {
  479. fprintf(dz->fp,"[%d]\t",j);
  480. for(m=0;m<chans;m++)
  481. fprintf(dz->fp,"%.6f\t",(float) dz->bigbuf[n+m]); /*RWD 12:2003 was %d */
  482. fprintf(dz->fp,"\n");
  483. if(n >= dz->ssampsread) {
  484. if((exit_status = read_samps(dz->bigbuf,dz))<0)
  485. return(exit_status);
  486. //TW CHANGED to samps
  487. display_virtual_time(k,dz);
  488. dz->iparam[PRNT_END] -= dz->ssampsread;
  489. n = 0;
  490. }
  491. }
  492. //TW CHANGED to samps
  493. display_virtual_time(k,dz);
  494. break;
  495. case(INFO_FINDHOLE):
  496. threshold = dz->param[HOLE_THRESH] * (double)F_MAXSAMP;
  497. while(dz->samps_left) {
  498. if((exit_status = read_samps(dz->bigbuf,dz))<0)
  499. return(exit_status);
  500. for(n = 0; n < dz->ssampsread; n++) {
  501. if(holesize==0) {
  502. if(fabs(dz->bigbuf[n])<threshold) {
  503. holesize = 1;
  504. holesamp = dz->total_samps_read - dz->ssampsread + n;
  505. }
  506. } else {
  507. if(fabs(dz->bigbuf[n])<threshold)
  508. holesize++;
  509. else {
  510. if(holesize > maxholesize) {
  511. maxholesize = holesize;
  512. maxholesamp = holesamp;
  513. }
  514. holesize = 0;
  515. }
  516. }
  517. }
  518. }
  519. maxholelen = (double)(maxholesize/chans) * inverse_sr;
  520. maxholetime = (double)(maxholesamp/chans) * inverse_sr;
  521. sprintf(errstr,"Maximum holesize is %.6lf at time %.6lf\n",maxholelen,maxholetime);
  522. print_outmessage(errstr);
  523. break;
  524. case(INFO_CDIFF):
  525. case(INFO_DIFF):
  526. if((exit_status = do_sfdiff(temp,dz))<0)
  527. return(exit_status);
  528. break;
  529. case(ZCROSS_RATIO):
  530. if((exit_status = do_zcross_ratio(dz))<0)
  531. return(exit_status);
  532. break;
  533. default:
  534. sprintf(errstr,"Unknown process in do_sndinfo()\n");
  535. return(PROGRAM_ERROR);
  536. }
  537. fflush(stdout);
  538. return(FINISHED);
  539. }
  540. /************************** TRY_HEADER ************************/
  541. int try_header(int chans,double inverse_sr,dataptr dz)
  542. {
  543. int pos_repeats, neg_repeats, repeats, maxloc, maxamp = -1;
  544. float maxpfamp, maxnfamp;
  545. double gain, dbgain;
  546. float newmaxamp = 0.0f;
  547. if(dz->infile->filetype != SNDFILE) {
  548. //TW SUBSTITUTED SNDgetprop
  549. if( sndgetprop(dz->ifd[0],"maxpfamp",(char *)&maxpfamp,sizeof(float)) < 0 )
  550. return(CONTINUE);
  551. if( sndgetprop(dz->ifd[0],"maxnfamp",(char *)&maxnfamp,sizeof(float)) < 0 )
  552. return(CONTINUE);
  553. if(sndgetprop(dz->ifd[0],"maxprep",(char *)&pos_repeats,sizeof(float)) < 0 )
  554. return(CONTINUE);
  555. if(sndgetprop(dz->ifd[0],"maxnrep",(char *)&neg_repeats,sizeof(int)) < 0 )
  556. return(CONTINUE);
  557. sprintf(errstr,"maximum float value: %f\n",maxpfamp);
  558. print_outmessage(errstr);
  559. sprintf(errstr,"occurs: ............ %d times\n",pos_repeats);
  560. print_outmessage(errstr);
  561. sprintf(errstr,"minimum float value: %f\n",maxnfamp);
  562. print_outmessage(errstr);
  563. sprintf(errstr,"occurs: ............ %d times\n",neg_repeats);
  564. print_outmessage(errstr);
  565. } else {
  566. if( sndgetprop(dz->ifd[0],"maxamp",(char *)&maxamp,sizeof(int)) < 0 /* old files */
  567. && sndgetprop(dz->ifd[0],"maxpfamp",(char *)&newmaxamp,sizeof(float)) < 0) /* new files */
  568. return(CONTINUE);
  569. if( sndgetprop(dz->ifd[0],"maxloc",(char *)&maxloc,sizeof(int)) < 0 )
  570. return(CONTINUE);
  571. if( sndgetprop(dz->ifd[0],"maxrep",(char *)&repeats,sizeof(int)) < 0 )
  572. return(CONTINUE);
  573. if(maxamp>=0)
  574. newmaxamp = (float)(maxamp/(double)MAXSAMP);
  575. sprintf(errstr,"maximum abs value:.. %f\n",newmaxamp);
  576. print_outmessage(errstr);
  577. sprintf(errstr,"at: ................ %d samples\n",maxloc);
  578. print_outmessage(errstr);
  579. sprintf(errstr,"time: .............. %.4lf secs\n",(double)(maxloc/chans) *inverse_sr);
  580. print_outmessage(errstr);
  581. sprintf(errstr,"repeated: .......... %d times\n",repeats);
  582. print_outmessage(errstr);
  583. if(newmaxamp>=0.0) {
  584. gain = 1.0/(double)maxamp;
  585. dbgain = log10(gain) * 20.0;
  586. sprintf(errstr,"max possible gain:.. %.4lf\n",gain);
  587. print_outmessage(errstr);
  588. sprintf(errstr,"max dB gain:........ %.4lf\n",dbgain);
  589. print_outmessage(errstr);
  590. }
  591. }
  592. return(FINISHED);
  593. }
  594. /************************** MAKE_TIME_DISPLAY ************************/
  595. void make_time_display(char temp[],char timestr[],double secs)
  596. {
  597. int mins = 0, hrs = 0;
  598. if(secs > 60.0) {
  599. mins = round(floor(secs/60.0));
  600. secs -= (double)(mins * 60);
  601. }
  602. if(mins > 60) {
  603. hrs = round(floor((double)mins/60.0));
  604. mins -= hrs * 60;
  605. }
  606. timestr[0] = ENDOFSTR;
  607. if(hrs) {
  608. sprintf(temp,"%d hrs ",hrs);
  609. strcat(timestr,temp);
  610. }
  611. if(mins) {
  612. sprintf(temp,"%d mins ",mins);
  613. strcat(timestr,temp);
  614. }
  615. sprintf(temp,"%.6lf secs ",secs);
  616. strcat(timestr,temp);
  617. }
  618. /************************** GET_AND_SET_FLOAT_MAXMIN ************************/
  619. /* RWD assumes analysis ?*/
  620. int get_and_set_float_maxmina(float *flbuf,dataptr dz)
  621. {
  622. int exit_status;
  623. double maxpdamp = DBL_MIN;
  624. double maxndamp = DBL_MAX;
  625. float maxpfamp, maxnfamp;
  626. int maxprep = 1, maxnrep = 1;
  627. int n;
  628. dz->samps_left = dz->insams[0];
  629. if(sndseekEx(dz->ifd[0],0,0)<0) {
  630. sprintf(errstr,"sndseek() failed. get_and_set_float_maxmin()\n");
  631. return(SYSTEM_ERROR);
  632. }
  633. while(dz->samps_left > 0) {
  634. if((exit_status = read_samps(flbuf,dz))<0)
  635. return(exit_status);
  636. for(n=0;n<dz->ssampsread;n++) {
  637. if(flbuf[n] < maxpdamp) /* IF < max, ignore */
  638. ;
  639. else if(flbuf[n] > maxpdamp) {
  640. maxpdamp = flbuf[n]; /* IF > max, reset max and count */
  641. maxprep = 1;
  642. } else /* else must be EQUAL to max; incr counter */
  643. maxprep++;
  644. if(flbuf[n] > maxndamp)
  645. ;
  646. else if(flbuf[n] < maxndamp) {
  647. maxndamp = flbuf[n];
  648. maxnrep = 1;
  649. } else
  650. maxnrep++;
  651. }
  652. }
  653. maxpfamp = (float)maxpdamp;
  654. maxnfamp = (float)maxndamp;
  655. //TW cannot reset header of a read-in file
  656. // if( sndputprop(dz->ifd[0],"maxpfamp",(char *)&maxpfamp,sizeof(float)) < 0 )
  657. // fprintf(stdout,"WARNING: Cannot write maximum float value to header\n");
  658. // if(sndputprop(dz->ifd[0],"maxprep",(char *)&maxprep,sizeof(long)) < 0 )
  659. // fprintf(stdout,"WARNING: Cannot write maxfloat repeats-count to header\n");
  660. // if( sndputprop(dz->ifd[0],"maxnfamp",(char *)&maxnfamp,sizeof(float)) < 0 )
  661. // fprintf(stdout,"WARNING: Cannot write mimimum float value to header\n");
  662. // if(sndputprop(dz->ifd[0],"maxnrep",(char *)&maxnrep,sizeof(long)) < 0 )
  663. // fprintf(stdout,"WARNING: Cannot write minfloat repeats-count to header\n");
  664. sprintf(errstr,"maximum float value: %f\n",maxpfamp);
  665. print_outmessage(errstr);
  666. sprintf(errstr,"occurs: ........... %d times\n",maxprep);
  667. print_outmessage(errstr);
  668. sprintf(errstr,"minimum float value: %f\n",maxnfamp);
  669. print_outmessage(errstr);
  670. sprintf(errstr,"occurs: ........... %d times\n",maxnrep);
  671. print_outmessage(errstr);
  672. return(FINISHED);
  673. }
  674. /************************** GET_AND_SET_SHORT_MAXMIN ************************/
  675. int get_and_set_float_maxmin(float *buf,int chans, double inverse_sr,dataptr dz)
  676. {
  677. int exit_status;
  678. /*int maxamp = MINSAMP, mag;*/
  679. float maxamp = F_MINSAMP, mag;
  680. int maxloc = 0;
  681. int maxrep = 1;
  682. int n;
  683. double gain = 0.0, dbgain = 0.0;
  684. while(dz->samps_left) {
  685. if((exit_status = read_samps(buf,dz))<0)
  686. return(exit_status);
  687. for(n=0;n<dz->ssampsread;n++) {
  688. mag = (float) fabs(buf[n]);
  689. if(mag > maxamp) {
  690. maxloc = dz->total_samps_read - dz->ssampsread + n;
  691. maxamp = mag;
  692. maxrep = 1;
  693. } else if(mag==maxamp)
  694. maxrep++;
  695. }
  696. }
  697. //TW Cannot alter heqader of an input file
  698. // if(sndputprop(dz->ifd[0],"maxamp",(char *)&maxamp,sizeof(float)) < 0 )
  699. // if(sndputprop(dz->ifd[0],"maxpfamp",(char *)&maxamp,sizeof(float)) < 0 )
  700. // fprintf(stdout,"WARNING: Cannot write maximum value to header.\n");
  701. // if(sndputprop(dz->ifd[0],"maxloc",(char *)&maxloc,sizeof(long)) < 0 )
  702. // fprintf(stdout,"WARNING: Cannot write location of maximum value to header.\n");
  703. // if(sndputprop(dz->ifd[0],"maxrep",(char *)&maxrep,sizeof(long)) < 0 )
  704. // fprintf(stdout,"WARNING: Cannot write maximum repeats to header.\n");
  705. if(maxamp>0.0f) {
  706. gain = F_MAXSAMP/(double)maxamp;
  707. dbgain = log10(gain) * 20.0;
  708. }
  709. sprintf(errstr,"maximum abs value:.. %f\n",maxamp);
  710. print_outmessage(errstr);
  711. sprintf(errstr,"at: ................ %d samples\n",maxloc);
  712. print_outmessage(errstr);
  713. sprintf(errstr,"time: .............. %.4lf secs\n",(double)(maxloc/chans) *inverse_sr);
  714. print_outmessage(errstr);
  715. sprintf(errstr,"repeated: .......... %d times\n",maxrep);
  716. print_outmessage(errstr);
  717. if(maxamp>0.0f) {
  718. sprintf(errstr,"max possible gain:.. %.4lf\n",gain);
  719. print_outmessage(errstr);
  720. sprintf(errstr,"max dB gain:........ %.4lf\n",dbgain);
  721. print_outmessage(errstr);
  722. }
  723. return(FINISHED);
  724. }
  725. /************************ COMPARE_INFILE_SIZES ***********************/
  726. int compare_infile_sizes(int *samesize,dataptr dz)
  727. {
  728. if(dz->insams[0] != dz->insams[1]) {
  729. print_outmessage_flush("Files are not same size.\n");
  730. if(!dz->vflag[IGNORE_LENDIFF])
  731. return(FINISHED);
  732. else {
  733. dz->insams[0] = min(dz->insams[0],dz->insams[1]);
  734. *samesize = FALSE;
  735. }
  736. }
  737. dz->samps_left = dz->insams[0];
  738. return(CONTINUE);
  739. }
  740. /************************** COMPARE_SNDFILE_PROPERTIES *********************/
  741. int compare_sndfile_properties(char temp[],dataptr dz)
  742. {
  743. errstr[0] = ENDOFSTR;
  744. if(dz->infile->srate != dz->otherfile->srate) {
  745. sprintf(errstr,"Files don't have same sample rate.\n");
  746. return(FINISHED);
  747. }
  748. if(dz->infile->channels != dz->otherfile->channels) {
  749. sprintf(errstr,"Files don't have same number of channels. ");
  750. if(dz->vflag[IGNORE_CHANDIFF]) {
  751. sprintf(temp,"1st has %d : 2nd has %d\n",dz->infile->channels,dz->otherfile->channels);
  752. strcat(errstr,temp);
  753. } else {
  754. strcat(errstr,"\n");
  755. return(FINISHED);
  756. }
  757. print_outmessage(errstr);
  758. }
  759. return(CONTINUE);
  760. }
  761. /*************************** SFDIFF_PROCESS **************************/
  762. int sfdiff_process(char temp[],int samesize,dataptr dz)
  763. {
  764. int exit_status;
  765. int limitcnt = 0, badmatch = 0;
  766. double threshold = dz->param[SFDIFF_THRESH] /* * (double)MAXSAMP*/;
  767. display_virtual_time(0L,dz);
  768. if(sndseekEx(dz->ifd[0],0,0)<0) {
  769. sprintf(errstr,"sndseekEx() problem in sfdiff_process()\n");
  770. return(SYSTEM_ERROR);
  771. }
  772. if(dz->process==INFO_DIFF && sndseekEx(dz->ifd[1],0,0)<0) {
  773. sprintf(errstr,"sndseekEx() problem 2 in sfdiff_process()\n");
  774. return(SYSTEM_ERROR);
  775. }
  776. while(dz->samps_left > 0) {
  777. if(dz->process==INFO_CDIFF) {
  778. if((exit_status = read_samps_for_cdiff(dz))<0)
  779. return(exit_status);
  780. } else {
  781. if((exit_status = read_both_the_files(samesize,dz))<0)
  782. return(exit_status);
  783. }
  784. compare_samps(temp,&badmatch,&limitcnt,threshold,dz);
  785. display_virtual_time(dz->total_samps_read,dz);
  786. fflush(stdout);
  787. }
  788. if(limitcnt == 0) {
  789. if(dz->process==INFO_CDIFF)
  790. sprintf(errstr,"Channels are IDENTICAL");
  791. else {
  792. if(samesize)
  793. sprintf(errstr,"Files are IDENTICAL");
  794. else
  795. sprintf(errstr,"Files are otherwise IDENTICAL");
  796. }
  797. if(dz->process==INFO_CDIFF) {
  798. if(dz->param[SFDIFF_THRESH] > 0) {
  799. sprintf(temp," to within %lf\n",dz->param[SFDIFF_THRESH]);
  800. strcat(errstr,temp);
  801. }else
  802. strcat(errstr,"\n");
  803. } else {
  804. switch(dz->infile->filetype) {
  805. case(SNDFILE):
  806. if(dz->param[SFDIFF_THRESH] > 0) {
  807. sprintf(temp," to within %lf\n",dz->param[SFDIFF_THRESH]);
  808. strcat(errstr,temp);
  809. } else
  810. strcat(errstr,"\n");
  811. break;
  812. default:
  813. if(dz->param[SFDIFF_THRESH] > 0.0) {
  814. sprintf(temp," to within %lf\n",dz->param[SFDIFF_THRESH]);
  815. strcat(errstr,temp);
  816. } else
  817. strcat(errstr,"\n");
  818. break;
  819. }
  820. }
  821. } else if(badmatch) {
  822. if(limitcnt < dz->iparam[SFDIFF_CNT])
  823. strcat(errstr," : as far as end of file.\n");
  824. else
  825. strcat(errstr," : comparison stopped here.\n");
  826. }
  827. return(FINISHED);
  828. }
  829. /************************ READ_BOTH_THE_FILES *******************************/
  830. int read_both_the_files(int samesize,dataptr dz)
  831. {
  832. int samps_read2;
  833. if((dz->ssampsread = fgetfbufEx(dz->sampbuf[0], /*dz->bigbufsize*/dz->buflen,dz->ifd[0],0)) < 0) {
  834. sprintf(errstr, "Can't read samps from 1st soundfile\n");
  835. return(SYSTEM_ERROR);
  836. }
  837. if((samps_read2 = fgetfbufEx(dz->sampbuf[1], dz->buflen,dz->ifd[1],0)) < 0) {
  838. sprintf(errstr, "Can't read samps from 2nd soundfile\n");
  839. return(SYSTEM_ERROR);
  840. }
  841. if((dz->ssampsread != samps_read2)) {
  842. if(samesize) {
  843. sprintf(errstr, "Anomaly in soundfile read.\n");
  844. return(PROGRAM_ERROR);
  845. } else
  846. dz->ssampsread = min(dz->ssampsread,samps_read2);
  847. }
  848. dz->total_samps_read += dz->ssampsread;
  849. dz->samps_left -= dz->ssampsread;
  850. return(FINISHED);
  851. }
  852. /************************ READ_SAMPS_FOR_CDIFF *******************************/
  853. int read_samps_for_cdiff(dataptr dz)
  854. {
  855. int n, m;
  856. if((dz->ssampsread = fgetfbufEx(dz->sampbuf[2], dz->buflen * 2,dz->ifd[0],0)) < 0) {
  857. sprintf(errstr, "Can't read samples from soundfile\n");
  858. return(SYSTEM_ERROR);
  859. }
  860. for(n=0,m=0;m<dz->ssampsread;n++,m+=2) {
  861. dz->sampbuf[0][n] = dz->sampbuf[2][m];
  862. dz->sampbuf[1][n] = dz->sampbuf[2][m+1];
  863. }
  864. dz->total_samps_read += dz->ssampsread;
  865. dz->samps_left -= dz->ssampsread;
  866. return(FINISHED);
  867. }
  868. /**************************** COMPARE_SAMPS ***************************/
  869. void compare_samps(char temp[],int *badmatch,int *limitcnt,double threshold,dataptr dz)
  870. {
  871. int n;
  872. int sampsread = dz->ssampsread;
  873. switch(dz->infile->filetype) {
  874. case(SNDFILE):
  875. if(dz->process==INFO_CDIFF)
  876. sampsread /= STEREO;
  877. for(n=0;n<sampsread;n++) {
  878. if(fabs(dz->sampbuf[0][n]-dz->sampbuf[1][n]) > threshold) {
  879. if(*badmatch==0) {
  880. sprintf(errstr,"Badmatch from ");
  881. snd_file_time(temp,n,dz);
  882. *badmatch = 1;
  883. if(++(*limitcnt) >= dz->iparam[SFDIFF_CNT]) {
  884. dz->samps_left = 0; /* force calling loop to end */
  885. return;
  886. }
  887. }
  888. } else {
  889. if(*badmatch) {
  890. strcat(errstr," as far as ");
  891. snd_file_time(temp,n,dz);
  892. strcat(errstr,"\n");
  893. print_outmessage(errstr);
  894. *badmatch = 0;
  895. }
  896. }
  897. }
  898. break;
  899. case(ANALFILE):
  900. dz->ssampsread = sampsread;
  901. for(n=0;n<dz->ssampsread;n+=2) {
  902. if(fabs(dz->flbufptr[0][n]-dz->flbufptr[1][n]) > threshold) {
  903. if(*badmatch==0) {
  904. sprintf(errstr,"Bad frq match from ");
  905. anal_file_time(temp,n,dz);
  906. *badmatch = 1;
  907. if(++(*limitcnt) >= dz->iparam[SFDIFF_CNT]) {
  908. dz->samps_left = 0;
  909. return;
  910. }
  911. }
  912. } else {
  913. if(*badmatch) {
  914. strcat(errstr," as far as ");
  915. anal_file_time(temp,n,dz);
  916. strcat(errstr,"\n");
  917. print_outmessage(errstr);
  918. *badmatch = 0;
  919. }
  920. }
  921. }
  922. if(*badmatch) {
  923. strcat(errstr," as far as ");
  924. anal_file_time(temp,n,dz);
  925. strcat(errstr,"\n");
  926. print_outmessage(errstr);
  927. *badmatch = 0;
  928. }
  929. for(n=1;n<dz->ssampsread;n+=2) {
  930. if(fabs(dz->flbufptr[0][n]-dz->flbufptr[1][n]) > threshold) {
  931. if(*badmatch==0) {
  932. sprintf(errstr,"Bad amp match from ");
  933. anal_file_time(temp,n,dz);
  934. *badmatch = 1;
  935. if(++(*limitcnt) >= dz->iparam[SFDIFF_CNT]) {
  936. dz->samps_left = 0;
  937. return;
  938. }
  939. }
  940. } else {
  941. if(*badmatch) {
  942. strcat(errstr," as far as ");
  943. anal_file_time(temp,n,dz);
  944. strcat(errstr,"\n");
  945. print_outmessage(errstr);
  946. *badmatch = 0;
  947. }
  948. }
  949. }
  950. if(*badmatch) {
  951. strcat(errstr," to buffer end ");
  952. anal_file_time(temp,n,dz);
  953. strcat(errstr,"\n");
  954. print_outmessage(errstr);
  955. *badmatch = 0;
  956. }
  957. break;
  958. default: /* float files */
  959. dz->ssampsread = sampsread;
  960. for(n=0;n<dz->ssampsread;n++) {
  961. if(fabs(dz->flbufptr[0][n]-dz->flbufptr[1][n]) > threshold) {
  962. if(*badmatch==0) {
  963. sprintf(errstr,"Badmatch from ");
  964. anal_file_time(temp,n,dz);
  965. *badmatch = 1;
  966. if(++(*limitcnt) >= dz->iparam[SFDIFF_CNT]) {
  967. dz->samps_left = 0;
  968. return;
  969. }
  970. }
  971. } else {
  972. if(*badmatch) {
  973. strcat(errstr," as far as ");
  974. anal_file_time(temp,n,dz);
  975. strcat(errstr,"\n");
  976. print_outmessage(errstr);
  977. *badmatch = 0;
  978. }
  979. }
  980. }
  981. break;
  982. }
  983. }
  984. /***************************** ANAL_FILE_TIME *************************/
  985. void anal_file_time(char temp[],int n,dataptr dz)
  986. {
  987. int this_channel;
  988. double this_time;
  989. int wanted;
  990. int this_sample = (dz->total_samps_read - dz->ssampsread) + n;
  991. int this_window;
  992. switch(dz->infile->filetype) {
  993. case(ANALFILE):
  994. wanted = dz->infile->Mlen + 2;
  995. this_window = this_sample/wanted; /* TRUNCATE */
  996. this_sample = this_sample%wanted; /* sample count from window base */
  997. this_channel = this_sample/2;
  998. this_time = (double)this_window/(double)dz->infile->arate;
  999. sprintf(temp," channel %d: window %d: time %.4lf ",this_channel,this_window,this_time);
  1000. break;
  1001. case(PITCHFILE):
  1002. case(TRANSPOSFILE):
  1003. this_window = this_sample;
  1004. this_time = (double)this_window/(double)dz->infile->arate;
  1005. sprintf(temp," window %d: time %.4lf ",this_window,this_time);
  1006. break;
  1007. case(ENVFILE):
  1008. this_window = this_sample;
  1009. this_time = (double)this_window * dz->infile->window_size * MS_TO_SECS;
  1010. sprintf(temp," window %d: time %.4lf ",this_window,this_time);
  1011. break;
  1012. case(FORMANTFILE):
  1013. this_sample -= dz->specenvcnt * DESCRIPTOR_DATA_BLOKS;
  1014. this_window = this_sample/dz->specenvcnt; /* TRUNCATE */
  1015. this_channel = this_sample%dz->specenvcnt;
  1016. this_time = (double)this_window/(double)dz->infile->arate;
  1017. sprintf(temp," channel %d: window %d: time %.4lf ",this_channel,this_window,this_time);
  1018. break;
  1019. }
  1020. strcat(errstr,temp);
  1021. }
  1022. /**************************** SND_FILE_TIME ***************************/
  1023. void snd_file_time(char temp [],int n,dataptr dz)
  1024. {
  1025. int this_sample;
  1026. double this_time, sr = (double)dz->infile->srate;
  1027. if(dz->process==INFO_CDIFF) {
  1028. this_sample = ((dz->total_samps_read - dz->ssampsread)/STEREO) + n;
  1029. this_time = (double)this_sample/sr;
  1030. } else {
  1031. this_sample = (dz->total_samps_read - dz->ssampsread) + n;
  1032. this_time = (double)this_sample/(sr * (double)dz->infile->channels);
  1033. }
  1034. sprintf(temp,"sample %d: time %.4lf ",this_sample,this_time);
  1035. strcat(errstr,temp);
  1036. }
  1037. /**************************** COMPARE_ANALFILE_PROPERTIES ***************************/
  1038. int compare_analfile_properties(dataptr dz)
  1039. {
  1040. errstr[0] = ENDOFSTR;
  1041. switch(dz->infile->filetype) {
  1042. case(ENVFILE):
  1043. if(dz->infile->window_size != dz->otherfile->window_size) {
  1044. sprintf(errstr,"Files do not have same WINDOW_SIZE.\n");
  1045. return(FINISHED);
  1046. }
  1047. break;
  1048. case(FORMANTFILE):
  1049. if(dz->infile->specenvcnt != dz->otherfile->specenvcnt) {
  1050. sprintf(errstr,"Files do not have same FORMANT WINDOW CNT.\n");
  1051. return(FINISHED);
  1052. }
  1053. break;
  1054. case(PITCHFILE):
  1055. case(TRANSPOSFILE):
  1056. if(dz->infile->origchans != dz->otherfile->origchans) {
  1057. sprintf(errstr,"Files do not have same ORIGINAL NO. OF CHANNELS.\n");
  1058. return(FINISHED);
  1059. }
  1060. break;
  1061. }
  1062. if(dz->infile->stype != dz->otherfile->stype) {
  1063. sprintf(errstr,"Files do not have same SAMPLE TYPE.\n");
  1064. return(FINISHED);
  1065. }
  1066. if(dz->infile->srate != dz->otherfile->srate) {
  1067. sprintf(errstr,"Files do not have same SAMPLING RATE.\n");
  1068. return(FINISHED);
  1069. }
  1070. if(dz->infile->channels != dz->otherfile->channels) {
  1071. sprintf(errstr,"Files do not have same NO. OF CHANNELS.\n");
  1072. return(FINISHED);
  1073. }
  1074. if(dz->infile->filetype!=ENVFILE) {
  1075. if(dz->infile->origstype != dz->otherfile->origstype) {
  1076. sprintf(errstr,"Files do not have same ORIGINAL SAMPLE TYPE.\n");
  1077. return(FINISHED);
  1078. }
  1079. if(dz->infile->origrate != dz->otherfile->origrate) {
  1080. sprintf(errstr,"Files do not have same ORIGINAL SAMPLING RATE.\n");
  1081. return(FINISHED);
  1082. }
  1083. if(dz->infile->arate != dz->otherfile->arate) {
  1084. sprintf(errstr,"Files do not have same ANALYSIS RATE.\n");
  1085. return(FINISHED);
  1086. }
  1087. if(dz->infile->Mlen != dz->otherfile->Mlen) {
  1088. sprintf(errstr,"Files do not have same ANALYSIS WINDOW LENGTH.\n");
  1089. return(FINISHED);
  1090. }
  1091. if(dz->infile->Dfac != dz->otherfile->Dfac) {
  1092. sprintf(errstr,"Files do not have same DECIMATION FACTOR.\n");
  1093. return(FINISHED);
  1094. }
  1095. }
  1096. return(CONTINUE);
  1097. }
  1098. /********************************* DO_SFDIFF ***********************************/
  1099. int do_sfdiff(char temp[],dataptr dz)
  1100. {
  1101. int exit_status;
  1102. int samesize = TRUE;
  1103. switch(dz->process) {
  1104. case(INFO_CDIFF):
  1105. if(dz->infile->channels!=2) {
  1106. sprintf(errstr,"Process only works with STEREO files.\n");
  1107. return(DATA_ERROR);
  1108. }
  1109. break;
  1110. default:
  1111. if(is_a_text_input_filetype(dz->infile->filetype)
  1112. || is_a_text_input_filetype(dz->otherfile->filetype)) {
  1113. sprintf(errstr,"Program only works with soundfiling system files.\n");
  1114. return(DATA_ERROR);
  1115. }
  1116. if(dz->infile->filetype != dz->otherfile->filetype) {
  1117. print_outmessage_flush("Files are not of the same type.\n");
  1118. return(FINISHED);
  1119. }
  1120. if(compare_infile_sizes(&samesize,dz)!=CONTINUE)
  1121. return(FINISHED);
  1122. switch(dz->infile->filetype) {
  1123. case(SNDFILE):
  1124. if(compare_sndfile_properties(temp,dz)!=CONTINUE) {
  1125. print_outmessage_flush(errstr);
  1126. return(FINISHED);
  1127. }
  1128. break;
  1129. default:
  1130. if(compare_analfile_properties(dz)!=CONTINUE) {
  1131. print_outmessage_flush(errstr);
  1132. return(FINISHED);
  1133. }
  1134. dz->flbufptr[0] = dz->sampbuf[0];
  1135. dz->flbufptr[1] = dz->sampbuf[1];
  1136. break;
  1137. }
  1138. break;
  1139. }
  1140. if((exit_status = sfdiff_process(temp,samesize,dz))<0)
  1141. return(exit_status);
  1142. print_outmessage_flush(errstr);
  1143. return(FINISHED);
  1144. }
  1145. /********************************* PRNTPROPS ***********************************/
  1146. /* RWD much adapted to report PEAK data if available */
  1147. int prntprops(SFPROPS *props,dataptr dz)
  1148. {
  1149. char *prop;
  1150. time_t thistime;
  1151. char *p;
  1152. CHPEAK peaks[2000];
  1153. int chans, peaktime;
  1154. if((prop = (char *)malloc(max(sizeof(unsigned int),sizeof(double))))==NULL) {
  1155. sprintf(errstr,"INSUFFICIENT MEMORY to get properties.\n");
  1156. return(MEMORY_ERROR);
  1157. }
  1158. /*RWD find PEAK chunk as priority */
  1159. if(snd_headread(dz->ifd[0],props)){
  1160. if((*props).type == wt_wave) {
  1161. switch(props->samptype){ /*RWD Nov 2003 show sample type now we have so many possibilities! */
  1162. case(SHORT16):
  1163. sprintf(errstr,"sample type: 16bit\n");
  1164. break;
  1165. case(FLOAT32):
  1166. sprintf(errstr,"sample type: 32bit floats\n");
  1167. break;
  1168. case(INT2424):
  1169. sprintf(errstr,"sample type: 24bit packed\n");
  1170. break;
  1171. case(SHORT8):
  1172. sprintf(errstr,"sample type: 8bit\n");
  1173. break;
  1174. case(INT2432):
  1175. sprintf(errstr,"sample type: 24bit in 32bit frames\n");
  1176. break;
  1177. case(INT_32):
  1178. sprintf(errstr,"sample type: 32bit integer\n");
  1179. break;
  1180. default:
  1181. sprintf(errstr,"sample type unknown (custom format)\n");
  1182. break;
  1183. }
  1184. print_outmessage(errstr);
  1185. chans = (*props).chans;
  1186. if(sndreadpeaks(dz->ifd[0],chans,peaks,&peaktime)>0){
  1187. int i;
  1188. thistime = (time_t) peaktime;
  1189. sprintf(errstr,"PEAK data at: %s\n",ctime(&thistime));
  1190. print_outmessage(errstr);
  1191. for(i=0;i < chans;i++){
  1192. sprintf(errstr,"CH %d:\tamp = %.4f (%.2f dB)\tFrame %u\n",
  1193. i+1,peaks[i].value,20 * log10(peaks[i].value),peaks[i].position);
  1194. print_outmessage(errstr);
  1195. }
  1196. }
  1197. else {
  1198. sprintf(errstr,"No PEAK chunk in this file");
  1199. print_outmessage(errstr);
  1200. }
  1201. }
  1202. }
  1203. if(sndgetprop(dz->ifd[0], "date", prop, sizeof(unsigned int))>=0
  1204. || sndgetprop(dz->ifd[0], "DATE", prop, sizeof(unsigned int))>=0) {
  1205. thistime = (time_t) *(int*)prop;
  1206. p = ctime(&thistime);
  1207. sprintf(errstr,"Date: %s\n",p);
  1208. print_outmessage(errstr);
  1209. }
  1210. fflush(stdout);
  1211. return(FINISHED);
  1212. }
  1213. /************************** GET_SHORT_MAXMIN ************************/
  1214. int get_float_maxmin(float *buf,int chans, double inverse_sr,dataptr dz)
  1215. {
  1216. int exit_status;
  1217. /*int maxamp = MINSAMP;*/
  1218. float maxamp = F_MINSAMP,mag;
  1219. int maxloc = 0;
  1220. int maxrep = 1;
  1221. int n;
  1222. double gain = 0.0, dbgain = 0.0;
  1223. double convertor = (double)(chans * dz->infile->srate);
  1224. int startsamp = round(dz->param[MAX_STIME] * convertor);
  1225. int endsamp = round(dz->param[MAX_ETIME] * convertor);
  1226. int last_total_samps_read;
  1227. int startsrch, endsrch;
  1228. dz->total_samps_read = 0; /* REDUNDANT ? */
  1229. while(dz->samps_left) {
  1230. last_total_samps_read = dz->total_samps_read;
  1231. if((exit_status = read_samps(buf,dz))<0)
  1232. return(exit_status);
  1233. if(dz->total_samps_read <= startsamp)
  1234. continue;
  1235. else
  1236. startsrch = max(0,startsamp - last_total_samps_read);
  1237. if(dz->total_samps_read > endsamp) {
  1238. if((endsrch = endsamp - last_total_samps_read) < 0)
  1239. break;
  1240. } else
  1241. endsrch = dz->ssampsread;
  1242. for(n=startsrch;n<endsrch;n++) {
  1243. mag = (float) fabs(buf[n]);
  1244. if(mag > maxamp) {
  1245. maxloc = last_total_samps_read + n;
  1246. maxamp = mag;
  1247. maxrep = 1;
  1248. } else if(mag==maxamp)
  1249. maxrep++;
  1250. }
  1251. }
  1252. if(maxamp>0.0f) {
  1253. gain = (double)F_MAXSAMP/(double)maxamp;
  1254. dbgain = log10(gain) * 20.0;
  1255. }
  1256. sprintf(errstr,"maximum abs value:.. %f\n",maxamp);
  1257. print_outmessage(errstr);
  1258. sprintf(errstr,"at: ................ %d samples\n",maxloc);
  1259. print_outmessage(errstr);
  1260. sprintf(errstr,"time: .............. %.4lf secs\n",(double)(maxloc/chans) *inverse_sr);
  1261. print_outmessage(errstr);
  1262. sprintf(errstr,"repeated: .......... %d times\n",maxrep);
  1263. print_outmessage(errstr);
  1264. if(maxamp>0.0f) {
  1265. sprintf(errstr,"max possible gain:.. %.4lf\n",gain);
  1266. print_outmessage(errstr);
  1267. sprintf(errstr,"max dB gain:........ %.4lf\n",dbgain);
  1268. print_outmessage(errstr);
  1269. }
  1270. return(FINISHED);
  1271. }
  1272. /*RWD 6:2001 read PEAK chunk */
  1273. int getpeakdata(int ifd, float *peakval,SFPROPS *props)
  1274. {
  1275. CHPEAK peaks[16];
  1276. int chans, peaktime;
  1277. float maxamp = 0.0f;
  1278. if(snd_headread(ifd,props)){
  1279. chans = (*props).chans;
  1280. if(sndreadpeaks(ifd,chans,peaks,&peaktime)){
  1281. int i;
  1282. for(i=0;i < chans;i++)
  1283. maxamp = max(maxamp,peaks[i].value);
  1284. *peakval = maxamp;
  1285. return 1;
  1286. }
  1287. }
  1288. /* sf_headread error; but can't do much about it */
  1289. return 0;
  1290. }
  1291. /************************** DO_ZCROSS_RATIO ************************/
  1292. int do_zcross_ratio(dataptr dz)
  1293. {
  1294. int exit_status;
  1295. int chans = dz->infile->channels, *phase, k, m;
  1296. int n, *cnt, cntsum = 0, zc0, zc1, lastzc0, lastzc1, bufstart, bufend, bufskip, skipsamps, totsams, total_samps_processed;
  1297. double zc_ratio;
  1298. float *buf = dz->sampbuf[0];
  1299. double srate = dz->infile->srate;
  1300. if((cnt = (int *)malloc(chans * sizeof(int)))==NULL) {
  1301. sprintf(errstr,"NO MEMORY TO STORE ZERO-CROSSING COUNTERS.\n");
  1302. return(MEMORY_ERROR);
  1303. }
  1304. if((phase = (int *)malloc(chans * sizeof(int)))==NULL) {
  1305. sprintf(errstr,"NO MEMORY TO STORE PHASE MARKERS.\n");
  1306. return(MEMORY_ERROR);
  1307. }
  1308. dz->iparam[ZC_START] = (int)round(dz->param[ZC_START] * srate) * chans;
  1309. bufend = (int)round(dz->param[ZC_END] * srate) * chans;
  1310. totsams = bufend - dz->iparam[ZC_START];
  1311. dz->tempsize = totsams;
  1312. bufstart = dz->iparam[ZC_START] % dz->buflen;
  1313. if((bufskip = dz->iparam[ZC_START] / dz->buflen) > 0) {
  1314. skipsamps = bufskip * dz->buflen;
  1315. sndseekEx(dz->ifd[0],skipsamps,0);
  1316. bufend -= skipsamps;
  1317. }
  1318. if((exit_status = read_samps(buf,dz)) < 0)
  1319. return(exit_status);
  1320. if(dz->ssampsread < chans * 2) {
  1321. sprintf(errstr,"INSUFFICIENT DATA TO COUNT ZERO-CROSSINGS.\n");
  1322. return(DATA_ERROR);
  1323. }
  1324. total_samps_processed = 0;
  1325. for(m=0,n = bufstart;m<chans;m++,n++) {
  1326. if(buf[n] > 0)
  1327. phase[m] = 1;
  1328. else if(buf[n] < 0)
  1329. phase[m] = -1;
  1330. else
  1331. phase[m] = 0;
  1332. cnt[m] = 0;
  1333. }
  1334. k = bufstart + chans;
  1335. while(bufend > dz->buflen) {
  1336. for(n = k; n < dz->ssampsread;n+=chans) {
  1337. for(m=0;m<chans;m++) {
  1338. switch(phase[m]) {
  1339. case(0):
  1340. if(buf[n+m] > 0)
  1341. phase[m] = 1;
  1342. else if(buf[n+m] < 0)
  1343. phase[m] = -1;
  1344. break;
  1345. case(1):
  1346. if(buf[n+m] < 0) {
  1347. cnt[m]++;
  1348. phase[m] = -1;
  1349. }
  1350. break;
  1351. case(-1):
  1352. if(buf[n+m] > 0) {
  1353. cnt[m]++;
  1354. phase[m] = 1;
  1355. }
  1356. break;
  1357. }
  1358. }
  1359. }
  1360. total_samps_processed += (dz->ssampsread - k);
  1361. display_virtual_time(total_samps_processed,dz);
  1362. if((exit_status = read_samps(buf,dz)) < 0)
  1363. return(exit_status);
  1364. bufend -= dz->buflen;
  1365. k = 0;
  1366. }
  1367. if(bufend > 0) {
  1368. for(n = k; n < bufend;n+=chans) {
  1369. for(m=0;m<chans;m++) {
  1370. switch(phase[m]) {
  1371. case(0):
  1372. if(buf[n+m] > 0)
  1373. phase[m] = 1;
  1374. else if(buf[n+m] < 0)
  1375. phase[m] = -1;
  1376. break;
  1377. case(1):
  1378. if(buf[n+m] < 0) {
  1379. cnt[m]++;
  1380. phase[m] = -1;
  1381. }
  1382. break;
  1383. case(-1):
  1384. if(buf[n+m] > 0) {
  1385. cnt[m]++;
  1386. phase[m] = 1;
  1387. }
  1388. break;
  1389. }
  1390. }
  1391. }
  1392. total_samps_processed += (bufend - k);
  1393. display_virtual_time(total_samps_processed,dz);
  1394. }
  1395. for(m=0;m<chans;m++)
  1396. cntsum += cnt[m];
  1397. zc_ratio = (double)cntsum/(double)totsams;
  1398. zc1 = 32768;
  1399. zc0 = (int)round(zc_ratio * zc1);
  1400. do {
  1401. lastzc0 = zc0;
  1402. lastzc1 = zc1;
  1403. zc1 /= 2;
  1404. zc0 = (int)round(zc_ratio * zc1);
  1405. } while(zc0 > 0 && zc1 >= 64);
  1406. zc0 = lastzc0;
  1407. zc1 = lastzc1;
  1408. while(EVEN(zc0)) {
  1409. zc0 /= 2;
  1410. zc1 /= 2;
  1411. }
  1412. fprintf(stdout,"INFO: Proportion of zero-crossings = %lf or approx %d:%d\n",zc_ratio,zc0,zc1);
  1413. fflush(stdout);
  1414. return FINISHED;
  1415. }