/* * 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 * */ #include #include #ifdef WIN32 #include #else #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //#ifdef unix #define round(x) lround((x)) //#endif /******************************************************************************/ /************************* FORMERLY IN procspec.c *****************************/ /******************************************************************************/ static int extend_ring(int change_in_size,dataptr dz); static int shrink_ring(int change_in_size,dataptr dz); static int zero_channels_between_partials(int *vvc,double frq_close_below_next_partial,dataptr dz); static int eliminate_all_but_loudest_channel_near_this_partial_frq (int *vvc,double frq_close_above_next_partial,dataptr dz); static int keep_all_channels_near_partial_frq(int *vvc,double frq_close_above_next_partial,dataptr dz); static int do_amplitude_poll(int bot,int top,dataptr dz); /******************************************************************************/ /************************* FORMERLY IN aplinit.c ******************************/ /******************************************************************************/ static int establish_application(dataptr dz); static int application_init(dataptr dz); static int initialise_vflags(dataptr dz); static int setup_and_init_input_param_activity(dataptr dz,int tipc); static int setup_and_init_input_brktable_constants(dataptr dz,int tipc); static int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz); static int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz); static int mark_parameter_types(dataptr dz,aplptr ap); static int establish_infile_constants(dataptr dz); static int setup_input_param_defaultval_stores(int tipc,aplptr ap); static int get_domain_and_image(char *str,char **domain, char **image); static int consistent_domain_and_image(int dmncnt,int imgcnt,char *domain,char *image,dataptr dz); static int make_map(int dmncnt,int imgcnt,int mapping,char *domain,char *image,dataptr dz); /**************************** SETUP_PARTICULAR_APPLICATION *******************************/ int setup_particular_application(dataptr dz) { int exit_status; aplptr ap; if((exit_status = establish_application(dz))<0) return(exit_status); ap = dz->application; if((exit_status = set_legal_param_structure(dz->process,dz->mode,ap))<0) return(exit_status); /* GLOBAL LIBRARY */ if((exit_status = set_legal_option_and_variant_structure(dz->process,dz->mode,ap))<0) return(exit_status); /* GLOBAL LIBRARY */ set_formant_flags(dz->process,dz->mode,ap); /* GLOBAL LIBRARY */ if((exit_status = set_legal_internalparam_structure(dz->process,dz->mode,ap))<0) return(exit_status); /* LIBRARY */ set_legal_infile_structure(dz); /* IN THIS FILE */ assign_process_logic(dz); /* IN THIS FILE */ if((exit_status = application_init(dz))<0) /* IN THIS FILE */ return(exit_status); return(FINISHED); } /****************************** ESTABLISH_APPLICATION *******************************/ int establish_application(dataptr dz) { aplptr ap; if((dz->application = (aplptr)malloc(sizeof (struct applic)))==NULL) { sprintf(errstr,"establish_application()\n"); return(MEMORY_ERROR); } ap = dz->application; memset((char *)ap,0,sizeof(struct applic)); return(FINISHED); } /***************************** APPLICATION_INIT **************************/ int application_init(dataptr dz) { int exit_status; int storage_cnt; int tipc, brkcnt; aplptr ap = dz->application; if(ap->vflag_cnt>0) initialise_vflags(dz); tipc = ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt; ap->total_input_param_cnt = (char)tipc; if(tipc>0) { if((exit_status = setup_input_param_range_stores(tipc,ap))<0) return(exit_status); if((exit_status = setup_input_param_defaultval_stores(tipc,ap))<0) return(exit_status); if((exit_status = setup_and_init_input_param_activity(dz,tipc))<0) return(exit_status); } brkcnt = tipc; if(dz->input_data_type==BRKFILES_ONLY || dz->input_data_type==UNRANGED_BRKFILE_ONLY || dz->input_data_type==DB_BRKFILES_ONLY || dz->input_data_type==SNDFILE_AND_BRKFILE || dz->input_data_type==SNDFILE_AND_UNRANGED_BRKFILE || dz->input_data_type==SNDFILE_AND_DB_BRKFILE || dz->input_data_type==ALL_FILES || dz->input_data_type==ANY_NUMBER_OF_ANY_FILES || dz->outfiletype==BRKFILE_OUT) { dz->extrabrkno = brkcnt; brkcnt++; /* extra brktable for input or output brkpntfile data */ } if(brkcnt>0) { if((exit_status = setup_and_init_input_brktable_constants(dz,brkcnt))<0) return(exit_status); } if((storage_cnt = tipc + ap->internal_param_cnt)>0) { if((exit_status = setup_parameter_storage_and_constants(storage_cnt,dz))<0) return(exit_status); if((exit_status = initialise_is_int_and_no_brk_constants(storage_cnt,dz))<0) return(exit_status); } if((exit_status = mark_parameter_types(dz,ap))<0) return(exit_status); if((exit_status = establish_infile_constants(dz))<0) return(exit_status); if((exit_status = establish_bufptrs_and_extra_buffers(dz))<0) return(exit_status); if((exit_status = setup_internal_arrays_and_array_pointers(dz))<0) return(exit_status); return(FINISHED); } /************************* INITIALISE_VFLAGS *************************/ int initialise_vflags(dataptr dz) { int n; if((dz->vflag = (char *)malloc(dz->application->vflag_cnt * sizeof(char)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY: vflag store,\n"); return(MEMORY_ERROR); } for(n=0;napplication->vflag_cnt;n++) dz->vflag[n] = FALSE; return FINISHED; } /***************************** SETUP_AND_INIT_INPUT_PARAM_ACTIVITY **************************/ int setup_and_init_input_param_activity(dataptr dz,int tipc) { int n; if((dz->is_active = (char *)malloc((size_t)tipc))==NULL) { sprintf(errstr,"setup_and_init_input_param_activity()\n"); return(MEMORY_ERROR); } for(n=0;nis_active[n] = (char)0; return(FINISHED); } /***************************** SETUP_AND_INIT_INPUT_BRKTABLE_CONSTANTS **************************/ int setup_and_init_input_brktable_constants(dataptr dz,int brkcnt) { int n; if((dz->brk = (double **)malloc(brkcnt * sizeof(double *)))==NULL) { sprintf(errstr,"setup_and_init_input_brktable_constants(): 1\n"); return(MEMORY_ERROR); } if((dz->brkptr = (double **)malloc(brkcnt * sizeof(double *)))==NULL) { sprintf(errstr,"setup_and_init_input_brktable_constants(): 6\n"); return(MEMORY_ERROR); } if((dz->brksize = (int *)malloc(brkcnt * sizeof(int) ))==NULL) { sprintf(errstr,"setup_and_init_input_brktable_constants(): 2\n"); return(MEMORY_ERROR); } if((dz->firstval = (double *)malloc(brkcnt * sizeof(double) ))==NULL) { sprintf(errstr,"setup_and_init_input_brktable_constants(): 3\n"); return(MEMORY_ERROR); } if((dz->lastind = (double *)malloc(brkcnt * sizeof(double) ))==NULL) { sprintf(errstr,"setup_and_init_input_brktable_constants(): 4\n"); return(MEMORY_ERROR); } if((dz->lastval = (double *)malloc(brkcnt * sizeof(double) ))==NULL) { sprintf(errstr,"setup_and_init_input_brktable_constants(): 5\n"); return(MEMORY_ERROR); } if((dz->brkinit = (int *)malloc(brkcnt * sizeof(int) ))==NULL) { sprintf(errstr,"setup_and_init_input_brktable_constants(): 7\n"); return(MEMORY_ERROR); } for(n=0;nbrk[n] = NULL; dz->brkptr[n] = NULL; dz->brkinit[n] = 0; dz->brksize[n] = 0; } return(FINISHED); } /********************** SETUP_PARAMETER_STORAGE_AND_CONSTANTS ********************/ /* RWD malloc changed to calloc; helps debug verison run as release! */ int setup_parameter_storage_and_constants(int storage_cnt,dataptr dz) { // RWD Apr 20100 add extra element storage_cnt += 1; if((dz->param = (double *)calloc(storage_cnt, sizeof(double)))==NULL) { sprintf(errstr,"setup_parameter_storage_and_constants(): 1\n"); return(MEMORY_ERROR); } if((dz->iparam = (int *)calloc(storage_cnt, sizeof(int) ))==NULL) { sprintf(errstr,"setup_parameter_storage_and_constants(): 2\n"); return(MEMORY_ERROR); } if((dz->is_int = (char *)calloc(storage_cnt, sizeof(char)))==NULL) { sprintf(errstr,"setup_parameter_storage_and_constants(): 3\n"); return(MEMORY_ERROR); } if((dz->no_brk = (char *)calloc(storage_cnt, sizeof(char)))==NULL) { sprintf(errstr,"setup_parameter_storage_and_constants(): 5\n"); return(MEMORY_ERROR); } return(FINISHED); } /************** INITIALISE_IS_INT_AND_NO_BRK_CONSTANTS *****************/ int initialise_is_int_and_no_brk_constants(int storage_cnt,dataptr dz) { int n; for(n=0;nis_int[n] = (char)0; dz->no_brk[n] = (char)0; } return(FINISHED); } /***************************** MARK_PARAMETER_TYPES **************************/ int mark_parameter_types(dataptr dz,aplptr ap) { int n, m; /* PARAMS */ for(n=0;nmax_param_cnt;n++) { switch(ap->param_list[n]) { case('0'): break; /* dz->is_active[n] = 0 is default */ case('i'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1;dz->no_brk[n] = (char)1; break; case('I'): dz->is_active[n] = (char)1; dz->is_int[n] = (char)1; break; case('d'): dz->is_active[n] = (char)1; dz->no_brk[n] = (char)1; break; case('D'): dz->is_active[n] = (char)1; /* normal case: double val or brkpnt file */ break; default: sprintf(errstr,"Programming error: invalid parameter type in mark_parameter_types()\n"); return(PROGRAM_ERROR); } } /* OPTIONS */ for(n=0,m=ap->max_param_cnt;noption_cnt;n++,m++) { switch(ap->option_list[n]) { //TW JULY 2006 case('0'): break; case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break; case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break; case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break; case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break; default: sprintf(errstr,"Programming error: invalid option type in mark_parameter_types()\n"); return(PROGRAM_ERROR); } } /* VARIANTS */ for(n=0,m=ap->max_param_cnt + ap->option_cnt;n < ap->variant_param_cnt; n++, m++) { switch(ap->variant_list[n]) { case('0'): break; case('i'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break; case('I'): dz->is_active[m] = (char)1; dz->is_int[m] = (char)1; break; case('d'): dz->is_active[m] = (char)1; dz->no_brk[m] = (char)1; break; case('D'): dz->is_active[m] = (char)1; /* normal case: double val or brkpnt file */ break; default: sprintf(errstr,"Programming error: invalid variant type in mark_parameter_types()\n"); return(PROGRAM_ERROR); } } /* INTERNAL */ for(n=0, m=ap->max_param_cnt + ap->option_cnt + ap->variant_param_cnt; ninternal_param_cnt; n++,m++) { switch(ap->internal_param_list[n]) { case('0'): break; /* dummy variables: variables not used: but important for internal paream numbering!! */ case('i'): dz->is_int[m] = (char)1; dz->no_brk[m] = (char)1; break; case('d'): dz->no_brk[m] = (char)1; break; default: sprintf(errstr,"Programming error: invalid internal param type in mark_parameter_types()\n"); return(PROGRAM_ERROR); } } return(FINISHED); } /******************** ESTABLISH_SPEC_BUFPTRS_AND_EXTRA_BUFFERS **************************/ int establish_spec_bufptrs_and_extra_buffers(dataptr dz) { int n; if(dz->extra_bufcnt) { if((dz->windowbuf = (float **)malloc(sizeof(float *) * dz->extra_bufcnt))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY for extra float sample buffers.\n"); return(MEMORY_ERROR); } for(n = 0; n < dz->extra_bufcnt;n++) dz->windowbuf[n] = NULL; } if(dz->bptrcnt) { if((dz->flbufptr = (float **)malloc(sizeof(float *) * dz->bptrcnt))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY for float sample buffers.\n"); return(MEMORY_ERROR); } for(n = 0;n bptrcnt; n++) dz->flbufptr[n] = NULL; } return(FINISHED); } /******************** ESTABLISH_GROUCHO_BUFPTRS_AND_EXTRA_BUFFERS **************************/ int establish_groucho_bufptrs_and_extra_buffers(dataptr dz) { int n; if(dz->bufcnt < 0) { sprintf(errstr,"bufcnt has not been set: establish_groucho_bufptrs_and_extra_buffers()\n"); return(PROGRAM_ERROR); } if(dz->extra_bufcnt < 0) { sprintf(errstr,"extrs_bufcnt has not been set: establish_groucho_bufptrs_and_extra_buffers()\n"); return(PROGRAM_ERROR); } if(dz->bufcnt) { if((dz->sampbuf = (float **)malloc(sizeof(float *) * (dz->bufcnt+1)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY establishing sample buffers.\n"); return(MEMORY_ERROR); } if((dz->sbufptr = (float **)malloc(sizeof(float *) * dz->bufcnt))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY establishing sample buffer pointers.\n"); return(MEMORY_ERROR); } for(n = 0;n bufcnt; n++) dz->sampbuf[n] = dz->sbufptr[n] = (float *)0; dz->sampbuf[n] = (float *)0; } if(dz->extra_bufcnt) { if((dz->extrabuf = (float **)malloc(sizeof(float *) * (dz->extra_bufcnt+1)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY establishing extra buffers.\n"); return(MEMORY_ERROR); } if((dz->extrabufptr = (float **)malloc(sizeof(float *) * (dz->extra_bufcnt+1)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY establishing extrabuffer pointers.\n"); return(MEMORY_ERROR); } for(n = 0;n extra_bufcnt; n++) dz->extrabuf[n] = dz->extrabufptr[n] = (float *)0; dz->extrabuf[n] = (float *)0; } return(FINISHED); } /***************************** ESTABLISH_INFILE_CONSTANTS **************************/ int establish_infile_constants(dataptr dz) { switch(dz->input_data_type) { case(MIXFILES_ONLY): case(SNDLIST_ONLY): case(SND_OR_MIXLIST_ONLY): case(SND_SYNC_OR_MIXLIST_ONLY): case(BRKFILES_ONLY): case(DB_BRKFILES_ONLY): case(UNRANGED_BRKFILE_ONLY): case(WORDLIST_ONLY): dz->infilecnt = ONE_NONSND_FILE; break; case(NO_FILE_AT_ALL): dz->infilecnt = 0; break; case(ALL_FILES): case(SNDFILES_ONLY): case(ENVFILES_ONLY): case(ANALFILE_ONLY): case(PITCHFILE_ONLY): case(PITCH_OR_TRANSPOS): case(FORMANTFILE_ONLY): dz->infilecnt = 1; break; case(TWO_SNDFILES): case(SNDFILE_AND_ENVFILE): case(SNDFILE_AND_BRKFILE): case(SNDFILE_AND_DB_BRKFILE): case(TWO_ANALFILES): case(ANAL_WITH_PITCHDATA): case(ANAL_WITH_TRANSPOS): case(ANAL_AND_FORMANTS): case(PITCH_AND_FORMANTS): case(PITCH_AND_PITCH): case(PITCH_AND_TRANSPOS): case(TRANSPOS_AND_TRANSPOS):case(SNDFILE_AND_UNRANGED_BRKFILE): dz->infilecnt = 2; break; case(THREE_ANALFILES): //TW NEW CASE case(PFE): dz->infilecnt = 3; break; case(MANY_ANALFILES): case(MANY_SNDFILES): dz->infilecnt = -2; /* flags 2 or more */ break; case(ONE_OR_MANY_SNDFILES): //TW NEW CASE case(ONE_OR_MORE_SNDSYS): case(ANY_NUMBER_OF_ANY_FILES): dz->infilecnt = -1; /* flags 1 or more */ break; default: sprintf(errstr,"Unknown input_process-type: establish_infile_constants()\n"); return(PROGRAM_ERROR); } return(FINISHED); } /****************************** SETUP_PROCESS_LOGIC *********************************/ void setup_process_logic(int input,int processing,int output,dataptr dz) { dz->input_data_type = input; dz->process_type = processing; dz->outfiletype = output; } /************************* SETUP_INPUT_PARAM_DEFAULTVALS *************************/ // RWD Apr 2011 added extra element int setup_input_param_defaultval_stores(int tipc,aplptr ap) { int n; tipc += 1; if((ap->default_val = (double *)malloc(tipc * sizeof(double)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY for application default values store\n"); return(MEMORY_ERROR); } for(n=0;ndefault_val[n] = 0.0; return(FINISHED); } /******************************************************************************/ /************************* FORMERLY IN internal.c *****************************/ /******************************************************************************/ /******** SET_INTERNALPARAM_DATA ***********************/ int set_internalparam_data(const char *this_paramlist,aplptr ap) { int count; if((count = (int)strlen(this_paramlist))>0) { if((ap->internal_param_list = (char *)malloc((size_t)(count+1)))==NULL) { sprintf(errstr,"set_internalparam_data()\n"); return(MEMORY_ERROR); } strcpy(ap->internal_param_list,this_paramlist); } ap->internal_param_cnt = (char ) count; /*RWD added cast */ return(FINISHED); } /******************************************************************************/ /************************* FORMERLY IN sinlib.c *******************************/ /******************************************************************************/ /************************* READ_SAMPS **************************/ //TW removed NOTDEF: not certain how to get to not-NOTDEF option int read_samps(float *bbuf,dataptr dz) { if((dz->ssampsread = fgetfbufEx(bbuf, dz->buflen,dz->ifd[0],0)) < 0) { sprintf(errstr,"Can't read samples from input soundfile.\n"); return(SYSTEM_ERROR); } dz->samps_left -= dz->ssampsread; dz->total_samps_read += dz->ssampsread; return(FINISHED); } /*************************** READ_VALUES_FROM_ALL_EXISTING_BRKTABLES **************************/ int read_values_from_all_existing_brktables(double thistime,dataptr dz) { int exit_status; aplptr ap = dz->application; int n; for(n=0;ntotal_input_param_cnt;n++) { if(dz->brksize[n]) { if((exit_status = read_value_from_brktable(thistime,n,dz))<0) return(exit_status); } } return(FINISHED); } /**************************** READ_VALUE_FROM_BRKTABLE *****************************/ int read_value_from_brktable(double thistime,int paramno,dataptr dz) { double *endpair, *p, val; double hival, loval, hiind, loind; if(!dz->brkinit[paramno]) { dz->brkptr[paramno] = dz->brk[paramno]; dz->firstval[paramno] = *(dz->brk[paramno]+1); endpair = dz->brk[paramno] + ((dz->brksize[paramno]-1)*2); dz->lastind[paramno] = *endpair; dz->lastval[paramno] = *(endpair+1); dz->brkinit[paramno] = 1; } p = dz->brkptr[paramno]; if(thistime <= *(dz->brk[paramno])) { dz->param[paramno] = dz->firstval[paramno]; if(dz->is_int[paramno]) dz->iparam[paramno] = round(dz->param[paramno]); return(FINISHED); } else if(thistime >= dz->lastind[paramno]) { dz->param[paramno] = dz->lastval[paramno]; if(dz->is_int[paramno]) dz->iparam[paramno] = round(dz->param[paramno]); return(FINISHED); } if(thistime > *(p)) { while(*(p)=thistime) p -= 2; p += 2; } hival = *(p+1); hiind = *p; loval = *(p-1); loind = *(p-2); val = (thistime - loind)/(hiind - loind); val *= (hival - loval); val += loval; dz->param[paramno] = val; if(dz->is_int[paramno]) dz->iparam[paramno] = round(dz->param[paramno]); dz->brkptr[paramno] = p; return(FINISHED); } /************************** GET_TOTALAMP ***********************/ int get_totalamp(double *totalamp,float *sbuf,int wanted) { int vc; *totalamp = 0.0; for(vc = 0; vc < wanted; vc += 2) *totalamp += sbuf[AMPP]; return(FINISHED); } /******************************************************************************/ /************************* FORMERLY IN specialin.c ****************************/ /******************************************************************************/ /************** READ_NEW_FILENAME ***********/ int read_new_filename(char *filename,dataptr dz) { if(dz->wordstor!=NULL) { if((dz->wordstor = (char **)realloc(dz->wordstor,(dz->all_words+1) * sizeof(char *)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY to reallocate word stores.\n"); return(MEMORY_ERROR); } } else { if(dz->all_words!=0 || dz->extra_word!=-1) { sprintf(errstr,"Array allocation error: read_new_filename().\n"); return(PROGRAM_ERROR); } if((dz->wordstor = (char **)malloc((dz->all_words+1) * sizeof(char *)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY to create word stores.\n"); return(MEMORY_ERROR); } } dz->extra_word = dz->all_words; dz->all_words++; if((dz->wordstor[dz->extra_word] = (char *)malloc((strlen(filename)+1) * sizeof(char)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY to create extra word store.\n"); return(MEMORY_ERROR); } strcpy(dz->wordstor[dz->extra_word],filename); return(FINISHED); } /**************************** READ_SHUFFLE_DATA **************************/ int read_shuffle_data(int dmnparam,int imgparam,int mapparam,char *str,dataptr dz) { int exit_status; char *domain, *image; if((exit_status = get_domain_and_image(str,&domain,&image))<0) return(exit_status); dz->iparam[dmnparam] = (int)strlen(domain); dz->iparam[imgparam] = (int)strlen(image); if((exit_status = consistent_domain_and_image(dmnparam,imgparam,domain,image,dz))!=TRUE) return(DATA_ERROR); return make_map(dmnparam,imgparam,mapparam,domain,image,dz); } /************************** GET_DOMAIN_AND_IMAGE ********************************/ int get_domain_and_image(char *str,char **domain, char **image) { char *p = str, *q = str; while(*p!='-' && *p != ':') { if(*p == ENDOFSTR) { sprintf(errstr,"Bad string for shuffle data: separator missing\n"); return(DATA_ERROR); } else if(!isalpha(*p)) { sprintf(errstr,"Invalid character ('%c') in string for shuffle data.\n",*p); return(DATA_ERROR); } p++; } if(p-q <=0) { sprintf(errstr,"Bad string for shuffle data: domain missing\n"); return(DATA_ERROR); } *p = ENDOFSTR; *domain = q; p++; q = p; while(*p!=ENDOFSTR) { if(!isalpha(*p)) { sprintf(errstr,"Invalid character ('%d') in string for shuffle data.\n",*p); return(DATA_ERROR); } p++; } if(p-q <=0) { sprintf(errstr,"Bad string for shuffle data: image missing\n"); return(DATA_ERROR); } *image = q; return(FINISHED); } /************************** MAKE_MAP ********************************/ int make_map(int dmncnt,int imgcnt,int mapping,char *domain,char *image,dataptr dz) { int n, m, OK; if((dz->iparray[mapping] = (int *)malloc(dz->iparam[imgcnt] * sizeof(int)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY for map.\n"); return(MEMORY_ERROR); } for(n=0;niparam[imgcnt];n++) { OK = 0; for(m=0;miparam[dmncnt];m++) { if(image[n] == domain[m]) { dz->iparray[mapping][n] = m; OK = 1; break; } } if(!OK) { sprintf(errstr,"Programming Problem: no match in make_map().\n"); return(PROGRAM_ERROR); } } return(FINISHED); } /************************** CONSISTENT_DOMAIN_AND_IMAGE ********************************/ int consistent_domain_and_image(int dmncnt,int imgcnt,char *domain,char *image,dataptr dz) { int n, m, OK; for(n=0;niparam[dmncnt]-1;n++) { for(m=n+1;miparam[dmncnt];m++) { if(domain[n]==domain[m]) { sprintf(errstr,"Duplicated symbol [%c] in domain string.\n",domain[n]); return(FALSE); } } } for(n=0;niparam[imgcnt];n++) { OK = 0; for(m=0;miparam[dmncnt];m++) { if(image[n] == domain[m]) { OK = 1; break; } } if(!OK) { sprintf(errstr,"Image symbol [%c] not in domain.\n",image[n]); return(FALSE); } } return(TRUE); } /******************************************************************************/ /************************* FORMERLY IN preprocess.c ***************************/ /******************************************************************************/ /***************************** FORCE_VALUE_AT_ZERO_TIME ******************************/ int force_value_at_zero_time(int paramno,dataptr dz) { double *p, *pend; double thistime,lasttime,timediff,timeratio,thisval,lastval,valdiff,val; int n; if(flteq(dz->brk[paramno][0],0.0)) { dz->brk[paramno][0] = 0.0; return(FINISHED); } if(dz->brk[paramno][0] > 0.0) { if((dz->brk[paramno] = (double *)realloc((char *)(dz->brk[paramno]),(dz->brksize[paramno]+1) * 2 * sizeof(double)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY to reallocate to force zero-time value.\n"); return(MEMORY_ERROR); } for(n = (dz->brksize[paramno] * 2) - 1; n>=0;n--) dz->brk[paramno][n+2] = dz->brk[paramno][n]; dz->brk[paramno][0] = 0.0; dz->brk[paramno][1] = dz->brk[paramno][3]; dz->brksize[paramno]++; } else { p = dz->brk[paramno]; pend = p + (dz->brksize[paramno] * 2); while(*p < 0.0) { p += 2; if(p >= pend) { p -= 2; memmove((char *)(dz->brk[paramno]),(char *)p,2 * sizeof(double)); dz->brk[paramno][0] = 0.0; if((dz->brk[paramno] = (double *)realloc((char *)(dz->brk[paramno]),2 * sizeof(double)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY to reallocate to force zero-time value.\n"); return(MEMORY_ERROR); } dz->brksize[paramno] = 1; return(FINISHED); } } if(*p > 0.0) { thistime = *p; lasttime = *(p-2); timediff = thistime - lasttime; timeratio = -(lasttime)/timediff; /* lasttime is -ve */ thisval = *(p+1); lastval = *(p-1); valdiff = thisval - lastval; val = lastval + (valdiff * timeratio); p -= 2; *p = 0.0; *(p+1) = val; } dz->brksize[paramno] = (pend - p)/2; memmove((char *)(dz->brk[paramno]),(char *)p,dz->brksize[paramno] * 2 * sizeof(double)); if((dz->brk[paramno] = (double *)realloc((char *)(dz->brk[paramno]),dz->brksize[paramno] * 2 * sizeof(double)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY to reallocate to force zero-time value.\n"); return(MEMORY_ERROR); } } dz->brkptr[paramno] = dz->brk[paramno]; return(FINISHED); } /***************************** INITIALISE_RANDOM_SEQUENCE ***************************/ void initialise_random_sequence(int seed_flagno,int seed_paramno,dataptr dz) { if(dz->vflag[seed_flagno]) srand((int)dz->iparam[seed_paramno]); else initrand48(); } /******************** CONVERT_MSECS_TO_SECS **********************/ int convert_msecs_to_secs(int brktableno,dataptr dz) { double *p, *pend; if(dz->brksize[brktableno]) { p = dz->brk[brktableno]; pend = p + (dz->brksize[brktableno] * 2); while(p < pend) { *p *= MS_TO_SECS; p+=2; } } else dz->param[brktableno] *= MS_TO_SECS; return(FINISHED); } /***************************** ESTABLISH_BOTTOM_FRQS_OF_CHANNELS **************/ int establish_bottom_frqs_of_channels(dataptr dz) { int cc; if((dz->windowbuf[CHBOT] = (float *) realloc((char *)dz->windowbuf[CHBOT],dz->clength * sizeof(float)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY for channel bottom frqs array.\n"); return(MEMORY_ERROR); } dz->windowbuf[CHBOT][0] = 0.0f; dz->windowbuf[CHBOT][1] = (float)dz->halfchwidth; for(cc = 2 ;cc < dz->clength; cc++) dz->windowbuf[CHBOT][cc] = (float)(dz->windowbuf[CHBOT][cc-1] + dz->chwidth); return(FINISHED); } /***************************** ESTABLISH_TESTTONE_AMPS *************************/ int establish_testtone_amps(dataptr dz) { int n; if((dz->windowbuf[TESTPAMP] = (float *)realloc((char *)dz->windowbuf[TESTPAMP],PARTIALS_IN_TEST_TONE * sizeof(float)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY for testtone amp array.\n"); return(MEMORY_ERROR); } if((dz->windowbuf[TOTPAMP] = (float *)realloc((char *)dz->windowbuf[TOTPAMP],PARTIALS_IN_TEST_TONE * sizeof(float)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY for testtone totalamp array.\n"); return(MEMORY_ERROR); } dz->windowbuf[TOTPAMP][0] = dz->windowbuf[TESTPAMP][0] = 1.0f; for(n = 1; n < PARTIALS_IN_TEST_TONE; n++) /* ACTUAL PARTIAL AMPS */ dz->windowbuf[TESTPAMP][n] = (float)(dz->windowbuf[TESTPAMP][n-1] * PARTIAL_DECIMATION); for(n = 1; n < PARTIALS_IN_TEST_TONE; n++) /* SUM OF PARTIAL AMPS */ dz->windowbuf[TOTPAMP][n] = (float)(dz->windowbuf[TOTPAMP][n-1] + dz->windowbuf[TESTPAMP][n]); return(FINISHED); } /************************** SETUP_RING ******************************/ int setup_ring(dataptr dz) { chvptr /*last,*/ head; if((dz->ringhead = (chvptr)malloc(sizeof(struct chanval)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY for ring buffer.\n"); return(MEMORY_ERROR); } head = dz->ringhead; head->next = head; /* Initialise its pointers to self-point */ head->last = head; // last = head; /* Mark current end of ring at ringhead */ dz->ringsize = 1; return(FINISHED); } /************ SETUP_INTERNAL_BITFLAGS *************/ int setup_internal_bitflags(int bflag_array_no,int longpow,int divmask, dataptr dz) { int exit_status; if((exit_status = log2_of_the_number_which_is_a_power_of_2(&(dz->iparam[longpow]),sizeof(int) * CHARBITSIZE))<0) return(exit_status); /* sizeof(int) in bytes as pow of 2 */ dz->iparam[divmask] = (int)(two_to_the_power_of(dz->iparam[longpow]) - 1); /* mask to calc MOD(longpow2) */ return init_bitflags_to_zero(bflag_array_no,dz); /* Create and set-to-zero bitflags */ } /********** LOG2_OF_THE_NUMBER_WHICH_IS_A_POWER_OF_2 *********/ int log2_of_the_number_which_is_a_power_of_2(int *n,int k) { int mask = 1; int m = 0; if(k < 0) { sprintf(errstr,"-ve number submiited to log2_of_the_number_which_is_a_power_of_2()\n"); return(PROGRAM_ERROR); } while(!(mask & k)) { mask <<= 1; m++; } *n = m; return(FINISHED); } /*********************** TWO_TO_THE_POWER_OF ********************** * * Find 2-to-power-of-k. */ int two_to_the_power_of(int k) { int n = 1; n <<= k; return(n); } /***************************** INIT_BITFLAGS_TO_ZERO ***************************/ int init_bitflags_to_zero(int bflag_array_no,dataptr dz) { int n; int flgsize = (dz->clength/(sizeof(int) * CHARBITSIZE)) + 1; if((dz->lparray[bflag_array_no] = (int *)malloc(flgsize * sizeof(int)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY for bitflags.\n"); return(MEMORY_ERROR); } for(n=0;nlparray[bflag_array_no][n] = 0; return(FINISHED); } /****************************** SETUP_STABILITY_ARRAYS_AND_CONSTANTS **************/ int setup_stability_arrays_and_constants(int stability_val,int sval_less_one,dataptr dz) { int n; if((dz->stable = (stabptr)malloc(sizeof(struct stability)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY for stability array.\n"); return(MEMORY_ERROR); } if(dz->wlength < dz->iparam[stability_val]) { sprintf(errstr,"File too short to use this program option.\nTry smaller value with '-s' (stability) flag.\n"); return(DATA_ERROR); } dz->stable->offset = dz->iparam[stability_val]/2; /* stabl is always ODD : gives middle window of windows buffer */ if((dz->stable->sbufstore = (float *)malloc(((dz->wanted*dz->iparam[stability_val])+1) * sizeof(float)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY for stability buffer store.\n"); return(MEMORY_ERROR); } /* baktraking windows buf */ if((dz->stable->sbuf = (float **)malloc((dz->iparam[stability_val]+1) * sizeof(float *)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY for stability backtracking buffer.\n"); return(MEMORY_ERROR); } /* ptrs to wndws within it */ dz->stable->sbuf[0] = dz->stable->sbufstore; for(n=1;niparam[stability_val]+1;n++) dz->stable->sbuf[n] = dz->stable->sbuf[n-1] + dz->wanted; if((dz->stable->specstore = (float *)malloc(((dz->infile->specenvcnt * dz->iparam[stability_val])+1) * sizeof(float)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY for stability spectral store.\n"); return(MEMORY_ERROR); } if((dz->stable->spec = (float **)malloc((dz->iparam[stability_val]+1) * sizeof(float*)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY for stability spectrum store.\n"); return(MEMORY_ERROR); } dz->stable->spec[0] = dz->stable->specstore; for(n=1;niparam[stability_val]+1;n++) dz->stable->spec[n] = dz->stable->spec[n-1] + dz->infile->specenvcnt; if((dz->stable->fpkstore = (int *)malloc(((dz->iparam[stability_val] * dz->infile->specenvcnt)+1)*sizeof(int)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY for stability peaks store.\n"); return(MEMORY_ERROR); } /* baktraking spectral-peaks buf */ if((dz->stable->fpk = (int **)malloc((dz->iparam[stability_val]+1) * sizeof(int *)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY for stability peaks backtrack store.\n"); return(MEMORY_ERROR); } /* pointers to peakstores within it */ dz->stable->fpk[0] = dz->stable->fpkstore; for(n=1;niparam[stability_val]+1;n++) dz->stable->fpk[n] = dz->stable->fpk[n-1] + dz->infile->specenvcnt; if((dz->stable->total_pkcnt = (int *)malloc((dz->iparam[stability_val]+1) * sizeof(int)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY for stability peakcount store.\n"); return(MEMORY_ERROR); } /* cnt of total peaks found per baktrak buf */ if((dz->stable->design_score = (int *)malloc((dz->infile->specenvcnt+1) * sizeof(int)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY for stability design score store.\n"); return(MEMORY_ERROR); } /* array for designing filter */ if((dz->stable->des = (desptr *)malloc((dz->infile->specenvcnt+1) * sizeof(desptr)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY for stability design store.\n"); return(MEMORY_ERROR); } dz->iparam[sval_less_one] = dz->iparam[stability_val]- 1; /* SET SAFETY VALUES */ dz->stable->specstore[dz->infile->specenvcnt * dz->iparam[stability_val]] = 0.0f; dz->stable->spec[dz->iparam[stability_val]] = (float *)0; dz->stable->fpkstore[dz->iparam[stability_val] * dz->infile->specenvcnt] = 0; dz->stable->fpk[dz->iparam[stability_val]] = (int *)0; dz->stable->total_pkcnt[dz->iparam[stability_val]] = 0; dz->stable->design_score[dz->infile->specenvcnt] = 0; /* array for designing filter */ dz->stable->des[dz->infile->specenvcnt] = (desptr)0; dz->stable->sbufstore[dz->wanted * dz->iparam[stability_val]] = 0.0f; dz->stable->sbuf[dz->iparam[stability_val]] = 0; return(FINISHED); } /******************************************************************************/ /************************* FORMERLY IN procgrou.c *****************************/ /******************************************************************************/ /***************************** ZERO_SOUND_BUFFERS **************************/ int zero_sound_buffers(dataptr dz) { int n; for(n=0;nbufcnt;n++) memset((char *)dz->sampbuf[n],0,(size_t)(dz->buflen * sizeof(float))); return(FINISHED); } /******************************************************************************/ /************************* FORMERLY IN procspec.c *****************************/ /******************************************************************************/ /***************************** RECTIFY_WINDOW ******************************/ void rectify_window(float *flbuf,dataptr dz) { int vc; for(vc = 0; vc < dz->wanted; vc += 2) { if(flbuf[FREQ] < 0.0) { flbuf[FREQ] = -flbuf[FREQ]; // FEB 2010 TW // if(dz->is_rectified==FALSE) { // fprintf(stdout,"WARNING: Negative frq(s) in source data: rectified.\n"); // fflush(stdout); // dz->is_rectified = TRUE; // } } } } /**************************** OUTER_LOOP ****************************/ int outer_loop(dataptr dz) { int exit_status; int samps_read, got, windows_in_buf,peakscore = 0, pitchcnt = 0; int in_start_portion = TRUE, least = 0, descnt = 0; dz->time = 0.0f; if(dz->bptrcnt <= 0) { sprintf(errstr,"flbufptr[0] not established by outer_loop()\n"); return(PROGRAM_ERROR); } while((samps_read = fgetfbufEx(dz->bigfbuf, dz->buflen,dz->ifd[0],0)) > 0) { got = samps_read; dz->flbufptr[0] = dz->bigfbuf; windows_in_buf = got/dz->wanted; if((exit_status = inner_loop(&peakscore,&descnt,&in_start_portion,&least,&pitchcnt,windows_in_buf,dz))<0) return(exit_status); if((exit_status = write_exact_samps(dz->bigfbuf,samps_read,dz))<0) return(exit_status); } if(samps_read < 0) { sprintf(errstr,"Sound read error.\n"); return(SYSTEM_ERROR); } return(FINISHED); } /*********************** INITIALISE_WINDOW_FRQS ********************** * * Give start values for channel frqs in zero-amp 1st window. */ int initialise_window_frqs(dataptr dz) { int cc, vc; double thisfrq = GLIS_REFERENCE_FRQ; if(dz->mode!=SELFGLIS) { do { cc = (int)((thisfrq + dz->halfchwidth)/dz->chwidth); /* TRUNCATE */ vc = cc * 2; dz->flbufptr[0][FREQ] = (float)thisfrq; thisfrq += dz->chwidth; } while (thisfrq < dz->nyquist); } return(FINISHED); } /******************************** GET_AMP_AND_FRQ ******************************/ int get_amp_and_frq(float *floatbuf,dataptr dz) { int cc, vc; for( cc = 0 ,vc = 0; cc < dz->clength; cc++, vc += 2){ dz->amp[cc] = floatbuf[AMPP]; dz->freq[cc] = floatbuf[FREQ]; } return(FINISHED); } /******************************** PUT_AMP_AND_FRQ ******************************/ int put_amp_and_frq(float *floatbuf,dataptr dz) { int cc, vc; for(cc = 0, vc = 0; cc < dz->clength; cc++, vc += 2){ floatbuf[AMPP] = dz->amp[cc]; floatbuf[FREQ] = dz->freq[cc]; } return(FINISHED); } /**************************** NORMALISE ***************************/ int normalise(double pre_totalamp,double post_totalamp,dataptr dz) { double normaliser; int vc; if(post_totalamp < VERY_TINY_VAL) { if(!dz->zeroset) { fprintf(stdout,"WARNING: Zero-amp spectral window(s) encountered: orig window(s) substituted.\n"); fflush(stdout); dz->zeroset = TRUE; } } else { normaliser = pre_totalamp/post_totalamp; /* REMOVED a multiplier of 0.5 : APRIL 1998 */ for(vc = 0; vc < dz->wanted; vc += 2) dz->flbufptr[0][AMPP] = (float)(dz->flbufptr[0][AMPP] * normaliser); } return(FINISHED); } /*************************** INITIALISE_RING_VALS ***************************/ int initialise_ring_vals(int thissize,double initial_amp,dataptr dz) { int exit_status; chvptr tthis; int change_in_size; if((change_in_size = thissize - dz->ringsize)!=0) { if(change_in_size>0) { if((exit_status = extend_ring(change_in_size,dz))<0) /* If ring gets bigger, extend it */ return(exit_status); } else { if((exit_status = shrink_ring(-change_in_size,dz))<0) /* If ring gets smaller, shrink it */ return(exit_status); } } tthis = dz->ringhead; do { /* Enter initval at all ring locations */ tthis->val = (float)initial_amp; } while ((tthis = tthis->next) != dz->ringhead); dz->ringsize = thissize; return(FINISHED); } /************************* EXTEND_RING *****************************/ int extend_ring(int change_in_size,dataptr dz) { int n; chvptr tthis, head, last; head = dz->ringhead; last = head->last; /* Mark current end of ring */ for(n=0;nnext = tthis; /* Connect new location to end of ring */ tthis->last = last; tthis->next = head;/* Connect new location to start of ring */ head->last = tthis; last = tthis; /* Mark curent end of ring */ } return(FINISHED); } /************************* SHRINK_RING *****************************/ int shrink_ring(int change_in_size,dataptr dz) { int n; chvptr tthat, head, tthis; head = dz->ringhead; tthis = head->last; for(n=0;nlast; /* Find new end of ring */ tthat = tthis->next; /* Point to start of redundant items */ while(tthat!=head) { tthat = tthat->next; /* Delete redundant items */ free(tthat->last); } tthis->next = head; /* Connect new-end-of-ring to ringhead */ head->last = tthis; return(FINISHED); } /************************** IF_ONE_OF_LOUDEST_CHANS_STORE_IN_RING *****************************/ int if_one_of_loudest_chans_store_in_ring(int vc,dataptr dz) { int exit_status; chvptr loudest = dz->ringhead; do { /* COMPARE LOUDNESS WITH THOSE IN RING */ if(dz->flbufptr[0][vc] > loudest->val) { /* IF LOUDER */ if((exit_status = rearrange_ring_to_allow_new_entry_and_return_entry_address(&loudest,dz))<0) return(exit_status); loudest->loc = vc; loudest->val = dz->flbufptr[0][vc]; break; } } while((loudest = loudest->next)!=dz->ringhead); return(FINISHED); } /************************** IF_ONE_OF_QUIETEST_CHANS_STORE_IN_RING *****************************/ int if_one_of_quietest_chans_store_in_ring(int vc,dataptr dz) { int exit_status; chvptr quietest = dz->ringhead; do { /* COMPARE QUIETNESS WITH THOSE IN RING */ if(dz->flbufptr[0][vc] < quietest->val) { /* IF QUIETER */ if((exit_status = rearrange_ring_to_allow_new_entry_and_return_entry_address(&quietest,dz))<0) return(exit_status); quietest->loc = vc; quietest->val = dz->flbufptr[0][vc]; break; } } while((quietest = quietest->next)!=dz->ringhead); return(FINISHED); } /**************** REARRANGE_RING_TO_ALLOW_NEW_ENTRY_AND_RETURN_ENTRY_ADDRESS ************* * * Shuffle the items in the list of loudest/quietest chans. */ int rearrange_ring_to_allow_new_entry_and_return_entry_address(chvptr *here,dataptr dz) { chvptr head = dz->ringhead; chvptr this, prethis, prehere; if(*here == head->last) /* If place of insertion is lastplace in ring */ return(FINISHED); /* Final item in ring just gets written over. */ if(*here==head) { /* IF place of insertion is start of ring.... */ dz->ringhead = head->last; /* Move head of ring back one place. */ *here = dz->ringhead; /* New value will be written there, */ return(FINISHED); } /* automatically deleting previous final item in ring. */ this = head->last; /* OTHERWISE: unlink last item from ring */ prethis = this->last; head->last = prethis; prethis->next = head; prehere = (*here)->last;/* Reuse adr-space ('this') by splicing */ this->last = prehere; /* it into ring at current position (here) */ prehere->next = this; this->next = *here; (*here)->last = this; *here = this; /* Return address of new current position ('this') */ return(FINISHED); } /****************************** CHOOSE_BITFLAG_AND_RESET_MASK_IF_NESS ****************************/ int choose_bflagno_and_reset_mask_if_ness(int *bflagno,int cc,int *mask,int longpow2,int divmask) { *bflagno = cc >> longpow2; /* bflagno chooses which bitflag */ if(!(cc & divmask)) /* If cc divisible by bitflag length */ *mask = 1; /* reset bitmask to 1, for next bitflag */ return(FINISHED); } /******************* MOVE_DATA_INTO_APPROPRIATE_CHANNEL ***************** * * If there turns out to be more than one partial to a channel, * keep partial that was loudest in orig sound, retaining its * loudness for further comparison. */ int move_data_into_appropriate_channel(int vc,int truevc,float thisamp,float thisfrq,dataptr dz) { if(dz->flbufptr[0][AMPP] > dz->windowbuf[0][truevc]) { dz->windowbuf[0][truevc++] = thisamp; dz->windowbuf[0][truevc] = thisfrq; } return(FINISHED); } /******************* MOVE_DATA_INTO_SOME_APPROPRIATE_CHANNEL ***************** * * On assumption that frq does NOT have to be in exact channel!! * Replace simpler idea....above.... * which tends to see several significant pieces of data disappear * as they overwrite one another in the same channel... BY .... * * (1) Put in correct empty channel IF POSSIBLE * (2) ELSE Put in an adj empty chan * (3) below * (4) ELSE above * (5) ELSE Replace val in true chan * (6) ELSE Replace val in adj chan * (7) below * (8) ELSE above * */ int move_data_into_some_appropriate_channel(int truevc,float thisamp,float thisfrq,dataptr dz) { #define THISCHANSCAN (4) int minscan, maxscan, n; if(dz->windowbuf[0][truevc] == 0.0f) { /* 1 */ dz->windowbuf[0][truevc++] = thisamp; dz->windowbuf[0][truevc] = thisfrq; return(FINISHED); } minscan = max(0,truevc - (THISCHANSCAN * 2)); /* 2 */ maxscan = min(dz->clength-1,truevc + (THISCHANSCAN * 2)); /* 3 */ for(n=truevc-2;n>minscan;n-=2) { if(dz->windowbuf[0][n] == 0.0f) { dz->windowbuf[0][n++] = thisamp; dz->windowbuf[0][n] = thisfrq; return(FINISHED); } } for(n=truevc+2;nwindowbuf[0][n] == 0.0f) { dz->windowbuf[0][n++] = thisamp; dz->windowbuf[0][n] = thisfrq; return(FINISHED); } } if(thisamp > dz->flbufptr[0][truevc]) { /* 5 */ dz->windowbuf[0][truevc++] = thisamp; dz->windowbuf[0][truevc] = thisfrq; return(FINISHED); } for(n=truevc-2;n>minscan;n-=2) { /* 6 */ if(thisamp > dz->windowbuf[0][n]) { /* 7 */ dz->windowbuf[0][n++] = thisamp; dz->windowbuf[0][n] = thisfrq; return(FINISHED); } } for(n=truevc+2;n dz->windowbuf[0][n]) { dz->windowbuf[0][n++] = thisamp; dz->windowbuf[0][n] = thisfrq; return(FINISHED); } } return(FINISHED); } /******************** GET_AMP ********************/ int get_amp(float *floatbuf,dataptr dz) { int cc, vc; for(cc = 0, vc = 0; cc < dz->clength; cc++, vc += 2) dz->amp[cc] = floatbuf[vc]; return(FINISHED); } /******************** PUT_AMP ********************/ int put_amp(float *floatbuf,dataptr dz) { int cc, vc; for(cc = 0, vc = 0; cc < dz->clength; cc++, vc += 2) floatbuf[vc] = dz->amp[cc]; return(FINISHED); } /*************************** ADVANCE_ONE_2FILEINPUT_WINDOW ***********************/ int advance_one_2fileinput_window(dataptr dz) { dz->flbufptr[0] += dz->wanted; dz->flbufptr[1] += dz->wanted; dz->total_windows++; dz->time = (float)(dz->time + dz->frametime); return(FINISHED); } /***************************** SPECBARE *********************************/ int specbare(int *pitchcnt,dataptr dz) { int exit_status; double error_range = SPAN_FACTOR * SEMITONE_INTERVAL; /* +or- error in finding pitch of partial */ double pitch; double thisfrq /* = pitch */, frq_close_above_next_partial, frq_close_below_next_partial; int n = 0; int vc = 0; double one_over_error_range = 1.0/error_range; double upper_freqdiff,lower_freqdiff; pitch = dz->pitches[(*pitchcnt)++]; if(pitch < 0.0) /* UNPITCHED WINDOW : marked in specpich */ return(FINISHED); upper_freqdiff = (pitch * error_range) - pitch; lower_freqdiff = pitch - (pitch * one_over_error_range); while(vc < dz->wanted && (thisfrq = pitch * (double)++n) < dz->nyquist) { frq_close_above_next_partial = thisfrq + upper_freqdiff; frq_close_below_next_partial = thisfrq - lower_freqdiff; if((exit_status = zero_channels_between_partials(&vc,frq_close_below_next_partial,dz))<0) return(exit_status); if(vc >= dz->wanted) break; if(dz->flbufptr[0][FREQ]>frq_close_above_next_partial) continue; else if(dz->vflag[BARE_LESS_BODY]) { if((exit_status = eliminate_all_but_loudest_channel_near_this_partial_frq (&vc,frq_close_above_next_partial,dz))<0) return(exit_status); } else { if((exit_status = keep_all_channels_near_partial_frq(&vc,frq_close_above_next_partial,dz))<0) return(exit_status); } } return(FINISHED); } /************** ZERO_CHANNELS_BETWEEN_PARTIALS ****************/ int zero_channels_between_partials(int *vvc,double frq_close_below_next_partial,dataptr dz) { int vc = *vvc; while(dz->flbufptr[0][FREQ] < frq_close_below_next_partial) { dz->flbufptr[0][AMPP] = 0.0f; if((vc += 2) >= dz->wanted) break; } *vvc = vc; return(FINISHED); } /******** ELIMINATE_ALL_BUT_LOUDEST_CHANNEL_NEAR_THIS_PARTIAL_FRQ *********/ int eliminate_all_but_loudest_channel_near_this_partial_frq(int *vvc,double frq_close_above_next_partial,dataptr dz) { int vc = *vvc; double maxamp = dz->flbufptr[0][AMPP]; /* SET MAXAMP TO 1ST IN-RANGE CH */ int k, maxloc = vc; /* NOTE NO. OF THE CH THUS MARKD */ int firstloc = vc; /* MARK FIRST CH IN SET */ while((vc += 2) < dz->wanted) { if(dz->flbufptr[0][FREQ]>frq_close_above_next_partial) /* IF BEYOND CURRENT RANGE, STOP */ break; if(dz->flbufptr[0][vc]>maxamp) { /* IF LOUDER THAN MAX,RESET MAX */ maxamp = dz->flbufptr[0][AMPP]; /* AND RESET MAXAMP CHANNEL NO. */ maxloc = vc; } } for(k=firstloc; kflbufptr[0][k] = 0.0f; } *vvc = vc; return(FINISHED); } /*********************** KEEP_ALL_CHANNELS_NEAR_PARTIAL_FRQ ******************/ int keep_all_channels_near_partial_frq(int *vvc,double frq_close_above_next_partial,dataptr dz) { int vc = *vvc; while((vc += 2) < dz->wanted) { if(dz->flbufptr[0][FREQ]>frq_close_above_next_partial) /* IF BEYOND CURRENT RANGE, STOP */ break; } *vvc = vc; return(FINISHED); } /****************************** GEN_AMPLITUDE_IN_LO_HALF_FILTERBAND ***************************/ int gen_amplitude_in_lo_half_filterband(double *thisamp,double thisfrq,double filt_centre_frq,dataptr dz) { double val; val = -LOG2(thisfrq/filt_centre_frq); /* octave distance from filter centre-frq */ val *= dz->scalefact; /* convert to a fraction of halfbwidth (range 0-1) & convert to range 0-PI */ val = cos(val); /* get cos val between 1 & -1 */ val += 1.0; /* convert range to 2 -> 0 */ val /= 2.0; /* convert range to 1 -> 0 */ *thisamp = val; return(FINISHED); } /****************************** GEN_AMPLITUDE_IN_HI_HALF_FILTERBAND ***************************/ int gen_amplitude_in_hi_half_filterband(double *thisamp,double thisfrq,double filt_centre_frq,dataptr dz) { double val; val = LOG2(thisfrq/filt_centre_frq); /* octave distance from filter centre-frq */ val *= dz->scalefact; /* convert to a fraction of halfbwidth (range 0-1) & convert to range 0-PI */ val = cos(val); /* get cos val between 1 & -1 */ val += 1.0; /* convert range to 2 -> 0 */ val /= 2.0; /* convert range to 1 -> 0 */ *thisamp = val; return(FINISHED); } /****************************** FILTER_BAND_TEST *************************** * * CHeck that filter values are within range - and that there ARE values there!!! */ int filter_band_test(dataptr dz) { int OK = 0, cc; for(cc=0;ccclength;cc++) { if(dz->fsampbuf[cc]>1.0 || dz->fsampbuf[cc]<0.0) { sprintf(errstr,"filter contour out of range. (item[%d] = %f): filter_band_test()\n",cc,dz->fsampbuf[cc]); return(PROGRAM_ERROR); } if(dz->fsampbuf[cc] > 0.0) OK = 1; } if(!OK && !dz->fzeroset) { fprintf(stdout,"WARNING: ZERO filter contour at window %d time %lf\n", dz->total_windows+1,dz->total_windows * dz->frametime); fflush(stdout); dz->fzeroset = TRUE; } else dz->fzeroset = FALSE; return(FINISHED); } /************************** GET_STATECHANGES ************************/ int get_statechanges(int avcnt,int scantableno,int avpitcharrayno,int statechangearrayno, double min_up_interval,double min_dn_interval,int datatype,dataptr dz) { #define RISING (1) #define FALLING (2) #define ONLEVEL (3) int exit_status; int n, window_cnt, pblok; double ttime = 0.0, intvl = 0.0; int *bbrk; if((bbrk = (int *)malloc(avcnt * sizeof(int)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY for statechange array.\n"); return(MEMORY_ERROR); } memset((char *)bbrk,0,avcnt * sizeof(int)); if(dz->brksize[scantableno]) { if((exit_status = read_value_from_brktable(ttime,scantableno,dz))<0) return(exit_status); } window_cnt = round(dz->param[scantableno]/dz->frametime); if((pblok = round(window_cnt/BLOKCNT))<2) { sprintf(errstr,"scanning-contour time_scale too short for this data.\n"); return(DATA_ERROR); } if(pblok >= avcnt) { sprintf(errstr,"scanning-contour time_scale too long for this data.\n"); return(DATA_ERROR); } for(n=pblok;nparray[avpitcharrayno][n] - dz->parray[avpitcharrayno][n-pblok]; break; case(IS_FRQ): intvl = dz->parray[avpitcharrayno][n]/dz->parray[avpitcharrayno][n-pblok]; break; } if(intvl > min_up_interval) bbrk[n] = RISING; else if(intvl < min_dn_interval) bbrk[n] = FALLING; else bbrk[n] = ONLEVEL; if(dz->brksize[scantableno]) { /* move along by an (averaged) BLOK of windows */ ttime += dz->frametime * BLOKCNT; if((exit_status = read_value_from_brktable(ttime,scantableno,dz))<0) return(exit_status); window_cnt = round(dz->param[scantableno]/dz->frametime); if((pblok = round(window_cnt/BLOKCNT))<2) { sprintf(errstr,"scanning-contour time_scale too short for this data.\n"); return(DATA_ERROR); } } } n = 0; /* Set types at very start, equal to actual first type already set */ while(!bbrk[n]) { if(++n >= avcnt) break; } if(n=0) { bbrk[n] = bbrk[n+1]; if(--n < 0) break; } } memset(dz->iparray[statechangearrayno],0,avcnt * sizeof(int)); dz->iparray[statechangearrayno][0] = 1; /* initial state change */ for(n=1;niparray[statechangearrayno][n] = 1; } free(bbrk); return(FINISHED); } /**************************** RECTIFY_FRQS ****************************/ int rectify_frqs(float *floatbuf,dataptr dz) { int vc; for(vc = 0; vc < dz->wanted; vc += 2) { if(floatbuf[FREQ] < 0.0f) floatbuf[FREQ] = (float)(-(floatbuf[FREQ])); } return(FINISHED); } /******************************* MOVE_ALONG_FORMANT_BUFFER ************************/ int move_along_formant_buffer(dataptr dz) { int samps_read; if((dz->flbufptr[1] += dz->infile->specenvcnt) >= dz->flbufptr[3]) { if((samps_read = fgetfbufEx(dz->flbufptr[2],dz->buflen2,dz->ifd[1],0))<0) { sprintf(errstr,"fgetfbufEx failure, move_along_formant_buffer()\n"); return(SYSTEM_ERROR); } if(samps_read <= 0) return(FINISHED); dz->flbufptr[1] = dz->flbufptr[2]; } return(CONTINUE); } /*************************** GET_LONGER_FILE ***********************/ int get_longer_file(dataptr dz) { int file_to_keep = 1; if(dz->insams[0] < dz->insams[1]) /* allows larger infile2 to be copied after infile1 finished */ file_to_keep = 2; return(file_to_keep); } /*************************** READ_BOTH_FILES ***********************/ int read_both_files(int *windows_in_buf,int *got,dataptr dz) { int samps_read, samps_read2; memset((char *)dz->bigfbuf,0,dz->buflen * sizeof(float)); if((samps_read = fgetfbufEx(dz->bigfbuf, dz->buflen,dz->ifd[0],0)) < 0) { sprintf(errstr,"Failed to read data from first file.\n"); return(SYSTEM_ERROR); } memset((char *)dz->flbufptr[2],0,dz->buflen* sizeof(float)); if((samps_read2 = fgetfbufEx(dz->flbufptr[2], dz->buflen,dz->ifd[1],0)) < 0) { sprintf(errstr,"Failed to read data from second file.\n"); return(SYSTEM_ERROR); } *got = max(samps_read,samps_read2); dz->flbufptr[0] = dz->bigfbuf; dz->flbufptr[1] = dz->flbufptr[2]; *windows_in_buf = *got/dz->wanted; return(FINISHED); } /*************************** KEEP_EXCESS_BYTES_FROM_CORRECT_FILE ***********************/ #ifdef NOTDEF int keep_excess_bytes_from_correct_file(int *bytes_to_write,int file_to_keep,int got,int wc,dataptr dz) { int floats_to_keep = got - ((wc+1) * dz->wanted); if(file_to_keep) { if(file_to_keep==2 && floats_to_keep > 0) memmove((char *)dz->flbufptr[0],(char *)dz->flbufptr[1],floats_to_keep * sizeof(float)); dz->flbufptr[0] += floats_to_keep; } *bytes_to_write = (dz->flbufptr[0] - dz->bigfbuf) * sizeof(float); return(FINISHED); } #else /*************************** KEEP_EXCESS_SAMPS_FROM_CORRECT_FILE ***********************/ int keep_excess_samps_from_correct_file(int *samps_to_write,int file_to_keep,int got,int wc,dataptr dz) { int floats_to_keep = got - ((wc+1) * dz->wanted); if(file_to_keep) { if(file_to_keep==2 && floats_to_keep > 0) memmove((char *)dz->flbufptr[0],(char *)dz->flbufptr[1],floats_to_keep * sizeof(float)); dz->flbufptr[0] += floats_to_keep; } //TW CORRECTED // *samps_to_write = (dz->flbufptr[0] - dz->bigfbuf) * sizeof(float); *samps_to_write = dz->flbufptr[0] - dz->bigfbuf; return(FINISHED); } #endif /*************************** READ_EITHER_FILE ***********************/ int read_either_file(int *samps_read,int file_to_keep,dataptr dz) { if(file_to_keep==2) { if((*samps_read = fgetfbufEx(dz->bigfbuf, dz->buflen,dz->ifd[1],0))<0) { sprintf(errstr,"Failed to read samples from file 2\n"); return(SYSTEM_ERROR); } } else { if((*samps_read = fgetfbufEx(dz->bigfbuf, dz->buflen,dz->ifd[0],0))<0) { sprintf(errstr,"Failed to read samples from file 1\n"); return(SYSTEM_ERROR); } } return(FINISHED); } /****************************** SCORE_PEAKS ******************************/ int score_peaks(int *peakscore,int sl1_var,int stabl_var,dataptr dz) { int n, m; if(dz->total_windows>dz->iparam[sl1_var]) { for(n = 0;n < dz->stable->total_pkcnt[dz->iparam[sl1_var]]; n++) { /* Add in the peaks in the last buf calcd */ dz->stable->design_score[dz->stable->fpk[dz->iparam[sl1_var]][n]]++; /* to the existing scores!! */ (*peakscore)++; } } else { for(m=0;miparam[stabl_var];m++) { /* For every stored array of peaks */ for(n = 0;n < dz->stable->total_pkcnt[m]; n++) { /* For every peak within that store */ dz->stable->design_score[dz->stable->fpk[m][n]]++; /* Score a point for each occurence of a specenvchan */ (*peakscore)++; /* Check to see if there are ANY peaks at all */ } } } return(FINISHED); } /****************************** COLLECT_SCORES ****************************** * * If any channel is used as a peak (score > 0),store channel-no and score * in a design_struct, and preset the amp_total to zero (see amplitude_poll). * Count the total number of such peaks. */ int collect_scores(int *cnt,int *descnt,dataptr dz) { int n; *cnt = 0; for(n=0;ninfile->specenvcnt;n++) { if(dz->stable->design_score[n]) { if(*cnt >= *descnt) { /* If this number of design_structs don't exist, make another */ if((dz->stable->des[*cnt] = (desptr)malloc(sizeof(struct design)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY for scoring array.\n"); return(MEMORY_ERROR); } (*descnt)++; } dz->stable->des[*cnt]->chan = n; dz->stable->des[*cnt]->score = dz->stable->design_score[n]; dz->stable->des[*cnt]->amp = 0.0; (*cnt)++; } } return(FINISHED); } /****************************** SORT_DESIGN *************************** * * Sort peak channels into descending order ofabundance */ int sort_design(int no_of_design_elements,dataptr dz) { int n, m, a, b; for(n=1;nstable->des[n]->chan; b = dz->stable->des[n]->score; m = n-1; while(m >= 0 && dz->stable->des[m]->score < b) { dz->stable->des[m+1]->chan = dz->stable->des[m]->chan; dz->stable->des[m+1]->score = dz->stable->des[m]->score; m--; } dz->stable->des[m+1]->chan = a; dz->stable->des[m+1]->score = b; } return(FINISHED); } /****************************** SORT_EQUIVALENT_SCORES ****************************** * * For channels with equivalent scores. Find the bottom and top of the range of * channels with equivalent scores. Save those below the bottom of the range as * acceptable peaks (they have higher scores than those in the range). * For the rest, select those channels having the maximum amplitude over the * whole timespan of the stabilise buffers. */ int sort_equivalent_scores(int this_pkcnt,dataptr dz) { int bot, top, n; if(dz->stable->des[dz->itemcnt-1]->score < dz->stable->des[dz->itemcnt]->score) { sprintf(errstr,"Problem in peak sorting: sort_equivalent_scores()\n"); return(PROGRAM_ERROR); } n = dz->itemcnt-1; while(n >= 0) { if(dz->stable->des[n]->score == dz->stable->des[dz->itemcnt]->score) n--; else break; } bot = n+1; n = dz->itemcnt+1; while(n stable->des[n]->score == dz->stable->des[dz->itemcnt]->score) n++; else break; } top = n; for(n=0;npeakno[n] = dz->stable->des[n]->chan; /* keep peaks that have definitely higher scores */ return do_amplitude_poll(bot,top,dz); } /****************************** DO_AMPLITUDE_POLL ***************************/ int do_amplitude_poll(int bot,int top,dataptr dz) { int n, m, here = 0, thischan; int nextpeak = bot; /* peaknumber of first of peaks still to allocate */ double thisamp, ampmax; for(n=bot;nstable->des[n]->chan; for(m=0;miparam[FOCU_STABL];m++) /* sum amplitudes in that chan across all specenv buffers */ dz->stable->des[n]->amp += dz->stable->spec[m][thischan]; /* and store in des-array assocd with channel */ } while(nextpeak < dz->itemcnt) { /* while there are still peaks to be chosen */ ampmax = 0.0; for(n=bot;nstable->des[n]->amp)>ampmax) { ampmax = thisamp; here = n; } } dz->peakno[nextpeak++] = dz->stable->des[here]->chan; /* Set next peak channel to this maxamp channel */ dz->stable->des[here]->amp = 0.0; /* zero amptotal in chosen des, to eliminate from next search */ } return(FINISHED); } /****************************** UNSCORE_PEAKS ******************************/ int unscore_peaks(int *peakscore,dataptr dz) { int n; for(n = 0;n < dz->stable->total_pkcnt[0]; n++) { /* Subtract score of peaks buffer no longer in use */ dz->stable->design_score[dz->stable->fpk[0][n]]--; /* from the existing scores!! */ (*peakscore)--; } return(FINISHED); } /******************************************************************************/ /************************* FORMERLY IN pconsistency.c *************************/ /******************************************************************************/ static void setup_pitchzero(int paramno,dataptr dz); /************************** HANDLE_PITCH_ZEROS ********************************/ void handle_pitch_zeros(dataptr dz) { switch(dz->process) { case(ARPE): setup_pitchzero(ARPE_LOFRQ,dz); setup_pitchzero(ARPE_HIFRQ,dz); break; case(CHORD): setup_pitchzero(CHORD_LOFRQ,dz); setup_pitchzero(CHORD_HIFRQ,dz); break; case(CLEAN): if(dz->mode==FILTERING) setup_pitchzero(CL_FRQ,dz); break; case(FOCUS): setup_pitchzero(FOCU_LOFRQ,dz); setup_pitchzero(FOCU_HIFRQ,dz); break; case(FOLD): setup_pitchzero(FOLD_LOFRQ,dz); setup_pitchzero(FOLD_HIFRQ,dz); break; case(FORM): setup_pitchzero(FORM_FTOP,dz); setup_pitchzero(FORM_FBOT,dz); break; case(MEAN): setup_pitchzero(MEAN_LOF,dz); setup_pitchzero(MEAN_HIF,dz); break; case(P_FIX): setup_pitchzero(PF_LOF,dz); setup_pitchzero(PF_HIF,dz); break; case(PEAK): setup_pitchzero(PEAK_CUTOFF,dz); break; case(REPORT): setup_pitchzero(REPORT_LOFRQ,dz); setup_pitchzero(REPORT_HIFRQ,dz); break; case(SHIFTP): setup_pitchzero(SHIFTP_FFRQ,dz); break; case(STRETCH): setup_pitchzero(STR_FFRQ,dz); break; case(S_TRACE): setup_pitchzero(TRAC_LOFRQ,dz); setup_pitchzero(TRAC_HIFRQ,dz); break; case(TRNSF): setup_pitchzero(TRNSF_HIFRQ,dz); setup_pitchzero(TRNSF_LOFRQ,dz); break; case(TRNSP): setup_pitchzero(TRNSP_HIFRQ,dz); setup_pitchzero(TRNSP_LOFRQ,dz); break; case(TUNE): setup_pitchzero(TUNE_BFRQ,dz); break; case(VOCODE): setup_pitchzero(VOCO_LOF,dz); setup_pitchzero(VOCO_HIF,dz); break; case(WAVER): setup_pitchzero(WAVER_LOFRQ,dz); break; } } /****************************** SETUP_PITCHZERO *******************************/ void setup_pitchzero(int paramno,dataptr dz) { double *p, *end; if(dz->brksize[paramno]) { p = dz->brk[paramno] + 1; end = dz->brk[paramno] + (dz->brksize[paramno] * 2); while(p < end) { if(*p < SPEC_MINFRQ) *p = SPEC_MINFRQ; p+=2; } } else if(dz->param[paramno] < SPEC_MINFRQ) dz->param[paramno] = 0.0; } /************************************ CHECK_DEPTH_VALS *************************************/ int check_depth_vals(int param_no,dataptr dz) { double *p; int n = 0; if(dz->brksize[param_no]==0) { if(flteq(dz->param[param_no],0.0)) { sprintf(errstr, "A non-varying depth value of zero will not change your source file.\n"); return(DATA_ERROR); } } else { p = dz->brk[param_no]+1; n = 0; while(n < dz->brksize[param_no]) { if(!flteq(*p,0.0)) return(FINISHED); p += 2; n++; } sprintf(errstr, "A non-varying depth value of zero will not change your source file.\n"); return(DATA_ERROR); } return(FINISHED); } /*********************** CONVERT_SHIFTP_VALS ***********************/ void convert_shiftp_vals(dataptr dz) { switch(dz->mode) { case(P_SHFT_UP_AND_DN): dz->param[SHIFTP_SHF1] *= OCTAVES_PER_SEMITONE; dz->param[SHIFTP_SHF1] = pow(2.0,dz->param[SHIFTP_SHF1]); dz->param[SHIFTP_SHF2] *= OCTAVES_PER_SEMITONE; dz->param[SHIFTP_SHF2] = pow(2.0,dz->param[SHIFTP_SHF2]); break; case(P_SHFT_DN): dz->param[SHIFTP_SHF1] *= OCTAVES_PER_SEMITONE; dz->param[SHIFTP_SHF1] = pow(2.0,dz->param[SHIFTP_SHF1]); break; case(P_SHFT_UP): dz->param[SHIFTP_SHF1] *= OCTAVES_PER_SEMITONE; dz->param[SHIFTP_SHF1] = pow(2.0,dz->param[SHIFTP_SHF1]); break; } } /******************************************************************************/ /************************* FORMERLY IN buffers.c ******************************/ /******************************************************************************/ /*************************** CREATE_SNDBUFS **************************/ /* 2009 MULTICHANNEL */ /* TW update Nov 2022, correct buflen for large anal chans */ int create_sndbufs(dataptr dz) { int n; size_t bigbufsize; int framesize; framesize = F_SECSIZE * dz->infile->channels; if(dz->sbufptr == 0 || dz->sampbuf==0) { sprintf(errstr,"buffer pointers not allocated: create_sndbufs()\n"); return(PROGRAM_ERROR); } bigbufsize = (size_t) Malloc(-1); bigbufsize /= dz->bufcnt; if(bigbufsize <=0) bigbufsize = framesize * sizeof(float); dz->buflen = (int)(bigbufsize / sizeof(float)); // NEW TW NOV 26 : 2022 --> if(dz->buflen < framesize) dz->buflen = framesize; else // <-- NEW TW NOV 26 : 2022 dz->buflen = (dz->buflen / framesize) * framesize; bigbufsize = dz->buflen * sizeof(float); if((dz->bigbuf = (float *)malloc(bigbufsize * dz->bufcnt)) == NULL) { sprintf(errstr,"INSUFFICIENT MEMORY to create sound buffers.\n"); return(PROGRAM_ERROR); } for(n=0;nbufcnt;n++) dz->sbufptr[n] = dz->sampbuf[n] = dz->bigbuf + (dz->buflen * n); dz->sampbuf[n] = dz->bigbuf + (dz->buflen * n); return(FINISHED); } /**************************** ALLOCATE_SINGLE_BUFFER ******************************/ //TW REVISED: buffers no longer multiples of secsize int allocate_single_buffer(dataptr dz) { // int bigbufsize; // int exit_status; unsigned int buffersize; if(dz->bptrcnt <= 0) { sprintf(errstr,"bufptr not established in allocate_single_buffer()\n"); return(PROGRAM_ERROR); } //TW // buffersize = dz->sampswanted * BUF_MULTIPLIER; buffersize = dz->wanted * BUF_MULTIPLIER; //TW MOVED THIS LINE: to get correct value of buflen (NOT after the +1) dz->buflen = buffersize; buffersize += 1; if((dz->bigfbuf = (float*) malloc(buffersize * sizeof(float)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY for sound buffers.\n"); return(MEMORY_ERROR); } dz->big_fsize = dz->buflen; dz->bigfbuf[dz->big_fsize] = 0.0f; /* safety value */ return(FINISHED); } /**************************** ALLOCATE_DOUBLE_BUFFER ******************************/ /* RWD MUST recheck this! */ int allocate_double_buffer(dataptr dz) { // int exit_status; unsigned int buffersize; if(dz->bptrcnt < 4) { sprintf(errstr,"Insufficient bufptrs established in allocate_double_buffer()\n"); return(PROGRAM_ERROR); } //TW REVISED: buffers don't need to be multiples of secsize buffersize = dz->wanted * BUF_MULTIPLIER; dz->buflen = buffersize; if((dz->bigfbuf = (float*)malloc(dz->buflen*2 * sizeof(float)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY for sound buffers.\n"); return(MEMORY_ERROR); } dz->big_fsize = dz->buflen; dz->flbufptr[2] = dz->bigfbuf + dz->big_fsize; dz->flbufptr[3] = dz->flbufptr[2] + dz->big_fsize; return(FINISHED); } /**************************** ALLOCATE_TRIPLE_BUFFER ******************************/ int allocate_triple_buffer(dataptr dz) { unsigned int buffersize; if(dz->bptrcnt < 5) { sprintf(errstr,"Insufficient bufptrs established in allocate_triple_buffer()\n"); return(PROGRAM_ERROR); } //TW REVISED: buffers don't need to be multiples of secsize buffersize = dz->wanted; dz->buflen = buffersize; if((dz->bigfbuf = (float*)malloc(dz->buflen*3 * sizeof(float)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY for sound buffers.\n"); return(MEMORY_ERROR); } dz->big_fsize = dz->buflen; dz->flbufptr[2] = dz->bigfbuf + dz->big_fsize; dz->flbufptr[3] = dz->flbufptr[2] + dz->big_fsize; dz->flbufptr[4] = dz->flbufptr[3] + dz->big_fsize; return(FINISHED); } /*************************** ALLOCATE_ANALDATA_PLUS_FORMANTDATA_BUFFER ****************************/ int allocate_analdata_plus_formantdata_buffer(dataptr dz) { int exit_status; unsigned int buffersize; /*int cnt = 0;*/ if(dz->bptrcnt < 4) { sprintf(errstr,"Insufficient bufptrs established in allocate_analdata_plus_formantdata_buffer()\n"); return(PROGRAM_ERROR); } if(dz->infile->specenvcnt==0) { sprintf(errstr,"specenvcnt not set: allocate_analdata_plus_formantdata_buffer()\n"); return(PROGRAM_ERROR); } if((exit_status = calculate_analdata_plus_formantdata_buffer(&buffersize,dz))<0) return(exit_status); if((dz->bigfbuf = (float*)malloc((size_t)buffersize * sizeof(float)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY for sound buffers.\n"); return(MEMORY_ERROR); } dz->big_fsize = /*dz->bigbufsize/sizeof(float);*/dz->buflen; dz->flbufptr[2] = dz->bigfbuf + dz->big_fsize; dz->flbufptr[3] = dz->flbufptr[2] + /*(dz->bigbufsize2/sizeof(float));*/ dz->buflen2; return(FINISHED); } /******************************* CALCULATE_ANALDATA_PLUS_FORMANTDATA_BUFFER **************************/ int calculate_analdata_plus_formantdata_buffer(unsigned int *buffersize,dataptr dz) { // int exit_status; int cnt = 0; unsigned int orig_buffersize = 0; dz->buflen2 = 0; //TW REVISED: no secsize-multiple restriction on buffers *buffersize = (dz->wanted + dz->infile->specenvcnt) * BUF_MULTIPLIER; while(dz->buflen2 < dz->descriptor_samps) { if(cnt == 0) orig_buffersize = *buffersize; else *buffersize += orig_buffersize; cnt++; dz->buflen = dz->wanted * BUF_MULTIPLIER * cnt; dz->buflen2 = dz->infile->specenvcnt * BUF_MULTIPLIER * cnt; } return(FINISHED); } /******************************* ALLOCATE_SINGLE_BUFFER_PLUS_EXTRA_POINTER **************************/ int allocate_single_buffer_plus_extra_pointer(dataptr dz) { int exit_status; if((exit_status = allocate_single_buffer(dz))<0) return(exit_status); if(dz->bptrcnt < 2) { sprintf(errstr,"dz->flbufptr[1] not established: allocate_larger_buffers()\n"); return(PROGRAM_ERROR); } dz->flbufptr[1] = dz->bigfbuf + dz->big_fsize; return(FINISHED); } /******************************************************************************/ /************************* FORMERLY IN cmdline.c *****************************/ /******************************************************************************/ /************************** GET_PROCESS_AND_MODE_FROM_CMDLINE *****************************/ int get_process_and_mode_from_cmdline(int *cmdlinecnt,char ***cmdline,dataptr dz) { int exit_status; if((exit_status = get_process_no((*cmdline)[0],dz))<0) return(exit_status); (*cmdline)++; (*cmdlinecnt)--; if((dz->maxmode = get_maxmode(dz->process))<0) return(PROGRAM_ERROR); if(dz->maxmode > 0) { if(*cmdlinecnt<=0) { sprintf(errstr,"Too few commandline parameters.\n"); return(USAGE_ONLY); } if((exit_status = get_mode_from_cmdline((*cmdline)[0],dz))<0) return(exit_status); (*cmdline)++; (*cmdlinecnt)--; } return(FINISHED); } /****************************** GET_MODE *********************************/ int get_mode_from_cmdline(char *str,dataptr dz) { if(sscanf(str,"%d",&dz->mode)!=1) { sprintf(errstr,"Cannot read mode of program.\n"); return(USAGE_ONLY); } if(dz->mode <= 0 || dz->mode > dz->maxmode) { sprintf(errstr,"Program mode value [%d] is out of range [1 - %d].\n",dz->mode,dz->maxmode); return(USAGE_ONLY); } dz->mode--; /* CHANGE TO INTERNAL REPRESENTATION OF MODE NO */ return(FINISHED); } /******************************************************************************/ /************************* FORMERLY IN usage.c ********************************/ /******************************************************************************/ /******************************** USAGE1 ********************************/ int usage(int argc,char *argv[]) { switch(argc) { case(1): return usage1(); case(2): return usage2(argv[1]); case(3): return usage3(argv[1],argv[2]); } sprintf(errstr,"Incorrect call to usage()\n"); return(PROGRAM_ERROR); } /******************************** USAGE1 ********************************/ //TW NEW CODE BELOW /******************************** GET_THE_VOWELS ********************************/ int get_the_vowels(char *filename,double **times,int **vowels,int *vcnt,dataptr dz) { FILE *fp; double *t, lasttime = 0.0, endtime; int *v, vv; int only_one_vowel = 0, non_zero_start = 0; int arraysize = BIGARRAY, n = 0; char temp[200], *q, *p; int istime; if((vv = get_vowel(filename))>=0) { if((*times = (double *)malloc(2 * sizeof(double)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY for time data.\n"); return(MEMORY_ERROR); } if((*vowels = (int *)malloc(2 * sizeof(int)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY for vowels data.\n"); return(MEMORY_ERROR); } (*times)[0] = 0.0; (*times)[1] = 0.0; (*vowels)[0] = vv; (*vowels)[1] = vv; return(FINISHED); } if((fp = fopen(filename,"r"))==NULL) { sprintf(errstr, "Can't open textfile %s to read vowel data.\n",filename); return(DATA_ERROR); } if((*times = (double *)malloc(arraysize * sizeof(double)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY for time data.\n"); return(MEMORY_ERROR); } if((*vowels = (int *)malloc(arraysize * sizeof(int)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY for vowels data.\n"); return(MEMORY_ERROR); } t = *times; v = *vowels; istime = 1; while(fgets(temp,200,fp)==temp) { q = temp; if(*q == ';') // Allow comments in file continue; while(get_word_from_string(&q,&p)) { if(istime) { if(sscanf(p,"%lf",t)!=1) { sprintf(errstr,"No time for time-vowel pair %d\n",n+1); return(DATA_ERROR); } if(n==0) { if(*t < 0.0) { sprintf(errstr,"First time is less than zero in vowel data\n"); return(DATA_ERROR); } else if(*t > 0.0) { print_outwarning_flush("FIRST TIME in vowel data IS NOT ZERO : assuming first vowel runs from time zero\n"); non_zero_start = 1; t++; *t = *(t-1); *(t-1) = 0.0; } } else { if (*t <= lasttime) { sprintf(errstr,"Times do not advance (from %lf to %lf at pair %d) in vowel data\n", lasttime,*t,n+1); return(DATA_ERROR); } } lasttime = *t++; } else { if((*v = get_vowel(p))<0) { sprintf(errstr,"Unrecognised vowel string %s at pair %d in vowel datafile\n",p,n+1); return(DATA_ERROR); } if((n==0) && non_zero_start) { v++; *v = *(v-1); n++; } v++; if(++n >= arraysize) { arraysize += BIGARRAY; if((*times = (double *)realloc((char *)(*times),arraysize * sizeof(double)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY to reallocate table of vowel-times.\n"); return(MEMORY_ERROR); } if((*vowels = (int *)realloc((char *)(*vowels),arraysize * sizeof(int)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY to reallocate table of vowels.\n"); return(MEMORY_ERROR); } t = *times + n; v = *vowels + n; } } istime = !istime; } } if(n == 0) { sprintf(errstr,"No data in vowel datafile %s\n",filename); return(DATA_ERROR); } if(!istime) { sprintf(errstr,"data in vowel datafile %s not paired correctly\n",filename); return(DATA_ERROR); } endtime = (dz->wlength + 1) * dz->frametime; if(n == 1) { only_one_vowel = 1; *t = endtime; *v = *(v-1); n = 2; } else { if(*(t-1) < endtime) { /* Force a time-value beyond end of infile */ *t = endtime; *v = *(v-1); n++; } } if((*times = (double *)realloc((char *)(*times),n * sizeof(double)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY to reallocate vowel-time table.\n"); return(MEMORY_ERROR); } if((*vowels = (int *)realloc((char *)(*vowels),n * sizeof(int)))==NULL) { sprintf(errstr,"INSUFFICIENT MEMORY to reallocate vowels table.\n"); return(MEMORY_ERROR); } if(fclose(fp)<0) { fprintf(stdout,"WARNING: Failed to close input textfile %s.\n",filename); fflush(stdout); } if(only_one_vowel) *vcnt = 0; else *vcnt = n; return(FINISHED); } /******************************** GET_VOWEL ********************************/ int get_vowel (char *str) { if (!strcmp(str,"ee")) return VOWEL_EE; else if(!strcmp(str,"i")) return VOWEL_I; else if(!strcmp(str,"ai")) return VOWEL_AI; else if(!strcmp(str,"aii")) return VOWEL_AII; else if(!strcmp(str,"e")) return VOWEL_E; else if(!strcmp(str,"a")) return VOWEL_A; else if(!strcmp(str,"ar")) return VOWEL_AR; else if(!strcmp(str,"o")) return VOWEL_O; else if(!strcmp(str,"oo")) return VOWEL_OO; else if(!strcmp(str,"oa")) return VOWEL_OA; else if(!strcmp(str,"or")) return VOWEL_OR; else if(!strcmp(str,"u")) return VOWEL_U; else if(!strcmp(str,"ui")) return VOWEL_UI; else if(!strcmp(str,"uu")) return VOWEL_UU; else if(!strcmp(str,"xx")) return VOWEL_XX; else if(!strcmp(str,"x")) return VOWEL_X; else if(!strcmp(str,"n")) return VOWEL_N; else if(!strcmp(str,"m")) return VOWEL_M; else if(!strcmp(str,"r")) return VOWEL_R; else if(!strcmp(str,"th")) return VOWEL_TH; return -1; } /************************** CLOSE_AND_DELETE_TEMPFILE *************************** * * The input file is a temporary file only: needs to be deleted * */ int close_and_delete_tempfile(char *newfilename,dataptr dz) { /*RWD Nov 2003: use sndunlink before calling this for soundfiles! */ if(sndunlink(dz->ifd[0])){ fprintf(stdout, "WARNING: Can't delete temporary file %s.\n",newfilename); fflush(stdout); } if(sndcloseEx(dz->ifd[0]) < 0) { fprintf(stdout, "WARNING: Can't close temporary file %s\n",newfilename); fflush(stdout); } else { dz->ifd[0] = -1; } #ifdef NOTDEF if(remove(newfilename) < 0) { fprintf(stdout, "WARNING: Can't delete temporary file %s.\n",newfilename); fflush(stdout); } #endif return FINISHED; }