| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966 |
- /*
- * 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 <stdio.h>
- #include <stdlib.h>
- #include <structures.h>
- #include <tkglobals.h>
- #include <pnames.h>
- #include <globcon.h>
- #include <modeno.h>
- #include <flags.h>
- #include <arrays.h>
- #include <focus.h>
- #include <cdpmain.h>
- #include <formants.h>
- #include <speccon.h>
- #include <sfsys.h>
- #include <float.h>
- #include <string.h>
- #include <focus.h>
- static int rwd_accumulate(int index,float *flbufptr, float *windowbuf);
- static int do_fold(int vc,double lofrq_limit,double hifrq_limit,dataptr dz);
- static int fold_in(int vc,double thisfrq,dataptr dz);
- static int do_stable_peaks_filter(int *peakscore,int *descnt,double lofrq_limit,double hifrq_limit,dataptr dz);
- static int extract_formant_peaks(int *pkcnt_here,double lofrq_limit,double hifrq_limit,int *least,dataptr dz);
- static int establish_bottom_and_top_of_filter_bands(int pkcnt_here,dataptr dz);
- static int do_focu_filter(float *thisbuf,dataptr dz);
- static int design_filter(int *peakscore,int *descnt,dataptr dz);
- static int increment_pointer_in_output_buffer(dataptr dz);
- static int insert_new_peak_in_peaklist(int position_in_formant,int *least,dataptr dz);
- static int sort_focu_peaks_by_frq(int pkcnt_here,dataptr dz);
- static int write_last_focu_buffers(dataptr dz);
- static int read_first_buffer(int *windows_in_buf,dataptr dz);
- static int sfwind(int *windows_in_buf,int *wndws_read_pre_thisbuf,dataptr dz);
- static int get_buffer_containing_frzpos(int frztime,int *frzpos,int *windows_in_buf,
- int *wndws_read_pre_thisbuf,dataptr dz);
- static int get_freeze_template(dataptr dz);
- static int get_startwindow_position(int *startwpos,int this_segtime,int *wndws_read_pre_thisbuf,
- int *windows_in_buf,int buffer_saved,dataptr dz);
- static int freeze_data(dataptr dz);
- static int save_buffer(dataptr dz);
- static int sfrewind(int *windows_in_buf,int window_sought,int *wndws_read_pre_thisbuf,dataptr dz);
- static int restore_buffer(dataptr dz);
- static int do_specstep(int wc,dataptr dz);
- /* NEW CODE */
- static int read_buffer(int *windows_in_buf,dataptr dz);
- /* NEW CODE */
- /********************************** SPECACCU **********************************/
- int specaccu(dataptr dz)
- {
- int exit_status;
- int vc, cc;
- if(dz->param[ACCU_GLIS] > 0.0) {
- if(dz->param[ACCU_DECAY] < 1.0) {
- for(cc = 0, vc = 0; cc < dz->clength; cc++, vc += 2) {
- dz->windowbuf[0][AMPP] = (float)(dz->windowbuf[0][AMPP] * dz->param[ACCU_DINDEX]);
- dz->windowbuf[0][FREQ] = (float)(dz->windowbuf[0][FREQ] * dz->param[ACCU_GINDEX]);
- if((exit_status = rwd_accumulate(vc,dz->flbufptr[0],dz->windowbuf[0]))<0)
- return(exit_status);
- }
- } else {
- for(cc = 0, vc = 0; cc < dz->clength; cc++, vc += 2) {
- dz->windowbuf[0][FREQ] = (float)(dz->windowbuf[0][FREQ] * dz->param[ACCU_GINDEX]);
- if((exit_status = rwd_accumulate(vc,dz->flbufptr[0],dz->windowbuf[0]))<0)
- return(exit_status);
- }
- }
- } else if(dz->param[ACCU_DECAY] < 1.0) {
- for(cc = 0, vc = 0; cc < dz->clength; cc++, vc += 2) {
- dz->windowbuf[0][AMPP] = (float)(dz->windowbuf[0][AMPP] * dz->param[ACCU_DINDEX]);
- if((exit_status = rwd_accumulate(vc,dz->flbufptr[0],dz->windowbuf[0]))<0)
- return(exit_status);
- }
- } else {
- for(cc = 0, vc = 0; cc < dz->clength; cc++, vc += 2) {
- if((exit_status = rwd_accumulate(vc,dz->flbufptr[0],dz->windowbuf[0]))<0)
- return(exit_status);
- }
- }
- return(FINISHED);
- }
- /********************************** RWD_ACCUMULATE **********************************/
- int rwd_accumulate(int index,float *flbufptr, float *windowbuf)
- {
- int frq = index+1;
- if(flbufptr[index] > windowbuf[index]) { /* if current amp > amp in accumulator */
- windowbuf[index] = flbufptr[index];
- windowbuf[frq] = flbufptr[frq]; /* replace amp in accumulator with current amp */
- } else {
- flbufptr[index] = windowbuf[index]; /* else replace current amp with amp in accumulator */
- flbufptr[frq] = windowbuf[frq];
- }
- return(FINISHED);
- }
- /**************************** SPECEXAG ****************************/
- int specexag(int *zero_set,dataptr dz)
- {
- int cc, vc;
- double post_totalamp = 0.0, pre_totalamp = 0.0;
- double maxamp = 0.0, normaliser;
- for( cc = 0 ,vc = 0; cc < dz->clength; cc++, vc += 2) {
- pre_totalamp += dz->flbufptr[0][vc];
- if(dz->flbufptr[0][vc] > maxamp)
- maxamp = dz->flbufptr[0][vc];
- }
- if(maxamp<=0.0) {
- *zero_set = TRUE;
- return(FINISHED);
- }
- normaliser = 1.0/maxamp;
- for(cc = 0 ,vc = 0; cc < dz->clength; cc++, vc += 2) {
- dz->flbufptr[0][vc] = (float)(dz->flbufptr[0][vc] * normaliser);
- dz->flbufptr[0][vc] = (float)(pow(dz->flbufptr[0][vc],dz->param[EXAG_EXAG]));
- post_totalamp += dz->flbufptr[0][vc];
- }
- return normalise(pre_totalamp,post_totalamp,dz);
- }
- /**************************** SPECFOLD ***************************/
- int specfold(dataptr dz)
- {
- int exit_status;
- int vc;
- double hifrq_limit = dz->param[FOLD_HIFRQ];
- double lofrq_limit = dz->param[FOLD_LOFRQ];
- if(hifrq_limit < lofrq_limit)
- swap(&lofrq_limit,&hifrq_limit);
- if(dz->brksize[FOLD_HIFRQ]) {
- dz->iparam[FOLD_HICHAN] = (int)((hifrq_limit + dz->halfchwidth)/dz->chwidth); /* TRUNCATE */
- dz->param[FOLD_HICHANTOP] = ((double)dz->iparam[FOLD_HICHAN] * dz->chwidth) + dz->halfchwidth;
- if(dz->iparam[FOLD_HICHAN] != 0)
- dz->iparam[FOLD_HICHAN] <<= 1;
- }
- if(dz->brksize[FOLD_LOFRQ]) {
- dz->iparam[FOLD_LOCHAN] = (int)((lofrq_limit + dz->halfchwidth)/dz->chwidth); /* TRUNCATE */
- if(dz->iparam[FOLD_LOCHAN] > 0)
- dz->param[FOLD_LOCHANBOT] = ((double)(dz->iparam[FOLD_LOCHAN]-1) * dz->chwidth) + dz->halfchwidth;
- else
- dz->param[FOLD_LOCHANBOT] = 0.0;
- if(dz->iparam[FOLD_LOCHAN] != 0)
- dz->iparam[FOLD_LOCHAN]<<= 1;
- }
- for(vc = 0; vc < dz->wanted; vc += 2) {
- if((exit_status = do_fold(vc,lofrq_limit,hifrq_limit,dz))<0)
- return(exit_status);
- }
- return(FINISHED);
- }
- /******************************* DO_FOLD **************************/
- int do_fold(int vc,double lofrq_limit,double hifrq_limit,dataptr dz)
- {
- int exit_status;
- double thisfrq = fabs((double)dz->flbufptr[0][FREQ]);
- if(thisfrq < 1.0) {
- dz->flbufptr[0][AMPP] = 0.0f;
- return(FINISHED);
- }
- if(thisfrq < lofrq_limit) {
- while(thisfrq < lofrq_limit)
- thisfrq *= 2.0;
- if(thisfrq < hifrq_limit) {
- if((exit_status = fold_in(vc,thisfrq,dz))<0)
- return(exit_status);
- }
- dz->flbufptr[0][AMPP] = 0.0f;
- } else {
- if(thisfrq > hifrq_limit) {
- while(thisfrq > hifrq_limit)
- thisfrq /= 2.0;
- if(thisfrq > lofrq_limit) {
- if((exit_status = fold_in(vc,thisfrq,dz))<0)
- return(exit_status);
- }
- dz->flbufptr[0][AMPP] = 0.0f;
- }
- }
- return(FINISHED);
- }
- /******************************** FOLD_IN ************************/
- int fold_in(int vc,double thisfrq,dataptr dz)
- {
- #define THISCHANSCAN (4)
- int truecc, truevc;
- int minscan, maxscan, n;
- truecc = (int)((thisfrq + dz->halfchwidth)/dz->chwidth); /* TRUNCATE */
- truevc = truecc * 2;
- switch(dz->vflag[FOLD_WITH_BODY]) {
- case(FALSE):
- if(dz->flbufptr[0][AMPP] > dz->flbufptr[0][truevc]) {
- dz->flbufptr[0][truevc++] = dz->flbufptr[0][AMPP];
- dz->flbufptr[0][truevc] = dz->flbufptr[0][FREQ];
- }
- break;
- case(TRUE):
- if(dz->flbufptr[0][AMPP] > dz->flbufptr[0][truevc]) {
- dz->flbufptr[0][truevc++] = dz->flbufptr[0][AMPP];
- dz->flbufptr[0][truevc] = dz->flbufptr[0][FREQ];
- return(FINISHED);
- }
- minscan = max(dz->iparam[FOLD_LOCHAN]-2,truevc - (THISCHANSCAN * 2));
- maxscan = min(dz->iparam[FOLD_HICHAN]+2,truevc + (THISCHANSCAN * 2));
- for(n=truevc-2;n>minscan;n-=2) {
- if(dz->flbufptr[0][AMPP] > dz->flbufptr[0][n]) {
- dz->flbufptr[0][n++] = dz->flbufptr[0][AMPP];
- dz->flbufptr[0][n] = dz->flbufptr[0][FREQ];
- return(FINISHED);
- }
- }
- for(n=truevc+2;n<maxscan;n+=2) {
- if(dz->flbufptr[0][AMPP] > dz->flbufptr[0][n]) {
- dz->flbufptr[0][n++] = dz->flbufptr[0][AMPP];
- dz->flbufptr[0][n] = dz->flbufptr[0][FREQ];
- return(FINISHED);
- }
- }
- break;
- default:
- sprintf(errstr,"Unknown case in fold_in()\n");
- return(PROGRAM_ERROR);
- }
- return(FINISHED);
- }
- /**************************** OUTER_FOCU_LOOP ****************************/
- int outer_focu_loop(dataptr dz)
- {
- int exit_status;
- int samps_read, got, windows_in_buf;
- int peakscore = 0, pitchcnt = 0;
- int in_start_portion = TRUE, least = 0, descnt = 0;
- if(dz->vflag[FOCUS_STABLE])
- dz->flbufptr[1] = dz->flbufptr[2];
- 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(!dz->vflag[FOCUS_STABLE] && (samps_read > 0)) {
- 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);
- }
- if(dz->vflag[FOCUS_STABLE])
- return write_last_focu_buffers(dz);
- return(FINISHED);
- }
- /**************************** SPECFOCUS ***************************/
- int specfocus(int *peakscore,int *descnt,int *least,dataptr dz)
- {
- int exit_status;
- double lofrq_limit, hifrq_limit, d;
- int pkcnt_here;
- lofrq_limit = dz->param[FOCU_LOFRQ];
- hifrq_limit = dz->param[FOCU_HIFRQ];
- if(dz->brksize[FOCU_LOFRQ] || dz->brksize[FOCU_HIFRQ]) {
- if(flteq(lofrq_limit,hifrq_limit)) {
- sprintf(errstr,"Frequency limits define a zero-width band at time %lf.\n",dz->time);
- return(USER_ERROR);
- }
- if(lofrq_limit > hifrq_limit)
- swap(&lofrq_limit,&hifrq_limit);
- }
- if(dz->brksize[FOCU_BW]) {
- d = dz->param[FOCU_BW]/2.0; /* d is halfbandwidth. */
- dz->scalefact = PI/d; /* Convert an 8va offset from filter centre-frq */
- /* to a fraction of the bandwidth * PI */
- dz->param[FOCU_BRATIO_UP] = pow(2.0,d); /* upward transp ratio to top of filtband */
- dz->param[FOCU_BRATIO_DN] = 1.0/dz->param[FOCU_BRATIO_UP];
- } /* Downward transp ratio to bot of fband */
- rectify_window(dz->flbufptr[0],dz);
- if((exit_status = extract_specenv(0,0,dz))<0)
- return(exit_status);
- if(dz->vflag[FOCUS_STABLE])
- return do_stable_peaks_filter(peakscore,descnt,lofrq_limit,hifrq_limit,dz);
- if((exit_status = extract_formant_peaks(&pkcnt_here,lofrq_limit,hifrq_limit,least,dz))<0)
- return(exit_status);
- if((exit_status = establish_bottom_and_top_of_filter_bands(pkcnt_here,dz))<0)
- return(exit_status);
- if((exit_status = construct_filter_envelope(pkcnt_here,dz->flbufptr[0],dz))<0)
- return(exit_status);
- return do_focu_filter(dz->flbufptr[0],dz);
- }
- /****************************** DO_STABLE_PEAKS_FILTER ***************************/
- int do_stable_peaks_filter(int *peakscore,int *descnt,double lofrq_limit,double hifrq_limit,dataptr dz)
- {
- int exit_status, thispkcnt;
- // int *fppk = dz->stable->fpk[dz->iparam[FOCU_SL1]], n;
- int n;
- /* shufl bak stord specenvs: */
- /* put latest specenvarray here */
- memmove((char *)dz->stable->spec[0],
- //TW CODE ERROR
- // (char *)dz->stable->spec[1],dz->iparam[FOCU_SL1] * dz->infile->specenvcnt * sizeof(int));
- (char *)dz->stable->spec[1],dz->iparam[FOCU_SL1] * dz->infile->specenvcnt * sizeof(float));
- memmove((char *)dz->stable->spec[dz->iparam[FOCU_SL1]],
- //TW CODE ERROR
- // (char *)dz->specenvamp,dz->infile->specenvcnt * sizeof(int));
- (char *)dz->specenvamp,dz->infile->specenvcnt * sizeof(float));
- memmove((char *)dz->stable->fpk[0], (char *)dz->stable->fpk[1],
- dz->iparam[FOCU_SL1] * dz->infile->specenvcnt * sizeof(int));
- memmove((char *)dz->stable->total_pkcnt,(char *)(dz->stable->total_pkcnt+1),dz->iparam[FOCU_SL1] * sizeof(int));
- /* shufl bak stord fpks & shufl bak stored fpk_totals */
- if((exit_status = extract_formant_peaks2(FOCU_SL1,&thispkcnt,lofrq_limit,hifrq_limit,dz))<0)
- return(exit_status); /* put into into last fpk[z] store */
- dz->stable->total_pkcnt[dz->iparam[FOCU_SL1]] = thispkcnt; /* put into into last fpk[z] store */
- if(dz->total_windows >= dz->iparam[FOCU_SL1]) { /* before this we can't design a filter */
- if((exit_status = design_filter(peakscore,descnt,dz))<0)
- return(exit_status);
- if(dz->total_windows==dz->iparam[FOCU_SL1]) { /* If 1st time to do filtering */
- memmove((char *)(dz->flbufptr[1]),(char *)dz->stable->sbuf[0],(size_t)dz->wanted * sizeof(float)); /* copy zero-amp-1st-buff */
- if((exit_status = increment_pointer_in_output_buffer(dz))<0)
- return(exit_status);
- for(n = 1; n <= dz->stable->offset; n++) { /* filter all windows <= offset, using 1st filter */
- if((exit_status = do_focu_filter(dz->stable->sbuf[n],dz))<0)
- return(exit_status); /* and output them */
- memmove((char *)(dz->flbufptr[1]),(char *)dz->stable->sbuf[n],(size_t)dz->wanted * sizeof(float));
- if((exit_status = increment_pointer_in_output_buffer(dz))<0)
- return(exit_status);
- }
- } else { /* all later times to do filtering */
- /* filter buffer at offset and output it */
- if((exit_status = do_focu_filter(dz->stable->sbuf[dz->stable->offset],dz))<0)
- return(exit_status);
- memmove((char *)dz->flbufptr[1],(char *)dz->stable->sbuf[dz->stable->offset],(size_t)dz->wanted * sizeof(float));
- if((exit_status = increment_pointer_in_output_buffer(dz))<0)
- return(exit_status);
- }
- }
- memmove((char *)dz->stable->sbuf[0],(char *)dz->stable->sbuf[1],
- (size_t)(dz->wanted * sizeof(float) * dz->iparam[FOCU_SL1])); /* shuffle back stored bufs */
- memmove((char *)dz->stable->sbuf[dz->iparam[FOCU_SL1]],(char *)dz->flbufptr[0],(size_t)dz->wanted * sizeof(float));
- return(FINISHED); /* copy new buf to store */
- }
- /****************************** EXTRACT_FORMANT_PEAKS ***************************/
- int extract_formant_peaks(int *pkcnt_here,double lofrq_limit,double hifrq_limit,int *least,dataptr dz)
- {
- int exit_status;
- int n = 0;
- int falling = 0, last_channel_was_in_range = 1;
- *pkcnt_here = 0;
- for(n=0;n<dz->itemcnt;n++)
- dz->filtpeak[n] = 0.0;
- n = 1;
- while(n<dz->infile->specenvcnt) {
- if(dz->specenvfrq[n] < lofrq_limit) {
- last_channel_was_in_range = 0;
- n++;
- continue;
- }
- if(dz->specenvamp[n] > dz->specenvamp[n-1])
- falling = 0;
- else {
- if(!falling) {
- if(last_channel_was_in_range) {
- if((exit_status = insert_new_peak_in_peaklist(n-1,least,dz))<0)
- return(exit_status);
- }
- (*pkcnt_here)++;
- falling = 1;
- }
- }
- last_channel_was_in_range = 1;
- if(dz->specenvfrq[n] > hifrq_limit)
- break;
- n++;
- }
- *pkcnt_here = min(*pkcnt_here,dz->itemcnt);
- return sort_focu_peaks_by_frq(*pkcnt_here,dz);
- }
- /******************************** ESTABLISH_BOTTOM_AND_TOP_OF_FILTER_BANDS ************************/
- int establish_bottom_and_top_of_filter_bands(int pkcnt_here,dataptr dz)
- {
- int n;
- for(n=0;n<pkcnt_here;n++) {
- dz->fbandbot[n] = dz->specenvfrq[dz->peakno[n]] * dz->param[FOCU_BRATIO_DN];
- dz->fbandtop[n] = min(dz->specenvfrq[dz->peakno[n]] * dz->param[FOCU_BRATIO_UP],dz->nyquist);
- }
- return(FINISHED);
- }
- /****************************** DO_FOCU_FILTER ***************************/
- int do_focu_filter(float *thisbuf,dataptr dz)
- {
- int cc, vc;
- for(cc=0, vc=0; cc < dz->clength; cc++, vc += 2)
- thisbuf[AMPP] = (float)(thisbuf[AMPP] * dz->fsampbuf[cc]);
- return(FINISHED);
- }
- /****************************** DESIGN_FILTER ******************************/
- int design_filter(int *peakscore,int *descnt,dataptr dz)
- {
- int exit_status;
- int this_pkcnt;
- int n = 0;
- int pkcnt_here;
- if(dz->total_windows<=dz->iparam[FOCU_SL1])
- memset((char *)dz->stable->design_score,0,dz->infile->specenvcnt * sizeof(int));
- if((exit_status = score_peaks(peakscore,FOCU_SL1,FOCU_STABL,dz))<0)
- return(exit_status);
- if(*peakscore==0) {
- memset(dz->fsampbuf,0,(size_t)dz->wanted * sizeof(float)); /* zero filter */
- return(FINISHED);
- }
- if((exit_status = collect_scores(&this_pkcnt,descnt,dz))<0)
- return(exit_status); /* Find how many times each peak occurs across the stabilise buffers */
- if((exit_status = sort_design(this_pkcnt,dz))<0) /* Sort these on the basis of the most commonly occuring */
- return(exit_status);
- if(this_pkcnt<=dz->itemcnt || (dz->stable->des[dz->itemcnt-1]->score > dz->stable->des[dz->itemcnt]->score)) {
- pkcnt_here = min(this_pkcnt,dz->itemcnt);
- for(n=0;n<pkcnt_here;n++) /* If most common pkcnt (or less) peaks more common than ALL others */
- dz->peakno[n] = dz->stable->des[n]->chan;/* these are the peaks to keep */
- } else { /* Else choose amongst equivalent peaks, in terms of amplitude */
- if((exit_status = sort_equivalent_scores(this_pkcnt,dz))<0)
- return(exit_status);
- pkcnt_here = dz->itemcnt;
- }
- if((exit_status = sort_focu_peaks_by_frq(pkcnt_here,dz))<0)
- return(exit_status);
- if((exit_status = establish_bottom_and_top_of_filter_bands(pkcnt_here,dz))<0)
- return(exit_status);
- if((exit_status = construct_filter_envelope(pkcnt_here,dz->stable->sbuf[dz->stable->offset],dz))<0)
- return(exit_status);
- if(dz->total_windows>dz->iparam[FOCU_SL1]) { /* Logically this should be '>=dz->iparam[FOCU_SL1]' : but */
- if((exit_status = unscore_peaks(peakscore,dz))<0)
- return(exit_status); /* don't have to subtract window 0, as there are NO PEAKS there */
- }
- return(FINISHED);
- }
- /****************************** INCREMENT_POINTER_IN_OUTPUT_BUFFER ***************************/
- int increment_pointer_in_output_buffer(dataptr dz)
- {
- int exit_status;
- if((dz->flbufptr[1] += dz->wanted) >= dz->flbufptr[3]) {
- if((exit_status = write_exact_samps(dz->flbufptr[2],dz->buflen,dz))<0)
- return(exit_status);
- dz->flbufptr[1] = dz->flbufptr[2];
- }
- return(FINISHED);
- }
- /****************************** INSERT_NEW_PEAK_IN_PEAKLIST ***************************/
- int insert_new_peak_in_peaklist(int position_in_formant,int *least,dataptr dz)
- {
- int n;
- double smallest = DBL_MAX;
- if(dz->specenvamp[position_in_formant] > dz->filtpeak[*least]) {
- dz->filtpeak[*least] = dz->specenvamp[position_in_formant];
- dz->peakno[*least] = position_in_formant;
- }
- for(n=0;n<dz->itemcnt;n++) {
- if(dz->filtpeak[n] < smallest) {
- *least = n;
- smallest = dz->filtpeak[n];
- }
- }
- return(FINISHED);
- }
- /****************************** SORT_FOCU_PEAKS_BY_FRQ ***************************/
- int sort_focu_peaks_by_frq(int pkcnt_here,dataptr dz)
- {
- int n, m, k;
- for(n=0;n<pkcnt_here-1;n++) {
- for(m=n+1;m<pkcnt_here;m++) {
- if(dz->specenvfrq[dz->peakno[n]] > dz->specenvfrq[dz->peakno[m]]) {
- k = dz->peakno[m];
- dz->peakno[m] = dz->peakno[n];
- dz->peakno[n] = k;
- }
- }
- }
- return(FINISHED);
- }
- /****************************** WRITE_LAST_FOCU_BUFFERS ******************************/
- int write_last_focu_buffers(dataptr dz)
- {
- int exit_status;
- int n;
- for(n = dz->stable->offset+1; n < dz->iparam[FOCU_STABL]; n++) {
- if((exit_status = do_focu_filter(dz->stable->sbuf[n],dz))<0)
- return(exit_status);
- memmove((char *)dz->flbufptr[1],(char *)dz->stable->sbuf[n],(size_t)dz->wanted * sizeof(float));
- if((exit_status = increment_pointer_in_output_buffer(dz))<0)
- return(exit_status);
- }
- if(dz->flbufptr[1]!=dz->flbufptr[2]) {
- if((exit_status = write_exact_samps(dz->flbufptr[2],(dz->flbufptr[1] - dz->flbufptr[2]),dz))<0)
- return(exit_status);
- }
- return(FINISHED);
- }
- /****************** SPECFREEZE ********************
- *
- * (1) if no freezing needed.
- * (2) write any complete buffers before next timepoint.
- * (3) advance to buffer containing freeze-window if ness.
- * (4) advance within current buffer, to freeze-window.
- * (5) get number of windows to process.
- * (6) set endwindow relative to current buffer.
- * (7) advance within current buffer, to start-window.
- * (8) process windows from here to end-window.
- * (9) if current buffer overrun: proceed to next buffer.
- * (10) readjust window counters to be relative to nextbuffer start.
- * (11) write data and go to next buffer.
- * (12) flush buffer.
- */
- int specfreeze(dataptr dz)
- {
- int exit_status;
- int n = 0, buffer_saved;
- int wc, wndws_read_pre_thisbuf = 0, frzpos;
- int startwpos = 0, endwpos = 0, windiff;
- int windows_in_buf;
- if((exit_status = read_first_buffer(&windows_in_buf,dz))<0)
- return(exit_status);
- while(n<dz->itemcnt-1) {
- if(dz->lparray[FRZ_FRZTIME][n] < 0L) { /* 1 */
- while(dz->lparray[FRZ_SEGTIME][n+1] > wndws_read_pre_thisbuf + windows_in_buf) {
- if((exit_status = sfwind(&windows_in_buf,&wndws_read_pre_thisbuf,dz))<0)
- return(exit_status); /* 2 */
- if(exit_status == FINISHED) {
- sprintf(errstr,"Window search miscalculation 1, specfreeze()\n");
- return(PROGRAM_ERROR);
- }
- }
- endwpos = dz->lparray[FRZ_SEGTIME][n+1] - wndws_read_pre_thisbuf;
- } else {
- buffer_saved = 0;
- frzpos = dz->lparray[FRZ_FRZTIME][n] - wndws_read_pre_thisbuf;
- if(frzpos > windows_in_buf) { /* 3 */
- if((exit_status = get_buffer_containing_frzpos
- (dz->lparray[FRZ_FRZTIME][n],&frzpos,&windows_in_buf,&wndws_read_pre_thisbuf,dz))<0)
- return(exit_status);
- buffer_saved = 1;
- }
- dz->flbufptr[0] = dz->bigfbuf + (frzpos * dz->wanted); /* 4 */
- if((exit_status = get_freeze_template(dz))<0)
- return(exit_status);
- windiff = dz->lparray[FRZ_SEGTIME][n+1] - dz->lparray[FRZ_SEGTIME][n];/* 5 */
- if((exit_status = get_startwindow_position
- (&startwpos,dz->lparray[FRZ_SEGTIME][n],&wndws_read_pre_thisbuf,&windows_in_buf,buffer_saved,dz))<0)
- return(exit_status);
- endwpos = startwpos + windiff; /* 6 */
- wc = startwpos; /* 7 */
- dz->flbufptr[0] = dz->bigfbuf + (startwpos * dz->wanted); /* 8 */
- exit_status = CONTINUE;
- while(wc<endwpos) {
- if(exit_status == FINISHED) {
- sprintf(errstr,"Window search miscalculation 2, specfreeze()\n");
- return(PROGRAM_ERROR);
- }
- if((exit_status = freeze_data(dz))<0)
- return(exit_status);
- dz->flbufptr[0] += dz->wanted;
- if(++wc >= windows_in_buf) { /* 9 */
- wc = 0; /* 10 */
- endwpos -= windows_in_buf; /* 11 */
- if((exit_status = sfwind(&windows_in_buf,&wndws_read_pre_thisbuf,dz))<0)
- return(exit_status);
- }
- }
- }
- n++;
- }
- if((endwpos > 0) && (windows_in_buf > 0)) { /* 12 */
- if((exit_status = write_exact_samps(dz->bigfbuf,windows_in_buf * dz->wanted,dz))<0)
- return(exit_status);
- }
- return(FINISHED);
- }
- /*************************** READ_FIRST_BUFFER ******************************/
- int read_first_buffer(int *windows_in_buf,dataptr dz)
- {
- int samps_read, got;
- if((samps_read = fgetfbufEx(dz->bigfbuf, dz->buflen,dz->ifd[0],0)) < 0) {
- sprintf(errstr,"Cannot read data from input file: read_first_buffer()\n");
- return(SYSTEM_ERROR);
- }
- got = samps_read;
- *windows_in_buf = got/dz->wanted;
- return(FINISHED);
- }
- /*************************** SFWIND *******************************/
- int sfwind(int *windows_in_buf,int *wndws_read_pre_thisbuf,dataptr dz)
- {
- int exit_status;
- int got, samps_read;
- *wndws_read_pre_thisbuf += *windows_in_buf;
- if(*windows_in_buf > 0) {
- if((exit_status = write_exact_samps(dz->bigfbuf,*windows_in_buf * dz->wanted,dz))<0)
- return(exit_status);
- }
- if((samps_read = fgetfbufEx(dz->bigfbuf, dz->buflen,dz->ifd[0],0)) < 0) {
- sprintf(errstr,"Failed to read sound data: sfwind()\n");
- return(SYSTEM_ERROR);
- }
- got = samps_read;
- *windows_in_buf = got/dz->wanted;
- dz->flbufptr[0] = dz->bigfbuf;
- if(samps_read==0)
- return(FINISHED);
- return(CONTINUE);
- }
- /*************************** GET_BUFFER_CONTAINING_FRZPOS *******************************/
- int get_buffer_containing_frzpos(int frztime,int *frzpos,int *windows_in_buf,int *wndws_read_pre_thisbuf,dataptr dz)
- {
- int exit_status;
- int samps_read, got;
- int buffer_saved = 0;
- while(*frzpos > *windows_in_buf) {
- if(!buffer_saved) {
- if((exit_status = save_buffer(dz))<0)
- return(exit_status);
- }
- buffer_saved = 1;
- *wndws_read_pre_thisbuf += *windows_in_buf;
- if((samps_read = fgetfbufEx(dz->bigfbuf, dz->buflen,dz->ifd[0],0)) <= 0) {
- if(samps_read<0) {
- sprintf(errstr,"Sound read error.\n");
- return(SYSTEM_ERROR);
- } else {
- sprintf(errstr,"Buffer accnting probl: Can't read input data: get_buffer_containing_frzpos()\n");
- return(PROGRAM_ERROR);
- }
- }
- got = samps_read;
- *windows_in_buf = got/dz->wanted;
- *frzpos = frztime - *wndws_read_pre_thisbuf;
- }
- return(FINISHED);
- }
- /*************************** GET_FREEZE_TEMPLATE *******************************/
- int get_freeze_template(dataptr dz)
- {
- int cc, vc;
- switch(dz->mode) {
- case(FRZ_AMP):
- for(cc = 0, vc = 0; cc < dz->clength; cc++, vc += 2)
- dz->windowbuf[0][AMPP] = dz->flbufptr[0][AMPP];
- break;
- case(FRZ_FRQ):
- for(cc = 0, vc = 0; cc < dz->clength; cc++, vc += 2)
- dz->windowbuf[0][FREQ] = dz->flbufptr[0][FREQ];
- break;
- case(FRZ_AMP_AND_FRQ):
- for(vc = 0; vc < dz->wanted; vc++)
- dz->windowbuf[0][vc] = dz->flbufptr[0][vc];
- break;
- default:
- sprintf(errstr,"unknown mode in get_freeze_template()\n");
- return(PROGRAM_ERROR);
- }
- return(FINISHED);
- }
- /*************************** GET_STARTWINDOW_POSITION ******************************
- *
- * If startwindow is not in this buffer: rewind.
- */
- int get_startwindow_position
- (int *startwpos,int this_segtime,int *wndws_read_pre_thisbuf,int *windows_in_buf,int buffer_saved,dataptr dz)
- {
- int exit_status;
- if((*startwpos = this_segtime - *wndws_read_pre_thisbuf)<0) {
- if((exit_status = sfrewind(windows_in_buf,this_segtime,wndws_read_pre_thisbuf,dz))<0)
- return(exit_status);
- if(buffer_saved) {
- if((exit_status = restore_buffer(dz))<0)
- return(exit_status);
- }
- *startwpos = this_segtime - *wndws_read_pre_thisbuf;
- }
- return(FINISHED);
- }
- /*************************** FREEZE_DATA ******************************/
- int freeze_data(dataptr dz)
- {
- int cc, vc;
- switch(dz->mode) {
- case(FRZ_AMP):
- for( cc = 0 ,vc = 0; cc < dz->clength; cc++, vc += 2)
- dz->flbufptr[0][AMPP] = dz->windowbuf[0][AMPP];
- break;
- case(FRZ_FRQ):
- for( cc = 0 ,vc = 0; cc < dz->clength; cc++, vc += 2)
- dz->flbufptr[0][FREQ] = dz->windowbuf[0][FREQ];
- break;
- case(FRZ_AMP_AND_FRQ):
- for(vc = 0; vc < dz->wanted; vc++)
- dz->flbufptr[0][vc] = dz->windowbuf[0][vc];
- break;
- default:
- sprintf(errstr,"unknown mode in freeze_data()\n");
- return(PROGRAM_ERROR);
- }
- return(CONTINUE);
- }
- /*************************** SAVE_BUFFER *******************************/
- int save_buffer(dataptr dz)
- {
- memmove((char *)(dz->flbufptr[2]),(char *)dz->bigfbuf,(size_t)dz->buflen * sizeof(float));
- return(FINISHED);
- }
- /***************************** SFREWIND ********************************/
- int sfrewind(int *windows_in_buf,int window_sought,int *wndws_read_pre_thisbuf,dataptr dz)
- {
- int samps_read, got;
- int big_wsize = dz->buflen/dz->wanted;
- int zzz = (window_sought/big_wsize) * big_wsize; /* TRUNCATE to a multiple of bigbufsize (in windows) */
- if((sndseekEx(dz->ifd[0],zzz * dz->wanted, 0))<0) {
- sprintf(errstr,"Window seek failed. sfrewind()\n");
- return(SYSTEM_ERROR);
- }
- *wndws_read_pre_thisbuf = zzz;
- if((samps_read = fgetfbufEx(dz->bigfbuf, dz->buflen,dz->ifd[0],0)) <= 0) {
- if(samps_read<0) {
- sprintf(errstr,"Sound read error.\n");
- return(SYSTEM_ERROR);
- } else {
- sprintf(errstr,"Window reverse search miscalculation.sfrewind()\n");
- return(PROGRAM_ERROR);
- }
- }
- got = samps_read;
- *windows_in_buf = got/dz->wanted;
- return(FINISHED);
- }
- /*************************** RESTORE_BUFFER *******************************/
- int restore_buffer(dataptr dz)
- {
- memmove((char *)dz->bigfbuf,(char *)(dz->flbufptr[2]),(size_t)dz->buflen * sizeof(float));
- return(FINISHED);
- }
- /**************************** SPECSTEP ****************************/
- int specstep(dataptr dz)
- {
- int exit_status;
- int samps_read, got, windows_in_buf, wc;
- 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;
- for(wc=0; wc<windows_in_buf; wc++) {
- if((exit_status = do_specstep(wc,dz))<0)
- return(exit_status);
- dz->total_windows++;
- dz->flbufptr[0] += dz->wanted;
- }
- if(dz->total_windows % dz->iparam[STEP_STEP]!=0) /* at bigbufend, if not at start of step */
- memmove((char *)(dz->windowbuf[0]),(char *)(dz->flbufptr[1]),(size_t)dz->wanted * sizeof(float));
- /* copy the unchanging window into saving buffer */
- if((exit_status = write_exact_samps(dz->bigfbuf,samps_read,dz))<0)
- return(exit_status);
- }
- return(FINISHED);
- }
- /**************************** DO_SPECSTEP ***************************/
- int do_specstep(int wc,dataptr dz)
- {
- if(wc==0) { /* if at start of a bigfbuf */
- if(dz->total_windows % dz->iparam[STEP_STEP]!=0) /* and not at start of a step */
- memmove((char *)(dz->flbufptr[0]),(char *)(dz->windowbuf[0]),(size_t)dz->wanted * sizeof(float));
- /* get the saved unchanging window into 1st buf of bigfbuf */
- dz->flbufptr[1] = dz->flbufptr[0];/* point to this window, as unchanging window */
- } else if(dz->total_windows % dz->iparam[STEP_STEP]==0) /* if at start of a step */
- dz->flbufptr[1] = dz->flbufptr[0];/* point to this window, as unchanging window */
- else /* if not at start of a step */
- memmove((char *)(dz->flbufptr[0]),(char *)(dz->flbufptr[1]),(size_t)dz->wanted * sizeof(float));
- /* copy the unchanging window into current window */
- return(FINISHED);
- }
- /* NEW CODE */
- /****************** SPECFREEZE2 ********************
- *
- * (1) if no freezing needed.
- * (2) write any complete buffers before next timepoint.
- * (3) advance to buffer containing freeze-window if ness.
- * (4) advance within current buffer, to freeze-window.
- * (5) get number of windows to process.
- * (6) set endwindow relative to current buffer.
- * (7) advance within current buffer, to start-window.
- * (8) process windows from here to end-window.
- * (9) if current buffer overrun: proceed to next buffer.
- * (10) readjust window counters to be relative to nextbuffer start.
- * (11) write data and go to next buffer.
- * (12) flush buffer.
- */
- int specfreeze2(dataptr dz)
- {
- int exit_status;
- int n = 0, m;
- int windows_in_buf, inwindowcnt = 0, outbufwincnt = 0, inbufwincnt = 0;
- int bufwinlen = dz->buflen/dz->wanted;
- if((exit_status = read_first_buffer(&windows_in_buf,dz))<0)
- return(exit_status);
- dz->flbufptr[0] = dz->bigfbuf;
- dz->flbufptr[1] = dz->flbufptr[2];
- while(n<dz->itemcnt) {
- while(inwindowcnt < dz->lparray[FRZ_FRZTIME][n]) { /* 1 */
- memcpy((char *)dz->flbufptr[1],(char *)dz->flbufptr[0],dz->wanted * sizeof(float));
- if(++inwindowcnt >= dz->wlength) {
- dz->finished = TRUE;
- break;
- } else if(++inbufwincnt >= windows_in_buf) {
- if((exit_status = read_buffer(&windows_in_buf,dz))<0)
- return(exit_status);
- dz->flbufptr[0] = dz->bigfbuf;
- inbufwincnt = 0;
- } else
- dz->flbufptr[0] += dz->wanted;
- if(++outbufwincnt >= bufwinlen) {
- if((exit_status = write_samps(dz->flbufptr[2],dz->buflen,dz))<0)
- return(exit_status);
- dz->flbufptr[1] = dz->flbufptr[2];
- outbufwincnt = 0;
- } else
- dz->flbufptr[1] += dz->wanted;
- }
- if(dz->finished)
- break;
- for(m=0;m<dz->lparray[FRZ_SEGTIME][n];m++) {
- memcpy((char *)dz->flbufptr[1],(char *)dz->flbufptr[0],dz->wanted * sizeof(float));
- if(++outbufwincnt >= bufwinlen) {
- if((exit_status = write_samps(dz->flbufptr[2],dz->buflen,dz))<0)
- return(exit_status);
- dz->flbufptr[1] = dz->flbufptr[2];
- outbufwincnt = 0;
- } else
- dz->flbufptr[1] += dz->wanted;
- }
- n++;
- }
- while(inwindowcnt < dz->wlength) {
- memcpy((char *)dz->flbufptr[1],(char *)dz->flbufptr[0],dz->wanted * sizeof(float));
- if(++outbufwincnt >= bufwinlen) {
- if((exit_status = write_samps(dz->flbufptr[2],dz->buflen,dz))<0)
- return(exit_status);
- dz->flbufptr[1] = dz->flbufptr[2];
- outbufwincnt = 0;
- } else
- dz->flbufptr[1] += dz->wanted;
- inwindowcnt++;
- if(++inbufwincnt >= windows_in_buf) {
- if((exit_status = read_buffer(&windows_in_buf,dz))<0)
- return(exit_status);
- dz->flbufptr[0] = dz->bigfbuf;
- inbufwincnt = 0;
- } else
- dz->flbufptr[0] += dz->wanted;
- }
- if(dz->flbufptr[1] != dz->flbufptr[2]) {
- if((exit_status = write_samps(dz->flbufptr[2],(dz->flbufptr[1] - dz->flbufptr[2]),dz))<0)
- return(exit_status);
- }
- return(FINISHED);
- }
- /*************************** READ_BUFFER ******************************/
- int read_buffer(int *windows_in_buf,dataptr dz)
- {
- int samps_read, got;
- if((samps_read = fgetfbufEx(dz->bigfbuf, dz->buflen,dz->ifd[0],0)) < 0) {
- sprintf(errstr,"Can't read samples from input soundfile.\n");
- return(SYSTEM_ERROR);
- }
- got = samps_read;
- *windows_in_buf = got/dz->wanted;
- return(FINISHED);
- }
- /* END OF NEW CODE */
|