| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674 |
- /*
- * 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
- *
- */
- /*floatsam version*/
- /*NB CUTGATE_SHRTBLOK RENAMED CUTGATE_SAMPBLOK*/
- #include <stdio.h>
- #include <stdlib.h>
- #include <structures.h>
- #include <tkglobals.h>
- #include <globcon.h>
- #include <cdpmain.h>
- #include <house.h>
- #include <modeno.h>
- #include <pnames.h>
- #include <logic.h>
- #include <flags.h>
- #include <arrays.h>
- /*RWD April 2004 TW forgot this...*/
- #include <processno.h>
- #include <sfsys.h>
- #include <string.h>
- #include <srates.h>
- #ifdef unix
- #define round(x) lround((x))
- #endif
- /* RWD keep this? */
- #define SAMPLE_T float
- #define IBUF (0)
- #define OBUF (1)
- #define BUFEND (2)
- #define WRAP (1)
- #define ENV (0)
- #define ENVEND (1)
- /* RWD ????? */
- //TW REDUNDANT
- //#define SR (22050)
- //#define SRDAT (24000)
- //#define SRDATLO (16000)
- #define MAXCUTS (999)
- #define TOPN_DEFAULT_SPLEN (15.0) /* MS */
- static int top_and_tail(dataptr dz);
- static int get_startsamp(float *ibuf,int chans,int nbuff,int *startsamp,double gate,double ngate,dataptr dz);
- static int get_endsamp(float *ibuf,int chans,int nbuff,int *endsamp,double gate,double ngate,dataptr dz);
- //TW REVISED
- //static int do_startsplice(float **ibuf,float **obuf,int splicecnt,
- // int startseek,int *sampseek,int *firsttime,int offset,int offset_samps,int wrap_samps,int input_report,dataptr dz);
- static int do_startsplice(int splicecnt,int startsamp,int *sampseek,int input_report,dataptr dz);
- //TW REVISED
- //static int advance_to_endsamp(float **ibuf,float **obuf,int endsamp,int *sampseek,
- // int *firsttime,int wrap_samps,int offset_samps,int input_report,dataptr dz);
- static int advance_to_endsamp(int endsamp,int *sampseek,int input_report,dataptr dz);
- //TW REVISED
- //static int do_end_splice(float **ibuf,float **obuf,int *k,int splicecnt,int firsttime,
- // int wrap_samps,int offset_samps,int input_report,dataptr dz);
- static int do_end_splice(int *k,int splicecnt,int input_report,dataptr dz);
- static int do_cutgate(dataptr dz);
- //TW SUGGESTS, REDUNDANT
- //static int get_bufmult_factor(int srate,int channels,dataptr dz);
- static int ggetenv(dataptr dz);
- static void searchpars(dataptr dz);
- static void readenv(int samps_to_process,SAMPLE_T **env,dataptr dz);
- static void get_maxsamp(SAMPLE_T *env,int startsamp,dataptr dz);
- static int findcuts(int *ccnt,dataptr dz);
- static int findcuts2(int *ccnt,dataptr dz);
- static int create_outfile_name(int ccnt,char *thisfilename,dataptr dz);
- static int output_cut_sndfile(int ccnt,char *filename,dataptr dz);
- static int store_cut_positions_in_samples(int ccnt,int startse,int endsec,dataptr dz) ;
- static int setup_naming(char **filename,dataptr dz);
- static int do_rectify(dataptr dz);
- static int create_cutgate_buffer(dataptr dz);
- static int create_topntail_buffer(dataptr dz);
- //TW FUNCTION NEW REDUNDANT
- //static int do_by_hand(dataptr dz);
- //TW UPDATES
- static int find_onset_cuts(int *ccnt,dataptr dz);
- static int store_startcut_positions_in_samples(int ccnt,int startsec,dataptr dz);
- /******************************* PCONSISTENCY_CLEAN *******************************/
- int pconsistency_clean(dataptr dz)
- {
- // int exit_status;
- double sr = (double)dz->infile->srate;
- int chans = dz->infile->channels;
- if(dz->process == TOPNTAIL_CLICKS) {
- if(!dz->vflag[STT_TRIM] && !dz->vflag[END_TRIM]) {
- sprintf(errstr,"Input file will be UNCHANGED.\n");
- return(GOAL_FAILED);
- }
- return FINISHED;
- }
- switch(dz->mode) {
- case(HOUSE_CUTGATE):
- dz->iparam[CUTGATE_SPLCNT] = round(dz->param[CUTGATE_SPLEN] * MS_TO_SECS * sr);
- dz->iparam[CUTGATE_SPLEN] = dz->iparam[CUTGATE_SPLCNT] * chans;
- /* fall thro */
- case(HOUSE_ONSETS):
- if(dz->param[CUTGATE_INITLEVEL]>0 && dz->iparam[CUTGATE_BAKTRAK]==0) {
- fprintf(stdout,"WARNING: INITIAL LEVEL set without Baktraking: no effect.\n");
- fflush(stdout);
- }
- if(flteq(dz->param[CUTGATE_ENDGATE],0.0))
- dz->param[CUTGATE_ENDGATE] = dz->param[CUTGATE_GATE];
- dz->iparam[CUTGATE_MINLEN] = round(dz->param[CUTGATE_MINLEN] * sr) * chans;
- /* fall thro */
- case(HOUSE_CUTGATE_PREVIEW):
- //TW SUGGESTS this will work fine, & still be consistent with old-buffering-protocol...
- dz->iparam[CUTGATE_SAMPBLOK] = F_SECSIZE * dz->infile->channels;
- break;
- //TW !!!!!
- case(HOUSE_TOPNTAIL):
- if(dz->vflag[NO_STT_TRIM] && dz->vflag[NO_END_TRIM]) {
- sprintf(errstr,"Input file will be UNCHANGED.\n");
- return(GOAL_FAILED);
- }
- //TW UPDATE (redundant)
- // dz->param[TOPN_NGATE] = -dz->param[TOPN_GATE];
- break;
- }
- return(FINISHED);
- }
- /******************************* CREATE_CLEAN_BUFFERS *******************************/
- int create_clean_buffers(dataptr dz)
- {
- if(dz->process == TOPNTAIL_CLICKS)
- return create_topntail_buffer(dz);
- switch(dz->mode) {
- case(HOUSE_CUTGATE_PREVIEW):
- //TW NEW CASE
- case(HOUSE_ONSETS):
- case(HOUSE_CUTGATE): return create_cutgate_buffer(dz);
- case(HOUSE_TOPNTAIL): return create_topntail_buffer(dz);
- }
- sprintf(errstr,"Unknown mode: create_clean_buffers()\n");
- return(PROGRAM_ERROR);
- }
- /******************************* CREATE_CUTGATE_BUFFER ****************************/
- int create_cutgate_buffer(dataptr dz)
- {
- int k, envelope_space,total_bufsize;
- int numsecs;
- int samp_blocksize = dz->iparam[CUTGATE_SAMPBLOK] * sizeof(float);
- size_t bigbufsize;
- bigbufsize = (size_t)Malloc(-1);
- if((bigbufsize = (bigbufsize/samp_blocksize) * samp_blocksize)<=0)
- bigbufsize = samp_blocksize;
- dz->buflen = (int)(bigbufsize/sizeof(float));
- /* dz->buflen needed for searchpars() */
- searchpars(dz);
- if((k =
- dz->iparam[CUTGATE_NUMSECS]/dz->iparam[CUTGATE_SAMPBLOK])* dz->iparam[CUTGATE_SAMPBLOK] < dz->iparam[CUTGATE_NUMSECS])
- k++;
- numsecs = k * dz->iparam[CUTGATE_SAMPBLOK];
- envelope_space = (numsecs + dz->iparam[CUTGATE_WINDOWS]) * sizeof(float);
- total_bufsize = bigbufsize + envelope_space + (F_SECSIZE * sizeof(float)); /* overflow sector in sndbuf */
- if((dz->bigbuf = (float *)malloc((size_t)total_bufsize)) == NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY for sound and envelope.\n");
- return(MEMORY_ERROR);
- }
- dz->sampbuf[ENV] = dz->bigbuf + dz->buflen + F_SECSIZE;
- return(FINISHED);
- }
- /******************************* PROCESS_CLEAN *******************************/
- int process_clean(dataptr dz)
- {
- if(dz->process == TOPNTAIL_CLICKS)
- return top_and_tail(dz);
- switch(dz->mode) {
- case(HOUSE_CUTGATE_PREVIEW):
- case(HOUSE_ONSETS):
- case(HOUSE_CUTGATE): return do_cutgate(dz);
- case(HOUSE_TOPNTAIL): return top_and_tail(dz);
- case(HOUSE_RECTIFY): return do_rectify(dz);
- default: /*RWD*/
- break;
- }
- sprintf(errstr,"Unknown mode: process_clean()\n");
- return(PROGRAM_ERROR);
- }
- /*************************** CREATE_TOPNTAIL_BUFFER ************************/
- //TW comment old-buffer-protocol not required
- int create_topntail_buffer(dataptr dz)
- {
- size_t bigbufsize;
- bigbufsize = (size_t) Malloc(-1);
- dz->buflen = (int)(bigbufsize / sizeof(float));
- dz->buflen = (dz->buflen / dz->infile->channels) * dz->infile->channels;
- if((dz->bigbuf = (float*) Malloc(dz->buflen * sizeof(float)))== NULL){
- sprintf(errstr, "Can't allocate memory for sound.\n");
- return(MEMORY_ERROR);
- }
- return(FINISHED);
- }
- /******************************* TOP_AND_TAIL *******************************/
- int top_and_tail(dataptr dz)
- {
- int exit_status;
- float *ibuf = dz->bigbuf;
- float *obuf = ibuf;
- int nbuff;
- // int gotend = FALSE;
- // int gotstart = FALSE;
- int chans = dz->infile->channels;
- // int firsttime = TRUE;
- int startsamp = 0;
- int endsamp = dz->insams[0];
- int splicecnt = round(dz->param[TOPN_SPLEN] * MS_TO_SECS * (double)dz->infile->srate);
- int splicesamps = splicecnt * chans;
- int sampseek = 0;
- int startsplice, endsplice = 0, samps_to_write;
- // int startseek;
- double gate, ngate;
- dz->ssampsread = 0;
- nbuff = dz->insams[0]/dz->buflen;
- if(nbuff * dz->buflen < dz->insams[0]) /* did have ; at end */
- nbuff++; /* number of buffers contaning entire file */
- gate = dz->param[TOPN_GATE] * (double)F_MAXSAMP;
- ngate = -gate;
- switch(dz->process) {
- case(TOPNTAIL_CLICKS):
- if(dz->vflag[STT_TRIM]) {
- if((exit_status = get_startsamp(ibuf,chans,nbuff,&startsplice,gate,ngate,dz))<0)
- return(exit_status);
- if((startsamp = startsplice + splicesamps) > dz->insams[0]) {
- sprintf(errstr,"At this gate level and splice length, entire file will be removed.\n");
- return(GOAL_FAILED);
- }
- } else
- startsplice = 0; /* Needed for settting wrap, offset, seek */
- if(dz->vflag[END_TRIM]) {
- if((exit_status = get_endsamp(ibuf,chans,nbuff,&endsplice,gate,ngate,dz))<0)
- return(exit_status);
- if((endsamp = (endsplice - splicesamps)) < 0) {
- sprintf(errstr,"At this gate level and splice length, entire file will be removed.\n");
- return(GOAL_FAILED);
- }
- }
- if((dz->tempsize = endsplice - startsplice) <= 2 * splicesamps) {
- sprintf(errstr,"At this gate level and splice length, entire file will be removed.\n");
- return(GOAL_FAILED);
- }
- break;
- default:
- if(!dz->vflag[NO_STT_TRIM]) {
- if((exit_status = get_startsamp(ibuf,chans,nbuff,&startsamp,gate,ngate,dz))<0)
- return(exit_status);
- }
- if(!dz->vflag[NO_END_TRIM]) {
- if((exit_status = get_endsamp(ibuf,chans,nbuff,&endsamp,gate,ngate,dz))<0)
- return(exit_status);
- }
- if(endsamp == startsamp) {
- sprintf(errstr,"At this gate level, entire file will be removed.\n");
- return(GOAL_FAILED);
- }
- if((startsplice = startsamp - splicesamps) < 0)
- dz->vflag[NO_STT_TRIM] = TRUE;
- endsplice = endsamp;
- if((endsamp -= splicesamps) <= 0) {
- sprintf(errstr,"At this gate level, entire file will be removed.\n");
- return(GOAL_FAILED);
- }
- if(dz->vflag[NO_STT_TRIM])
- startsplice = 0;
- break;
- }
-
- // startseek = startsamp * sizeof(float);
- // DEC 2004
- dz->ssampsread = 0;
- if(((dz->process == TOPNTAIL_CLICKS) && dz->vflag[STT_TRIM])
- || ((dz->process != TOPNTAIL_CLICKS) && !dz->vflag[NO_STT_TRIM])) {
- if((exit_status = do_startsplice(splicecnt,startsamp,&sampseek,0,dz))<0)
- return(exit_status);
- } else {
- if(sndseekEx(dz->ifd[0],startsamp,0)<0) {
- sprintf(errstr,"sndseekEx() failed: A\n");
- return(SYSTEM_ERROR);
- }
- sampseek = startsamp;
- }
- if(((dz->process == TOPNTAIL_CLICKS) && !dz->vflag[END_TRIM])
- || ((dz->process != TOPNTAIL_CLICKS) && dz->vflag[NO_END_TRIM]))
- endsamp = endsplice = dz->insams[0];
- if((exit_status = advance_to_endsamp(endsamp,&sampseek,0,dz))<0)
- return(exit_status);
- samps_to_write = endsamp - sampseek;
- if(((dz->process == TOPNTAIL_CLICKS) && dz->vflag[END_TRIM])
- || ((dz->process != TOPNTAIL_CLICKS) && !dz->vflag[NO_END_TRIM])) {
- if((exit_status = do_end_splice(&samps_to_write,splicecnt,0,dz))<0)
- return(exit_status);
- }
- if(samps_to_write > 0) {
- if((exit_status = write_samps(obuf,samps_to_write,dz))<0)
- return(exit_status);
- }
- dz->total_samps_written = endsplice - startsplice;
- return(FINISHED);
- }
- /******************************* GET_STARTSAMP *******************************/
- int get_startsamp(float *ibuf,int chans,int nbuff,int *startsamp,double gate,double ngate,dataptr dz)
- {
- int exit_status;
- int gotstart = FALSE;
- int thisbuff = 0;
- int n;
- while(!gotstart && thisbuff < nbuff) {
- if((exit_status = read_samps(ibuf,dz))<0)
- return(exit_status);
- for(n = 0;n < dz->ssampsread - 1;n++) {
- if(ibuf[n] > gate || ibuf[n] < ngate) {
- gotstart = TRUE;
- break;
- }
- }
- if(gotstart) {
- *startsamp = n + (thisbuff * dz->buflen);
- *startsamp = (*startsamp/chans) * chans; /* align to channel group boundary */
- break;
- }
- thisbuff++;
- }
- if(!gotstart) {
- sprintf(errstr,"Entire file is below gate level\n");
- return(GOAL_FAILED);
- }
- return(FINISHED);
- }
- /******************************* GET_ENDSAMP *******************************/
- //RWD based on SECSIZE-aligned
- //TW: No, just searching for last sample above gate
- int get_endsamp(float *ibuf,int chans,int nbuff,int *endsamp,double gate,double ngate,dataptr dz)
- {
- int exit_status;
- int n;
- int gotend = FALSE;
- int thisbuff = nbuff - 1; /* buffer that contains last sample */
- while(!gotend && thisbuff >= 0) {
- if(sndseekEx(dz->ifd[0],thisbuff * dz->buflen,0)<0) {
- sprintf(errstr,"sndseek() failed: 1\n");
- return(SYSTEM_ERROR);
- }
- if((exit_status = read_samps(ibuf,dz))<0)
- return(exit_status);
- for(n = dz->ssampsread - 1;n>=0;n--) {
- if(ibuf[n] > gate || ibuf[n] < ngate) {
- gotend = TRUE;
- break;
- }
- }
- if(gotend) {
- *endsamp = n + (thisbuff * dz->buflen);
- *endsamp = (*endsamp/chans) * chans; /* align to channel group boundary */
- break;
- }
- thisbuff--;
- }
- if(!gotend) {
- sprintf(errstr,"Entire file is below gate level.\n");
- return(GOAL_FAILED);
- }
- return(FINISHED);
- }
- /******************************* DO_STARTSPLICE *******************************/
- int do_startsplice(int splicecnt,int startsamp,int *sampseek,int input_report,dataptr dz)
- {
- int exit_status;
- int chans = dz->infile->channels;
- int k, samps_written;
- double aincr, a1;
- int n;
- int m;
- if(sndseekEx(dz->ifd[0],startsamp,0)<0) {
- sprintf(errstr,"sndseek() failed: 3\n");
- return(SYSTEM_ERROR);
- }
- // NEW TW June 2004
- *sampseek = startsamp;
- if((exit_status = read_samps(dz->bigbuf,dz))<0) /* read buffer with additional sector */
- return(exit_status);
- k = 0;
- aincr = 1.0/(double)splicecnt;
- a1 = 0.0;
- for(n = 0;n < splicecnt;n++) {
- for(m = 0; m < chans; m++) {
- dz->bigbuf[k] = (float) ((double)dz->bigbuf[k] * a1);
- k++;
- }
- if(k >= dz->ssampsread) {
- if(input_report) {
- if((exit_status = write_samps_no_report(dz->bigbuf,dz->buflen,&samps_written,dz))<0)
- return(exit_status);
- } else {
- if((exit_status = write_samps(dz->bigbuf,dz->buflen,dz))<0)
- return(exit_status);
- }
- *sampseek += dz->ssampsread;
- if((exit_status = read_samps(dz->bigbuf,dz))<0) /*RWD added * */
- return(exit_status);
- if(dz->ssampsread <=0)
- return(FINISHED);
- k = 0;
- }
- a1 += aincr;
- }
- return(FINISHED);
- }
- /******************************* ADVANCE_TO_ENDSAMP *******************************/
- int advance_to_endsamp(int endsamp,int *sampseek,int input_report,dataptr dz)
- {
- int exit_status;
- int samps_written;
- while(endsamp > *sampseek + dz->ssampsread) {
- if(dz->ssampsread > 0) {
- if(input_report) {
- if((exit_status = write_samps_no_report(dz->bigbuf,dz->ssampsread,&samps_written,dz))<0)
- return(exit_status);
- } else {
- if((exit_status = write_samps(dz->bigbuf,dz->ssampsread,dz))<0)
- return(exit_status);
- }
- }
- *sampseek += dz->ssampsread;
- if((exit_status = read_samps(dz->bigbuf,dz))<0)
- return(exit_status);
- if(dz->ssampsread ==0) {
- return FINISHED;
- }
- }
- return(FINISHED);
- }
- /******************************* DO_END_SPLICE *******************************/
- /*k = nSAMPS*/
- int do_end_splice(int *k,int splicecnt,int input_report,dataptr dz)
- {
- int exit_status;
- int chans = dz->infile->channels;
- int n, samps_written;
- int m;
- double aincr = -(1.0/splicecnt);
- double a1 = 1.0 + aincr;
- for(n = 0;n < splicecnt;n++) {
- for(m = 0; m < chans; m++) {
- dz->bigbuf[*k] = (float) ((double)dz->bigbuf[*k] * a1);
- (*k)++;
- }
- if(*k >= dz->ssampsread) {
- if(dz->ssampsread > 0) {
- if(input_report) {
- if((exit_status = write_samps_no_report(dz->bigbuf,dz->ssampsread,&samps_written,dz))<0)
- return(exit_status);
- } else {
- if((exit_status = write_samps(dz->bigbuf,dz->ssampsread,dz))<0)
- return(exit_status);
- }
- }
- if((exit_status = read_samps(dz->bigbuf,dz))<0)
- return(exit_status);
- if(dz->ssampsread <=0) {
- return(FINISHED);
- }
- *k = 0;
- }
- a1 += aincr;
- }
- return(FINISHED);
- }
- /******************************* DO_CUTGATE ****************************/
- int do_cutgate(dataptr dz)
- {
- int exit_status;
- int n, ccnt = 0;
- int outsize, samps_written;
- char *thisfilename;
- double val;
- dz->sbufptr[ENV] = dz->sampbuf[ENV];
- fprintf(stdout,"INFO: Extracting envelope.\n");
- fflush(stdout);
- if((exit_status = ggetenv(dz))<0)
- return(exit_status);
- switch(dz->mode) {
- case(HOUSE_CUTGATE_PREVIEW):
- outsize = dz->iparam[CUTGATE_NUMSECS];
- if(outsize > 0) {
- if((exit_status = write_samps_no_report(dz->sampbuf[ENV],outsize,&samps_written,dz))<0)
- return(exit_status);
- }
- dz->infile->channels = 1;
- dz->infile->srate = SR_DEFAULT;
- break;
- case(HOUSE_CUTGATE):
- display_virtual_time(0,dz);
- dz->sbufptr[ENV] = dz->sampbuf[ENV];
- fprintf(stdout,"INFO: Finding cutpoints.\n");
- fflush(stdout);
- if(dz->iparam[CUTGATE_SUSTAIN]>0) {
- if((exit_status = findcuts2(&ccnt,dz))<0)
- return(exit_status);
- } else if((exit_status = findcuts(&ccnt,dz))<0)
- return(exit_status);
- if(ccnt==0) {
- sprintf(errstr,"No segments to extract at this gatelevel.\n");
- return(GOAL_FAILED);
- }
- if((exit_status = setup_naming(&thisfilename,dz))<0)
- return(exit_status);
- fprintf(stdout,"INFO: Cutting file.\n");
- fflush(stdout);
- // MULTICHAN -->
- dz->outchans = dz->infile->channels;
- // <-- MULTICHAN
- if((exit_status = reset_peak_finder(dz))<0)
- return(exit_status);
- for(n=0;n<ccnt;n++) {
- if (ccnt > 9999) {
- fprintf(stdout,"WARNING: More than 9999 segments: Finishing here\n");
- fflush(stdout);
- free(thisfilename);
- return(FINISHED);
- }
- reset_filedata_counters(dz);
- if(sndseekEx(dz->ifd[0],0,0)<0) {
- sprintf(errstr,"sndseek() failed.\n");
- return(SYSTEM_ERROR);
- }
- if((exit_status = create_outfile_name(n,thisfilename,dz))<0)
- return(exit_status);
- if((exit_status = output_cut_sndfile(n,thisfilename,dz))<0)
- return(exit_status);
- }
- free(thisfilename);
- fprintf(stdout,"INFO: %d segments extracted.\n",ccnt);
- fflush(stdout);
- break;
- //TW UPDATE : NEW CASE
- case(HOUSE_ONSETS):
- display_virtual_time(0,dz);
- dz->sbufptr[ENV] = dz->sampbuf[ENV];
- fprintf(stdout,"INFO: Finding cutpoints.\n");
- fflush(stdout);
- if((exit_status = find_onset_cuts(&ccnt,dz))<0)
- return(exit_status);
- if(ccnt==0) {
- sprintf(errstr,"No segments to extract at this gatelevel.\n");
- return(GOAL_FAILED);
- }
- for(n=0;n<ccnt;n++) {
- val = (double)(dz->lparray[CUTGATE_STIME][n]/dz->infile->channels)/(double)dz->infile->srate;
- fprintf(dz->fp,"%.6lf\n",val);
- }
- fprintf(stdout,"INFO: %d segments extracted.\n",ccnt);
- fflush(stdout);
- break;
- }
- return(FINISHED);
- }
- /******************************** GGETENV ******************************/
- int ggetenv(dataptr dz)
- {
- int exit_status;
- int n;
- int sampstoget;
- float *realend;
- display_virtual_time(0,dz);
- realend = dz->sampbuf[ENV] + dz->iparam[CUTGATE_NUMSECS];
- /* 1ST PASS : WHOLE BUFFERS */
- for(n = 0; n < dz->iparam[CUTGATE_NBUFS]; n++) {
- if((exit_status = read_samps(dz->bigbuf,dz))<0)
- return(exit_status);
- readenv(dz->buflen,&(dz->sbufptr[ENV]),dz);
- display_virtual_time(dz->total_samps_read,dz);
- }
- /* 2ND PASS : WHOLE SHRTBLOKS */
- sampstoget = dz->iparam[CUTGATE_NSEC] * dz->iparam[CUTGATE_SAMPBLOK];
- if((dz->ssampsread = fgetfbufEx(dz->bigbuf, sampstoget,dz->ifd[0],0))!=sampstoget) {
- sprintf(errstr,"Sound read anomaly.\n");
- if(dz->ssampsread < 0)
- return(SYSTEM_ERROR);
- return(PROGRAM_ERROR);
- }
- readenv(sampstoget,&(dz->sbufptr[ENV]),dz);
- dz->sbufptr[ENVEND] = dz->sbufptr[ENV]; /* end of data */
- while(dz->sbufptr[ENV] < realend + dz->iparam[CUTGATE_WINDOWS]) { /* pad end of buffer with zeroes */
- *dz->sbufptr[ENV] = 0;
- dz->sbufptr[ENV]++;
- }
- dz->sbufptr[ENV] = dz->sampbuf[ENV];
- display_virtual_time(dz->total_samps_read,dz);
- return(FINISHED);
- }
- /****************************** SEARCHPARS ******************************/
- void searchpars(dataptr dz)
- {
- int searchsize;
- dz->iparam[CUTGATE_NUMSECS] = dz->insams[0]/dz->iparam[CUTGATE_SAMPBLOK];
- searchsize = dz->iparam[CUTGATE_NUMSECS] * dz->iparam[CUTGATE_SAMPBLOK];
- dz->iparam[CUTGATE_NBUFS] = searchsize/dz->buflen; /* no. of whole buffs to search */
- dz->iparam[CUTGATE_NSEC] = (searchsize%dz->buflen)/dz->iparam[CUTGATE_SAMPBLOK]; /* no. further secs to search */
- return;
- }
- /************************* READENV *******************************/
- void readenv(int samps_to_process,float **env,dataptr dz)
- { int d;
- for(d=0; d<samps_to_process; d+=dz->iparam[CUTGATE_SAMPBLOK]) {
- get_maxsamp(*env,d,dz);
- (*env)++;
- }
- }
- /*************************** GET_MAXSAMP ******************************/
- void get_maxsamp(float *env,int startsamp,dataptr dz)
- {
- int i, endsamp = startsamp + dz->iparam[CUTGATE_SAMPBLOK];
- double thisenv = 0;
- for(i = startsamp; i<endsamp; i++)
- thisenv = max(thisenv,fabs(dz->bigbuf[i]));
- *env = (float)min(thisenv,F_MAXSAMP); /* avoids overflowing */
- }
- /**************************** FINDCUTS ********************************
- *
- * (1)
- * (2) If we are NOT inside a sound-to-keep.
- * (3) If the level is below the gate level..
- * (4) Ignore and continue..
- * (5) If the sound is above gate level..
- * mark this as (potential) start of a sound-to-keep
- * (6) flag sound-to-keep
- * (7) set the maximum level in segment to a minimum (0)
- * (8) If we are INSIDE a sound-to-keep
- * (9) If the sound level drops below gate
- * (10) Check that 'dz->iparam[CUTGATE_WINDOWS]' succeeding segments are below gate level..
- * (11) If this is true,
- * (12) if the maximum level in sound-to-keep exceeded dz->iparam[CUTGATE_THRESH]..
- * save the sound start and end times..
- * (13) In ANY case, mark that we are NO LONGER in a sound-to-keep.
- * If it is NOT true, we are still INSIDE a sound-to-keep..
- * (14) If however, the sound is above the gate
- * (15) Check level of sound, and readjust maxlevel, if necessary..
- */
- int findcuts(int *ccnt,dataptr dz)
- {
- int exit_status, tooshort_segs = 0, tooquiet_segs = 0;
- int startsec = 0, endsec;
- int inside_sound = FALSE, OK, n;
- // float maxlevel = 0, keepit = FALSE;
- float maxlevel = 0;
- float *bak, *endbak;
- int minlen = max(dz->iparam[CUTGATE_SPLEN] * 2,dz->iparam[CUTGATE_MINLEN]);
- double gate = dz->param[CUTGATE_GATE] * (double)F_MAXSAMP;
- double endgate = dz->param[CUTGATE_ENDGATE] * (double)F_MAXSAMP;
- double initlevel = dz->param[CUTGATE_INITLEVEL] * (double)F_MAXSAMP;
- double threshold = dz->param[CUTGATE_THRESH] * (double)F_MAXSAMP;
-
- while(dz->sbufptr[ENV]<dz->sbufptr[ENVEND]) {
- switch(inside_sound) { /* 1 */
- case(FALSE): /* 2 */
- if(*(dz->sbufptr[ENV]) <= gate) /* 3 */
- break; /* 4 */
- if(dz->iparam[CUTGATE_BAKTRAK]) {
- bak = dz->sbufptr[ENV];
- if((endbak = dz->sbufptr[ENV] - dz->iparam[CUTGATE_BAKTRAK]) < dz->sampbuf[ENV])
- endbak = dz->sampbuf[ENV];
- while(bak>endbak) {
- if(*(bak-1) >= initlevel)
- bak--;
- else
- break;
- }
- startsec = bak - dz->sampbuf[ENV];
- } else
- startsec = dz->sbufptr[ENV] - dz->sampbuf[ENV]; /* 5 */
- inside_sound = /*1*/TRUE; /* 6 */ /*RWD was 1 */
- maxlevel = *(dz->sbufptr[ENV]); /* 7 */
- break;
- case(TRUE): /* 8 */
- if(*(dz->sbufptr[ENV]) <= endgate) { /* 9 */
- OK = TRUE;
- if(dz->iparam[CUTGATE_WINDOWS]>0) {
- for(n=1;n<dz->iparam[CUTGATE_WINDOWS];n++) { /* 10 */
- if(*(dz->sbufptr[ENV]+n)>endgate) {
- OK = FALSE;
- break;
- }
- }
- }
- if(OK) { /* 11 */
- endsec = dz->sbufptr[ENV] - dz->sampbuf[ENV];
- if((endsec - startsec) * dz->iparam[CUTGATE_SAMPBLOK] > minlen) {
- if(maxlevel >= threshold) { /* 12 */
- if((exit_status = store_cut_positions_in_samples(*ccnt,startsec,endsec,dz))<0)
- return(exit_status);
- (*ccnt)++;
- } else {
- tooquiet_segs++;
- }
- } else {
- tooshort_segs++;
- }
- inside_sound = FALSE; /* 13 */
- }
- } else { /* 14 */
- if(*(dz->sbufptr[ENV]) > maxlevel) /* 15 */
- maxlevel = *(dz->sbufptr[ENV]);
- }
- break;
- }
- (dz->sbufptr[ENV])++;
- }
- if(inside_sound) { /* Ensure any significant block at very end is grabbed */
- endsec = dz->sbufptr[ENV] - dz->sampbuf[ENV];
- if((endsec - startsec) * dz->iparam[CUTGATE_SAMPBLOK] > minlen) {
- if(maxlevel >= threshold) { /* 12 */
- if((exit_status = store_cut_positions_in_samples(*ccnt,startsec,endsec,dz))<0)
- return(exit_status);
- (*ccnt)++;
- } else {
- tooquiet_segs++;
- }
- } else {
- tooshort_segs++;
- }
- }
- if(*ccnt <= 0) {
- if(tooshort_segs || tooquiet_segs) {
- if(tooshort_segs && tooquiet_segs)
- sprintf(errstr,"%d segments shorter than min duration set (or twice splicelen), and %d too quiet.\n",tooshort_segs,tooquiet_segs);
- else if(tooquiet_segs)
- sprintf(errstr,"%d segments to extract are too quiet (below threshold you set).\n",tooquiet_segs);
- else
- sprintf(errstr,"%d segments are shorter than minimum duration you set, or than twice splicelen.\n",tooshort_segs);
- } else {
- sprintf(errstr,"Whole file is below the gate level.\n");
- }
- return(GOAL_FAILED);
- }
- return(FINISHED);
- }
- /******************************* FINDCUTS2 ******************************/
- int findcuts2(int *ccnt,dataptr dz)
- {
- int exit_status, tooshort_segs = 0;
- int oldstartsec = 0, startsec, endsec;
- int inside_sound = FALSE, OK, n;
- /*short maxlevel = 0, keepit = FALSE, *bak, *endbak;*/
- //TW UPDATE : prevents WARNING
- int keepit = FALSE;
- float maxlevel = 0.0f, *bak, *endbak;
- int minlen = max(dz->iparam[CUTGATE_SPLEN] * 2,dz->iparam[CUTGATE_MINLEN]);
- double gate = dz->param[CUTGATE_GATE] * (double)F_MAXSAMP;
- double endgate = dz->param[CUTGATE_ENDGATE] * (double)F_MAXSAMP;
- double threshold = dz->param[CUTGATE_THRESH] * (double)F_MAXSAMP;
- double initlevel = dz->param[CUTGATE_INITLEVEL] * (double)F_MAXSAMP;
- while(dz->sbufptr[ENV]<dz->sbufptr[ENVEND]) {
- switch(inside_sound) { /* 1 */
- case(FALSE): /* 2 */
- if(*(dz->sbufptr[ENV]) <= gate) /* 3 */
- break; /* 4 */
- if(dz->iparam[CUTGATE_BAKTRAK]) {
- bak = dz->sbufptr[ENV];
- if((endbak = dz->sbufptr[ENV] - dz->iparam[CUTGATE_BAKTRAK]) < dz->sampbuf[ENV])
- endbak = dz->sampbuf[ENV];
- while(bak>endbak) {
- if(*(bak-1) >= initlevel)
- bak--;
- else
- break;
- }
- startsec = bak - dz->sampbuf[ENV];
- } else
- startsec = dz->sbufptr[ENV] - dz->sampbuf[ENV]; /* 5 */
- if(keepit && ((endsec = startsec - dz->iparam[CUTGATE_SUSTAIN]) > oldstartsec)) {
- if((endsec - oldstartsec) * dz->iparam[CUTGATE_SAMPBLOK] > minlen) {
- if((exit_status =
- store_cut_positions_in_samples(*ccnt,oldstartsec,startsec - dz->iparam[CUTGATE_SUSTAIN],dz))<0)
- return(exit_status);
- (*ccnt)++;
- } else {
- tooshort_segs = 1;
- }
- }
- keepit = FALSE;
- oldstartsec = startsec;
- inside_sound = /*1*/TRUE; /* 6 */
- maxlevel = *(dz->sbufptr[ENV]); /* 7 */
- break;
- case(TRUE): /* 8 */
- if(*(dz->sbufptr[ENV]) <= endgate) { /* 9 */
- OK = TRUE;
- if(dz->iparam[CUTGATE_WINDOWS]>0) {
- for(n=1;n<dz->iparam[CUTGATE_WINDOWS];n++) { /* 10 */
- if(*(dz->sbufptr[ENV]+n)>gate) {
- OK = FALSE;
- break;
- }
- }
- }
- if(OK) { /* 11 */
- if(maxlevel > threshold) /* 12 */
- keepit = TRUE;
- else
- keepit = FALSE;
- inside_sound = FALSE; /* 13 */
- }
- } else { /* 14 */
- if(*(dz->sbufptr[ENV]) > maxlevel) /* 15 */
- maxlevel = *(dz->sbufptr[ENV]);
- }
- break;
- }
- (dz->sbufptr[ENV])++;
- }
- endsec = dz->sbufptr[ENVEND] - dz->sampbuf[ENV];
- if(keepit && ((endsec - oldstartsec) * dz->iparam[CUTGATE_SAMPBLOK]) > minlen) {
- if(maxlevel >= threshold) { /* 12 */
- if((exit_status = store_cut_positions_in_samples(*ccnt,oldstartsec,endsec,dz))<0)
- return(exit_status);
- }
- (*ccnt)++;
- }
- if((*ccnt <= 0) && tooshort_segs) {
- sprintf(errstr,"Segments to extract are shorter than minimum duration you set, or than twice splicelen.\n");
- return(GOAL_FAILED);
- }
- return(FINISHED);
- }
- /******************************* SETUP_NAMING ******************************/
- int setup_naming(char **thisfilename,dataptr dz)
- {
- int innamelen = strlen(dz->wordstor[0]);
- int numlen = 5;
- if((*thisfilename = (char *)malloc((innamelen + numlen + 1) * sizeof(char)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY for outfilename.\n");
- return(MEMORY_ERROR);
- }
- return(FINISHED);
- }
- /********************************** CREATE_OUTFILE_NAME ********************************/
- int create_outfile_name(int ccnt,char *thisfilename,dataptr dz)
- {
- //TW REVISED Dec 2002
- strcpy(thisfilename,dz->wordstor[0]);
- insert_new_number_at_filename_end(thisfilename,ccnt,1);
- return(FINISHED);
- }
- /********************************** OUTPUT_CUT_SNDFILE ********************************/
- int output_cut_sndfile(int ccnt,char *filename,dataptr dz)
- {
- int exit_status;
- // int firsttime = TRUE;
- int sampseek, startsamp, endsamp, k, samps_to_write, samps_written;
- dz->process_type = UNEQUAL_SNDFILE; /* allow sndfile to be created */
- if((exit_status = create_sized_outfile(filename,dz))<0) {
- fprintf(stdout, "WARNING: Soundfile %s already exists.\n", filename);
- fflush(stdout);
- dz->process_type = OTHER_PROCESS;
- dz->ofd = -1;
- if(dz->vflag[STOP_ON_SAMENAME])
- return(GOAL_FAILED);
- return(FINISHED);
- }
- startsamp = dz->lparray[CUTGATE_STIME][ccnt];
- sampseek = startsamp;
- if((exit_status= do_startsplice(dz->iparam[CUTGATE_SPLCNT],startsamp,&sampseek,1,dz))<0)
- return(exit_status);
- endsamp = dz->lparray[CUTGATE_ETIME][ccnt] - dz->iparam[CUTGATE_SPLEN];
- if((exit_status = advance_to_endsamp(endsamp,&sampseek,1,dz))<0)
- return(exit_status);
- k = endsamp - sampseek;
- if((exit_status = do_end_splice(&k,dz->iparam[CUTGATE_SPLCNT],1,dz))<0)
- return(exit_status);
- if((samps_to_write = k)>0) {
- if((exit_status = write_samps_no_report(dz->bigbuf,samps_to_write,&samps_written,dz))<0)
- return(exit_status);
- }
- display_virtual_time(startsamp + dz->total_samps_read,dz);
- dz->outfiletype = SNDFILE_OUT; /* allows header to be written */
- if((exit_status = headwrite(dz->ofd,dz))<0)
- return(exit_status);
- dz->process_type = OTHER_PROCESS; /* restore true status */
- dz->outfiletype = NO_OUTPUTFILE; /* restore true status */
- if((exit_status = reset_peak_finder(dz))<0)
- return(exit_status);
- if(sndcloseEx(dz->ofd) < 0) {
- fprintf(stdout,"WARNING: Can't close output soundfile %s\n",filename);
- fflush(stdout);
- }
- dz->ofd = -1;
- return(FINISHED);
- }
- /********************************** STORE_CUT_POSITIONS_IN_SAMPLES ********************************/
- int store_cut_positions_in_samples(int ccnt,int startsec,int endsec,dataptr dz)
- {
- if(ccnt==0) {
- if((dz->lparray[CUTGATE_STIME] = (int *)malloc(sizeof(int)))==NULL
- || (dz->lparray[CUTGATE_ETIME] = (int *)malloc(sizeof(int)))==NULL) {
- sprintf(errstr,"INSUFFICENT MEMORY to store cut times.\n");
- return(MEMORY_ERROR);
- }
- } else {
- if((dz->lparray[CUTGATE_STIME] =
- (int *)realloc(dz->lparray[CUTGATE_STIME],(ccnt+1) * sizeof(int)))==NULL
- || (dz->lparray[CUTGATE_ETIME] =
- (int *)realloc(dz->lparray[CUTGATE_ETIME],(ccnt+1) * sizeof(int)))==NULL) {
- sprintf(errstr,"INSUFFICENT MEMORY to store more cut times.\n");
- return(MEMORY_ERROR);
- }
- }
- dz->lparray[CUTGATE_STIME][ccnt] = startsec * dz->iparam[CUTGATE_SAMPBLOK];
- dz->lparray[CUTGATE_ETIME][ccnt] = endsec * dz->iparam[CUTGATE_SAMPBLOK];
- return(FINISHED);
- }
- /********************************** DO_RECTIFY ********************************/
- int do_rectify(dataptr dz)
- {
- int exit_status;
- int n;
- float *buf = dz->sampbuf[0], maxsamp, minsamp;
- double rectify_shift = dz->param[RECTIFY_SHIFT] * (double)F_MAXSAMP;
- if(flteq(rectify_shift,0.0)) {
- sprintf(errstr,"NO CHANGE to original sound file.\n");
- return(GOAL_FAILED);
- }
- if(rectify_shift > 0.0) {
- fprintf(stdout,"INFO: Finding maximum sample in file.\n");
- fflush(stdout);
- maxsamp = F_MINSAMP;
- while(dz->samps_left > 0) {
- if((exit_status = read_samps(buf,dz))<0)
- return(exit_status);
- for(n= 0;n<dz->ssampsread;n++)
- maxsamp = max(maxsamp,buf[n]);
- }
- if(maxsamp + rectify_shift > (double)F_MAXSAMP) {
- sprintf(errstr,"This rectification will distort the sound.\n");
- return(GOAL_FAILED);
- }
- } else {
- fprintf(stdout,"INFO: Finding minimum sample in file.\n");
- fflush(stdout);
- // minsamp = MAXSAMP;
- minsamp = F_MAXSAMP;
- while(dz->samps_left > 0) {
- if((exit_status = read_samps(buf,dz))<0)
- return(exit_status);
- for(n= 0;n<dz->ssampsread;n++)
- minsamp = min(minsamp,buf[n]);
- }
- if(minsamp + rectify_shift < (double)F_MINSAMP) {
- sprintf(errstr,"This rectification will distort the sound.\n");
- return(GOAL_FAILED);
- }
- }
- reset_filedata_counters(dz);
- if(sndseekEx(dz->ifd[0],0,0)<0) {
- sprintf(errstr,"sndseekEx failed.\n");
- return(SYSTEM_ERROR);
- }
- fprintf(stdout,"INFO: Rectifying.\n");
- fflush(stdout);
- while(dz->samps_left > 0) {
- if((exit_status = read_samps(buf,dz))<0)
- return(exit_status);
- for(n= 0;n<dz->ssampsread;n++)
- buf[n] = (float)(buf[n] + rectify_shift);
- if(dz->ssampsread > 0) {
- if((exit_status = write_exact_samps(buf,dz->ssampsread,dz))<0)
- return(exit_status);
- }
- }
- return(FINISHED);
- }
- //TW FUNCTION NOW REDUNDANT
- /********************************** DO_BY_HAND ********************************/
- //
- //int do_by_hand(dataptr dz)
- //{
- // int n = 0, all_fixes_done = 0, exit_status;
- // int k, last_total_ssampsread = 0;
- // double *la = dz->parray[0];
- // float *buf = dz->sampbuf[0];
- //
- // while(dz->samps_left > 0) {
- // if((exit_status = read_samps(buf,dz))<0)
- // return(exit_status);
- // if(!all_fixes_done) {
- // while(dz->total_samps_read > *la) {
- // k = round(*la++) - last_total_ssampsread;
- /* NOT SHORT, IF BUFS NOT SHORT : 2000 */
- // buf[k] = (float)(*la++);
- // if(la >= dz->parray[1]) {
- // all_fixes_done = 1;
- // break;
- // }
- // }
- // last_total_ssampsread = dz->total_samps_read;
- // }
- // if((exit_status = write_samps(buf,dz->ssampsread,dz))<0)
- // return(exit_status);
- // }
- // return(FINISHED);
- //}
- //
- //TW UPDATE: NEW FUNCTIONS BELOW (updated for flotsams)
- /**************************** FIND_ONSET_CUTS *********************************/
- int find_onset_cuts(int *ccnt,dataptr dz)
- {
- int exit_status, tooshort_segs = 0, tooquiet_segs = 0;
- int startsec = 0, endsec;
- int inside_sound = FALSE, OK, n = 0;
- // short keepit = FALSE;
- float maxlevel = 0;
- float *bak, *endbak, *minpos, *here, minval;
- int minlen = dz->iparam[CUTGATE_MINLEN];
- double gate = dz->param[CUTGATE_GATE] * (double)F_MAXSAMP;
- double endgate = dz->param[CUTGATE_ENDGATE] * (double)F_MAXSAMP;
- double initlevel = dz->param[CUTGATE_INITLEVEL] * (double)F_MAXSAMP;
- double threshold = dz->param[CUTGATE_THRESH] * (double)F_MAXSAMP;
-
- int envlen = dz->sbufptr[ENVEND] - dz->sbufptr[ENV];
- int ratio = dz->insams[0]/envlen;
- int envstep = envlen/10, envmark = envstep;
- while(dz->sbufptr[ENV]<dz->sbufptr[ENVEND]) {
- switch(inside_sound) { /* 1 */
- case(FALSE): /* 2 */
- if(*(dz->sbufptr[ENV]) <= gate) /* 3 */
- break; /* 4 */
- if(dz->iparam[CUTGATE_BAKTRAK]) {
- bak = dz->sbufptr[ENV];
- if((endbak = dz->sbufptr[ENV] - dz->iparam[CUTGATE_BAKTRAK]) < dz->sampbuf[ENV])
- endbak = dz->sampbuf[ENV];
- while(bak>endbak) {
- if(*(bak-1) > endgate) {
- minval = *bak;
- minpos = bak;
- for(here = bak+1;here <= dz->sbufptr[ENV];here++) {
- if(*here < minval) {
- minval = *here;
- minpos = here;
- }
- }
- bak = minpos;
- break;
- } else if(*(bak-1) >= initlevel)
- bak--;
- else
- break;
- }
- startsec = bak - dz->sampbuf[ENV];
- } else
- startsec = dz->sbufptr[ENV] - dz->sampbuf[ENV]; /* 5 */
- inside_sound = 1; /* 6 */
- maxlevel = *(dz->sbufptr[ENV]); /* 7 */
- break;
- case(TRUE): /* 8 */
- if(*(dz->sbufptr[ENV]) <= endgate) { /* 9 */
- OK = TRUE;
- if(dz->iparam[CUTGATE_WINDOWS]>0) {
- for(n=1;n<dz->iparam[CUTGATE_WINDOWS];n++) { /* 10 */
- if(*(dz->sbufptr[ENV]+n)>endgate) {
- OK = FALSE;
- break;
- }
- }
- }
- if(OK) { /* 11 */
- endsec = dz->sbufptr[ENV] - dz->sampbuf[ENV];
- if((endsec - startsec) * dz->iparam[CUTGATE_SAMPBLOK] > minlen) {
- if(maxlevel >= threshold) { /* 12 */
- if((exit_status = store_startcut_positions_in_samples(*ccnt,startsec,dz))<0)
- return(exit_status);
- (*ccnt)++;
- } else {
- tooquiet_segs = 1;
- }
- } else {
- tooshort_segs = 1;
- }
- inside_sound = FALSE; /* 13 */
- }
- } else { /* 14 */
- if(*(dz->sbufptr[ENV]) > maxlevel) /* 15 */
- maxlevel = *(dz->sbufptr[ENV]);
- }
- break;
- }
- (dz->sbufptr[ENV])++;
- if(++n > envmark) {
- if(sloom) {
- envmark += envstep;
- display_virtual_time(n * ratio,dz);
- }
- }
- }
- if(inside_sound) { /* Ensure any significant block at very end is grabbed */
- endsec = dz->sbufptr[ENV] - dz->sampbuf[ENV];
- if((endsec - startsec) * dz->iparam[CUTGATE_SAMPBLOK] > minlen) {
- if(maxlevel >= threshold) { /* 12 */
- if((exit_status = store_cut_positions_in_samples(*ccnt,startsec,endsec,dz))<0)
- return(exit_status);
- (*ccnt)++;
- } else {
- tooquiet_segs++;
- }
- } else {
- tooshort_segs++;
- }
- }
- if(*ccnt <= 0) {
- if(tooshort_segs || tooquiet_segs) {
- if(tooshort_segs && tooquiet_segs)
- sprintf(errstr,"%d segments shorter than min duration set (or twice splicelen), and %d too quiet.\n",tooshort_segs,tooquiet_segs);
- else if(tooquiet_segs)
- sprintf(errstr,"%d segments to extract are too quiet (below threshold you set).\n",tooquiet_segs);
- else
- sprintf(errstr,"%d segments are shorter than minimum duration you set, or than twice splicelen.\n",tooshort_segs);
- } else {
- sprintf(errstr,"Whole file is below the gate level.\n");
- }
- return(GOAL_FAILED);
- }
- return(FINISHED);
- }
- /********************************** STORE_STARTCUT_POSITIONS_IN_SAMPLES ********************************/
- int store_startcut_positions_in_samples(int ccnt,int startsec,dataptr dz)
- {
- if(ccnt==0) {
- if((dz->lparray[CUTGATE_STIME] = (int *)malloc(sizeof(int)))==NULL) {
- sprintf(errstr,"INSUFFICENT MEMORY to store cut times.\n");
- return(MEMORY_ERROR);
- }
- } else {
- if((dz->lparray[CUTGATE_STIME] =
- (int *)realloc(dz->lparray[CUTGATE_STIME],(ccnt+1) * sizeof(int)))==NULL) {
- sprintf(errstr,"INSUFFICENT MEMORY to store more cut times.\n");
- return(MEMORY_ERROR);
- }
- }
- dz->lparray[CUTGATE_STIME][ccnt] = startsec * dz->iparam[CUTGATE_SAMPBLOK];
- return(FINISHED);
- }
- /********************************** HOUSE_GATE ********************************/
- int house_gate(dataptr dz)
- {
- int exit_status;
- int gotfirst = 0;
- // int zerosgot = 0, finished = 0, cutcount = 0, chans = dz->infile->channels;
- int zerosgot = 0, finished = 0, chans = dz->infile->channels;
- int startsamp = 0, arraysize = BIGARRAY, n, i, j;
- // int samps_to_get = dz->buflen, samps_to_write;
- int samps_to_write;
- int *cutpoint;
- // int total_samps_read = 0, cutcnt = 0, secseek;
- int total_samps_read = 0, cutcnt = 0;
- char *thisfilename;
- int endsamp;
- if((cutpoint = (int *)malloc(arraysize * sizeof(int)))==NULL) {
- sprintf(errstr,"Insufficient memory to store cutting points.\n");
- return(MEMORY_ERROR);
- }
- display_virtual_time(0,dz);
- fprintf(stdout,"INFO: Finding cutpoints.\n");
- fflush(stdout);
- if((exit_status = read_samps(dz->sampbuf[1],dz)) < 0) {
- sprintf(errstr,"Sound read anomaly.\n");
- return(SYSTEM_ERROR);
- }
- total_samps_read += dz->ssampsread;
- display_virtual_time(total_samps_read,dz);
- n = dz->buflen;
- do {
- memcpy((char *)dz->sampbuf[0],(char *)dz->sampbuf[1],dz->buflen * sizeof(float));
- if(dz->ssampsread != dz->buflen)
- finished = 1;
- if(!finished) {
- if((exit_status = read_samps(dz->sampbuf[1],dz)) < 0) {
- sprintf(errstr,"Sound read anomaly.\n");
- return(SYSTEM_ERROR);
- }
- if(dz->ssampsread != dz->buflen) {
- total_samps_read += dz->ssampsread;
- display_virtual_time(total_samps_read,dz);
- }
- }
- n -= dz->buflen;
- if(!finished) {
- endsamp = max(dz->ssampsread,(dz->iparam[GATE_ZEROS] * chans));
- endsamp += dz->buflen;
- } else
- endsamp = dz->ssampsread;
-
- while(n<endsamp) {
- if(smpflteq(dz->sampbuf[0][n],0.0)) {
- if(!gotfirst) {
- n += chans;
- continue;
- }
- zerosgot++;
- if(zerosgot > dz->iparam[GATE_ZEROS]) {
- n += chans;
- continue;
- }
- else if(zerosgot == dz->iparam[GATE_ZEROS]) {
- cutpoint[cutcnt++] = (startsamp + n - ((dz->iparam[GATE_ZEROS]-1) * chans));
- if(cutcnt >= arraysize) {
- arraysize += BIGARRAY;
- if((cutpoint = (int *)realloc((char *)cutpoint,arraysize * sizeof(int)))==NULL) {
- sprintf(errstr,"Insufficient memory to store cutting points.\n");
- return(MEMORY_ERROR);
- }
- }
- }
- } else {
- if(!gotfirst) {
- cutpoint[cutcnt++] = (startsamp + n);
- gotfirst = 1;
- n += chans;
- continue;
- } else {
- if(zerosgot >= dz->iparam[GATE_ZEROS]) {
- cutpoint[cutcnt++] = (startsamp + n);
- if(cutcnt >= arraysize) {
- arraysize += BIGARRAY;
- if((cutpoint = (int *)realloc((char *)cutpoint,arraysize * sizeof(int)))==NULL) {
- sprintf(errstr,"Insufficient memory to store cutting points.\n");
- return(MEMORY_ERROR);
- }
- }
- }
- zerosgot = 0;
- }
- }
- n += chans;
- }
- startsamp += dz->buflen;
- } while(!finished);
- if(gotfirst) {
- if(zerosgot < dz->iparam[GATE_ZEROS])
- cutpoint[cutcnt++] = dz->insams[0];
- } else {
- sprintf(errstr,"No silent gaps found: no cuts made.\n");
- return(GOAL_FAILED);
- }
- if(!EVEN(cutcnt)) {
- sprintf(errstr,"cut points not paired correctly.\n");
- return(PROGRAM_ERROR);
- }
- cutcnt /= 2;
- if((exit_status = setup_naming(&thisfilename,dz))<0)
- return(exit_status);
- fprintf(stdout,"INFO: Cutting file.\n");
- fflush(stdout);
- // MULTICHAN -->
- dz->outchans = dz->infile->channels;
- // <-- MULTICHAN
- if((exit_status = reset_peak_finder(dz))<0)
- return(exit_status);
- display_virtual_time(0,dz);
- for(n = 0,i= 0,j=1; n < cutcnt; n++,i+=2,j+=2) {
- if (n > 1999) {
- fprintf(stdout,"WARNING: More than 9999 segments: Finishing here\n");
- fflush(stdout);
- free(thisfilename);
- return(FINISHED);
- }
- reset_filedata_counters(dz);
- if((exit_status = create_outfile_name(n,thisfilename,dz))<0)
- return(exit_status);
- dz->process_type = UNEQUAL_SNDFILE; /* allow sndfile to be created */
- if((exit_status = create_sized_outfile(thisfilename,dz))<0) {
- fprintf(stdout, "WARNING: Soundfile %s already exists.\n", thisfilename);
- fflush(stdout);
- dz->process_type = OTHER_PROCESS;
- dz->ofd = -1;
- return(FINISHED);
- }
- sndseekEx(dz->ifd[0],cutpoint[i],0);
- display_virtual_time(cutpoint[i],dz);
- if((exit_status = read_samps(dz->sampbuf[0],dz)) < 0) {
- sprintf(errstr,"Sound read anomaly.\n");
- return(SYSTEM_ERROR);
- }
- samps_to_write = cutpoint[j] - cutpoint[i];
-
- while(samps_to_write > dz->buflen) {
- if((exit_status = write_samps(dz->sampbuf[0],dz->buflen,dz))<0)
- return(exit_status);
- samps_to_write -= dz->buflen;
- if((exit_status = read_samps(dz->sampbuf[0],dz)) < 0) {
- sprintf(errstr,"Sound read anomaly.\n");
- return(SYSTEM_ERROR);
- }
- }
- if(samps_to_write) {
- if((exit_status = write_samps(dz->sampbuf[0],samps_to_write,dz))<0)
- return(exit_status);
- }
- dz->outfiletype = SNDFILE_OUT; /* allows header to be written */
- if((exit_status = headwrite(dz->ofd,dz))<0)
- return(exit_status);
- dz->process_type = OTHER_PROCESS; /* restore true status */
- dz->outfiletype = NO_OUTPUTFILE; /* restore true status */
- if((exit_status = reset_peak_finder(dz))<0)
- return(exit_status);
- if(sndcloseEx(dz->ofd) < 0) {
- fprintf(stdout,"WARNING: Can't close output soundfile %s\n",thisfilename);
- fflush(stdout);
- }
- dz->ofd = -1;
- }
- display_virtual_time(dz->insams[0],dz);
- free(thisfilename);
- fprintf(stdout,"INFO: %d segments extracted.\n",cutcnt);
- fflush(stdout);
- return(FINISHED);
- }
- /********************************** HOUSE_GATE2 ********************************/
- #define NOTHING_FOUND 0
- #define INTERGLITCH_FOUND 1
- #define MEASURING_GLITCH 2
- #define MEASURING_INTERGLITCH 3
- int house_gate2(dataptr dz)
- {
- int exit_status;
- float *ibuf = dz->sampbuf[0], *filtbuf, *maxsamp = NULL;
- int n, k, f, cnt, z = 0, possible_start = 0;
- int splicelen = dz->iparam[GATE2_SPLEN];
- double spliceratio, spliceincr = 1.0/(double)splicelen, sum, sum2, thissamp;
- int m, j, gotzero, search_state = 0, chans = dz->infile->channels;
- int nonzerosgot = 0, zerosgot = 0,*pos;
- int endcut = 0, startcut = 0, cutcnt, last_total_samps_read, endsplice, startsplice;
- int filtlen = dz->iparam[GATE2_FILT] * chans, filt_index;
- k = (int)ceil((double)dz->insams[0]/(double)(dz->iparam[GATE2_ZEROS] * chans));
- k += 2;
- k *= 2;
- if(k < 0 || ((dz->lparray[0] = (int *)malloc(k * sizeof(int)))==NULL)) {
- sprintf(errstr,"Insufficient memory to store glitch positions.\n");
- return(MEMORY_ERROR);
- }
- if((filtbuf = (float *)malloc(filtlen * sizeof(float)))==NULL) {
- sprintf(errstr,"Insufficient memory to create filter buffer.\n");
- return(MEMORY_ERROR);
- }
- if(dz->vflag[0]) {
- if((maxsamp = (float *)malloc((k/2) * sizeof(float)))==NULL) {
- sprintf(errstr,"No memory to store glitch maxima.\n");
- return(MEMORY_ERROR);
- }
- memset((char *)maxsamp,0,(k/2) * sizeof(float));
- }
- memset((char *)filtbuf,0,filtlen * sizeof(float));
- pos = dz->lparray[0];
- k = 0;
- fprintf(stdout,"INFO: Searching for glitches.\n");
- fflush(stdout);
- if((exit_status = read_samps(ibuf,dz))<0)
- return(exit_status);
- last_total_samps_read = 0;
- sum = 0;
- filt_index = 0;
- cnt = 0;
- while(dz->ssampsread > 0) {
- n = 0;
- while(n<dz->ssampsread) {
- cnt += chans;
- gotzero = 0;
- thissamp = 0.0;
- for(m=0;m < chans ;m++) { /* add samples cyclically to a buffer */
- filtbuf[filt_index++] = ibuf[n+m];
- thissamp += fabs(ibuf[n+m]);
- }
- filt_index %= filtlen; /* cycle around buffer */
- thissamp /= (double)chans; /* average abs size of samples in all channels at this point */
- cnt = min(cnt,filtlen);
- sum = 0.0; /* sum over filt buffer len, or total no of samps read, whichever is smaller */
- for(f = 0;f < cnt;f++)
- sum += fabs(filtbuf[f]);
- sum /= (double)cnt; /* find average abs samp val over last 'filtlen' samps */
- if(sum <= dz->param[GATE2_LEVEL])
- gotzero = 1;
- if(thissamp > dz->param[GATE2_LEVEL]) { /* note abs level of this sample */
- possible_start = n + last_total_samps_read;
- gotzero = 0;
- }
- if(gotzero) {
- nonzerosgot = 0;
- zerosgot++;
- switch(search_state) {
- case(NOTHING_FOUND): /* not yet enough pre-glitch sub-threshold signal */
- if(zerosgot >= dz->iparam[GATE2_ZEROS])
- search_state = INTERGLITCH_FOUND;
- break;
- case(INTERGLITCH_FOUND): /* already got enough pre-glitch sub-threshold signal */
- break;
- case(MEASURING_GLITCH): /* found glitch: mark end, prepare to measure post-glitch */
- endcut = last_total_samps_read + n;
- search_state = MEASURING_INTERGLITCH;
- break;
- case(MEASURING_INTERGLITCH): /* waiting for enough post-glitch, sub-threshold signal */
- if(zerosgot >= dz->iparam[GATE2_ZEROS]) {
- pos[k++] = startcut;
- pos[k++] = endcut;
- z++;
- search_state = INTERGLITCH_FOUND;
- } /* if enough found, also enough preglitch for next glitch */
- break;
- }
- } else {
- nonzerosgot++;
- zerosgot = 0;
- switch(search_state) {
- case(NOTHING_FOUND): /* not yet enough pre-glitch sub-threshold signal */
- break;
- case(INTERGLITCH_FOUND): /* enough signal before threshold, mark start of excision */
- startcut = possible_start;
- if(dz->vflag[0]) {
- f = filt_index - chans;
- maxsamp[z] = 0.0f;
- for(j = n + last_total_samps_read; j >= startcut; j-=chans, f -= chans) {
- if(f < 0) /* use filtbuf to find maxsamp between here & possible_start */
- f += filtlen;
- thissamp = 0.0;
- for(m=0;m < chans ;m++)
- thissamp += fabs(filtbuf[f+m]);
- thissamp /= (double)chans;
- maxsamp[z] = (float)max(thissamp,(double)maxsamp[z]);
- }
- }
- nonzerosgot += (n + last_total_samps_read - possible_start);
- search_state = MEASURING_GLITCH;
- break;
- case(MEASURING_GLITCH): /* measuring possible glitch: if too long, abandon */
- if(dz->vflag[0])
- maxsamp[z] = (float)max((double)maxsamp[z],thissamp);
- if(nonzerosgot > dz->iparam[GATE2_DUR])
- search_state = NOTHING_FOUND;
- break;
- case(MEASURING_INTERGLITCH): /* was waiting for enough postglitch 'ZEROS' but not enough */
- search_state = NOTHING_FOUND;
- break;
- }
- }
- n += chans;
- }
- last_total_samps_read += dz->ssampsread;
- if((exit_status = read_samps(ibuf,dz))<0)
- return(exit_status);
- }
- if(search_state == 2) {
- pos[k++] = startcut;
- pos[k++] = dz->insams[0];
- }
- cutcnt = k;
- fprintf(stdout,"INFO: glitches found = %d\n",k/2);
- fflush(stdout);
- if(dz->vflag[0]) {
- for(n=0,z=0;n<cutcnt;n+=2,z++) {
- k = (pos[n+1] - pos[n])/chans;
- sum = (double)(k * SECS_TO_MS)/(double)dz->infile->srate;
- k = pos[n]/chans;
- sum2 = (double)k/(double)dz->infile->srate;
- fprintf(stdout,"INFO: GLITCH length %.2lf ms : val %f : at (grouped)sample %d : time %lf secs\n",sum,maxsamp[z],k,sum2);
- }
- fflush(stdout);
- }
- if(cutcnt == 0) {
- sprintf(errstr,"None of the sound will be gated.\n");
- return(GOAL_FAILED);
- }
- sndseekEx(dz->ifd[0],0,0);
- reset_filedata_counters(dz);
- fprintf(stdout,"INFO: Gating the file.\n");
- fflush(stdout);
- last_total_samps_read = 0;
- if((exit_status = read_samps(ibuf,dz))<0)
- return(exit_status);
- for(k=0;k < cutcnt;k+=2) {
- startcut = pos[k] - last_total_samps_read;
- endsplice = startcut;
- startcut -= (splicelen * chans);
- if(startcut < 0) {
- sprintf(errstr,"Bad initial cut: program error.\n");
- return(PROGRAM_ERROR);
- }
- endcut = pos[k+1] - last_total_samps_read;
- startsplice = endcut;
- endcut += (splicelen * chans);
- if(endcut > dz->insams[0]) {
- endcut = dz->insams[0];
- n = endcut - startsplice;
- if(n!=0)
- spliceincr = 1.0/(double)(n/chans);
- }
- spliceratio = 1.0;
- n = startcut;
- while(n >= dz->ssampsread) {
- if((exit_status = write_samps(ibuf,dz->ssampsread,dz))<0)
- return(exit_status);
- last_total_samps_read = dz->total_samps_read;
- if((exit_status = read_samps(ibuf,dz))<0)
- return(exit_status);
- n -= dz->buflen;
- endsplice -= dz->buflen;
- startsplice -= dz->buflen;
- endcut -= dz->buflen;
- }
- while(n<endsplice) {
- spliceratio -= spliceincr;
- for(m=0;m<chans;m++)
- ibuf[n+m] = (float)(ibuf[n+m] * spliceratio);
- n += chans;
- if(n >= dz->ssampsread) {
- if((exit_status = write_samps(ibuf,dz->ssampsread,dz))<0)
- return(exit_status);
- last_total_samps_read = dz->total_samps_read;
- if((exit_status = read_samps(ibuf,dz))<0)
- return(exit_status);
- n -= dz->buflen;
- endsplice -= dz->buflen;
- startsplice -= dz->buflen;
- endcut -= dz->buflen;
- }
- }
- while(n < startsplice) {
- ibuf[n++] = 0.0f;
- if(n >= dz->ssampsread) {
- if((exit_status = write_samps(ibuf,dz->ssampsread,dz))<0)
- return(exit_status);
- last_total_samps_read = dz->total_samps_read;
- if((exit_status = read_samps(ibuf,dz))<0)
- return(exit_status);
- n -= dz->buflen;
- startsplice -= dz->buflen;
- endcut -= dz->buflen;
- }
- }
- spliceratio = 0.0;
- while(n < endcut) {
- spliceratio += spliceincr;
- for(m=0;m<chans;m++)
- ibuf[n+m] = (float)(ibuf[n+m] * spliceratio);
- n += chans;
- if(n >= dz->ssampsread) {
- if((exit_status = write_samps(ibuf,dz->ssampsread,dz))<0)
- return(exit_status);
- last_total_samps_read = dz->total_samps_read;
- if((exit_status = read_samps(ibuf,dz))<0)
- return(exit_status);
- n -= dz->buflen;
- endcut -= dz->buflen;
- }
- }
- }
- while(dz->ssampsread > 0) {
- if((exit_status = write_samps(ibuf,dz->ssampsread,dz))<0)
- return(exit_status);
- if((exit_status = read_samps(ibuf,dz))<0)
- return(exit_status);
- }
- return(FINISHED);
- }
|