/* * Copyright (c) 1983-2013 Trevor Wishart and Composers Desktop Project Ltd * http://www.trevorwishart.co.uk * http://www.composersdesktop.com * This file is part of the CDP System. The CDP System is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The CDP System is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the CDP System; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ /* floats version */ /* RECEIVES FROM TK * * Name of input file. * * SENDS TO TK * * (1) Various file constants, which TK needs to STORE, to pass back at subsequent stage. */ /**** FEB 1999 MODS * * Force cdparams() output to be printed to stdout on a single line, with items separated by * single spaces, forming a valid TK list * * Recognise Float-sndfiles. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //OCT 2005 #include /* NEW CODE June 1st 2000 */ #ifndef CDP97 #define CDP97 //RWD.6.98 need this! #endif #ifdef _DEBUG #include #endif void maxsamp(int ifd,double *maxamp,double *maxloc,int *maxrep); /* END OF NEW CODE */ #define POSSIBLE (TRUE) #ifdef IS_CDPARSE char errstr[400]; /* only for app version, not for cdp2k library version */ #endif //RWD debugging #define LOCALMEMBYTES (4000) #ifdef unix #define round(x) lround((x)) #endif static void initialise_fileptr(infileptr inputfile); static int check_for_data_in_file(char *filename,infileptr inputfile); static int set_wlength_and_check_data(char *filename,int ifd,infileptr inputfile); static int check_pitch_or_transpos_binary_data(infileptr inputfile,char *filename,int ifd); static int megaparsec(char *filename,FILE *fp,infileptr inputfile); static int initial_parse_textfile(char *filename,FILE *fp,int *linelist, int *has_comments,int *dB_notation,int *total_wordcnt, int *numcnt,int *linecnt,int *max_line_word_cnt,int *min_line_word_cnt); static void initial_textfile_check(int dB_notation,int *sndlist,int *mixlist,int *brklist,int *numlist, int numcnt,int total_wordcnt,int max_line_word_cnt,int in_line_word_cnt); static int valid_start_of_mixfile_line(int k,int *chans,int lineno,char **wordstor,int *srate, int *mixlist,infileptr inputfile,char *filename,double *dur); #ifdef IS_CDPARSE static int is_valid_end_of_mixfile_line(int j,int chans,int lineno,char **wordstor,int *wordcnt); #else static int is_valid_end_of_mixfile_line(int j,int chans,int lineno,char **wordstor,int *wordcnt,char *filename); #endif static int confirm_true_stereo(int *chans,int *is_left,int *is_right,int *is_central,char *panword); static int is_a_possible_mixfile(char **wordstor,int *wordcnt,int linecnt, int *mixlist,int *srate,infileptr inputfile, char *filename,double *dur); static int OK_level(char *str); static int is_a_dB_value(char *str); static int get_leveldb_frame(char *str,double *val); static int is_a_valid_sndfile_for_mixfile(char *filename,char *sndfilename,int *srate, int chans,int linecnt,infileptr inputfile,double time,double *dur,int multichan); static int check_for_brklist_and_count_numbers(char **wordstor,int *wordcnt, int linecnt,int *brklist,infileptr inputfile,char *filename); static int check_for_a_linelist(int line_word_cnt,int *linelist,char **wordstor,infileptr inputfile); static int store_wordlist_without_comments (FILE *fp,char *temp,int total_wordcnt,char **wordstor,int *wordcnt,infileptr inputfile); /* NEW CODE */ static int assign_type(int sndlist,int numlist,int brklist,int mixlist,int synclist,int linelist, int extended_brkfile,infileptr inputfile); /* NEW CODE */ static int check_for_sndlist(char **wordstor,int *wordcnt,int linecnt,int *sndlist); static int check_for_a_synclist(int *synclist,char **wordstor,int *wordcnt,infileptr inputfile,char *filename); static int is_a_valid_sndfile_for_sync(char *filename,char *sndfilename,int *srate,int linecnt,infileptr inputfile); static int set_sndlist_flags(infileptr inputfile,char **wordstor); static int assign_brkfile_type(infileptr inputfile,int linelist); #ifdef NO_DUPLICATE_SNDFILES #ifdef IS_CDPARSE static int duplicated_filenames(int linecnt,char **wordstor,int *wordcnt); #else static int duplicated_filenames(int linecnt,char **wordstor,int *wordcnt,char *filename); #endif #endif static int check_for_an_extended_brkfile (int *extended_brkfile,char **wordstor,int *wordcnt,int linecnt,int total_words,infileptr inputfile); static int extract_value_pair (int *n,double *time, double *val,double *maxval,double *minval,double *lasttime, char **wordstor); static void utol(char *str); extern int smpflteq(double a,double b); int do_exit(int exit_status); /* RWD TODO: use sndsystem */ #ifdef IS_CDPARSE //static int nuheadread(infileptr inputfile,int ifd,char *filename,double *maxamp,double *maxloc, int *maxrep,int getmax); #endif static int parse_a_textfile(char *filename,infileptr inputfile); static int get_multichan_mixdata_in_line(int wordcnt,char **wordstor,int total_words,double *time,int *chans,int maxoutchan); static int is_a_possible_multichannel_mixfile (int numlist,int brklist,int sndlist,int linecnt,char **wordstor,int *wordcnt,char *mixfilename,infileptr inputfile); static int IsNumeric(char *str); /***************************** MAIN **************************/ #ifdef IS_CDPARSE int sloom = 1; int sloombatch = 0; const char* cdp_version = "7.1.0"; int main(int argc,char *argv[]) { char *filename; infileptr inputfile; char temp[/*2000*/LOCALMEMBYTES], *p; /*** Added FEB 1999 *****/ int getmaxinfo = 1; #else int cdparse(char *filename,infileptr inputfile) { int getmaxinfo = 0; #endif int exit_status; int ifd; double maxamp = 0.0, maxloc = -1.0; int maxrep = 0; int getmax = 0; #ifdef IS_CDPARSE /* NEW CODE : June 1st 2000 */ if(argc==2 && (strcmp(argv[1],"--version") == 0)) { fprintf(stdout,"%s\n",cdp_version); fflush(stdout); return 0; } if(argc!=3) { sprintf(errstr,"Incorrect call to cdparse()\n"); exit_status = FAILED; return do_exit(exit_status); } if(sscanf(argv[2],"%d",&getmax)!=1) { sprintf(errstr,"Incorrect call to cdparse()\n"); exit_status = FAILED; return do_exit(exit_status); } filename = argv[1]; if(file_has_invalid_startchar(filename)) { sprintf(errstr, "Filename %s has invalid starting character(s)\n",filename); exit_status = FAILED; return do_exit(exit_status); } if(file_has_invalid_extension(filename)) { sprintf(errstr, "Filename %s has invalid extension for CDP work\n",filename); exit_status = FAILED; return do_exit(exit_status); } if((inputfile = (infileptr)malloc(sizeof(struct filedata)))==NULL) { sprintf(errstr,"Insufficient memory for parsing file %s.\n",filename); exit_status = MEMORY_ERROR; return do_exit(exit_status); } #endif initialise_fileptr(inputfile); if((ifd = sndopenEx(filename,0,CDP_OPEN_RDONLY)) >= 0) { if((exit_status = readhead(inputfile,ifd,filename,&maxamp,&maxloc,&maxrep,getmax,getmaxinfo))<0) { if(sndcloseEx(ifd)<0) { sprintf(errstr, "Failed to close file %s\n",filename); exit_status = SYSTEM_ERROR; return do_exit(exit_status); } return do_exit(exit_status); } if(getmaxinfo && getmax && (maxrep < 0)) { /* if maxsamp required & not in header, get it by searching file */ //TW only get maxsamp if it's a soundfile if(inputfile->filetype == SNDFILE) { maxsamp(ifd,&maxamp,&maxloc,&maxrep); /*RWD TODO */ sndseekEx(ifd,0,0); /* RWD TODO */ } } if((inputfile->insams = sndsizeEx(ifd))<0) { sprintf(errstr, "Can't read size of input file %s\n",filename); exit_status = DATA_ERROR; if(sndcloseEx(ifd)<0) { sprintf(errstr, "Failed to close file %s: %s\n",filename,sferrstr()); exit_status = SYSTEM_ERROR; } return do_exit(exit_status); } if((exit_status = check_for_data_in_file(filename,inputfile))<0) { if(sndcloseEx(ifd)<0) { sprintf(errstr, "Failed to close file %s\n",filename); exit_status = SYSTEM_ERROR; } return do_exit(exit_status); } switch(inputfile->filetype) { case(ANALFILE): case(PITCHFILE): case(TRANSPOSFILE): case(FORMANTFILE): inputfile->nyquist = inputfile->origrate/2.0; inputfile->frametime = (float)(1.0/inputfile->arate); /*inputfile->insams = inputfile->infilesize/sizeof(float); */ if((exit_status = set_wlength_and_check_data(filename,ifd,inputfile))<0) { if(sndcloseEx(ifd)<0) { sprintf(errstr, "Failed to close file %s\n",filename); exit_status = SYSTEM_ERROR; } return do_exit(exit_status); } inputfile->duration = inputfile->wlength * inputfile->frametime; if(inputfile->duration <= FLTERR) { sprintf(errstr, "file %s has ZERO duration : ignoring it\n",filename); exit_status = DATA_ERROR; return do_exit(exit_status); } break; case(ENVFILE): if(sndgetprop(ifd,"window size",(char *)&inputfile->window_size,sizeof(float)) < 0) { sprintf(errstr, "Cannot read window size for file %s\n",filename); exit_status = DATA_ERROR; return do_exit(exit_status); } inputfile->duration = inputfile->window_size * inputfile->insams * MS_TO_SECS; if(inputfile->duration <= FLTERR) { sprintf(errstr, "file %s has zero duration : ignoring it\n",filename); exit_status = DATA_ERROR; return do_exit(exit_status); } break; case(SNDFILE): case(FLT_SNDFILE): /*RWD 2001 added - needed? */ /*inputfile->insams = inputfile->infilesize/sizeof(short); */ inputfile->nyquist = (double)inputfile->srate/2.0; inputfile->duration = (double)(inputfile->insams/inputfile->channels)/(double)(inputfile->srate); if(inputfile->duration <= FLTERR) { sprintf(errstr, "file %s has zero duration : ignoring it\n",filename); exit_status = DATA_ERROR; return do_exit(exit_status); } //RWD.7.99 need to reset this to FLT_SNDFILE if stype==FLOAT ? break; default: exit_status = DATA_ERROR; sprintf(errstr,"Unknown type of file: file %s\n",filename); if(sndcloseEx(ifd)<0) { sprintf(errstr, "Failed to close file %s\n",filename); exit_status = SYSTEM_ERROR; } return do_exit(exit_status); } if(sndcloseEx(ifd)<0) { sprintf(errstr, "Failed to close file %s\n",filename); exit_status = SYSTEM_ERROR; return do_exit(exit_status); } } else { if((exit_status = parse_a_textfile(filename,inputfile)) < 0) return(exit_status); } #ifdef IS_CDPARSE p = temp; sprintf(p,"%d ",inputfile->filetype); /* 0 */ p = temp + strlen(temp); //TW CORRECTED, FOR COMPATIBILITY WITH tkinput: first value OUTPUT is NOW in samples (it was, infilesize) // sprintf(p,"%d ", inputfile->infilesize /* 1 */ p = temp + strlen(temp); sprintf(p,"%d ", inputfile->insams); /* 1 */ p = temp + strlen(temp); sprintf(p,"%d ", inputfile->insams); /* 2 */ p = temp + strlen(temp); sprintf(p,"%d ", inputfile->srate); /* 3 */ p = temp + strlen(temp); sprintf(p,"%d ", inputfile->channels); /* 4 */ p = temp + strlen(temp); sprintf(p,"%d ", inputfile->wanted); /* 5 */ p = temp + strlen(temp); sprintf(p,"%d ", inputfile->wlength); /* 6 */ p = temp + strlen(temp); sprintf(p,"%d ", inputfile->linecnt); /* 7 */ p = temp + strlen(temp); sprintf(p,"%f ", inputfile->arate); /* 8 */ p = temp + strlen(temp); sprintf(p,"%.12f ",inputfile->frametime); /* 9 */ p = temp + strlen(temp); sprintf(p,"%lf ", inputfile->nyquist); /* 10 */ p = temp + strlen(temp); sprintf(p,"%lf ", inputfile->duration); /* 11 */ p = temp + strlen(temp); sprintf(p,"%d ", inputfile->stype); /* 12 */ p = temp + strlen(temp); sprintf(p,"%d ", inputfile->origstype); /* 13 */ p = temp + strlen(temp); sprintf(p,"%d ", inputfile->origrate); /* 14 */ p = temp + strlen(temp); sprintf(p,"%d ", inputfile->Mlen); /* 15 */ p = temp + strlen(temp); sprintf(p,"%d ", inputfile->Dfac); /* 16 */ p = temp + strlen(temp); sprintf(p,"%d ", inputfile->origchans); /* 17 */ p = temp + strlen(temp); sprintf(p,"%d ", inputfile->specenvcnt); /* 18 */ p = temp + strlen(temp); sprintf(p,"%d ", inputfile->out_chans); /* 19 */ p = temp + strlen(temp); //TW REVISED // sprintf(p,"%d ", inputfile->descriptor_bytes); /* 20 * p = temp + strlen(temp); /*RWD TODO : ??? */ sprintf(p,"%d ", inputfile->descriptor_samps); /* 20 */ p = temp + strlen(temp); sprintf(p,"%d ", inputfile->is_transpos); /* 21 */ p = temp + strlen(temp); sprintf(p,"%d ", inputfile->could_be_transpos); /* 22 */ p = temp + strlen(temp); sprintf(p,"%d ", inputfile->could_be_pitch); /* 23 */ p = temp + strlen(temp); sprintf(p,"%d ", inputfile->different_srates); /* 24 */ p = temp + strlen(temp); sprintf(p,"%d ", inputfile->duplicate_snds); /* 25 */ p = temp + strlen(temp); sprintf(p,"%d ", inputfile->brksize); /* 26 */ p = temp + strlen(temp); sprintf(p,"%d ", inputfile->numsize); /* 27 */ p = temp + strlen(temp); sprintf(p,"%d ", inputfile->all_words); /* 28 */ p = temp + strlen(temp); sprintf(p,"%f ", inputfile->window_size); /* 29 */ p = temp + strlen(temp); sprintf(p,"%lf ", inputfile->minbrk); /* 30 */ p = temp + strlen(temp); sprintf(p,"%lf ", inputfile->maxbrk); /* 31 */ p = temp + strlen(temp); sprintf(p,"%lf ", inputfile->minnum); /* 32 */ p = temp + strlen(temp); sprintf(p,"%lf ", inputfile->maxnum); /* 33 */ p = temp + strlen(temp); //TW maxsamp is now float value sprintf(p,"%lf ", maxamp); /* 34 value of maxsamp */ p = temp + strlen(temp); sprintf(p,"%d ", (int)round(maxloc)); /* 35 location maxsamp */ p = temp + strlen(temp); sprintf(p,"%d\n", maxrep); /* 36 no of repets, [old usage, -1 flagged no maxval] */ fprintf(stdout,"%s",temp); fprintf(stdout,"END\n"); fflush(stdout); return(SUCCEEDED); #else return(FINISHED); #endif } /********************************** CHECK_FOR_DATA_IN_FILE ************************************/ int check_for_data_in_file(char *filename,infileptr inputfile) { switch(inputfile->filetype) { case(FORMANTFILE): /*if(inputfile->infilesize <= (int)(DESCRIPTOR_DATA_BLOKS * inputfile->specenvcnt * sizeof(float))) */ if(inputfile->insams <= (int)(DESCRIPTOR_DATA_BLOKS * inputfile->specenvcnt)) { sprintf(errstr, "FILE %s contains no data.\n",filename); return(DATA_ERROR); } break; default: if(inputfile->insams <= 0L) { sprintf(errstr, "FILE %s contains no data.\n",filename); return(DATA_ERROR); } break; } return(FINISHED); } /************************* INITIALISE_FILEPTR *************************/ void initialise_fileptr(infileptr inputfile) { inputfile->filetype = 0; /*inputfile->infilesize = 0;*/ inputfile->insams = 0; inputfile->srate = 0; inputfile->channels = 0; inputfile->stype = 0; inputfile->origstype = 0; inputfile->origrate = 0; inputfile->Mlen = 0; inputfile->Dfac = 0; inputfile->origchans = 0; inputfile->specenvcnt = 0; inputfile->wanted = 0; inputfile->wlength = 0; inputfile->out_chans = 0; inputfile->descriptor_samps = 0; inputfile->is_transpos = FALSE; inputfile->could_be_transpos = FALSE; inputfile->could_be_pitch = FALSE; inputfile->different_srates = FALSE; inputfile->duplicate_snds = FALSE; inputfile->brksize = 0; inputfile->numsize = 0; inputfile->linecnt = 0; inputfile->all_words = 0; inputfile->arate = 0.0f; inputfile->frametime = 0.0f; inputfile->window_size = 0.0f; inputfile->nyquist = 0.0; inputfile->duration = 0.0; inputfile->minbrk = 0.0; inputfile->maxbrk = 0.0; inputfile->minnum = 0.0; inputfile->maxnum = 0.0; } /***************************** SET_WLENGTH_AND_CHECK_DATA *******************************/ int set_wlength_and_check_data(char *filename,int ifd,infileptr inputfile) { int exit_status; switch(inputfile->filetype) { case(ANALFILE): inputfile->wanted = inputfile->channels; inputfile->wlength = inputfile->insams/inputfile->wanted; break; case(PITCHFILE): case(TRANSPOSFILE): inputfile->wlength = inputfile->insams; inputfile->wanted = 1; /* notional: to avoid error calls with bad command lines */ if((exit_status = check_pitch_or_transpos_binary_data(inputfile,filename,ifd))<0) return(exit_status); break; case(FORMANTFILE): inputfile->wlength = (inputfile->insams/inputfile->specenvcnt) - DESCRIPTOR_DATA_BLOKS; inputfile->descriptor_samps = inputfile->specenvcnt * DESCRIPTOR_DATA_BLOKS; inputfile->wanted = inputfile->origchans; /* temporary val for initialise_specenv */ /* working val set in ...chunklen...() */ break; default: sprintf(errstr,"Invalid case: set_wlength_and_check_data()\n"); return(PROGRAM_ERROR); } return(FINISHED); } /********************* CHECK_PITCH_OR_TRANSPOS_BINARY_DATA *************************/ int check_pitch_or_transpos_binary_data(infileptr inputfile,char *filename,int ifd) { int samps_read; int samps_to_read = inputfile->insams; int n; float *thisdata; if((thisdata = (float *)malloc((size_t)(samps_to_read * sizeof(float))))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY for pitch_or_transpos_binary_data of file %s\n",filename); return(MEMORY_ERROR); } samps_read = fgetfbufEx(thisdata, samps_to_read,ifd,0); if(samps_read!= inputfile->insams) { /*RWD.6.98 lets discriminate!*/ if(samps_read < 0){ sprintf(errstr,"Failed to read infile data.\n"); return SYSTEM_ERROR; } sprintf(errstr,"Problem reading binary pitch or transposition data in file %s.\n",filename); return(PROGRAM_ERROR); } switch(inputfile->filetype) { case(PITCHFILE): for(n=0;ninsams;n++) { //TW BRACKETED OUT: NEW CODE DEALS WITH UNPITCHED, AND SILENT WINDOWS /* if(thisdata[n] < FLTERR) { sprintf(errstr,"File %s contains unpitched windows: cannot proceed.\n",filename); return(DATA_ERROR); } */ if(thisdata[n] >= inputfile->nyquist) { sprintf(errstr,"File %s contains pitches beyond nyquist: cannot proceed.\n",filename); return(DATA_ERROR); } } break; case(TRANSPOSFILE): for(n=0;ninsams;n++) { if(thisdata[n] < MIN_TRANSPOS || thisdata[n] >= MAX_TRANSPOS) { sprintf(errstr,"Transposition data item %d (%f):file %s: out of range (%lf to %lf)\n", n+1,thisdata[n],filename,MIN_TRANSPOS,MAX_TRANSPOS); return(DATA_ERROR); } } inputfile->is_transpos = TRUE; break; } free(thisdata); return(FINISHED); } /************************************* MEGAPARSEC ******************************/ int megaparsec(char *filename,FILE *fp,infileptr inputfile) { int exit_status; /* NEW CODE */ int extended_brkfile = POSSIBLE; /* NEW CODE */ int sndlist = POSSIBLE; int numlist = POSSIBLE; int brklist = POSSIBLE; int mixlist = POSSIBLE; int linelist = POSSIBLE; int synclist = POSSIBLE; int has_comments = FALSE; int dB_notation = FALSE; char temp[/*2000*/LOCALMEMBYTES]; char **wordstor; int *wordcnt; int numcnt = 0, linecnt = 0, total_wordcnt = 0, max_line_word_cnt = 0, min_line_word_cnt, n, srate; double dur = 0.0; if((exit_status = initial_parse_textfile(filename,fp,&linelist,&has_comments,&dB_notation, &total_wordcnt,&numcnt,&linecnt,&max_line_word_cnt,&min_line_word_cnt))<0) return(exit_status); initial_textfile_check(dB_notation,&sndlist,&mixlist,&brklist, &numlist,numcnt,total_wordcnt,max_line_word_cnt,min_line_word_cnt); if((wordstor = (char **)malloc(total_wordcnt * sizeof(char *)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY for wordstor: file %s\n",filename); return(MEMORY_ERROR); } for(n=0;nall_words = total_wordcnt; if((wordcnt = (int *)malloc(linecnt * sizeof(int)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY for wordcnt: file %s\n",filename); return(MEMORY_ERROR); } for(n=0;nall_words,wordstor,wordcnt,inputfile))<0) return(exit_status); //OCT 2005 if((exit_status = is_a_possible_multichannel_mixfile (numlist,brklist,sndlist,linecnt,wordstor,wordcnt,filename,inputfile)) == FINISHED) { inputfile->filetype = MIX_MULTI; return(FINISHED); } if(sndlist==POSSIBLE) { if((exit_status = check_for_sndlist(wordstor,wordcnt,linecnt,&sndlist))<0) return(exit_status); } else if(numlist==POSSIBLE) { if((exit_status = check_for_brklist_and_count_numbers(wordstor,wordcnt,linecnt,&brklist,inputfile,filename))<0) return(exit_status); } if(sndlist==POSSIBLE || numlist==POSSIBLE) mixlist = FALSE; if(mixlist==POSSIBLE) { if((exit_status = is_a_possible_mixfile(wordstor,wordcnt,linecnt,&mixlist,&srate,inputfile,filename,&dur))<0) return(exit_status); if(mixlist==FALSE) inputfile->out_chans = 0; else { inputfile->srate = srate; inputfile->duration = dur; synclist = FALSE; brklist = FALSE; sndlist = FALSE; extended_brkfile = FALSE; } } if(linelist==POSSIBLE) { if((exit_status = check_for_a_linelist(max_line_word_cnt,&linelist,wordstor,inputfile))<0) return(exit_status); } if(sndlist==POSSIBLE) { if((exit_status = set_sndlist_flags(inputfile,wordstor))<0) return(exit_status); if(inputfile->different_srates #ifdef NO_DUPLICATE_SNDFILES || inputfile->duplicate_snds #endif ) synclist = FALSE; } else if(synclist==POSSIBLE) { if((exit_status = check_for_a_synclist(&synclist,wordstor,wordcnt,inputfile,filename))<0) return(exit_status); } //TW REMOVED COMMENTS if(extended_brkfile==POSSIBLE) { if((exit_status = check_for_an_extended_brkfile(&extended_brkfile,wordstor,wordcnt,linecnt,total_wordcnt,inputfile))<0) return(exit_status); } if((inputfile->filetype = assign_type(sndlist,numlist,brklist,mixlist,synclist,linelist,extended_brkfile,inputfile))<0) return(inputfile->filetype); return(FINISHED); } /************************************* INITIAL_PARSE_TEXTFILE ******************************/ int initial_parse_textfile (char *filename,FILE *fp,int *linelist,int *has_comments,int *dB_notation, int *total_wordcnt,int *numcnt,int *linecnt,int *max_line_word_cnt,int *min_line_word_cnt) { char temp[LOCALMEMBYTES], *p, *q, c; // RWD was 2000 double val; int line_num_cnt = 0; int last_line_word_cnt = 0, last_line_num_cnt = 0; int line_word_cnt = 0; *max_line_word_cnt = 0; *min_line_word_cnt = INT_MAX; while((c = (char)fgetc(fp))!=EOF) { if(!isalnum(c) && !ispunct(c) && !isspace(c)) { sprintf(errstr,"%s is not a valid CDP file\n",filename); return(DATA_ERROR); } } if(fseek(fp,0,0) != 0) { sprintf(errstr,"Cannot rewind to start of file %s\n",filename); return(DATA_ERROR); } while(fgets(temp,2000,fp)!=NULL) { p = temp; if(is_a_comment(p)) { *has_comments = TRUE; continue; } else if(is_an_empty_line(p)) continue; line_word_cnt = 0; line_num_cnt = 0; while(get_word_from_string(&p,&q)) { line_word_cnt++; if(is_a_dB_value(q)) { *dB_notation = TRUE; (*numcnt)++; line_num_cnt++; } else if(get_float_from_within_string(&q,&val)) { (*numcnt)++; line_num_cnt++; } } if(*linecnt) { if(line_word_cnt != last_line_word_cnt || line_num_cnt != last_line_num_cnt) *linelist = FALSE; } *max_line_word_cnt = max(*max_line_word_cnt,line_word_cnt); *min_line_word_cnt = min(*min_line_word_cnt,line_word_cnt); last_line_word_cnt = line_word_cnt; last_line_num_cnt = line_num_cnt; *total_wordcnt += line_word_cnt; (*linecnt)++; } if(*total_wordcnt==0) { sprintf(errstr,"Cannot get any data from file %s\n",filename); return(DATA_ERROR); } return(FINISHED); } /************************************* INITIAL_TEXTFILE_CHECK ******************************/ void initial_textfile_check(int dB_notation,int *sndlist,int *mixlist,int *brklist,int *numlist, int numcnt,int wordcnt,int max_line_word_cnt,int min_line_word_cnt) { if((numcnt < wordcnt) || dB_notation) { *numlist = FALSE; *brklist = FALSE; } if(numcnt == wordcnt) { *mixlist = FALSE; *sndlist = FALSE; } if(ODD(numcnt)) *brklist = FALSE; if(numcnt>0) *sndlist = FALSE; else *mixlist = FALSE; if(min_line_word_cntMIX_MAXLINE) *mixlist = FALSE; } /************************************* VALID_START_OF_MIXFILE_LINE ******************************/ #ifdef IS_CDPARSE int valid_start_of_mixfile_line (int k,int *chans,int lineno,char **wordstor,int *srate,int *mixlist,infileptr inputfile,char *filename,double *dur) { int exit_status; double time; char *sndfilename; sndfilename = wordstor[k++]; if(sscanf(wordstor[k++],"%lf",&time)!=1) { *mixlist = FALSE; return(FINISHED); } if(time<0.0) { *mixlist = FALSE; return(FINISHED); } if(sscanf(wordstor[k++],"%d",chans)!=1) { *mixlist = FALSE; return(FINISHED); } if(*chans < MONO || *chans > STEREO) { *mixlist = FALSE; return(FINISHED); } if((exit_status = is_a_valid_sndfile_for_mixfile(filename,sndfilename,srate,*chans,lineno,inputfile,time,dur,0))<0) return(exit_status); if(exit_status == FALSE) { *mixlist = FALSE; return(FINISHED); } if(!OK_level(wordstor[k])) { /* must be numeric, and witihin range */ *mixlist = FALSE; return(FINISHED); } return(FINISHED); } #else int valid_start_of_mixfile_line (int k,int *chans,int lineno,char **wordstor,int *srate,int *mixlist,infileptr inputfile,char *filename,double *dur) { int exit_status; double time; char *sndfilename; sndfilename = wordstor[k++]; if(sscanf(wordstor[k++],"%lf",&time)!=1) { if(lineno>0) { fprintf(stdout,"WARNING: If %s is a mixfile: Invalid or missing time val on line %d\n",filename,lineno+1); fflush(stdout); } *mixlist = FALSE; return(FINISHED); } if(time<0.0) { if(lineno>0) { fprintf(stdout,"WARNING: If %s is a mixfile: starttime less than zero [%lf]: line %d\n", filename,time,lineno+1); fflush(stdout); } *mixlist = FALSE; return(FINISHED); } if(sscanf(wordstor[k++],"%d",chans)!=1) { if(lineno>0) { fprintf(stdout,"WARNING: If %s is a mixfile: Invalid or missing channel val on line %d\n", filename,lineno+1); fflush(stdout); } *mixlist = FALSE; return(FINISHED); } if(*chans < MONO || *chans > STEREO) { if(lineno>0) { fprintf(stdout,"WARNING: If %s is a mixfile: Invalid channel-cnt on line %d\n",filename,lineno+1); fflush(stdout); } *mixlist = FALSE; return(FINISHED); } if((exit_status = is_a_valid_sndfile_for_mixfile(filename,sndfilename,srate,*chans,lineno,inputfile,time,dur,0))<0) return(exit_status); if(exit_status == FALSE) { *mixlist = FALSE; return(FINISHED); } if(!OK_level(wordstor[k])) { /* must be numeric, and witihin range */ if(lineno>0) { fprintf(stdout,"WARNING: If %s is a mixfile: Invalid [channel 1] level val on line %d\n", filename,lineno+1); fflush(stdout); } *mixlist = FALSE; return(FINISHED); } return(FINISHED); } #endif /************************************* IS_VALID_END_OF_MIXFILE_LINE ******************************/ #ifdef IS_CDPARSE int is_valid_end_of_mixfile_line(int j,int chans,int lineno,char **wordstor,int *wordcnt) { double pan; //TW UPDATE: AVOID WARNING int got_numeric_panval = sscanf(wordstor[j],"%lf",&pan); if(strcmp(wordstor[j],"C") && strcmp(wordstor[j],"L") && strcmp(wordstor[j],"R") && got_numeric_panval!=1) return(FALSE); if(got_numeric_panval && (pan < MINPAN || pan >MAXPAN)) return(FALSE); if(chans==MONO) { if(wordcnt[lineno]>MIX_MIDLINE) { return(FALSE); } return(TRUE); } else { if(wordcnt[lineno] MAXPAN)) { return(FALSE); } return(TRUE); } #else int is_valid_end_of_mixfile_line(int j,int chans,int lineno,char **wordstor,int *wordcnt,char *filename) { double pan; //TW UPDATE: AVOID WARNING int got_numeric_panval = sscanf(wordstor[j],"%lf",&pan); if(strcmp(wordstor[j],"C") && strcmp(wordstor[j],"L") && strcmp(wordstor[j],"R") && got_numeric_panval!=1) { if(lineno>0) { fprintf(stdout,"WARNING: If %s is a mixfile: Invalid (1st) pan val, line %d\n",filename,lineno+1); fflush(stdout); } return(FALSE); } if(got_numeric_panval && (pan < MINPAN || pan >MAXPAN)) { if(lineno>0) { fprintf(stdout,"WARNING: If %s is a mixfile: Invalid (1st) pan val [%lf], line %d\n", filename,pan,lineno+1); fflush(stdout); } return(FALSE); } if(chans==MONO) { if(wordcnt[lineno]>MIX_MIDLINE) { if(lineno>0) { fprintf(stdout,"WARNING: If %s is a mixfile: Too many words on line %d\n",filename,lineno+1); fflush(stdout); } return(FALSE); } return(TRUE); } else { if(wordcnt[lineno]0) { fprintf(stdout,"WARNING: If %s is a mixfile: Too few entries for stereo file on line %d\n", filename,lineno+1); fflush(stdout); } return(FALSE); } } j++; if(!OK_level(wordstor[j++])) { /* level must be numeric or dB & in range */ if(lineno>0) { fprintf(stdout,"WARNING: If %s is a mixfile: Missing level for chan2 on line %d\n",filename,lineno+1); fflush(stdout); } return(FALSE); } got_numeric_panval = 0; //TW UPDATE: AVOID WARNING got_numeric_panval = sscanf(wordstor[j],"%lf",&pan); if(strcmp(wordstor[j],"C") && strcmp(wordstor[j],"L") && strcmp(wordstor[j],"R") && (got_numeric_panval !=1)) { /* pan must be C,R,L or numeric */ if(lineno>0) { fprintf(stdout,"WARNING: If %s is a mixfile: Missing chan2 pan val on line %d\n", filename,lineno+1); fflush(stdout); } return(FALSE); } if(got_numeric_panval && (pan < MINPAN || pan > MAXPAN)) { if(lineno>0) { fprintf(stdout,"WARNING: If %s is a mixfile: Invalid 2nd pan val [%lf], line %d\n", filename,pan,lineno+1); fflush(stdout); } return(FALSE); } return(TRUE); } #endif /************************************* CONFIRM_TRUE_STEREO ******************************/ int confirm_true_stereo(int *chans,int *is_left,int *is_right,int *is_central,char *panword) { double pan; if(!strcmp(panword,"L")) { *is_left = TRUE; /* panned hard Left */ *chans = MONO; } else if(!strcmp(panword,"R")) { *is_right = TRUE; /* panned hard Right */ *chans = MONO; } else if(strcmp(panword,"C")) { if(sscanf(panword,"%lf",&pan)!=1) { sprintf(errstr,"Parsing error 2: confirm_true_stereo()\n"); return(PROGRAM_ERROR); } if(pan <= -1.0) { *is_left = TRUE; /* panned hard Left */ *chans = MONO; } else if(pan >= 1.0) { *is_right = TRUE; /* panned hard Right */ *chans = MONO; } // TW REMOVED COMMENTS else *chans = STEREO; } else *is_central = TRUE; return(FINISHED); } /**************** IS_A_POSSIBLE_MIXFILE **********************/ int is_a_possible_mixfile(char **wordstor,int *wordcnt,int linecnt,int *mixlist, int *srate,infileptr inputfile,char *filename,double *dur) { int exit_status; int is_left = FALSE, is_right = FALSE, is_central = FALSE; int /*cnt = 0,*/ chans; int k = 0, j, lineno; if(linecnt > SF_MAXFILES-1) { #ifndef IS_CDPARSE fprintf(stdout,"WARNING: If %s is a mixfile: cannot mix more than %d files in one mix\n", filename,SF_MAXFILES-1); fflush(stdout); #endif *mixlist = FALSE; return(FINISHED); } for(lineno=0;linenoMIX_MINLINE) { j = k + MIX_MINLINE; #ifdef IS_CDPARSE if(!is_valid_end_of_mixfile_line(j,chans,lineno,wordstor,wordcnt)) { #else if(!is_valid_end_of_mixfile_line(j,chans,lineno,wordstor,wordcnt,filename)) { #endif *mixlist = FALSE; return(FINISHED); } if(wordcnt[lineno]==MIX_MIDLINE && chans==MONO) { if((exit_status = confirm_true_stereo(&chans,&is_left,&is_right,&is_central,wordstor[j]))<0) return(exit_status); } } else is_central = TRUE; inputfile->out_chans = max(inputfile->out_chans,chans); k += wordcnt[lineno]; } #ifdef NO_DUPLICATE_SNDFILES #ifdef IS_CDPARSE if(duplicated_filenames(linecnt,wordstor,wordcnt)) #else if(duplicated_filenames(linecnt,wordstor,wordcnt,filename)) #endif { *mixlist = FALSE; return(FINISHED); } #endif if(inputfile->out_chans==MONO) { if((is_left && is_right) || (is_left && is_central) || (is_right && is_central)) inputfile->out_chans = STEREO; } if(inputfile->out_chans < MONO) { sprintf(errstr,"Impossible out_chans value\n"); return(PROGRAM_ERROR); } return(FINISHED); } /******************* DUPLICATED_FILENAMES **************************/ #ifdef IS_CDPARSE int duplicated_filenames(int linecnt,char **wordstor,int *wordcnt) { int n, m; int j, k = 0; for(n=0;n1) return(FALSE); } else return(FALSE); p++; } if(!has_digits || sscanf(str,"%lf",&val)!=1) return(FALSE); return(TRUE); } /**************************** GET_LEVELDB_FRAME ********************************/ int get_leveldb_frame(char *str,double *val) { int is_neg = 0; if(sscanf(str,"%lf",val)!=1) return(FALSE); *val = max(*val,MIN_DB_ON_16_BIT); if(flteq(*val,0.0)) { *val = 1.0; return(TRUE); } if(*val<0.0) { *val = -(*val); is_neg = 1; } *val /= 20.0; *val = pow(10.0,*val); if(is_neg) *val = 1.0/(*val); return(TRUE); } /***************************** IS_A_VALID_SNDFILE_FOR_MIXFILE **************************/ int is_a_valid_sndfile_for_mixfile (char *filename,char *sndfilename,int *srate,int chans,int linecnt,infileptr inputfile,double time,double *dur,int multichan) { int exit_status; /*int minsize = 0L;*/ double thisdur; int ifd; double maxamp, maxloc; int maxrep; #ifdef IS_CDPARSE int getmaxinfo = 1; #else int getmaxinfo = 0; #endif char *p = strrchr(sndfilename, '.'); if(p == NULL) { #ifndef IS_CDPARSE fprintf(stdout,"WARNING: If %s is a mixfile: uses %s which has no sndfile extension\n",filename,sndfilename); fflush(stdout); return(FALSE); #endif } p++; #ifdef NOTDEF /*RWD 4:2002 this is silly! sfsys accepts aiff files, so cdparse certainly can! */ // APRIL 2010 // if(_stricmp(p,(getenv("CDP_SOUND_EXT")))) { if(_stricmp(p,".wav") || _stricmp(p,".aiff")) { #ifndef IS_CDPARSE // APRIL 2010 // 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")); 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); fflush(stdout); return(FALSE); #endif } #endif if((ifd = sndopenEx(sndfilename,0,CDP_OPEN_RDONLY)) < 0) { #ifndef IS_CDPARSE fprintf(stdout,"WARNING: If %s is a mixfile: uses %s which is not a sndfile\n",filename,sndfilename); fflush(stdout); #endif return(FALSE); } if((exit_status = readhead(inputfile,ifd,sndfilename,&maxamp,&maxloc,&maxrep,0,getmaxinfo))<0) { /* READ THE FILE HEADER */ if(sndcloseEx(ifd)<0) sprintf(errstr,"Failed to close file %s when checking file %s\n",sndfilename,filename); return(exit_status); } exit_status = TRUE; if(inputfile->filetype!=SNDFILE) { #ifndef IS_CDPARSE fprintf(stdout,"WARNING: If %s is a mixfile: uses %s which is not a sndfile\n",filename,sndfilename); fflush(stdout); #endif exit_status=FALSE; } else if(inputfile->channels != chans) { #ifndef IS_CDPARSE if(chans==MONO) fprintf(stdout,"WARNING: If %s is a mixfile: %s is not a mono sndfile\n",filename,sndfilename); else if(chans==STEREO) /*RWD 4:2001 added test */ fprintf(stdout,"WARNING: If %s is a mixfile: %s is not a stereo sndfile\n",filename,sndfilename); //OCT 2005 else fprintf(stdout,"WARNING: If %s is a mixfile: %s has different no. of chans (%d) to that indicated in mixfile line (%d)\n", filename,sndfilename,inputfile->channels,chans); fflush(stdout); #endif exit_status=FALSE; } else if((inputfile->insams = sndsizeEx(ifd))<0) { /* FIND SIZE OF FILE */ sprintf(errstr, "Can't read size of input file %s: used in file %s\n",sndfilename,filename); exit_status=PROGRAM_ERROR; } else if(inputfile->insams <= 0L) { #ifndef IS_CDPARSE fprintf(stdout,"WARNING: If %s is a mixfile: file %s contains no data.\n",filename,sndfilename); fflush(stdout); #endif exit_status=FALSE; } else if (linecnt==multichan) { *srate = inputfile->srate; } else if(inputfile->srate != *srate) { #ifndef IS_CDPARSE fprintf(stdout,"WARNING: If %s is a mixfile: Incompatible sample-rate in file %s\n",filename,sndfilename); fflush(stdout); #endif exit_status=FALSE; } #ifdef NOTDEF /* RWD 4:2001 */ switch(inputfile->filetype) { case(SNDFILE): inputfile->insams = inputfile->infilesize/sizeof(short); break; case(FLT_SNDFILE): inputfile->insams = inputfile->infilesize/sizeof(float); break; } #endif #ifdef _DEBUG assert(inputfile->insams > 0); #endif thisdur = time + (inputfile->insams/inputfile->channels/(double)inputfile->srate); *dur = max(*dur,thisdur); // inputfile->infilesize = 0; inputfile->insams = 0; inputfile->filetype = 0; inputfile->srate = 0; inputfile->channels = 0; inputfile->stype = 0; if(sndcloseEx(ifd)<0) { sprintf(errstr,"Failed to close file %s while checking file %s\n",sndfilename,filename); exit_status=SYSTEM_ERROR; } return(exit_status); } /*************************** CHECK_FOR_BRKLIST_AND_STORE_NUMBERS ***********************/ int check_for_brklist_and_count_numbers (char **wordstor,int *wordcnt,int linecnt,int *brklist,infileptr inputfile,char *filename) { double p, lasttime = 0.0; int istime = TRUE; int lineno, word_in_line, dcount = 0, k = 0; for(lineno=0;linenomaxnum = p; inputfile->minnum = p; } else { inputfile->maxnum = max(p,inputfile->maxnum); inputfile->minnum = min(p,inputfile->minnum); } } else { if(k==1) { inputfile->maxbrk = p; inputfile->minbrk = p; } else { inputfile->maxbrk = max(p,inputfile->maxbrk); inputfile->minbrk = min(p,inputfile->minbrk); } inputfile->maxnum = max(p,inputfile->maxnum); inputfile->minnum = min(p,inputfile->minnum); } istime = !istime; k++; } } if(k == 0) { sprintf(errstr,"No numeric data found in file %s\n",filename); return(DATA_ERROR); } if(*brklist==POSSIBLE) { if(k < 4) /* Must be at least 2 point in a brkfile */ *brklist = FALSE; } if(*brklist==POSSIBLE) { if(((dcount = k/2) * 2) != k) *brklist = FALSE; } if(*brklist==POSSIBLE) { inputfile->brksize = dcount; inputfile->duration = lasttime; } else inputfile->brksize = 0; inputfile->numsize = k; return(FINISHED); } /*************************** CHECK_FOR_A_LINELIST ***********************/ #define OTHER (0) #define NUMERICAL (1) #define DBLIKE (2) int check_for_a_linelist(int line_word_cnt,int *linelist,char **wordstor,infileptr inputfile) { int linecnt = 0, n, m; int total_wordcnt = 0; //TW AGREED REMOVAL of 'OK' int k; double val; char *wordtype[2], *p; if((wordtype[0] = (char *)malloc(line_word_cnt * sizeof(char)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY for wordtype[0]\n"); return(MEMORY_ERROR); } if((wordtype[1] = (char *)malloc(line_word_cnt * sizeof(char)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY for wordtype[1]\n"); free(wordtype[0]); return(MEMORY_ERROR); } for(n=0;nlinecnt;n++) { if(n==0) k = 0; else k = 1; for(m=0;m0) { for(m=0;m total_wordcnt) { sprintf(errstr,"Error in word accounting: store_wordlist_without_comments()\n"); return(PROGRAM_ERROR); } wordcnt_in_line++; } wordcnt[linecnt] = wordcnt_in_line; linecnt++; } inputfile->linecnt = linecnt; return(FINISHED); } /***************************** ASSIGN_TYPE **************************/ //TW REMOVED OLD COMMENT LINES int assign_type(int sndlist,int numlist,int brklist,int mixlist,int synclist,int linelist,int extended_brkfile,infileptr inputfile) { //TW AGREED WARNING SHOULD BE MOVED if(sndlist==POSSIBLE) { if(synclist==POSSIBLE) { if(linelist==POSSIBLE) return SNDLIST_OR_SYNCLIST_LINELIST_OR_WORDLIST; else return SNDLIST_OR_SYNCLIST_OR_WORDLIST; } else { if(linelist==POSSIBLE) return SNDLIST_OR_LINELIST_OR_WORDLIST; else return SNDLIST_OR_WORDLIST; } } else if(numlist==POSSIBLE) { if(brklist==POSSIBLE) return assign_brkfile_type(inputfile,linelist); else { if(linelist==POSSIBLE) return NUMLIST_OR_LINELIST_OR_WORDLIST; else return NUMLIST_OR_WORDLIST; } } else if(mixlist==POSSIBLE) { if(linelist==POSSIBLE) return MIXLIST_OR_LINELIST_OR_WORDLIST; else return MIXLIST_OR_WORDLIST; } else if(synclist==POSSIBLE) { if(linelist==POSSIBLE) return SYNCLIST_OR_LINELIST_OR_WORDLIST; else return SYNCLIST_OR_WORDLIST; } else if(linelist==POSSIBLE) return LINELIST_OR_WORDLIST; //RWD.8.98 do this test here! if(extended_brkfile==POSSIBLE) { fprintf(stderr,"WARNING:Extended format brkfiles not yet supported by commandline programs.\n"); } return WORDLIST; } /****************************************** CHECK_FOR_A_SYNCLIST ****************************************/ int check_for_a_synclist(int *synclist,char **wordstor,int *wordcnt,infileptr inputfile,char *filename) { int exit_status; int n; int total_words = 0; int srate = 0; double starttime, endtime; for(n=0;nlinecnt;n++) { /* Must be 1 or 3 words on each line */ if(wordcnt[n]!=1 && wordcnt[n]!=3) { *synclist = FALSE; return(FINISHED); } } for(n=0;nlinecnt;n++) { /* Every line must start with a sndfilename */ if((exit_status = is_a_valid_sndfile_for_sync(filename,wordstor[total_words],&srate,n,inputfile))<0) return(exit_status); if(exit_status == FALSE) { *synclist = FALSE; return(FINISHED); } total_words += wordcnt[n]; } total_words = 0; for(n=0;nlinecnt;n++) { /* Any other values must be numbers */ if(wordcnt[n] > 1) { if(sscanf(wordstor[total_words+1],"%lf\n",&starttime)!=1) { *synclist = FALSE; return(FINISHED); } else if(sscanf(wordstor[total_words+2],"%lf\n",&endtime)!=1) { *synclist = FALSE; return(FINISHED); } else if(starttime < 0.0 || endtime < 0.0) { #ifndef IS_CDPARSE fprintf(stdout,"WARNING: If %s is a synclist, it contains negative times\n",filename); fflush(stdout); #endif *synclist = FALSE; return(FINISHED); } else if(starttime > endtime) { #ifndef IS_CDPARSE fprintf(stdout,"WARNING: If %s is a synclist, starttime > endtime in line %d\n",filename,n+1); fflush(stdout); #endif *synclist = FALSE; return(FINISHED); } } total_words += wordcnt[n]; } #ifdef NO_DUPLICATE_SNDFILES #ifdef CDPARSE if(duplicated_filenames(inputfile->linecnt,wordstor,wordcnt)) #else if(duplicated_filenames(inputfile->linecnt,wordstor,wordcnt,filename)) #endif return(FALSE); #endif inputfile->srate = srate; return(FINISHED); } /***************************** IS_A_VALID_SNDFILE_FOR_SYNC **************************/ int is_a_valid_sndfile_for_sync(char *filename,char *sndfilename,int *srate,int linecnt,infileptr inputfile) { int exit_status; //TW AGREED REMOVAL minsize int ifd; double maxamp, maxloc; int maxrep; #ifdef IS_CDPARSE int getmaxinfo = 1; #else int getmaxinfo = 0; #endif if((ifd = sndopenEx(sndfilename,0,CDP_OPEN_RDONLY)) < 0) return(FALSE); if((exit_status = readhead(inputfile,ifd,sndfilename,&maxamp,&maxloc,&maxrep,0,getmaxinfo))<0) { /* READ THE FILE HEADER */ if(sndcloseEx(ifd)<0) { sprintf(errstr,"Failed to close sndfile %s while checking file %s\n",sndfilename,filename); exit_status = SYSTEM_ERROR; } return(exit_status); } exit_status = TRUE; if(inputfile->filetype!=SNDFILE) { #ifndef IS_CDPARSE fprintf(stdout,"WARNING: If %s is a syncfile: %s is not a sndfile.\n",filename,sndfilename); fflush(stdout); #endif exit_status=FALSE; } else if((inputfile->insams = sndsizeEx(ifd))<0) { /* FIND SIZE OF FILE */ sprintf(errstr, "Can't read size of input file %s: while checking file %s\n",sndfilename,filename); exit_status = SYSTEM_ERROR; /*RWD 4.2001 was PROGRAM_ERROR */ } else if(inputfile->insams == 0L) /*RWD 4.2001 was <= */ exit_status=FALSE; else if (linecnt==0) *srate = inputfile->srate; else if(inputfile->srate != *srate) { #ifndef IS_CDPARSE fprintf(stdout,"WARNING: If %s is a syncfile: Incompatible sample-rate in file %s\n",filename,sndfilename); fflush(stdout); #endif exit_status=FALSE; } // inputfile->infilesize = 0; inputfile->insams = 0; inputfile->filetype = 0; inputfile->srate = 0; inputfile->channels = 0; inputfile->stype = 0; if(sndcloseEx(ifd)<0) { sprintf(errstr,"Failed to close sndfile %s while testing file %s\n",sndfilename,filename); return(SYSTEM_ERROR); } return(exit_status); } /***************************** SET_SNDLIST_FLAGS **************************/ int set_sndlist_flags(infileptr inputfile,char **wordstor) { int exit_status; int srate = 0, wordcnt, m; char *filename; int ifd; double maxamp, maxloc; int maxrep; #ifdef IS_CDPARSE int getmaxinfo = 1; #else int getmaxinfo = 0; #endif for(wordcnt=0;wordcntall_words;wordcnt++) { filename = wordstor[wordcnt]; if(inputfile->different_srates == FALSE) { if((ifd = sndopenEx(filename,0,CDP_OPEN_RDONLY)) < 0) { #ifdef _DEBUG sprintf(errstr,"Anomaly reopening sndfile %s: set_sndfilelist_flags()\n",filename); #else sprintf(errstr,"Anomaly reopening sndfile %s: %s\n",filename,rsferrstr); #endif return(SYSTEM_ERROR); } if((exit_status = readhead(inputfile,ifd,filename,&maxamp,&maxloc,&maxrep,0,getmaxinfo))<0) { /* READ THE FILE HEADER */ sprintf(errstr,"Anomaly Rereading header of sndfile %s: set_sndfilelist_flags()\n",filename); if(sndcloseEx(ifd) < 0) sprintf(errstr, "Can't close soundfile %s: set_sndlist_flags()\n",filename); return(SYSTEM_ERROR); } if(wordcnt==0) srate = inputfile->srate; else if(inputfile->srate != srate) { inputfile->different_srates = TRUE; inputfile->srate = 0; } // inputfile->infilesize = 0; inputfile->insams = 0; inputfile->filetype = 0; inputfile->channels = 0; inputfile->stype = 0; if(sndcloseEx(ifd) < 0) { sprintf(errstr, "Can't close soundfile %s: set_sndlist_flags()\n",filename); return(SYSTEM_ERROR); } } } for(wordcnt=0;wordcntall_words;wordcnt++) { for(m=wordcnt+1;mall_words;m++) { if(!strcmp(wordstor[wordcnt],wordstor[m])) { inputfile->duplicate_snds = TRUE; break; } } if(inputfile->duplicate_snds) break; } return(FINISHED); } /****************************************** ASSIGN_BRKFILE_TYPE ****************************************/ int assign_brkfile_type(infileptr inputfile,int linelist) { int normalised_brkfile = FALSE; int dB_brkfile = FALSE; int pitch_brkfile = FALSE; int transpos_brkfile = FALSE; int positive_brkfile = FALSE; if(inputfile->minbrk >= 0.0) positive_brkfile = TRUE; if(inputfile->maxbrk <= 1.0 && inputfile->minbrk >= 0.0) normalised_brkfile = TRUE; else if (inputfile->maxbrk <= DEFAULT_NYQUIST && inputfile->minbrk >= -1.0) { inputfile->could_be_pitch = TRUE; pitch_brkfile = TRUE; } if(inputfile->maxbrk <= 0.0 && inputfile->minbrk >= MIN_DB_ON_16_BIT) dB_brkfile = TRUE; if(inputfile->maxbrk <= MAX_TRANSPOS && inputfile->minbrk >= MIN_TRANSPOS) { inputfile->could_be_transpos = TRUE; transpos_brkfile = TRUE; } if(transpos_brkfile) { if(normalised_brkfile) { if(linelist==POSSIBLE) return TRANSPOS_OR_NORMD_BRKFILE_OR_NUMLIST_OR_LINELIST_OR_WORDLIST; else return TRANSPOS_OR_NORMD_BRKFILE_OR_NUMLIST_OR_WORDLIST; } else if(pitch_brkfile) { if(linelist==POSSIBLE) return TRANSPOS_OR_PITCH_BRKFILE_OR_NUMLIST_OR_LINELIST_OR_WORDLIST; else return TRANSPOS_OR_PITCH_BRKFILE_OR_NUMLIST_OR_WORDLIST; } else { if(linelist==POSSIBLE) return TRANSPOS_OR_UNRANGED_BRKFILE_OR_NUMLIST_OR_LINELIST_OR_WORDLIST; else return TRANSPOS_OR_UNRANGED_BRKFILE_OR_NUMLIST_OR_WORDLIST; } } else { if(normalised_brkfile) { if(linelist==POSSIBLE) return NORMD_BRKFILE_OR_NUMLIST_OR_LINELIST_OR_WORDLIST; else return NORMD_BRKFILE_OR_NUMLIST_OR_WORDLIST; } else if(dB_brkfile) { if(linelist==POSSIBLE) return DB_BRKFILE_OR_NUMLIST_OR_LINELIST_OR_WORDLIST; else return DB_BRKFILE_OR_NUMLIST_OR_WORDLIST; } else if(pitch_brkfile) { if(linelist==POSSIBLE) { if(positive_brkfile) return PITCH_POSITIVE_BRKFILE_OR_NUMLIST_OR_LINELIST_OR_WORDLIST; else return PITCH_BRKFILE_OR_NUMLIST_OR_LINELIST_OR_WORDLIST; } else { if(positive_brkfile) return PITCH_POSITIVE_BRKFILE_OR_NUMLIST_OR_WORDLIST; else return PITCH_BRKFILE_OR_NUMLIST_OR_WORDLIST; } } else if(positive_brkfile) { if(linelist==POSSIBLE) return POSITIVE_BRKFILE_OR_NUMLIST_OR_LINELIST_OR_WORDLIST; else return POSITIVE_BRKFILE_OR_NUMLIST_OR_WORDLIST; } else { if(linelist==POSSIBLE) return UNRANGED_BRKFILE_OR_NUMLIST_OR_LINELIST_OR_WORDLIST; else return UNRANGED_BRKFILE_OR_NUMLIST_OR_WORDLIST; } } } #define MIN_BRKSLOPE (1.0) #define MAX_BRKSLOPE (6.0) /************************************ CHECK_FOR_AN_EXTENDED_BRKFILE *********************************/ int check_for_an_extended_brkfile (int *extended_brkfile,char **wordstor,int *wordcnt,int linecnt,int total_words,infileptr inputfile) { int wordno = 0, lineno; int is_extended_format = FALSE; double lasttime = -1.0, time, val; double maxval = -(double)(MAXRANGE+1); double minval = (double)(MAXRANGE+1); if(wordcnt[0]!=2) { *extended_brkfile = FALSE; return(FINISHED); } if(!extract_value_pair(&wordno,&time,&val,&maxval,&minval,&lasttime,wordstor)) { *extended_brkfile = FALSE; return(FINISHED); } if(time!=0.0) { *extended_brkfile = FALSE; return(FINISHED); } for(lineno=1;lineno total_words) { *extended_brkfile = FALSE; return(FINISHED); } if(wordcnt[lineno]<2 || wordcnt[lineno]>4) { *extended_brkfile = FALSE; return(FINISHED); } if(!extract_value_pair(&wordno,&time,&val,&maxval,&minval,&lasttime,wordstor)) { *extended_brkfile = FALSE; return(FINISHED); } if(wordcnt[lineno]>2) { if(wordno >=total_words) { sprintf(errstr,"Failure in word-counting logic 2: check_for_an_extended_brkfile()\n"); return(PROGRAM_ERROR); } utol(wordstor[wordno]); if(strcmp(wordstor[wordno],"lin") && strcmp(wordstor[wordno],"exp") && strcmp(wordstor[wordno],"log")) { *extended_brkfile = FALSE; return(FINISHED); } wordno++; is_extended_format = TRUE; } if(wordcnt[lineno]>3) { if(wordno >=total_words) { sprintf(errstr,"Failure in word-counting logic 3: check_for_an_extended_brkfile()\n"); return(PROGRAM_ERROR); } if(sscanf(wordstor[wordno],"%lf",&val)!=1 || val < MIN_BRKSLOPE || val > MAX_BRKSLOPE) { *extended_brkfile = FALSE; return(FINISHED); } wordno++; } } if(is_extended_format) { inputfile->maxbrk = maxval; inputfile->minbrk = minval; } else *extended_brkfile = FALSE; return(FINISHED); } /****************************************** EXTRACT_VALUE_PAIR ****************************************/ int extract_value_pair(int *n,double *time, double *val,double *maxval,double *minval, double *lasttime, char **wordstor) { if(sscanf(wordstor[*n],"%lf",time)!=1 || sscanf(wordstor[(*n)+1],"%lf",val)!=1) return(FALSE); //TW // if(*time <= *lasttime || *val > (double)MAXSAMP || *val < -(double)MAXSAMP) if(*time <= *lasttime || *val > (double)MAXRANGE || *val < -(double)MAXRANGE) return(FALSE); *lasttime = *time; *n += 2; *maxval = max(*maxval,*val); *minval = min(*minval,*val); return(TRUE); } /****************************************** UTOL ****************************************/ #define UPPER_TO_LOWER_CASE (32) void utol(char *str) { int n, k = (int) strlen(str); for(n=0;n= 'A' && str[n] <= 'Z') str[n] += UPPER_TO_LOWER_CASE; } } /* NEW CODE : June 1st : 2000 */ /****************************************** MAXSAMP ****************************************/ //TW Rewritten: floating point data only is retained: //This version cannot write maxsamp info to header void maxsamp(int ifd,double *maxamp,double *maxloc,int *maxrep) { int got, totalsamps = 0, samps, i /*, maxxloc*/; double maxdamp = 0.0; float *bigbuf, *fbuf; int repeats = 0; /* counts how many times the max repeats */ size_t bufsize; *maxrep = -1; /* flags that maxamp and maxloc are not found */ *maxamp = 0.0; *maxloc = 0.0; // if((bufsize =(int) (long)Malloc(-1)) < sizeof(float)) if ((bufsize = (size_t) Malloc(-1)) < sizeof(float)) return; /*bufsize = (bufsize/SECSIZE)*SECSIZE; */ /* round to sector boundary */ bufsize /= sizeof(float); if((bigbuf = (float *)malloc(bufsize * sizeof(float)))==NULL) return; fbuf = (float *)bigbuf; while((got = fgetfbufEx(bigbuf,(int) bufsize,ifd,0)) > 0 ) { samps = got; for( i=0 ; i= 0.0) { if(fbuf[i] > maxdamp) { maxdamp = fbuf[i]; *maxloc = (double)(totalsamps + i); repeats = 1; } } else { if (-fbuf[i] > maxdamp) { maxdamp = -fbuf[i]; *maxloc = (double)(totalsamps + i); repeats = 1; } } } totalsamps += got; } if( got < 0 ) { free(bigbuf); return; } if(totalsamps > 0) { if(repeats <= 0) { Mfree(bigbuf); return; } *maxamp = maxdamp; /* return info to SoundLoom */ // maxxloc = (int)round(*maxloc); /*RWD NB: NOTUSED */ *maxrep = repeats; } Mfree(bigbuf); } /************************************** DO_EXIT ************************************/ int do_exit(int exit_status) { #ifdef IS_CDPARSE if(exit_status == DATA_ERROR) fprintf(stdout,"WARNING: %s",errstr); /* Sound Loom responds to message headers */ else /* and differently to different message headers */ fprintf(stdout,"ERROR: %s",errstr); /* but ignores the return value */ fflush(stdout); #endif return(exit_status); /* cmdline responds to value of 'exit_status' */ } /***************************** PARSE_A_TEXTFILE *****************************/ int parse_a_textfile(char *filename,infileptr inputfile) { int exit_status; FILE *fp; if((fp = fopen(filename,"r"))==NULL) { sprintf(errstr, "Can't open file %s to read data.\n",filename); exit_status = DATA_ERROR; return do_exit(exit_status); } if(file_has_reserved_extension(filename)) { sprintf(errstr, "File %s either has unredable header, or is a textfile with a CDP reserved extension.\n",filename); //TW ADDED: ESSENTIAL TO CLOSE FILE or NOTIFY SOUND LOOM OF FAILURE TO CLOSE: for Sound Loom INTEGRITY if(fclose(fp)<0) { sprintf(errstr, "Failed to close file %s\n",filename); exit_status = SYSTEM_ERROR; return do_exit(exit_status); } exit_status = DATA_ERROR; return do_exit(exit_status); } if((exit_status = megaparsec(filename,fp,inputfile))<0) { if(fclose(fp)<0) { sprintf(errstr, "Failed to close file %s\n",filename); exit_status = SYSTEM_ERROR; } return do_exit(exit_status); } if(fclose(fp)<0) { sprintf(errstr, "Failed to close file %s\n",filename); exit_status = SYSTEM_ERROR; return do_exit(exit_status); } return FINISHED; } /**************************** IS_A_POSSIBLE_MULTICHANNEL_MIXFILE ********************************/ int is_a_possible_multichannel_mixfile (int numlist,int brklist,int sndlist,int linecnt,char **wordstor,int *wordcnt,char *mixfilename,infileptr inputfile) { int exit_status; int total_words = 0; int srate = 0; double dur = 0.0, time; int n, chans, maxoutchan = 0; char *filename, *p, *q; if(numlist == POSSIBLE || brklist == POSSIBLE || sndlist == POSSIBLE) return -1; if(wordcnt[0] != 1) /* 1st mixfile line shouldv be = outchannels */ return -1; p = wordstor[0]; q = p + strlen(wordstor[0]); while(p < q) { if(!isdigit(*p)) return -1; p++; } maxoutchan = atoi(wordstor[0]); if(maxoutchan < 1 || maxoutchan > MAX_OUTCHAN) return -1; total_words++; for(n=1;nsrate = srate; inputfile->linecnt = linecnt; inputfile->duration = dur; inputfile->out_chans = maxoutchan; inputfile->all_words = total_words; return FINISHED; } /**************************** GET_MULTICHAN_MIXDATA_IN_LINE ********************************/ int get_multichan_mixdata_in_line(int wordcnt,char **wordstor,int total_words,double *time,int *chans,int maxoutchan) { int here, is_level, inchan = 0, outchan; int got_colon; char *p; char *q, *z = NULL; double level; int entrycnt = 0; if((wordcnt <= 3) || EVEN(wordcnt)) return -1; if(sscanf(wordstor[total_words+1],"%lf",time)!=1 || sscanf(wordstor[total_words+2],"%d",chans)!=1) return -1; here = total_words+3; is_level = 0; while(here < total_words + wordcnt) { if(entrycnt >= 256) return -1; if(is_level) { if(is_dB(wordstor[here])) { if(!get_leveldb(wordstor[here],&level)) return -1; } else if(!(IsNumeric(wordstor[here]))) return -1; else if(sscanf(wordstor[here],"%lf",&level)!=1) return -1; } else { if(strlen(wordstor[here]) < 3) return -1; p = wordstor[here]; q = p + strlen(wordstor[here]); got_colon = 0; while(p < q) { if(!isdigit(*p)) { if(p == wordstor[here]) return -1; else if(got_colon) return -1; else if(*p != ':') return -1; else { *p = ENDOFSTR; inchan = atoi(wordstor[here]); *p = ':'; z = p+1; got_colon = 1; } } p++; } if(!got_colon || z == p) return -1; outchan = atoi(z); if(inchan > *chans || inchan <= 0) return -1; if(outchan > maxoutchan) return -1; // END OF NEW CODE 2007 } if(is_level) entrycnt++; is_level = !is_level; here++; } return(FINISHED); } /*************************** ISNUMERIC **************************/ int IsNumeric(char *str) { char *p; int got_point = 0; p = str; while(*p != ENDOFSTR) { if(isdigit(*p)) p++; else if(*p == '.') { if(got_point) return 0; got_point = 1; p++; } else return 0; } if(p == str) return 0; return 1; }