cdparse.c 65 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147
  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. /* floats version */
  22. /* RECEIVES FROM TK
  23. *
  24. * Name of input file.
  25. *
  26. * SENDS TO TK
  27. *
  28. * (1) Various file constants, which TK needs to STORE, to pass back at subsequent stage.
  29. */
  30. /**** FEB 1999 MODS
  31. *
  32. * Force cdparams() output to be printed to stdout on a single line, with items separated by
  33. * single spaces, forming a valid TK list
  34. *
  35. * Recognise Float-sndfiles.
  36. */
  37. #include <stdio.h>
  38. #include <osbind.h>
  39. #include <math.h>
  40. #include <float.h>
  41. #include <structures.h>
  42. #include <sfsys.h>
  43. #include <cdpstate.h>
  44. #include <tkglobals.h>
  45. #include <filetype.h>
  46. #include <globcon.h>
  47. #include <headread.h>
  48. #include <speccon.h>
  49. #include <processno.h>
  50. #include <stdlib.h>
  51. #include <ctype.h>
  52. #include <limits.h>
  53. #include <string.h>
  54. //OCT 2005
  55. #include <standalone.h>
  56. /* NEW CODE June 1st 2000 */
  57. #ifndef CDP97
  58. #define CDP97 //RWD.6.98 need this!
  59. #endif
  60. #ifdef _DEBUG
  61. #include <assert.h>
  62. #endif
  63. void maxsamp(int ifd,double *maxamp,double *maxloc,int *maxrep);
  64. /* END OF NEW CODE */
  65. #define POSSIBLE (TRUE)
  66. char errstr[400];
  67. //RWD debugging
  68. #define LOCALMEMBYTES (4000)
  69. #ifdef unix
  70. #define round(x) lround((x))
  71. #endif
  72. static void initialise_fileptr(infileptr inputfile);
  73. static int check_for_data_in_file(char *filename,infileptr inputfile);
  74. static int set_wlength_and_check_data(char *filename,int ifd,infileptr inputfile);
  75. static int check_pitch_or_transpos_binary_data(infileptr inputfile,char *filename,int ifd);
  76. static int megaparsec(char *filename,FILE *fp,infileptr inputfile);
  77. static int initial_parse_textfile(char *filename,FILE *fp,int *linelist,
  78. int *has_comments,int *dB_notation,int *total_wordcnt,
  79. int *numcnt,int *linecnt,int *max_line_word_cnt,int *min_line_word_cnt);
  80. static void initial_textfile_check(int dB_notation,int *sndlist,int *mixlist,int *brklist,int *numlist,
  81. int numcnt,int total_wordcnt,int max_line_word_cnt,int in_line_word_cnt);
  82. static int valid_start_of_mixfile_line(int k,int *chans,int lineno,char **wordstor,int *srate,
  83. int *mixlist,infileptr inputfile,char *filename,double *dur);
  84. #ifdef IS_CDPARSE
  85. static int is_valid_end_of_mixfile_line(int j,int chans,int lineno,char **wordstor,int *wordcnt);
  86. #else
  87. static int is_valid_end_of_mixfile_line(int j,int chans,int lineno,char **wordstor,int *wordcnt,char *filename);
  88. #endif
  89. static int confirm_true_stereo(int *chans,int *is_left,int *is_right,int *is_central,char *panword);
  90. static int is_a_possible_mixfile(char **wordstor,int *wordcnt,int linecnt,
  91. int *mixlist,int *srate,infileptr inputfile, char *filename,double *dur);
  92. static int OK_level(char *str);
  93. static int is_a_dB_value(char *str);
  94. static int get_leveldb_frame(char *str,double *val);
  95. static int is_a_valid_sndfile_for_mixfile(char *filename,char *sndfilename,int *srate,
  96. int chans,int linecnt,infileptr inputfile,double time,double *dur,int multichan);
  97. static int check_for_brklist_and_count_numbers(char **wordstor,int *wordcnt,
  98. int linecnt,int *brklist,infileptr inputfile,char *filename);
  99. static int check_for_a_linelist(int line_word_cnt,int *linelist,char **wordstor,infileptr inputfile);
  100. static int store_wordlist_without_comments
  101. (FILE *fp,char *temp,int total_wordcnt,char **wordstor,int *wordcnt,infileptr inputfile);
  102. /* NEW CODE */
  103. static int assign_type(int sndlist,int numlist,int brklist,int mixlist,int synclist,int linelist,
  104. int extended_brkfile,infileptr inputfile);
  105. /* NEW CODE */
  106. static int check_for_sndlist(char **wordstor,int *wordcnt,int linecnt,int *sndlist);
  107. static int check_for_a_synclist(int *synclist,char **wordstor,int *wordcnt,infileptr inputfile,char *filename);
  108. static int is_a_valid_sndfile_for_sync(char *filename,char *sndfilename,int *srate,int linecnt,infileptr inputfile);
  109. static int set_sndlist_flags(infileptr inputfile,char **wordstor);
  110. static int assign_brkfile_type(infileptr inputfile,int linelist);
  111. #ifdef NO_DUPLICATE_SNDFILES
  112. #ifdef IS_CDPARSE
  113. static int duplicated_filenames(int linecnt,char **wordstor,int *wordcnt);
  114. #else
  115. static int duplicated_filenames(int linecnt,char **wordstor,int *wordcnt,char *filename);
  116. #endif
  117. #endif
  118. static int check_for_an_extended_brkfile
  119. (int *extended_brkfile,char **wordstor,int *wordcnt,int linecnt,int total_words,infileptr inputfile);
  120. static int extract_value_pair
  121. (int *n,double *time, double *val,double *maxval,double *minval,double *lasttime, char **wordstor);
  122. static void utol(char *str);
  123. extern int smpflteq(double a,double b);
  124. int do_exit(int exit_status);
  125. /* RWD TODO: use sndsystem */
  126. #ifdef IS_CDPARSE
  127. //static int nuheadread(infileptr inputfile,int ifd,char *filename,double *maxamp,double *maxloc, int *maxrep,int getmax);
  128. #endif
  129. static int parse_a_textfile(char *filename,infileptr inputfile);
  130. static int get_multichan_mixdata_in_line(int wordcnt,char **wordstor,int total_words,double *time,int *chans,int maxoutchan);
  131. static int is_a_possible_multichannel_mixfile
  132. (int numlist,int brklist,int sndlist,int linecnt,char **wordstor,int *wordcnt,char *mixfilename,infileptr inputfile);
  133. static int IsNumeric(char *str);
  134. /***************************** MAIN **************************/
  135. #ifdef IS_CDPARSE
  136. int sloom = 1;
  137. int sloombatch = 0;
  138. const char* cdp_version = "7.1.0";
  139. int main(int argc,char *argv[])
  140. {
  141. char *filename;
  142. infileptr inputfile;
  143. char temp[/*2000*/LOCALMEMBYTES], *p; /*** Added FEB 1999 *****/
  144. int getmaxinfo = 1;
  145. #else
  146. int cdparse(char *filename,infileptr inputfile)
  147. {
  148. int getmaxinfo = 0;
  149. #endif
  150. int exit_status;
  151. int ifd;
  152. double maxamp = 0.0, maxloc = -1.0;
  153. int maxrep = 0;
  154. int getmax = 0;
  155. #ifdef IS_CDPARSE
  156. /* NEW CODE : June 1st 2000 */
  157. if(argc==2 && (strcmp(argv[1],"--version") == 0)) {
  158. fprintf(stdout,"%s\n",cdp_version);
  159. fflush(stdout);
  160. return 0;
  161. }
  162. if(argc!=3) {
  163. sprintf(errstr,"Incorrect call to cdparse()\n");
  164. exit_status = FAILED;
  165. return do_exit(exit_status);
  166. }
  167. if(sscanf(argv[2],"%d",&getmax)!=1) {
  168. sprintf(errstr,"Incorrect call to cdparse()\n");
  169. exit_status = FAILED;
  170. return do_exit(exit_status);
  171. }
  172. filename = argv[1];
  173. if(file_has_invalid_startchar(filename)) {
  174. sprintf(errstr, "Filename %s has invalid starting character(s)\n",filename);
  175. exit_status = FAILED;
  176. return do_exit(exit_status);
  177. }
  178. if(file_has_invalid_extension(filename)) {
  179. sprintf(errstr, "Filename %s has invalid extension for CDP work\n",filename);
  180. exit_status = FAILED;
  181. return do_exit(exit_status);
  182. }
  183. if((inputfile = (infileptr)malloc(sizeof(struct filedata)))==NULL) {
  184. sprintf(errstr,"Insufficient memory for parsing file %s.\n",filename);
  185. exit_status = MEMORY_ERROR;
  186. return do_exit(exit_status);
  187. }
  188. #endif
  189. initialise_fileptr(inputfile);
  190. if((ifd = sndopenEx(filename,0,CDP_OPEN_RDONLY)) >= 0) {
  191. if((exit_status = readhead(inputfile,ifd,filename,&maxamp,&maxloc,&maxrep,getmax,getmaxinfo))<0) {
  192. if(sndcloseEx(ifd)<0) {
  193. sprintf(errstr, "Failed to close file %s\n",filename);
  194. exit_status = SYSTEM_ERROR;
  195. return do_exit(exit_status);
  196. }
  197. return do_exit(exit_status);
  198. }
  199. if(getmaxinfo && getmax && (maxrep < 0)) { /* if maxsamp required & not in header, get it by searching file */
  200. //TW only get maxsamp if it's a soundfile
  201. if(inputfile->filetype == SNDFILE) {
  202. maxsamp(ifd,&maxamp,&maxloc,&maxrep); /*RWD TODO */
  203. sndseekEx(ifd,0,0); /* RWD TODO */
  204. }
  205. }
  206. if((inputfile->insams = sndsizeEx(ifd))<0) {
  207. sprintf(errstr, "Can't read size of input file %s\n",filename);
  208. exit_status = DATA_ERROR;
  209. if(sndcloseEx(ifd)<0) {
  210. sprintf(errstr, "Failed to close file %s: %s\n",filename,sferrstr());
  211. exit_status = SYSTEM_ERROR;
  212. }
  213. return do_exit(exit_status);
  214. }
  215. if((exit_status = check_for_data_in_file(filename,inputfile))<0) {
  216. if(sndcloseEx(ifd)<0) {
  217. sprintf(errstr, "Failed to close file %s\n",filename);
  218. exit_status = SYSTEM_ERROR;
  219. }
  220. return do_exit(exit_status);
  221. }
  222. switch(inputfile->filetype) {
  223. case(ANALFILE):
  224. case(PITCHFILE):
  225. case(TRANSPOSFILE):
  226. case(FORMANTFILE):
  227. inputfile->nyquist = inputfile->origrate/2.0;
  228. inputfile->frametime = (float)(1.0/inputfile->arate);
  229. /*inputfile->insams = inputfile->infilesize/sizeof(float); */
  230. if((exit_status = set_wlength_and_check_data(filename,ifd,inputfile))<0) {
  231. if(sndcloseEx(ifd)<0) {
  232. sprintf(errstr, "Failed to close file %s\n",filename);
  233. exit_status = SYSTEM_ERROR;
  234. }
  235. return do_exit(exit_status);
  236. }
  237. inputfile->duration = inputfile->wlength * inputfile->frametime;
  238. if(inputfile->duration <= FLTERR) {
  239. sprintf(errstr, "file %s has ZERO duration : ignoring it\n",filename);
  240. exit_status = DATA_ERROR;
  241. return do_exit(exit_status);
  242. }
  243. break;
  244. case(ENVFILE):
  245. if(sndgetprop(ifd,"window size",(char *)&inputfile->window_size,sizeof(float)) < 0) {
  246. sprintf(errstr, "Cannot read window size for file %s\n",filename);
  247. exit_status = DATA_ERROR;
  248. return do_exit(exit_status);
  249. }
  250. inputfile->duration = inputfile->window_size * inputfile->insams * MS_TO_SECS;
  251. if(inputfile->duration <= FLTERR) {
  252. sprintf(errstr, "file %s has zero duration : ignoring it\n",filename);
  253. exit_status = DATA_ERROR;
  254. return do_exit(exit_status);
  255. }
  256. break;
  257. case(SNDFILE):
  258. case(FLT_SNDFILE): /*RWD 2001 added - needed? */
  259. /*inputfile->insams = inputfile->infilesize/sizeof(short); */
  260. inputfile->nyquist = (double)inputfile->srate/2.0;
  261. inputfile->duration = (double)(inputfile->insams/inputfile->channels)/(double)(inputfile->srate);
  262. if(inputfile->duration <= FLTERR) {
  263. sprintf(errstr, "file %s has zero duration : ignoring it\n",filename);
  264. exit_status = DATA_ERROR;
  265. return do_exit(exit_status);
  266. }
  267. //RWD.7.99 need to reset this to FLT_SNDFILE if stype==FLOAT ?
  268. break;
  269. default:
  270. exit_status = DATA_ERROR;
  271. sprintf(errstr,"Unknown type of file: file %s\n",filename);
  272. if(sndcloseEx(ifd)<0) {
  273. sprintf(errstr, "Failed to close file %s\n",filename);
  274. exit_status = SYSTEM_ERROR;
  275. }
  276. return do_exit(exit_status);
  277. }
  278. if(sndcloseEx(ifd)<0) {
  279. sprintf(errstr, "Failed to close file %s\n",filename);
  280. exit_status = SYSTEM_ERROR;
  281. return do_exit(exit_status);
  282. }
  283. } else {
  284. if((exit_status = parse_a_textfile(filename,inputfile)) < 0)
  285. return(exit_status);
  286. }
  287. #ifdef IS_CDPARSE
  288. p = temp;
  289. sprintf(p,"%d ",inputfile->filetype); /* 0 */
  290. p = temp + strlen(temp);
  291. //TW CORRECTED, FOR COMPATIBILITY WITH tkinput: first value OUTPUT is NOW in samples (it was, infilesize)
  292. // sprintf(p,"%d ", inputfile->infilesize /* 1 */ p = temp + strlen(temp);
  293. sprintf(p,"%d ", inputfile->insams); /* 1 */ p = temp + strlen(temp);
  294. sprintf(p,"%d ", inputfile->insams); /* 2 */ p = temp + strlen(temp);
  295. sprintf(p,"%d ", inputfile->srate); /* 3 */ p = temp + strlen(temp);
  296. sprintf(p,"%d ", inputfile->channels); /* 4 */ p = temp + strlen(temp);
  297. sprintf(p,"%d ", inputfile->wanted); /* 5 */ p = temp + strlen(temp);
  298. sprintf(p,"%d ", inputfile->wlength); /* 6 */ p = temp + strlen(temp);
  299. sprintf(p,"%d ", inputfile->linecnt); /* 7 */ p = temp + strlen(temp);
  300. sprintf(p,"%f ", inputfile->arate); /* 8 */ p = temp + strlen(temp);
  301. sprintf(p,"%.12f ",inputfile->frametime); /* 9 */ p = temp + strlen(temp);
  302. sprintf(p,"%lf ", inputfile->nyquist); /* 10 */ p = temp + strlen(temp);
  303. sprintf(p,"%lf ", inputfile->duration); /* 11 */ p = temp + strlen(temp);
  304. sprintf(p,"%d ", inputfile->stype); /* 12 */ p = temp + strlen(temp);
  305. sprintf(p,"%d ", inputfile->origstype); /* 13 */ p = temp + strlen(temp);
  306. sprintf(p,"%d ", inputfile->origrate); /* 14 */ p = temp + strlen(temp);
  307. sprintf(p,"%d ", inputfile->Mlen); /* 15 */ p = temp + strlen(temp);
  308. sprintf(p,"%d ", inputfile->Dfac); /* 16 */ p = temp + strlen(temp);
  309. sprintf(p,"%d ", inputfile->origchans); /* 17 */ p = temp + strlen(temp);
  310. sprintf(p,"%d ", inputfile->specenvcnt); /* 18 */ p = temp + strlen(temp);
  311. sprintf(p,"%d ", inputfile->out_chans); /* 19 */ p = temp + strlen(temp);
  312. //TW REVISED
  313. // sprintf(p,"%d ", inputfile->descriptor_bytes); /* 20 * p = temp + strlen(temp); /*RWD TODO : ??? */
  314. sprintf(p,"%d ", inputfile->descriptor_samps); /* 20 */ p = temp + strlen(temp);
  315. sprintf(p,"%d ", inputfile->is_transpos); /* 21 */ p = temp + strlen(temp);
  316. sprintf(p,"%d ", inputfile->could_be_transpos); /* 22 */ p = temp + strlen(temp);
  317. sprintf(p,"%d ", inputfile->could_be_pitch); /* 23 */ p = temp + strlen(temp);
  318. sprintf(p,"%d ", inputfile->different_srates); /* 24 */ p = temp + strlen(temp);
  319. sprintf(p,"%d ", inputfile->duplicate_snds); /* 25 */ p = temp + strlen(temp);
  320. sprintf(p,"%d ", inputfile->brksize); /* 26 */ p = temp + strlen(temp);
  321. sprintf(p,"%d ", inputfile->numsize); /* 27 */ p = temp + strlen(temp);
  322. sprintf(p,"%d ", inputfile->all_words); /* 28 */ p = temp + strlen(temp);
  323. sprintf(p,"%f ", inputfile->window_size); /* 29 */ p = temp + strlen(temp);
  324. sprintf(p,"%lf ", inputfile->minbrk); /* 30 */ p = temp + strlen(temp);
  325. sprintf(p,"%lf ", inputfile->maxbrk); /* 31 */ p = temp + strlen(temp);
  326. sprintf(p,"%lf ", inputfile->minnum); /* 32 */ p = temp + strlen(temp);
  327. sprintf(p,"%lf ", inputfile->maxnum); /* 33 */ p = temp + strlen(temp);
  328. //TW maxsamp is now float value
  329. sprintf(p,"%lf ", maxamp); /* 34 value of maxsamp */ p = temp + strlen(temp);
  330. sprintf(p,"%d ", (int)round(maxloc)); /* 35 location maxsamp */ p = temp + strlen(temp);
  331. sprintf(p,"%d\n", maxrep); /* 36 no of repets, [old usage, -1 flagged no maxval] */
  332. fprintf(stdout,"%s",temp);
  333. fprintf(stdout,"END\n");
  334. fflush(stdout);
  335. return(SUCCEEDED);
  336. #else
  337. return(FINISHED);
  338. #endif
  339. }
  340. /********************************** CHECK_FOR_DATA_IN_FILE ************************************/
  341. int check_for_data_in_file(char *filename,infileptr inputfile)
  342. {
  343. switch(inputfile->filetype) {
  344. case(FORMANTFILE):
  345. /*if(inputfile->infilesize <= (int)(DESCRIPTOR_DATA_BLOKS * inputfile->specenvcnt * sizeof(float))) */
  346. if(inputfile->insams <= (int)(DESCRIPTOR_DATA_BLOKS * inputfile->specenvcnt)) {
  347. sprintf(errstr, "FILE %s contains no data.\n",filename);
  348. return(DATA_ERROR);
  349. }
  350. break;
  351. default:
  352. if(inputfile->insams <= 0L) {
  353. sprintf(errstr, "FILE %s contains no data.\n",filename);
  354. return(DATA_ERROR);
  355. }
  356. break;
  357. }
  358. return(FINISHED);
  359. }
  360. /************************* INITIALISE_FILEPTR *************************/
  361. void initialise_fileptr(infileptr inputfile)
  362. {
  363. inputfile->filetype = 0;
  364. /*inputfile->infilesize = 0;*/
  365. inputfile->insams = 0;
  366. inputfile->srate = 0;
  367. inputfile->channels = 0;
  368. inputfile->stype = 0;
  369. inputfile->origstype = 0;
  370. inputfile->origrate = 0;
  371. inputfile->Mlen = 0;
  372. inputfile->Dfac = 0;
  373. inputfile->origchans = 0;
  374. inputfile->specenvcnt = 0;
  375. inputfile->wanted = 0;
  376. inputfile->wlength = 0;
  377. inputfile->out_chans = 0;
  378. inputfile->descriptor_samps = 0;
  379. inputfile->is_transpos = FALSE;
  380. inputfile->could_be_transpos = FALSE;
  381. inputfile->could_be_pitch = FALSE;
  382. inputfile->different_srates = FALSE;
  383. inputfile->duplicate_snds = FALSE;
  384. inputfile->brksize = 0;
  385. inputfile->numsize = 0;
  386. inputfile->linecnt = 0;
  387. inputfile->all_words = 0;
  388. inputfile->arate = 0.0f;
  389. inputfile->frametime = 0.0f;
  390. inputfile->window_size = 0.0f;
  391. inputfile->nyquist = 0.0;
  392. inputfile->duration = 0.0;
  393. inputfile->minbrk = 0.0;
  394. inputfile->maxbrk = 0.0;
  395. inputfile->minnum = 0.0;
  396. inputfile->maxnum = 0.0;
  397. }
  398. /***************************** SET_WLENGTH_AND_CHECK_DATA *******************************/
  399. int set_wlength_and_check_data(char *filename,int ifd,infileptr inputfile)
  400. {
  401. int exit_status;
  402. switch(inputfile->filetype) {
  403. case(ANALFILE):
  404. inputfile->wanted = inputfile->channels;
  405. inputfile->wlength = inputfile->insams/inputfile->wanted;
  406. break;
  407. case(PITCHFILE):
  408. case(TRANSPOSFILE):
  409. inputfile->wlength = inputfile->insams;
  410. inputfile->wanted = 1; /* notional: to avoid error calls with bad command lines */
  411. if((exit_status = check_pitch_or_transpos_binary_data(inputfile,filename,ifd))<0)
  412. return(exit_status);
  413. break;
  414. case(FORMANTFILE):
  415. inputfile->wlength = (inputfile->insams/inputfile->specenvcnt) - DESCRIPTOR_DATA_BLOKS;
  416. inputfile->descriptor_samps = inputfile->specenvcnt * DESCRIPTOR_DATA_BLOKS;
  417. inputfile->wanted = inputfile->origchans; /* temporary val for initialise_specenv */
  418. /* working val set in ...chunklen...() */
  419. break;
  420. default:
  421. sprintf(errstr,"Invalid case: set_wlength_and_check_data()\n");
  422. return(PROGRAM_ERROR);
  423. }
  424. return(FINISHED);
  425. }
  426. /********************* CHECK_PITCH_OR_TRANSPOS_BINARY_DATA *************************/
  427. int check_pitch_or_transpos_binary_data(infileptr inputfile,char *filename,int ifd)
  428. {
  429. int samps_read;
  430. int samps_to_read = inputfile->insams;
  431. int n;
  432. float *thisdata;
  433. if((thisdata = (float *)malloc((size_t)(samps_to_read * sizeof(float))))==NULL) {
  434. sprintf(errstr,"INSUFFICIENT MEMORY for pitch_or_transpos_binary_data of file %s\n",filename);
  435. return(MEMORY_ERROR);
  436. }
  437. samps_read = fgetfbufEx(thisdata, samps_to_read,ifd,0);
  438. if(samps_read!= inputfile->insams) {
  439. /*RWD.6.98 lets discriminate!*/
  440. if(samps_read < 0){
  441. sprintf(errstr,"Failed to read infile data.\n");
  442. return SYSTEM_ERROR;
  443. }
  444. sprintf(errstr,"Problem reading binary pitch or transposition data in file %s.\n",filename);
  445. return(PROGRAM_ERROR);
  446. }
  447. switch(inputfile->filetype) {
  448. case(PITCHFILE):
  449. for(n=0;n<inputfile->insams;n++) {
  450. //TW BRACKETED OUT: NEW CODE DEALS WITH UNPITCHED, AND SILENT WINDOWS
  451. /*
  452. if(thisdata[n] < FLTERR) {
  453. sprintf(errstr,"File %s contains unpitched windows: cannot proceed.\n",filename);
  454. return(DATA_ERROR);
  455. }
  456. */
  457. if(thisdata[n] >= inputfile->nyquist) {
  458. sprintf(errstr,"File %s contains pitches beyond nyquist: cannot proceed.\n",filename);
  459. return(DATA_ERROR);
  460. }
  461. }
  462. break;
  463. case(TRANSPOSFILE):
  464. for(n=0;n<inputfile->insams;n++) {
  465. if(thisdata[n] < MIN_TRANSPOS || thisdata[n] >= MAX_TRANSPOS) {
  466. sprintf(errstr,"Transposition data item %d (%f):file %s: out of range (%lf to %lf)\n",
  467. n+1,thisdata[n],filename,MIN_TRANSPOS,MAX_TRANSPOS);
  468. return(DATA_ERROR);
  469. }
  470. }
  471. inputfile->is_transpos = TRUE;
  472. break;
  473. }
  474. free(thisdata);
  475. return(FINISHED);
  476. }
  477. /************************************* MEGAPARSEC ******************************/
  478. int megaparsec(char *filename,FILE *fp,infileptr inputfile)
  479. {
  480. int exit_status;
  481. /* NEW CODE */
  482. int extended_brkfile = POSSIBLE;
  483. /* NEW CODE */
  484. int sndlist = POSSIBLE;
  485. int numlist = POSSIBLE;
  486. int brklist = POSSIBLE;
  487. int mixlist = POSSIBLE;
  488. int linelist = POSSIBLE;
  489. int synclist = POSSIBLE;
  490. int has_comments = FALSE;
  491. int dB_notation = FALSE;
  492. char temp[/*2000*/LOCALMEMBYTES];
  493. char **wordstor;
  494. int *wordcnt;
  495. int numcnt = 0, linecnt = 0, total_wordcnt = 0, max_line_word_cnt = 0, min_line_word_cnt, n, srate;
  496. double dur = 0.0;
  497. if((exit_status = initial_parse_textfile(filename,fp,&linelist,&has_comments,&dB_notation,
  498. &total_wordcnt,&numcnt,&linecnt,&max_line_word_cnt,&min_line_word_cnt))<0)
  499. return(exit_status);
  500. initial_textfile_check(dB_notation,&sndlist,&mixlist,&brklist,
  501. &numlist,numcnt,total_wordcnt,max_line_word_cnt,min_line_word_cnt);
  502. if((wordstor = (char **)malloc(total_wordcnt * sizeof(char *)))==NULL) {
  503. sprintf(errstr,"INSUFFICIENT MEMORY for wordstor: file %s\n",filename);
  504. return(MEMORY_ERROR);
  505. }
  506. for(n=0;n<total_wordcnt;n++) /* initialise, for testing and safe freeing */
  507. wordstor[n] = NULL;
  508. inputfile->all_words = total_wordcnt;
  509. if((wordcnt = (int *)malloc(linecnt * sizeof(int)))==NULL) {
  510. sprintf(errstr,"INSUFFICIENT MEMORY for wordcnt: file %s\n",filename);
  511. return(MEMORY_ERROR);
  512. }
  513. for(n=0;n<linecnt;n++) /* initialise, for later testing */
  514. wordcnt[n] = 0;
  515. if(fseek(fp,0,0)<0) {
  516. sprintf(errstr,"fseek failed in megaparsec(): 1\n");
  517. return(PROGRAM_ERROR);
  518. }
  519. if((exit_status = store_wordlist_without_comments(fp,temp,inputfile->all_words,wordstor,wordcnt,inputfile))<0)
  520. return(exit_status);
  521. //OCT 2005
  522. if((exit_status = is_a_possible_multichannel_mixfile
  523. (numlist,brklist,sndlist,linecnt,wordstor,wordcnt,filename,inputfile)) == FINISHED) {
  524. inputfile->filetype = MIX_MULTI;
  525. return(FINISHED);
  526. }
  527. if(sndlist==POSSIBLE) {
  528. if((exit_status = check_for_sndlist(wordstor,wordcnt,linecnt,&sndlist))<0)
  529. return(exit_status);
  530. } else if(numlist==POSSIBLE) {
  531. if((exit_status = check_for_brklist_and_count_numbers(wordstor,wordcnt,linecnt,&brklist,inputfile,filename))<0)
  532. return(exit_status);
  533. }
  534. if(sndlist==POSSIBLE || numlist==POSSIBLE)
  535. mixlist = FALSE;
  536. if(mixlist==POSSIBLE) {
  537. if((exit_status = is_a_possible_mixfile(wordstor,wordcnt,linecnt,&mixlist,&srate,inputfile,filename,&dur))<0)
  538. return(exit_status);
  539. if(mixlist==FALSE)
  540. inputfile->out_chans = 0;
  541. else {
  542. inputfile->srate = srate;
  543. inputfile->duration = dur;
  544. synclist = FALSE;
  545. brklist = FALSE;
  546. sndlist = FALSE;
  547. extended_brkfile = FALSE;
  548. }
  549. }
  550. if(linelist==POSSIBLE) {
  551. if((exit_status = check_for_a_linelist(max_line_word_cnt,&linelist,wordstor,inputfile))<0)
  552. return(exit_status);
  553. }
  554. if(sndlist==POSSIBLE) {
  555. if((exit_status = set_sndlist_flags(inputfile,wordstor))<0)
  556. return(exit_status);
  557. if(inputfile->different_srates
  558. #ifdef NO_DUPLICATE_SNDFILES
  559. || inputfile->duplicate_snds
  560. #endif
  561. )
  562. synclist = FALSE;
  563. } else if(synclist==POSSIBLE) {
  564. if((exit_status = check_for_a_synclist(&synclist,wordstor,wordcnt,inputfile,filename))<0)
  565. return(exit_status);
  566. }
  567. //TW REMOVED COMMENTS
  568. if(extended_brkfile==POSSIBLE) {
  569. if((exit_status =
  570. check_for_an_extended_brkfile(&extended_brkfile,wordstor,wordcnt,linecnt,total_wordcnt,inputfile))<0)
  571. return(exit_status);
  572. }
  573. if((inputfile->filetype = assign_type(sndlist,numlist,brklist,mixlist,synclist,linelist,extended_brkfile,inputfile))<0)
  574. return(inputfile->filetype);
  575. return(FINISHED);
  576. }
  577. /************************************* INITIAL_PARSE_TEXTFILE ******************************/
  578. int initial_parse_textfile
  579. (char *filename,FILE *fp,int *linelist,int *has_comments,int *dB_notation,
  580. int *total_wordcnt,int *numcnt,int *linecnt,int *max_line_word_cnt,int *min_line_word_cnt)
  581. {
  582. char temp[LOCALMEMBYTES], *p, *q, c; // RWD was 2000
  583. double val;
  584. int line_num_cnt = 0;
  585. int last_line_word_cnt = 0, last_line_num_cnt = 0;
  586. int line_word_cnt = 0;
  587. *max_line_word_cnt = 0;
  588. *min_line_word_cnt = INT_MAX;
  589. while((c = (char)fgetc(fp))!=EOF) {
  590. if(!isalnum(c) && !ispunct(c) && !isspace(c)) {
  591. sprintf(errstr,"%s is not a valid CDP file\n",filename);
  592. return(DATA_ERROR);
  593. }
  594. }
  595. if(fseek(fp,0,0) != 0) {
  596. sprintf(errstr,"Cannot rewind to start of file %s\n",filename);
  597. return(DATA_ERROR);
  598. }
  599. while(fgets(temp,2000,fp)!=NULL) {
  600. p = temp;
  601. if(is_a_comment(p)) {
  602. *has_comments = TRUE;
  603. continue;
  604. } else if(is_an_empty_line(p))
  605. continue;
  606. line_word_cnt = 0;
  607. line_num_cnt = 0;
  608. while(get_word_from_string(&p,&q)) {
  609. line_word_cnt++;
  610. if(is_a_dB_value(q)) {
  611. *dB_notation = TRUE;
  612. (*numcnt)++;
  613. line_num_cnt++;
  614. } else if(get_float_from_within_string(&q,&val)) {
  615. (*numcnt)++;
  616. line_num_cnt++;
  617. }
  618. }
  619. if(*linecnt) {
  620. if(line_word_cnt != last_line_word_cnt
  621. || line_num_cnt != last_line_num_cnt)
  622. *linelist = FALSE;
  623. }
  624. *max_line_word_cnt = max(*max_line_word_cnt,line_word_cnt);
  625. *min_line_word_cnt = min(*min_line_word_cnt,line_word_cnt);
  626. last_line_word_cnt = line_word_cnt;
  627. last_line_num_cnt = line_num_cnt;
  628. *total_wordcnt += line_word_cnt;
  629. (*linecnt)++;
  630. }
  631. if(*total_wordcnt==0) {
  632. sprintf(errstr,"Cannot get any data from file %s\n",filename);
  633. return(DATA_ERROR);
  634. }
  635. return(FINISHED);
  636. }
  637. /************************************* INITIAL_TEXTFILE_CHECK ******************************/
  638. void initial_textfile_check(int dB_notation,int *sndlist,int *mixlist,int *brklist,int *numlist,
  639. int numcnt,int wordcnt,int max_line_word_cnt,int min_line_word_cnt)
  640. {
  641. if((numcnt < wordcnt) || dB_notation) {
  642. *numlist = FALSE;
  643. *brklist = FALSE;
  644. }
  645. if(numcnt == wordcnt) {
  646. *mixlist = FALSE;
  647. *sndlist = FALSE;
  648. }
  649. if(ODD(numcnt))
  650. *brklist = FALSE;
  651. if(numcnt>0)
  652. *sndlist = FALSE;
  653. else
  654. *mixlist = FALSE;
  655. if(min_line_word_cnt<MIX_MINLINE || max_line_word_cnt>MIX_MAXLINE)
  656. *mixlist = FALSE;
  657. }
  658. /************************************* VALID_START_OF_MIXFILE_LINE ******************************/
  659. #ifdef IS_CDPARSE
  660. int valid_start_of_mixfile_line
  661. (int k,int *chans,int lineno,char **wordstor,int *srate,int *mixlist,infileptr inputfile,char *filename,double *dur)
  662. {
  663. int exit_status;
  664. double time;
  665. char *sndfilename;
  666. sndfilename = wordstor[k++];
  667. if(sscanf(wordstor[k++],"%lf",&time)!=1) {
  668. *mixlist = FALSE;
  669. return(FINISHED);
  670. }
  671. if(time<0.0) {
  672. *mixlist = FALSE;
  673. return(FINISHED);
  674. }
  675. if(sscanf(wordstor[k++],"%d",chans)!=1) {
  676. *mixlist = FALSE;
  677. return(FINISHED);
  678. }
  679. if(*chans < MONO || *chans > STEREO) {
  680. *mixlist = FALSE;
  681. return(FINISHED);
  682. }
  683. if((exit_status = is_a_valid_sndfile_for_mixfile(filename,sndfilename,srate,*chans,lineno,inputfile,time,dur,0))<0)
  684. return(exit_status);
  685. if(exit_status == FALSE) {
  686. *mixlist = FALSE;
  687. return(FINISHED);
  688. }
  689. if(!OK_level(wordstor[k])) { /* must be numeric, and witihin range */
  690. *mixlist = FALSE;
  691. return(FINISHED);
  692. }
  693. return(FINISHED);
  694. }
  695. #else
  696. int valid_start_of_mixfile_line
  697. (int k,int *chans,int lineno,char **wordstor,int *srate,int *mixlist,infileptr inputfile,char *filename,double *dur)
  698. {
  699. int exit_status;
  700. double time;
  701. char *sndfilename;
  702. sndfilename = wordstor[k++];
  703. if(sscanf(wordstor[k++],"%lf",&time)!=1) {
  704. if(lineno>0) {
  705. fprintf(stdout,"WARNING: If %s is a mixfile: Invalid or missing time val on line %d\n",filename,lineno+1);
  706. fflush(stdout);
  707. }
  708. *mixlist = FALSE;
  709. return(FINISHED);
  710. }
  711. if(time<0.0) {
  712. if(lineno>0) {
  713. fprintf(stdout,"WARNING: If %s is a mixfile: starttime less than zero [%lf]: line %d\n",
  714. filename,time,lineno+1);
  715. fflush(stdout);
  716. }
  717. *mixlist = FALSE;
  718. return(FINISHED);
  719. }
  720. if(sscanf(wordstor[k++],"%d",chans)!=1) {
  721. if(lineno>0) {
  722. fprintf(stdout,"WARNING: If %s is a mixfile: Invalid or missing channel val on line %d\n",
  723. filename,lineno+1);
  724. fflush(stdout);
  725. }
  726. *mixlist = FALSE;
  727. return(FINISHED);
  728. }
  729. if(*chans < MONO || *chans > STEREO) {
  730. if(lineno>0) {
  731. fprintf(stdout,"WARNING: If %s is a mixfile: Invalid channel-cnt on line %d\n",filename,lineno+1);
  732. fflush(stdout);
  733. }
  734. *mixlist = FALSE;
  735. return(FINISHED);
  736. }
  737. if((exit_status = is_a_valid_sndfile_for_mixfile(filename,sndfilename,srate,*chans,lineno,inputfile,time,dur,0))<0)
  738. return(exit_status);
  739. if(exit_status == FALSE) {
  740. *mixlist = FALSE;
  741. return(FINISHED);
  742. }
  743. if(!OK_level(wordstor[k])) { /* must be numeric, and witihin range */
  744. if(lineno>0) {
  745. fprintf(stdout,"WARNING: If %s is a mixfile: Invalid [channel 1] level val on line %d\n",
  746. filename,lineno+1);
  747. fflush(stdout);
  748. }
  749. *mixlist = FALSE;
  750. return(FINISHED);
  751. }
  752. return(FINISHED);
  753. }
  754. #endif
  755. /************************************* IS_VALID_END_OF_MIXFILE_LINE ******************************/
  756. #ifdef IS_CDPARSE
  757. int is_valid_end_of_mixfile_line(int j,int chans,int lineno,char **wordstor,int *wordcnt)
  758. {
  759. double pan;
  760. //TW UPDATE: AVOID WARNING
  761. int got_numeric_panval = sscanf(wordstor[j],"%lf",&pan);
  762. if(strcmp(wordstor[j],"C") && strcmp(wordstor[j],"L") && strcmp(wordstor[j],"R")
  763. && got_numeric_panval!=1)
  764. return(FALSE);
  765. if(got_numeric_panval && (pan < MINPAN || pan >MAXPAN))
  766. return(FALSE);
  767. if(chans==MONO) {
  768. if(wordcnt[lineno]>MIX_MIDLINE) {
  769. return(FALSE);
  770. }
  771. return(TRUE);
  772. } else {
  773. if(wordcnt[lineno]<MIX_MAXLINE) {
  774. return(FALSE);
  775. }
  776. }
  777. j++;
  778. if(!OK_level(wordstor[j++])) /* level must be numeric or dB & in range */
  779. return(FALSE);
  780. got_numeric_panval = 0;
  781. //TW UPDATE: AVOID WARNING
  782. got_numeric_panval = sscanf(wordstor[j],"%lf",&pan);
  783. if(strcmp(wordstor[j],"C") && strcmp(wordstor[j],"L") && strcmp(wordstor[j],"R")
  784. && (got_numeric_panval !=1)) /* pan must be C,R,L or numeric */
  785. return(FALSE);
  786. if(got_numeric_panval && (pan < MINPAN || pan > MAXPAN)) {
  787. return(FALSE);
  788. }
  789. return(TRUE);
  790. }
  791. #else
  792. int is_valid_end_of_mixfile_line(int j,int chans,int lineno,char **wordstor,int *wordcnt,char *filename)
  793. {
  794. double pan;
  795. //TW UPDATE: AVOID WARNING
  796. int got_numeric_panval = sscanf(wordstor[j],"%lf",&pan);
  797. if(strcmp(wordstor[j],"C") && strcmp(wordstor[j],"L") && strcmp(wordstor[j],"R")
  798. && got_numeric_panval!=1) {
  799. if(lineno>0) {
  800. fprintf(stdout,"WARNING: If %s is a mixfile: Invalid (1st) pan val, line %d\n",filename,lineno+1);
  801. fflush(stdout);
  802. }
  803. return(FALSE);
  804. }
  805. if(got_numeric_panval && (pan < MINPAN || pan >MAXPAN)) {
  806. if(lineno>0) {
  807. fprintf(stdout,"WARNING: If %s is a mixfile: Invalid (1st) pan val [%lf], line %d\n",
  808. filename,pan,lineno+1);
  809. fflush(stdout);
  810. }
  811. return(FALSE);
  812. }
  813. if(chans==MONO) {
  814. if(wordcnt[lineno]>MIX_MIDLINE) {
  815. if(lineno>0) {
  816. fprintf(stdout,"WARNING: If %s is a mixfile: Too many words on line %d\n",filename,lineno+1);
  817. fflush(stdout);
  818. }
  819. return(FALSE);
  820. }
  821. return(TRUE);
  822. } else {
  823. if(wordcnt[lineno]<MIX_MAXLINE) {
  824. if(lineno>0) {
  825. fprintf(stdout,"WARNING: If %s is a mixfile: Too few entries for stereo file on line %d\n",
  826. filename,lineno+1);
  827. fflush(stdout);
  828. }
  829. return(FALSE);
  830. }
  831. }
  832. j++;
  833. if(!OK_level(wordstor[j++])) { /* level must be numeric or dB & in range */
  834. if(lineno>0) {
  835. fprintf(stdout,"WARNING: If %s is a mixfile: Missing level for chan2 on line %d\n",filename,lineno+1);
  836. fflush(stdout);
  837. }
  838. return(FALSE);
  839. }
  840. got_numeric_panval = 0;
  841. //TW UPDATE: AVOID WARNING
  842. got_numeric_panval = sscanf(wordstor[j],"%lf",&pan);
  843. if(strcmp(wordstor[j],"C") && strcmp(wordstor[j],"L") && strcmp(wordstor[j],"R")
  844. && (got_numeric_panval !=1)) { /* pan must be C,R,L or numeric */
  845. if(lineno>0) {
  846. fprintf(stdout,"WARNING: If %s is a mixfile: Missing chan2 pan val on line %d\n",
  847. filename,lineno+1);
  848. fflush(stdout);
  849. }
  850. return(FALSE);
  851. }
  852. if(got_numeric_panval && (pan < MINPAN || pan > MAXPAN)) {
  853. if(lineno>0) {
  854. fprintf(stdout,"WARNING: If %s is a mixfile: Invalid 2nd pan val [%lf], line %d\n",
  855. filename,pan,lineno+1);
  856. fflush(stdout);
  857. }
  858. return(FALSE);
  859. }
  860. return(TRUE);
  861. }
  862. #endif
  863. /************************************* CONFIRM_TRUE_STEREO ******************************/
  864. int confirm_true_stereo(int *chans,int *is_left,int *is_right,int *is_central,char *panword)
  865. {
  866. double pan;
  867. if(!strcmp(panword,"L")) {
  868. *is_left = TRUE; /* panned hard Left */
  869. *chans = MONO;
  870. } else if(!strcmp(panword,"R")) {
  871. *is_right = TRUE; /* panned hard Right */
  872. *chans = MONO;
  873. } else if(strcmp(panword,"C")) {
  874. if(sscanf(panword,"%lf",&pan)!=1) {
  875. sprintf(errstr,"Parsing error 2: confirm_true_stereo()\n");
  876. return(PROGRAM_ERROR);
  877. }
  878. if(pan <= -1.0) {
  879. *is_left = TRUE; /* panned hard Left */
  880. *chans = MONO;
  881. } else if(pan >= 1.0) {
  882. *is_right = TRUE; /* panned hard Right */
  883. *chans = MONO;
  884. }
  885. // TW REMOVED COMMENTS
  886. else
  887. *chans = STEREO;
  888. }
  889. else
  890. *is_central = TRUE;
  891. return(FINISHED);
  892. }
  893. /**************** IS_A_POSSIBLE_MIXFILE **********************/
  894. int is_a_possible_mixfile(char **wordstor,int *wordcnt,int linecnt,int *mixlist,
  895. int *srate,infileptr inputfile,char *filename,double *dur)
  896. {
  897. int exit_status;
  898. int is_left = FALSE, is_right = FALSE, is_central = FALSE;
  899. int /*cnt = 0,*/ chans;
  900. int k = 0, j, lineno;
  901. if(linecnt > SF_MAXFILES-1) {
  902. #ifndef IS_CDPARSE
  903. fprintf(stdout,"WARNING: If %s is a mixfile: cannot mix more than %d files in one mix\n",
  904. filename,SF_MAXFILES-1);
  905. fflush(stdout);
  906. #endif
  907. *mixlist = FALSE;
  908. return(FINISHED);
  909. }
  910. for(lineno=0;lineno<linecnt;lineno++) {
  911. if((exit_status = valid_start_of_mixfile_line(k,&chans,lineno,wordstor,srate,mixlist,inputfile,filename,dur))<0)
  912. return(exit_status);
  913. if(*mixlist==FALSE)
  914. return(FINISHED);
  915. if(wordcnt[lineno]>MIX_MINLINE) {
  916. j = k + MIX_MINLINE;
  917. #ifdef IS_CDPARSE
  918. if(!is_valid_end_of_mixfile_line(j,chans,lineno,wordstor,wordcnt)) {
  919. #else
  920. if(!is_valid_end_of_mixfile_line(j,chans,lineno,wordstor,wordcnt,filename)) {
  921. #endif
  922. *mixlist = FALSE;
  923. return(FINISHED);
  924. }
  925. if(wordcnt[lineno]==MIX_MIDLINE && chans==MONO) {
  926. if((exit_status = confirm_true_stereo(&chans,&is_left,&is_right,&is_central,wordstor[j]))<0)
  927. return(exit_status);
  928. }
  929. } else
  930. is_central = TRUE;
  931. inputfile->out_chans = max(inputfile->out_chans,chans);
  932. k += wordcnt[lineno];
  933. }
  934. #ifdef NO_DUPLICATE_SNDFILES
  935. #ifdef IS_CDPARSE
  936. if(duplicated_filenames(linecnt,wordstor,wordcnt))
  937. #else
  938. if(duplicated_filenames(linecnt,wordstor,wordcnt,filename))
  939. #endif
  940. {
  941. *mixlist = FALSE;
  942. return(FINISHED);
  943. }
  944. #endif
  945. if(inputfile->out_chans==MONO) {
  946. if((is_left && is_right)
  947. || (is_left && is_central)
  948. || (is_right && is_central))
  949. inputfile->out_chans = STEREO;
  950. }
  951. if(inputfile->out_chans < MONO) {
  952. sprintf(errstr,"Impossible out_chans value\n");
  953. return(PROGRAM_ERROR);
  954. }
  955. return(FINISHED);
  956. }
  957. /******************* DUPLICATED_FILENAMES **************************/
  958. #ifdef IS_CDPARSE
  959. int duplicated_filenames(int linecnt,char **wordstor,int *wordcnt)
  960. {
  961. int n, m;
  962. int j, k = 0;
  963. for(n=0;n<linecnt-1;n++) {
  964. j = k;
  965. for(m=n+1;m<linecnt;m++) {
  966. j += wordcnt[m-1];
  967. if(!strcmp(wordstor[k],wordstor[j]))
  968. return(TRUE);
  969. }
  970. k += wordcnt[n];
  971. }
  972. return(FALSE);
  973. }
  974. #else
  975. int duplicated_filenames(int linecnt,char **wordstor,int *wordcnt,char *filename)
  976. {
  977. int n, m;
  978. int j, k = 0;
  979. for(n=0;n<linecnt-1;n++) {
  980. j = k;
  981. for(m=n+1;m<linecnt;m++) {
  982. j += wordcnt[m-1];
  983. if(!strcmp(wordstor[k],wordstor[j])) {
  984. #ifndef IS_CDPARSE
  985. fprintf(stdout,"WARNING: If %s is a mix or syncfile: filename duplicates found (not allowed).\n",filename);
  986. fflush(stdout);
  987. #endif
  988. return(TRUE);
  989. }
  990. }
  991. k += wordcnt[n];
  992. }
  993. return(FALSE);
  994. }
  995. #endif
  996. /*************** OK_LEVEL ******************/
  997. int OK_level(char *str)
  998. {
  999. int exit_status = TRUE;
  1000. double level;
  1001. if(is_a_dB_value(str))
  1002. exit_status = get_leveldb_frame(str,&level);
  1003. else {
  1004. if(sscanf(str,"%lf",&level)!=1)
  1005. exit_status = FALSE;
  1006. }
  1007. if(exit_status==FALSE || level < 0.0)
  1008. return(FALSE);
  1009. return(TRUE);
  1010. }
  1011. /************************************* IS_A_DB_VALUE ******************************/
  1012. int is_a_dB_value(char *str)
  1013. {
  1014. int decimal_point_cnt = 0;
  1015. int has_digits = FALSE;
  1016. double val;
  1017. char *p, *end_of_number;
  1018. //p = str + strlen(str) - 2;
  1019. // RWD debug test - avoid valgrind complaints
  1020. if(strlen(str) < 3)
  1021. return FALSE;
  1022. p = str + strlen(str) - 2;
  1023. if(strcmp(p,"dB") && strcmp(p,"DB") && strcmp(p,"db"))
  1024. return(FALSE);
  1025. if(p==str)
  1026. return(FALSE);
  1027. end_of_number = p;
  1028. p = str;
  1029. switch(*p) {
  1030. case('-'): break;
  1031. case('.'): decimal_point_cnt=1; break;
  1032. default:
  1033. if(!isdigit(*p))
  1034. return(FALSE);
  1035. has_digits = TRUE;
  1036. break;
  1037. }
  1038. p++;
  1039. while(p!=end_of_number) {
  1040. if(isdigit(*p))
  1041. has_digits = TRUE;
  1042. else if(*p == '.') {
  1043. if(++decimal_point_cnt>1)
  1044. return(FALSE);
  1045. } else
  1046. return(FALSE);
  1047. p++;
  1048. }
  1049. if(!has_digits || sscanf(str,"%lf",&val)!=1)
  1050. return(FALSE);
  1051. return(TRUE);
  1052. }
  1053. /**************************** GET_LEVELDB_FRAME ********************************/
  1054. int get_leveldb_frame(char *str,double *val)
  1055. {
  1056. int is_neg = 0;
  1057. if(sscanf(str,"%lf",val)!=1)
  1058. return(FALSE);
  1059. *val = max(*val,MIN_DB_ON_16_BIT);
  1060. if(flteq(*val,0.0)) {
  1061. *val = 1.0;
  1062. return(TRUE);
  1063. }
  1064. if(*val<0.0) {
  1065. *val = -(*val);
  1066. is_neg = 1;
  1067. }
  1068. *val /= 20.0;
  1069. *val = pow(10.0,*val);
  1070. if(is_neg)
  1071. *val = 1.0/(*val);
  1072. return(TRUE);
  1073. }
  1074. /***************************** IS_A_VALID_SNDFILE_FOR_MIXFILE **************************/
  1075. int is_a_valid_sndfile_for_mixfile
  1076. (char *filename,char *sndfilename,int *srate,int chans,int linecnt,infileptr inputfile,double time,double *dur,int multichan)
  1077. {
  1078. int exit_status;
  1079. /*int minsize = 0L;*/
  1080. double thisdur;
  1081. int ifd;
  1082. double maxamp, maxloc;
  1083. int maxrep;
  1084. #ifdef IS_CDPARSE
  1085. int getmaxinfo = 1;
  1086. #else
  1087. int getmaxinfo = 0;
  1088. #endif
  1089. char *p = strrchr(sndfilename, '.');
  1090. if(p == NULL) {
  1091. #ifndef IS_CDPARSE
  1092. fprintf(stdout,"WARNING: If %s is a mixfile: uses %s which has no sndfile extension\n",filename,sndfilename);
  1093. fflush(stdout);
  1094. return(FALSE);
  1095. #endif
  1096. }
  1097. p++;
  1098. #ifdef NOTDEF
  1099. /*RWD 4:2002 this is silly! sfsys accepts aiff files, so cdparse certainly can! */
  1100. // APRIL 2010
  1101. // if(_stricmp(p,(getenv("CDP_SOUND_EXT")))) {
  1102. if(_stricmp(p,".wav") || _stricmp(p,".aiff")) {
  1103. #ifndef IS_CDPARSE
  1104. // APRIL 2010
  1105. // fprintf(stdout,"WARNING: If %s is a mixfile: uses %s which has an invalid sndfile extension : %s is not %s\n",filename,sndfilename,p,getenv("CDP_SOUND_EXT"));
  1106. fprintf(stdout,"WARNING: If %s is a mixfile: uses %s which has an invalid sndfile extension : %s is not '.wav' or '.aiff'\n",filename,sndfilename,p);
  1107. fflush(stdout);
  1108. return(FALSE);
  1109. #endif
  1110. }
  1111. #endif
  1112. if((ifd = sndopenEx(sndfilename,0,CDP_OPEN_RDONLY)) < 0) {
  1113. #ifndef IS_CDPARSE
  1114. fprintf(stdout,"WARNING: If %s is a mixfile: uses %s which is not a sndfile\n",filename,sndfilename);
  1115. fflush(stdout);
  1116. #endif
  1117. return(FALSE);
  1118. }
  1119. if((exit_status = readhead(inputfile,ifd,sndfilename,&maxamp,&maxloc,&maxrep,0,getmaxinfo))<0) { /* READ THE FILE HEADER */
  1120. if(sndcloseEx(ifd)<0)
  1121. sprintf(errstr,"Failed to close file %s when checking file %s\n",sndfilename,filename);
  1122. return(exit_status);
  1123. }
  1124. exit_status = TRUE;
  1125. if(inputfile->filetype!=SNDFILE) {
  1126. #ifndef IS_CDPARSE
  1127. fprintf(stdout,"WARNING: If %s is a mixfile: uses %s which is not a sndfile\n",filename,sndfilename);
  1128. fflush(stdout);
  1129. #endif
  1130. exit_status=FALSE;
  1131. } else if(inputfile->channels != chans) {
  1132. #ifndef IS_CDPARSE
  1133. if(chans==MONO)
  1134. fprintf(stdout,"WARNING: If %s is a mixfile: %s is not a mono sndfile\n",filename,sndfilename);
  1135. else if(chans==STEREO) /*RWD 4:2001 added test */
  1136. fprintf(stdout,"WARNING: If %s is a mixfile: %s is not a stereo sndfile\n",filename,sndfilename);
  1137. //OCT 2005
  1138. else
  1139. fprintf(stdout,"WARNING: If %s is a mixfile: %s has different no. of chans (%d) to that indicated in mixfile line (%d)\n",
  1140. filename,sndfilename,inputfile->channels,chans);
  1141. fflush(stdout);
  1142. #endif
  1143. exit_status=FALSE;
  1144. } else if((inputfile->insams = sndsizeEx(ifd))<0) { /* FIND SIZE OF FILE */
  1145. sprintf(errstr, "Can't read size of input file %s: used in file %s\n",sndfilename,filename);
  1146. exit_status=PROGRAM_ERROR;
  1147. } else if(inputfile->insams <= 0L) {
  1148. #ifndef IS_CDPARSE
  1149. fprintf(stdout,"WARNING: If %s is a mixfile: file %s contains no data.\n",filename,sndfilename);
  1150. fflush(stdout);
  1151. #endif
  1152. exit_status=FALSE;
  1153. } else if (linecnt==multichan) {
  1154. *srate = inputfile->srate;
  1155. } else if(inputfile->srate != *srate) {
  1156. #ifndef IS_CDPARSE
  1157. fprintf(stdout,"WARNING: If %s is a mixfile: Incompatible sample-rate in file %s\n",filename,sndfilename);
  1158. fflush(stdout);
  1159. #endif
  1160. exit_status=FALSE;
  1161. }
  1162. #ifdef NOTDEF /* RWD 4:2001 */
  1163. switch(inputfile->filetype) {
  1164. case(SNDFILE): inputfile->insams = inputfile->infilesize/sizeof(short); break;
  1165. case(FLT_SNDFILE): inputfile->insams = inputfile->infilesize/sizeof(float); break;
  1166. }
  1167. #endif
  1168. #ifdef _DEBUG
  1169. assert(inputfile->insams > 0);
  1170. #endif
  1171. thisdur = time + (inputfile->insams/inputfile->channels/(double)inputfile->srate);
  1172. *dur = max(*dur,thisdur);
  1173. // inputfile->infilesize = 0;
  1174. inputfile->insams = 0;
  1175. inputfile->filetype = 0;
  1176. inputfile->srate = 0;
  1177. inputfile->channels = 0;
  1178. inputfile->stype = 0;
  1179. if(sndcloseEx(ifd)<0) {
  1180. sprintf(errstr,"Failed to close file %s while checking file %s\n",sndfilename,filename);
  1181. exit_status=SYSTEM_ERROR;
  1182. }
  1183. return(exit_status);
  1184. }
  1185. /*************************** CHECK_FOR_BRKLIST_AND_STORE_NUMBERS ***********************/
  1186. int check_for_brklist_and_count_numbers
  1187. (char **wordstor,int *wordcnt,int linecnt,int *brklist,infileptr inputfile,char *filename)
  1188. {
  1189. double p, lasttime = 0.0;
  1190. int istime = TRUE;
  1191. int lineno, word_in_line, dcount = 0, k = 0;
  1192. for(lineno=0;lineno<linecnt;lineno++) {
  1193. for(word_in_line = 0;word_in_line < wordcnt[lineno];word_in_line++) {
  1194. if(sscanf(wordstor[k],"%lf",&p)!=1) {
  1195. sprintf(errstr,"scan anomaly: check_for_brklist_and_count_numbers()\n");
  1196. return(PROGRAM_ERROR);
  1197. }
  1198. if(istime) {
  1199. if(*brklist==POSSIBLE) {
  1200. if(k==0) {
  1201. if(p < 0.0)
  1202. *brklist = FALSE;
  1203. } else if(p <= lasttime)
  1204. *brklist = FALSE;
  1205. lasttime = p;
  1206. }
  1207. if(k==0) {
  1208. inputfile->maxnum = p;
  1209. inputfile->minnum = p;
  1210. } else {
  1211. inputfile->maxnum = max(p,inputfile->maxnum);
  1212. inputfile->minnum = min(p,inputfile->minnum);
  1213. }
  1214. } else {
  1215. if(k==1) {
  1216. inputfile->maxbrk = p;
  1217. inputfile->minbrk = p;
  1218. } else {
  1219. inputfile->maxbrk = max(p,inputfile->maxbrk);
  1220. inputfile->minbrk = min(p,inputfile->minbrk);
  1221. }
  1222. inputfile->maxnum = max(p,inputfile->maxnum);
  1223. inputfile->minnum = min(p,inputfile->minnum);
  1224. }
  1225. istime = !istime;
  1226. k++;
  1227. }
  1228. }
  1229. if(k == 0) {
  1230. sprintf(errstr,"No numeric data found in file %s\n",filename);
  1231. return(DATA_ERROR);
  1232. }
  1233. if(*brklist==POSSIBLE) {
  1234. if(k < 4) /* Must be at least 2 point in a brkfile */
  1235. *brklist = FALSE;
  1236. }
  1237. if(*brklist==POSSIBLE) {
  1238. if(((dcount = k/2) * 2) != k)
  1239. *brklist = FALSE;
  1240. }
  1241. if(*brklist==POSSIBLE) {
  1242. inputfile->brksize = dcount;
  1243. inputfile->duration = lasttime;
  1244. }
  1245. else
  1246. inputfile->brksize = 0;
  1247. inputfile->numsize = k;
  1248. return(FINISHED);
  1249. }
  1250. /*************************** CHECK_FOR_A_LINELIST ***********************/
  1251. #define OTHER (0)
  1252. #define NUMERICAL (1)
  1253. #define DBLIKE (2)
  1254. int check_for_a_linelist(int line_word_cnt,int *linelist,char **wordstor,infileptr inputfile)
  1255. {
  1256. int linecnt = 0, n, m;
  1257. int total_wordcnt = 0;
  1258. //TW AGREED REMOVAL of 'OK'
  1259. int k;
  1260. double val;
  1261. char *wordtype[2], *p;
  1262. if((wordtype[0] = (char *)malloc(line_word_cnt * sizeof(char)))==NULL) {
  1263. sprintf(errstr,"INSUFFICIENT MEMORY for wordtype[0]\n");
  1264. return(MEMORY_ERROR);
  1265. }
  1266. if((wordtype[1] = (char *)malloc(line_word_cnt * sizeof(char)))==NULL) {
  1267. sprintf(errstr,"INSUFFICIENT MEMORY for wordtype[1]\n");
  1268. free(wordtype[0]);
  1269. return(MEMORY_ERROR);
  1270. }
  1271. for(n=0;n<inputfile->linecnt;n++) {
  1272. if(n==0) k = 0;
  1273. else k = 1;
  1274. for(m=0;m<line_word_cnt;m++) {
  1275. p = wordstor[total_wordcnt];
  1276. if(is_a_dB_value(wordstor[total_wordcnt]))
  1277. wordtype[k][m] = (char)DBLIKE;
  1278. else if(get_float_from_within_string(&p,&val))
  1279. wordtype[k][m] = (char)NUMERICAL;
  1280. else
  1281. wordtype[k][m] = (char)OTHER;
  1282. total_wordcnt++;
  1283. }
  1284. if(linecnt>0) {
  1285. for(m=0;m<line_word_cnt;m++) {
  1286. if(wordtype[0][m] != wordtype[1][m]) {
  1287. *linelist = FALSE;
  1288. break;
  1289. }
  1290. }
  1291. }
  1292. if(!(*linelist))
  1293. break;
  1294. linecnt++;
  1295. }
  1296. free(wordtype[0]);
  1297. free(wordtype[1]);
  1298. return(FINISHED);
  1299. }
  1300. /***************************** CHECK_FOR_SNDLIST **************************/
  1301. int check_for_sndlist(char **wordstor,int *wordcnt,int linecnt,int *sndlist)
  1302. {
  1303. char *filename;
  1304. int ifd;
  1305. int k = 0, lineno, word_in_line;
  1306. SFPROPS props = {0};
  1307. for(lineno=0;lineno<linecnt;lineno++) {
  1308. for(word_in_line=0;word_in_line<wordcnt[lineno];word_in_line++) {
  1309. filename = wordstor[k];
  1310. if((ifd = sndopenEx(filename,0,CDP_OPEN_RDONLY)) < 0) {
  1311. *sndlist = FALSE;
  1312. return(FINISHED);
  1313. }
  1314. //RWD added 9.98
  1315. /* TEST THIS !!! */
  1316. if(!snd_headread(ifd,&props)){
  1317. sprintf(errstr,"Cannot read soundfile header: %s\n",filename);
  1318. sndcloseEx(ifd);
  1319. return(SYSTEM_ERROR);
  1320. }
  1321. if(!(props.type==wt_wave)){
  1322. *sndlist = FALSE;
  1323. sprintf(errstr,"soundfile %s is not a wave file\n",filename);
  1324. sndcloseEx(ifd);
  1325. return FINISHED;
  1326. }
  1327. if(sndcloseEx(ifd)<0) {
  1328. sprintf(errstr,"Cannot close sndfile %s: check_for_sndlist()\n",filename);
  1329. return(SYSTEM_ERROR);
  1330. }
  1331. k++;
  1332. }
  1333. }
  1334. return(FINISHED);
  1335. }
  1336. /***************************** STORE_WORDLIST_WITHOUT_COMMENTS **************************/
  1337. int store_wordlist_without_comments(FILE *fp,char *temp,int total_wordcnt,char **wordstor,int *wordcnt,infileptr inputfile)
  1338. {
  1339. char *p , *q;
  1340. int this_wordcnt = 0;
  1341. int wordcnt_in_line;
  1342. int linecnt = 0;
  1343. while(fgets(temp,/*2000*/LOCALMEMBYTES,fp)!=NULL) {
  1344. p = temp;
  1345. if(is_an_empty_line_or_a_comment(p))
  1346. continue;
  1347. wordcnt_in_line = 0;
  1348. while(get_word_from_string(&p,&q)) {
  1349. if((wordstor[this_wordcnt] = (char *)malloc((strlen(q) + 1) * sizeof(char)))==NULL) {
  1350. sprintf(errstr,"INSUFFICIENT MEMORY for word %d\n",this_wordcnt+1);
  1351. return(MEMORY_ERROR);
  1352. }
  1353. strcpy(wordstor[this_wordcnt],q);
  1354. if(++this_wordcnt > total_wordcnt) {
  1355. sprintf(errstr,"Error in word accounting: store_wordlist_without_comments()\n");
  1356. return(PROGRAM_ERROR);
  1357. }
  1358. wordcnt_in_line++;
  1359. }
  1360. wordcnt[linecnt] = wordcnt_in_line;
  1361. linecnt++;
  1362. }
  1363. inputfile->linecnt = linecnt;
  1364. return(FINISHED);
  1365. }
  1366. /***************************** ASSIGN_TYPE **************************/
  1367. //TW REMOVED OLD COMMENT LINES
  1368. int assign_type(int sndlist,int numlist,int brklist,int mixlist,int synclist,int linelist,int extended_brkfile,infileptr inputfile)
  1369. {
  1370. //TW AGREED WARNING SHOULD BE MOVED
  1371. if(sndlist==POSSIBLE) {
  1372. if(synclist==POSSIBLE) {
  1373. if(linelist==POSSIBLE)
  1374. return SNDLIST_OR_SYNCLIST_LINELIST_OR_WORDLIST;
  1375. else
  1376. return SNDLIST_OR_SYNCLIST_OR_WORDLIST;
  1377. } else {
  1378. if(linelist==POSSIBLE)
  1379. return SNDLIST_OR_LINELIST_OR_WORDLIST;
  1380. else
  1381. return SNDLIST_OR_WORDLIST;
  1382. }
  1383. } else if(numlist==POSSIBLE) {
  1384. if(brklist==POSSIBLE)
  1385. return assign_brkfile_type(inputfile,linelist);
  1386. else {
  1387. if(linelist==POSSIBLE)
  1388. return NUMLIST_OR_LINELIST_OR_WORDLIST;
  1389. else
  1390. return NUMLIST_OR_WORDLIST;
  1391. }
  1392. } else if(mixlist==POSSIBLE) {
  1393. if(linelist==POSSIBLE)
  1394. return MIXLIST_OR_LINELIST_OR_WORDLIST;
  1395. else
  1396. return MIXLIST_OR_WORDLIST;
  1397. } else if(synclist==POSSIBLE) {
  1398. if(linelist==POSSIBLE)
  1399. return SYNCLIST_OR_LINELIST_OR_WORDLIST;
  1400. else
  1401. return SYNCLIST_OR_WORDLIST;
  1402. } else if(linelist==POSSIBLE)
  1403. return LINELIST_OR_WORDLIST;
  1404. //RWD.8.98 do this test here!
  1405. if(extended_brkfile==POSSIBLE) {
  1406. fprintf(stderr,"WARNING:Extended format brkfiles not yet supported by commandline programs.\n");
  1407. }
  1408. return WORDLIST;
  1409. }
  1410. /****************************************** CHECK_FOR_A_SYNCLIST ****************************************/
  1411. int check_for_a_synclist(int *synclist,char **wordstor,int *wordcnt,infileptr inputfile,char *filename)
  1412. {
  1413. int exit_status;
  1414. int n;
  1415. int total_words = 0;
  1416. int srate = 0;
  1417. double starttime, endtime;
  1418. for(n=0;n<inputfile->linecnt;n++) { /* Must be 1 or 3 words on each line */
  1419. if(wordcnt[n]!=1 && wordcnt[n]!=3) {
  1420. *synclist = FALSE;
  1421. return(FINISHED);
  1422. }
  1423. }
  1424. for(n=0;n<inputfile->linecnt;n++) { /* Every line must start with a sndfilename */
  1425. if((exit_status = is_a_valid_sndfile_for_sync(filename,wordstor[total_words],&srate,n,inputfile))<0)
  1426. return(exit_status);
  1427. if(exit_status == FALSE) {
  1428. *synclist = FALSE;
  1429. return(FINISHED);
  1430. }
  1431. total_words += wordcnt[n];
  1432. }
  1433. total_words = 0;
  1434. for(n=0;n<inputfile->linecnt;n++) { /* Any other values must be numbers */
  1435. if(wordcnt[n] > 1) {
  1436. if(sscanf(wordstor[total_words+1],"%lf\n",&starttime)!=1) {
  1437. *synclist = FALSE;
  1438. return(FINISHED);
  1439. }
  1440. else if(sscanf(wordstor[total_words+2],"%lf\n",&endtime)!=1) {
  1441. *synclist = FALSE;
  1442. return(FINISHED);
  1443. } else if(starttime < 0.0 || endtime < 0.0) {
  1444. #ifndef IS_CDPARSE
  1445. fprintf(stdout,"WARNING: If %s is a synclist, it contains negative times\n",filename);
  1446. fflush(stdout);
  1447. #endif
  1448. *synclist = FALSE;
  1449. return(FINISHED);
  1450. } else if(starttime > endtime) {
  1451. #ifndef IS_CDPARSE
  1452. fprintf(stdout,"WARNING: If %s is a synclist, starttime > endtime in line %d\n",filename,n+1);
  1453. fflush(stdout);
  1454. #endif
  1455. *synclist = FALSE;
  1456. return(FINISHED);
  1457. }
  1458. }
  1459. total_words += wordcnt[n];
  1460. }
  1461. #ifdef NO_DUPLICATE_SNDFILES
  1462. #ifdef CDPARSE
  1463. if(duplicated_filenames(inputfile->linecnt,wordstor,wordcnt))
  1464. #else
  1465. if(duplicated_filenames(inputfile->linecnt,wordstor,wordcnt,filename))
  1466. #endif
  1467. return(FALSE);
  1468. #endif
  1469. inputfile->srate = srate;
  1470. return(FINISHED);
  1471. }
  1472. /***************************** IS_A_VALID_SNDFILE_FOR_SYNC **************************/
  1473. int is_a_valid_sndfile_for_sync(char *filename,char *sndfilename,int *srate,int linecnt,infileptr inputfile)
  1474. {
  1475. int exit_status;
  1476. //TW AGREED REMOVAL minsize
  1477. int ifd;
  1478. double maxamp, maxloc;
  1479. int maxrep;
  1480. #ifdef IS_CDPARSE
  1481. int getmaxinfo = 1;
  1482. #else
  1483. int getmaxinfo = 0;
  1484. #endif
  1485. if((ifd = sndopenEx(sndfilename,0,CDP_OPEN_RDONLY)) < 0)
  1486. return(FALSE);
  1487. if((exit_status = readhead(inputfile,ifd,sndfilename,&maxamp,&maxloc,&maxrep,0,getmaxinfo))<0) { /* READ THE FILE HEADER */
  1488. if(sndcloseEx(ifd)<0) {
  1489. sprintf(errstr,"Failed to close sndfile %s while checking file %s\n",sndfilename,filename);
  1490. exit_status = SYSTEM_ERROR;
  1491. }
  1492. return(exit_status);
  1493. }
  1494. exit_status = TRUE;
  1495. if(inputfile->filetype!=SNDFILE) {
  1496. #ifndef IS_CDPARSE
  1497. fprintf(stdout,"WARNING: If %s is a syncfile: %s is not a sndfile.\n",filename,sndfilename);
  1498. fflush(stdout);
  1499. #endif
  1500. exit_status=FALSE;
  1501. } else if((inputfile->insams = sndsizeEx(ifd))<0) { /* FIND SIZE OF FILE */
  1502. sprintf(errstr, "Can't read size of input file %s: while checking file %s\n",sndfilename,filename);
  1503. exit_status = SYSTEM_ERROR; /*RWD 4.2001 was PROGRAM_ERROR */
  1504. } else if(inputfile->insams == 0L) /*RWD 4.2001 was <= */
  1505. exit_status=FALSE;
  1506. else if (linecnt==0)
  1507. *srate = inputfile->srate;
  1508. else if(inputfile->srate != *srate) {
  1509. #ifndef IS_CDPARSE
  1510. fprintf(stdout,"WARNING: If %s is a syncfile: Incompatible sample-rate in file %s\n",filename,sndfilename);
  1511. fflush(stdout);
  1512. #endif
  1513. exit_status=FALSE;
  1514. }
  1515. // inputfile->infilesize = 0;
  1516. inputfile->insams = 0;
  1517. inputfile->filetype = 0;
  1518. inputfile->srate = 0;
  1519. inputfile->channels = 0;
  1520. inputfile->stype = 0;
  1521. if(sndcloseEx(ifd)<0) {
  1522. sprintf(errstr,"Failed to close sndfile %s while testing file %s\n",sndfilename,filename);
  1523. return(SYSTEM_ERROR);
  1524. }
  1525. return(exit_status);
  1526. }
  1527. /***************************** SET_SNDLIST_FLAGS **************************/
  1528. int set_sndlist_flags(infileptr inputfile,char **wordstor)
  1529. {
  1530. int exit_status;
  1531. int srate = 0, wordcnt, m;
  1532. char *filename;
  1533. int ifd;
  1534. double maxamp, maxloc;
  1535. int maxrep;
  1536. #ifdef IS_CDPARSE
  1537. int getmaxinfo = 1;
  1538. #else
  1539. int getmaxinfo = 0;
  1540. #endif
  1541. for(wordcnt=0;wordcnt<inputfile->all_words;wordcnt++) {
  1542. filename = wordstor[wordcnt];
  1543. if(inputfile->different_srates == FALSE) {
  1544. if((ifd = sndopenEx(filename,0,CDP_OPEN_RDONLY)) < 0) {
  1545. #ifdef _DEBUG
  1546. sprintf(errstr,"Anomaly reopening sndfile %s: set_sndfilelist_flags()\n",filename);
  1547. #else
  1548. sprintf(errstr,"Anomaly reopening sndfile %s: %s\n",filename,rsferrstr);
  1549. #endif
  1550. return(SYSTEM_ERROR);
  1551. }
  1552. if((exit_status = readhead(inputfile,ifd,filename,&maxamp,&maxloc,&maxrep,0,getmaxinfo))<0) { /* READ THE FILE HEADER */
  1553. sprintf(errstr,"Anomaly Rereading header of sndfile %s: set_sndfilelist_flags()\n",filename);
  1554. if(sndcloseEx(ifd) < 0)
  1555. sprintf(errstr, "Can't close soundfile %s: set_sndlist_flags()\n",filename);
  1556. return(SYSTEM_ERROR);
  1557. }
  1558. if(wordcnt==0)
  1559. srate = inputfile->srate;
  1560. else if(inputfile->srate != srate) {
  1561. inputfile->different_srates = TRUE;
  1562. inputfile->srate = 0;
  1563. }
  1564. // inputfile->infilesize = 0;
  1565. inputfile->insams = 0;
  1566. inputfile->filetype = 0;
  1567. inputfile->channels = 0;
  1568. inputfile->stype = 0;
  1569. if(sndcloseEx(ifd) < 0) {
  1570. sprintf(errstr, "Can't close soundfile %s: set_sndlist_flags()\n",filename);
  1571. return(SYSTEM_ERROR);
  1572. }
  1573. }
  1574. }
  1575. for(wordcnt=0;wordcnt<inputfile->all_words;wordcnt++) {
  1576. for(m=wordcnt+1;m<inputfile->all_words;m++) {
  1577. if(!strcmp(wordstor[wordcnt],wordstor[m])) {
  1578. inputfile->duplicate_snds = TRUE;
  1579. break;
  1580. }
  1581. }
  1582. if(inputfile->duplicate_snds)
  1583. break;
  1584. }
  1585. return(FINISHED);
  1586. }
  1587. /****************************************** ASSIGN_BRKFILE_TYPE ****************************************/
  1588. int assign_brkfile_type(infileptr inputfile,int linelist)
  1589. {
  1590. int normalised_brkfile = FALSE;
  1591. int dB_brkfile = FALSE;
  1592. int pitch_brkfile = FALSE;
  1593. int transpos_brkfile = FALSE;
  1594. int positive_brkfile = FALSE;
  1595. if(inputfile->minbrk >= 0.0)
  1596. positive_brkfile = TRUE;
  1597. if(inputfile->maxbrk <= 1.0 && inputfile->minbrk >= 0.0)
  1598. normalised_brkfile = TRUE;
  1599. else if (inputfile->maxbrk <= DEFAULT_NYQUIST && inputfile->minbrk >= -1.0) {
  1600. inputfile->could_be_pitch = TRUE;
  1601. pitch_brkfile = TRUE;
  1602. }
  1603. if(inputfile->maxbrk <= 0.0 && inputfile->minbrk >= MIN_DB_ON_16_BIT)
  1604. dB_brkfile = TRUE;
  1605. if(inputfile->maxbrk <= MAX_TRANSPOS && inputfile->minbrk >= MIN_TRANSPOS) {
  1606. inputfile->could_be_transpos = TRUE;
  1607. transpos_brkfile = TRUE;
  1608. }
  1609. if(transpos_brkfile) {
  1610. if(normalised_brkfile) {
  1611. if(linelist==POSSIBLE)
  1612. return TRANSPOS_OR_NORMD_BRKFILE_OR_NUMLIST_OR_LINELIST_OR_WORDLIST;
  1613. else
  1614. return TRANSPOS_OR_NORMD_BRKFILE_OR_NUMLIST_OR_WORDLIST;
  1615. } else if(pitch_brkfile) {
  1616. if(linelist==POSSIBLE)
  1617. return TRANSPOS_OR_PITCH_BRKFILE_OR_NUMLIST_OR_LINELIST_OR_WORDLIST;
  1618. else
  1619. return TRANSPOS_OR_PITCH_BRKFILE_OR_NUMLIST_OR_WORDLIST;
  1620. } else {
  1621. if(linelist==POSSIBLE)
  1622. return TRANSPOS_OR_UNRANGED_BRKFILE_OR_NUMLIST_OR_LINELIST_OR_WORDLIST;
  1623. else
  1624. return TRANSPOS_OR_UNRANGED_BRKFILE_OR_NUMLIST_OR_WORDLIST;
  1625. }
  1626. } else {
  1627. if(normalised_brkfile) {
  1628. if(linelist==POSSIBLE)
  1629. return NORMD_BRKFILE_OR_NUMLIST_OR_LINELIST_OR_WORDLIST;
  1630. else
  1631. return NORMD_BRKFILE_OR_NUMLIST_OR_WORDLIST;
  1632. } else if(dB_brkfile) {
  1633. if(linelist==POSSIBLE)
  1634. return DB_BRKFILE_OR_NUMLIST_OR_LINELIST_OR_WORDLIST;
  1635. else
  1636. return DB_BRKFILE_OR_NUMLIST_OR_WORDLIST;
  1637. } else if(pitch_brkfile) {
  1638. if(linelist==POSSIBLE) {
  1639. if(positive_brkfile)
  1640. return PITCH_POSITIVE_BRKFILE_OR_NUMLIST_OR_LINELIST_OR_WORDLIST;
  1641. else
  1642. return PITCH_BRKFILE_OR_NUMLIST_OR_LINELIST_OR_WORDLIST;
  1643. } else {
  1644. if(positive_brkfile)
  1645. return PITCH_POSITIVE_BRKFILE_OR_NUMLIST_OR_WORDLIST;
  1646. else
  1647. return PITCH_BRKFILE_OR_NUMLIST_OR_WORDLIST;
  1648. }
  1649. } else if(positive_brkfile) {
  1650. if(linelist==POSSIBLE)
  1651. return POSITIVE_BRKFILE_OR_NUMLIST_OR_LINELIST_OR_WORDLIST;
  1652. else
  1653. return POSITIVE_BRKFILE_OR_NUMLIST_OR_WORDLIST;
  1654. } else {
  1655. if(linelist==POSSIBLE)
  1656. return UNRANGED_BRKFILE_OR_NUMLIST_OR_LINELIST_OR_WORDLIST;
  1657. else
  1658. return UNRANGED_BRKFILE_OR_NUMLIST_OR_WORDLIST;
  1659. }
  1660. }
  1661. }
  1662. #define MIN_BRKSLOPE (1.0)
  1663. #define MAX_BRKSLOPE (6.0)
  1664. /************************************ CHECK_FOR_AN_EXTENDED_BRKFILE *********************************/
  1665. int check_for_an_extended_brkfile
  1666. (int *extended_brkfile,char **wordstor,int *wordcnt,int linecnt,int total_words,infileptr inputfile)
  1667. {
  1668. int wordno = 0, lineno;
  1669. int is_extended_format = FALSE;
  1670. double lasttime = -1.0, time, val;
  1671. double maxval = -(double)(MAXRANGE+1);
  1672. double minval = (double)(MAXRANGE+1);
  1673. if(wordcnt[0]!=2) {
  1674. *extended_brkfile = FALSE;
  1675. return(FINISHED);
  1676. }
  1677. if(!extract_value_pair(&wordno,&time,&val,&maxval,&minval,&lasttime,wordstor)) {
  1678. *extended_brkfile = FALSE;
  1679. return(FINISHED);
  1680. }
  1681. if(time!=0.0) {
  1682. *extended_brkfile = FALSE;
  1683. return(FINISHED);
  1684. }
  1685. for(lineno=1;lineno<linecnt;lineno++) {
  1686. if(wordno+2 > total_words) {
  1687. *extended_brkfile = FALSE;
  1688. return(FINISHED);
  1689. }
  1690. if(wordcnt[lineno]<2 || wordcnt[lineno]>4) {
  1691. *extended_brkfile = FALSE;
  1692. return(FINISHED);
  1693. }
  1694. if(!extract_value_pair(&wordno,&time,&val,&maxval,&minval,&lasttime,wordstor)) {
  1695. *extended_brkfile = FALSE;
  1696. return(FINISHED);
  1697. }
  1698. if(wordcnt[lineno]>2) {
  1699. if(wordno >=total_words) {
  1700. sprintf(errstr,"Failure in word-counting logic 2: check_for_an_extended_brkfile()\n");
  1701. return(PROGRAM_ERROR);
  1702. }
  1703. utol(wordstor[wordno]);
  1704. if(strcmp(wordstor[wordno],"lin")
  1705. && strcmp(wordstor[wordno],"exp")
  1706. && strcmp(wordstor[wordno],"log")) {
  1707. *extended_brkfile = FALSE;
  1708. return(FINISHED);
  1709. }
  1710. wordno++;
  1711. is_extended_format = TRUE;
  1712. }
  1713. if(wordcnt[lineno]>3) {
  1714. if(wordno >=total_words) {
  1715. sprintf(errstr,"Failure in word-counting logic 3: check_for_an_extended_brkfile()\n");
  1716. return(PROGRAM_ERROR);
  1717. }
  1718. if(sscanf(wordstor[wordno],"%lf",&val)!=1
  1719. || val < MIN_BRKSLOPE || val > MAX_BRKSLOPE) {
  1720. *extended_brkfile = FALSE;
  1721. return(FINISHED);
  1722. }
  1723. wordno++;
  1724. }
  1725. }
  1726. if(is_extended_format) {
  1727. inputfile->maxbrk = maxval;
  1728. inputfile->minbrk = minval;
  1729. } else
  1730. *extended_brkfile = FALSE;
  1731. return(FINISHED);
  1732. }
  1733. /****************************************** EXTRACT_VALUE_PAIR ****************************************/
  1734. int extract_value_pair(int *n,double *time, double *val,double *maxval,double *minval, double *lasttime, char **wordstor)
  1735. {
  1736. if(sscanf(wordstor[*n],"%lf",time)!=1 || sscanf(wordstor[(*n)+1],"%lf",val)!=1)
  1737. return(FALSE);
  1738. //TW
  1739. // if(*time <= *lasttime || *val > (double)MAXSAMP || *val < -(double)MAXSAMP)
  1740. if(*time <= *lasttime || *val > (double)MAXRANGE || *val < -(double)MAXRANGE)
  1741. return(FALSE);
  1742. *lasttime = *time;
  1743. *n += 2;
  1744. *maxval = max(*maxval,*val);
  1745. *minval = min(*minval,*val);
  1746. return(TRUE);
  1747. }
  1748. /****************************************** UTOL ****************************************/
  1749. #define UPPER_TO_LOWER_CASE (32)
  1750. void utol(char *str)
  1751. {
  1752. int n, k = strlen(str);
  1753. for(n=0;n<k;n++) {
  1754. if(str[n] >= 'A' && str[n] <= 'Z')
  1755. str[n] += UPPER_TO_LOWER_CASE;
  1756. }
  1757. }
  1758. /* NEW CODE : June 1st : 2000 */
  1759. /****************************************** MAXSAMP ****************************************/
  1760. //TW Rewritten: floating point data only is retained:
  1761. //This version cannot write maxsamp info to header
  1762. void maxsamp(int ifd,double *maxamp,double *maxloc,int *maxrep)
  1763. {
  1764. int got, totalsamps = 0, samps, i /*, maxxloc*/;
  1765. double maxdamp = 0.0;
  1766. float *bigbuf, *fbuf;
  1767. int repeats = 0; /* counts how many times the max repeats */
  1768. int bufsize;
  1769. *maxrep = -1; /* flags that maxamp and maxloc are not found */
  1770. *maxamp = 0.0;
  1771. *maxloc = 0.0;
  1772. if((bufsize =(int) (long)Malloc(-1)) < sizeof(float))
  1773. return;
  1774. /*bufsize = (bufsize/SECSIZE)*SECSIZE; */ /* round to sector boundary */
  1775. bufsize /= sizeof(float);
  1776. if((bigbuf = (float *)malloc(bufsize * sizeof(float)))==NULL)
  1777. return;
  1778. fbuf = (float *)bigbuf;
  1779. while((got = fgetfbufEx(bigbuf,bufsize,ifd,0)) > 0 ) {
  1780. samps = got;
  1781. for( i=0 ; i<samps ; i++ ) {
  1782. if(smpflteq(fbuf[i],maxdamp) || smpflteq(-fbuf[i],maxdamp))
  1783. repeats++;
  1784. else if(fbuf[i] >= 0.0) {
  1785. if(fbuf[i] > maxdamp) {
  1786. maxdamp = fbuf[i];
  1787. *maxloc = (double)(totalsamps + i);
  1788. repeats = 1;
  1789. }
  1790. } else {
  1791. if (-fbuf[i] > maxdamp) {
  1792. maxdamp = -fbuf[i];
  1793. *maxloc = (double)(totalsamps + i);
  1794. repeats = 1;
  1795. }
  1796. }
  1797. }
  1798. totalsamps += got;
  1799. }
  1800. if( got < 0 ) {
  1801. free(bigbuf);
  1802. return;
  1803. }
  1804. if(totalsamps > 0) {
  1805. if(repeats <= 0) {
  1806. Mfree(bigbuf);
  1807. return;
  1808. }
  1809. *maxamp = maxdamp; /* return info to SoundLoom */
  1810. // maxxloc = (int)round(*maxloc); /*RWD NB: NOTUSED */
  1811. *maxrep = repeats;
  1812. }
  1813. Mfree(bigbuf);
  1814. }
  1815. /************************************** DO_EXIT ************************************/
  1816. int do_exit(int exit_status) {
  1817. #ifdef IS_CDPARSE
  1818. if(exit_status == DATA_ERROR)
  1819. fprintf(stdout,"WARNING: %s",errstr); /* Sound Loom responds to message headers */
  1820. else /* and differently to different message headers */
  1821. fprintf(stdout,"ERROR: %s",errstr); /* but ignores the return value */
  1822. fflush(stdout);
  1823. #endif
  1824. return(exit_status); /* cmdline responds to value of 'exit_status' */
  1825. }
  1826. /***************************** PARSE_A_TEXTFILE *****************************/
  1827. int parse_a_textfile(char *filename,infileptr inputfile)
  1828. {
  1829. int exit_status;
  1830. FILE *fp;
  1831. if((fp = fopen(filename,"r"))==NULL) {
  1832. sprintf(errstr, "Can't open file %s to read data.\n",filename);
  1833. exit_status = DATA_ERROR;
  1834. return do_exit(exit_status);
  1835. }
  1836. if(file_has_reserved_extension(filename)) {
  1837. sprintf(errstr, "File %s either has unredable header, or is a textfile with a CDP reserved extension.\n",filename);
  1838. //TW ADDED: ESSENTIAL TO CLOSE FILE or NOTIFY SOUND LOOM OF FAILURE TO CLOSE: for Sound Loom INTEGRITY
  1839. if(fclose(fp)<0) {
  1840. sprintf(errstr, "Failed to close file %s\n",filename);
  1841. exit_status = SYSTEM_ERROR;
  1842. return do_exit(exit_status);
  1843. }
  1844. exit_status = DATA_ERROR;
  1845. return do_exit(exit_status);
  1846. }
  1847. if((exit_status = megaparsec(filename,fp,inputfile))<0) {
  1848. if(fclose(fp)<0) {
  1849. sprintf(errstr, "Failed to close file %s\n",filename);
  1850. exit_status = SYSTEM_ERROR;
  1851. }
  1852. return do_exit(exit_status);
  1853. }
  1854. if(fclose(fp)<0) {
  1855. sprintf(errstr, "Failed to close file %s\n",filename);
  1856. exit_status = SYSTEM_ERROR;
  1857. return do_exit(exit_status);
  1858. }
  1859. return FINISHED;
  1860. }
  1861. /**************************** IS_A_POSSIBLE_MULTICHANNEL_MIXFILE ********************************/
  1862. int is_a_possible_multichannel_mixfile
  1863. (int numlist,int brklist,int sndlist,int linecnt,char **wordstor,int *wordcnt,char *mixfilename,infileptr inputfile)
  1864. {
  1865. int exit_status;
  1866. int total_words = 0;
  1867. int srate = 0;
  1868. double dur = 0.0, time;
  1869. int n, chans, maxoutchan = 0;
  1870. char *filename, *p, *q;
  1871. if(numlist == POSSIBLE || brklist == POSSIBLE || sndlist == POSSIBLE)
  1872. return -1;
  1873. if(wordcnt[0] != 1) /* 1st mixfile line shouldv be = outchannels */
  1874. return -1;
  1875. p = wordstor[0];
  1876. q = p + strlen(wordstor[0]);
  1877. while(p < q) {
  1878. if(!isdigit(*p))
  1879. return -1;
  1880. p++;
  1881. }
  1882. maxoutchan = atoi(wordstor[0]);
  1883. if(maxoutchan < 1 || maxoutchan > MAX_OUTCHAN)
  1884. return -1;
  1885. total_words++;
  1886. for(n=1;n<linecnt;n++) { /* for each mixfile line */
  1887. filename = wordstor[total_words]; /* get the filename */
  1888. if(strlen(filename)<=0)
  1889. return -1;
  1890. if((exit_status = get_multichan_mixdata_in_line(wordcnt[n],wordstor,total_words,&time,&chans,maxoutchan))<0)
  1891. return(exit_status);
  1892. total_words += wordcnt[n];
  1893. if((exit_status = is_a_valid_sndfile_for_mixfile(mixfilename,filename,&srate,chans,n,inputfile,time,&dur,1))<=0)
  1894. return -1;
  1895. }
  1896. inputfile->srate = srate;
  1897. inputfile->linecnt = linecnt;
  1898. inputfile->duration = dur;
  1899. inputfile->out_chans = maxoutchan;
  1900. inputfile->all_words = total_words;
  1901. return FINISHED;
  1902. }
  1903. /**************************** GET_MULTICHAN_MIXDATA_IN_LINE ********************************/
  1904. int get_multichan_mixdata_in_line(int wordcnt,char **wordstor,int total_words,double *time,int *chans,int maxoutchan)
  1905. {
  1906. int here, is_level, inchan = 0, outchan;
  1907. int got_colon;
  1908. char *p;
  1909. char *q, *z = NULL;
  1910. double level;
  1911. int entrycnt = 0;
  1912. if((wordcnt <= 3) || EVEN(wordcnt))
  1913. return -1;
  1914. if(sscanf(wordstor[total_words+1],"%lf",time)!=1
  1915. || sscanf(wordstor[total_words+2],"%d",chans)!=1)
  1916. return -1;
  1917. here = total_words+3;
  1918. is_level = 0;
  1919. while(here < total_words + wordcnt) {
  1920. if(entrycnt >= 256)
  1921. return -1;
  1922. if(is_level) {
  1923. if(is_dB(wordstor[here])) {
  1924. if(!get_leveldb(wordstor[here],&level))
  1925. return -1;
  1926. } else if(!(IsNumeric(wordstor[here])))
  1927. return -1;
  1928. else if(sscanf(wordstor[here],"%lf",&level)!=1)
  1929. return -1;
  1930. } else {
  1931. if(strlen(wordstor[here]) < 3)
  1932. return -1;
  1933. p = wordstor[here];
  1934. q = p + strlen(wordstor[here]);
  1935. got_colon = 0;
  1936. while(p < q) {
  1937. if(!isdigit(*p)) {
  1938. if(p == wordstor[here])
  1939. return -1;
  1940. else if(got_colon)
  1941. return -1;
  1942. else if(*p != ':')
  1943. return -1;
  1944. else {
  1945. *p = ENDOFSTR;
  1946. inchan = atoi(wordstor[here]);
  1947. *p = ':';
  1948. z = p+1;
  1949. got_colon = 1;
  1950. }
  1951. }
  1952. p++;
  1953. }
  1954. if(!got_colon || z == p)
  1955. return -1;
  1956. outchan = atoi(z);
  1957. if(inchan > *chans || inchan <= 0)
  1958. return -1;
  1959. if(outchan > maxoutchan)
  1960. return -1;
  1961. // END OF NEW CODE 2007
  1962. }
  1963. if(is_level)
  1964. entrycnt++;
  1965. is_level = !is_level;
  1966. here++;
  1967. }
  1968. return(FINISHED);
  1969. }
  1970. /*************************** ISNUMERIC **************************/
  1971. int IsNumeric(char *str)
  1972. {
  1973. char *p;
  1974. int got_point = 0;
  1975. p = str;
  1976. while(*p != ENDOFSTR) {
  1977. if(isdigit(*p))
  1978. p++;
  1979. else if(*p == '.') {
  1980. if(got_point)
  1981. return 0;
  1982. got_point = 1;
  1983. p++;
  1984. } else
  1985. return 0;
  1986. }
  1987. if(p == str)
  1988. return 0;
  1989. return 1;
  1990. }