clean.c 53 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674
  1. /*
  2. * Copyright (c) 1983-2013 Trevor Wishart and Composers Desktop Project Ltd
  3. * http://www.trevorwishart.co.uk
  4. * http://www.composersdesktop.com
  5. *
  6. This file is part of the CDP System.
  7. The CDP System is free software; you can redistribute it
  8. and/or modify it under the terms of the GNU Lesser General Public
  9. License as published by the Free Software Foundation; either
  10. version 2.1 of the License, or (at your option) any later version.
  11. The CDP System is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. GNU Lesser General Public License for more details.
  15. You should have received a copy of the GNU Lesser General Public
  16. License along with the CDP System; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  18. 02111-1307 USA
  19. *
  20. */
  21. /*floatsam version*/
  22. /*NB CUTGATE_SHRTBLOK RENAMED CUTGATE_SAMPBLOK*/
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <structures.h>
  26. #include <tkglobals.h>
  27. #include <globcon.h>
  28. #include <cdpmain.h>
  29. #include <house.h>
  30. #include <modeno.h>
  31. #include <pnames.h>
  32. #include <logic.h>
  33. #include <flags.h>
  34. #include <arrays.h>
  35. /*RWD April 2004 TW forgot this...*/
  36. #include <processno.h>
  37. #include <sfsys.h>
  38. #include <string.h>
  39. #include <srates.h>
  40. #ifdef unix
  41. #define round(x) lround((x))
  42. #endif
  43. /* RWD keep this? */
  44. #define SAMPLE_T float
  45. #define IBUF (0)
  46. #define OBUF (1)
  47. #define BUFEND (2)
  48. #define WRAP (1)
  49. #define ENV (0)
  50. #define ENVEND (1)
  51. /* RWD ????? */
  52. //TW REDUNDANT
  53. //#define SR (22050)
  54. //#define SRDAT (24000)
  55. //#define SRDATLO (16000)
  56. #define MAXCUTS (999)
  57. #define TOPN_DEFAULT_SPLEN (15.0) /* MS */
  58. static int top_and_tail(dataptr dz);
  59. static int get_startsamp(float *ibuf,int chans,int nbuff,int *startsamp,double gate,double ngate,dataptr dz);
  60. static int get_endsamp(float *ibuf,int chans,int nbuff,int *endsamp,double gate,double ngate,dataptr dz);
  61. //TW REVISED
  62. //static int do_startsplice(float **ibuf,float **obuf,int splicecnt,
  63. // int startseek,int *sampseek,int *firsttime,int offset,int offset_samps,int wrap_samps,int input_report,dataptr dz);
  64. static int do_startsplice(int splicecnt,int startsamp,int *sampseek,int input_report,dataptr dz);
  65. //TW REVISED
  66. //static int advance_to_endsamp(float **ibuf,float **obuf,int endsamp,int *sampseek,
  67. // int *firsttime,int wrap_samps,int offset_samps,int input_report,dataptr dz);
  68. static int advance_to_endsamp(int endsamp,int *sampseek,int input_report,dataptr dz);
  69. //TW REVISED
  70. //static int do_end_splice(float **ibuf,float **obuf,int *k,int splicecnt,int firsttime,
  71. // int wrap_samps,int offset_samps,int input_report,dataptr dz);
  72. static int do_end_splice(int *k,int splicecnt,int input_report,dataptr dz);
  73. static int do_cutgate(dataptr dz);
  74. //TW SUGGESTS, REDUNDANT
  75. //static int get_bufmult_factor(int srate,int channels,dataptr dz);
  76. static int ggetenv(dataptr dz);
  77. static void searchpars(dataptr dz);
  78. static void readenv(int samps_to_process,SAMPLE_T **env,dataptr dz);
  79. static void get_maxsamp(SAMPLE_T *env,int startsamp,dataptr dz);
  80. static int findcuts(int *ccnt,dataptr dz);
  81. static int findcuts2(int *ccnt,dataptr dz);
  82. static int create_outfile_name(int ccnt,char *thisfilename,dataptr dz);
  83. static int output_cut_sndfile(int ccnt,char *filename,dataptr dz);
  84. static int store_cut_positions_in_samples(int ccnt,int startse,int endsec,dataptr dz) ;
  85. static int setup_naming(char **filename,dataptr dz);
  86. static int do_rectify(dataptr dz);
  87. static int create_cutgate_buffer(dataptr dz);
  88. static int create_topntail_buffer(dataptr dz);
  89. //TW FUNCTION NEW REDUNDANT
  90. //static int do_by_hand(dataptr dz);
  91. //TW UPDATES
  92. static int find_onset_cuts(int *ccnt,dataptr dz);
  93. static int store_startcut_positions_in_samples(int ccnt,int startsec,dataptr dz);
  94. /******************************* PCONSISTENCY_CLEAN *******************************/
  95. int pconsistency_clean(dataptr dz)
  96. {
  97. // int exit_status;
  98. double sr = (double)dz->infile->srate;
  99. int chans = dz->infile->channels;
  100. if(dz->process == TOPNTAIL_CLICKS) {
  101. if(!dz->vflag[STT_TRIM] && !dz->vflag[END_TRIM]) {
  102. sprintf(errstr,"Input file will be UNCHANGED.\n");
  103. return(GOAL_FAILED);
  104. }
  105. return FINISHED;
  106. }
  107. switch(dz->mode) {
  108. case(HOUSE_CUTGATE):
  109. dz->iparam[CUTGATE_SPLCNT] = round(dz->param[CUTGATE_SPLEN] * MS_TO_SECS * sr);
  110. dz->iparam[CUTGATE_SPLEN] = dz->iparam[CUTGATE_SPLCNT] * chans;
  111. /* fall thro */
  112. case(HOUSE_ONSETS):
  113. if(dz->param[CUTGATE_INITLEVEL]>0 && dz->iparam[CUTGATE_BAKTRAK]==0) {
  114. fprintf(stdout,"WARNING: INITIAL LEVEL set without Baktraking: no effect.\n");
  115. fflush(stdout);
  116. }
  117. if(flteq(dz->param[CUTGATE_ENDGATE],0.0))
  118. dz->param[CUTGATE_ENDGATE] = dz->param[CUTGATE_GATE];
  119. dz->iparam[CUTGATE_MINLEN] = round(dz->param[CUTGATE_MINLEN] * sr) * chans;
  120. /* fall thro */
  121. case(HOUSE_CUTGATE_PREVIEW):
  122. //TW SUGGESTS this will work fine, & still be consistent with old-buffering-protocol...
  123. dz->iparam[CUTGATE_SAMPBLOK] = F_SECSIZE * dz->infile->channels;
  124. break;
  125. //TW !!!!!
  126. case(HOUSE_TOPNTAIL):
  127. if(dz->vflag[NO_STT_TRIM] && dz->vflag[NO_END_TRIM]) {
  128. sprintf(errstr,"Input file will be UNCHANGED.\n");
  129. return(GOAL_FAILED);
  130. }
  131. //TW UPDATE (redundant)
  132. // dz->param[TOPN_NGATE] = -dz->param[TOPN_GATE];
  133. break;
  134. }
  135. return(FINISHED);
  136. }
  137. /******************************* CREATE_CLEAN_BUFFERS *******************************/
  138. int create_clean_buffers(dataptr dz)
  139. {
  140. if(dz->process == TOPNTAIL_CLICKS)
  141. return create_topntail_buffer(dz);
  142. switch(dz->mode) {
  143. case(HOUSE_CUTGATE_PREVIEW):
  144. //TW NEW CASE
  145. case(HOUSE_ONSETS):
  146. case(HOUSE_CUTGATE): return create_cutgate_buffer(dz);
  147. case(HOUSE_TOPNTAIL): return create_topntail_buffer(dz);
  148. }
  149. sprintf(errstr,"Unknown mode: create_clean_buffers()\n");
  150. return(PROGRAM_ERROR);
  151. }
  152. /******************************* CREATE_CUTGATE_BUFFER ****************************/
  153. int create_cutgate_buffer(dataptr dz)
  154. {
  155. int k, envelope_space,total_bufsize;
  156. int numsecs;
  157. int samp_blocksize = dz->iparam[CUTGATE_SAMPBLOK] * sizeof(float);
  158. size_t bigbufsize;
  159. bigbufsize = (size_t)Malloc(-1);
  160. if((bigbufsize = (bigbufsize/samp_blocksize) * samp_blocksize)<=0)
  161. bigbufsize = samp_blocksize;
  162. dz->buflen = (int)(bigbufsize/sizeof(float));
  163. /* dz->buflen needed for searchpars() */
  164. searchpars(dz);
  165. if((k =
  166. dz->iparam[CUTGATE_NUMSECS]/dz->iparam[CUTGATE_SAMPBLOK])* dz->iparam[CUTGATE_SAMPBLOK] < dz->iparam[CUTGATE_NUMSECS])
  167. k++;
  168. numsecs = k * dz->iparam[CUTGATE_SAMPBLOK];
  169. envelope_space = (numsecs + dz->iparam[CUTGATE_WINDOWS]) * sizeof(float);
  170. total_bufsize = bigbufsize + envelope_space + (F_SECSIZE * sizeof(float)); /* overflow sector in sndbuf */
  171. if((dz->bigbuf = (float *)malloc((size_t)total_bufsize)) == NULL) {
  172. sprintf(errstr,"INSUFFICIENT MEMORY for sound and envelope.\n");
  173. return(MEMORY_ERROR);
  174. }
  175. dz->sampbuf[ENV] = dz->bigbuf + dz->buflen + F_SECSIZE;
  176. return(FINISHED);
  177. }
  178. /******************************* PROCESS_CLEAN *******************************/
  179. int process_clean(dataptr dz)
  180. {
  181. if(dz->process == TOPNTAIL_CLICKS)
  182. return top_and_tail(dz);
  183. switch(dz->mode) {
  184. case(HOUSE_CUTGATE_PREVIEW):
  185. case(HOUSE_ONSETS):
  186. case(HOUSE_CUTGATE): return do_cutgate(dz);
  187. case(HOUSE_TOPNTAIL): return top_and_tail(dz);
  188. case(HOUSE_RECTIFY): return do_rectify(dz);
  189. default: /*RWD*/
  190. break;
  191. }
  192. sprintf(errstr,"Unknown mode: process_clean()\n");
  193. return(PROGRAM_ERROR);
  194. }
  195. /*************************** CREATE_TOPNTAIL_BUFFER ************************/
  196. //TW comment old-buffer-protocol not required
  197. int create_topntail_buffer(dataptr dz)
  198. {
  199. size_t bigbufsize;
  200. bigbufsize = (size_t) Malloc(-1);
  201. dz->buflen = (int)(bigbufsize / sizeof(float));
  202. dz->buflen = (dz->buflen / dz->infile->channels) * dz->infile->channels;
  203. if((dz->bigbuf = (float*) Malloc(dz->buflen * sizeof(float)))== NULL){
  204. sprintf(errstr, "Can't allocate memory for sound.\n");
  205. return(MEMORY_ERROR);
  206. }
  207. return(FINISHED);
  208. }
  209. /******************************* TOP_AND_TAIL *******************************/
  210. int top_and_tail(dataptr dz)
  211. {
  212. int exit_status;
  213. float *ibuf = dz->bigbuf;
  214. float *obuf = ibuf;
  215. int nbuff;
  216. // int gotend = FALSE;
  217. // int gotstart = FALSE;
  218. int chans = dz->infile->channels;
  219. // int firsttime = TRUE;
  220. int startsamp = 0;
  221. int endsamp = dz->insams[0];
  222. int splicecnt = round(dz->param[TOPN_SPLEN] * MS_TO_SECS * (double)dz->infile->srate);
  223. int splicesamps = splicecnt * chans;
  224. int sampseek = 0;
  225. int startsplice, endsplice = 0, samps_to_write;
  226. // int startseek;
  227. double gate, ngate;
  228. dz->ssampsread = 0;
  229. nbuff = dz->insams[0]/dz->buflen;
  230. if(nbuff * dz->buflen < dz->insams[0]) /* did have ; at end */
  231. nbuff++; /* number of buffers contaning entire file */
  232. gate = dz->param[TOPN_GATE] * (double)F_MAXSAMP;
  233. ngate = -gate;
  234. switch(dz->process) {
  235. case(TOPNTAIL_CLICKS):
  236. if(dz->vflag[STT_TRIM]) {
  237. if((exit_status = get_startsamp(ibuf,chans,nbuff,&startsplice,gate,ngate,dz))<0)
  238. return(exit_status);
  239. if((startsamp = startsplice + splicesamps) > dz->insams[0]) {
  240. sprintf(errstr,"At this gate level and splice length, entire file will be removed.\n");
  241. return(GOAL_FAILED);
  242. }
  243. } else
  244. startsplice = 0; /* Needed for settting wrap, offset, seek */
  245. if(dz->vflag[END_TRIM]) {
  246. if((exit_status = get_endsamp(ibuf,chans,nbuff,&endsplice,gate,ngate,dz))<0)
  247. return(exit_status);
  248. if((endsamp = (endsplice - splicesamps)) < 0) {
  249. sprintf(errstr,"At this gate level and splice length, entire file will be removed.\n");
  250. return(GOAL_FAILED);
  251. }
  252. }
  253. if((dz->tempsize = endsplice - startsplice) <= 2 * splicesamps) {
  254. sprintf(errstr,"At this gate level and splice length, entire file will be removed.\n");
  255. return(GOAL_FAILED);
  256. }
  257. break;
  258. default:
  259. if(!dz->vflag[NO_STT_TRIM]) {
  260. if((exit_status = get_startsamp(ibuf,chans,nbuff,&startsamp,gate,ngate,dz))<0)
  261. return(exit_status);
  262. }
  263. if(!dz->vflag[NO_END_TRIM]) {
  264. if((exit_status = get_endsamp(ibuf,chans,nbuff,&endsamp,gate,ngate,dz))<0)
  265. return(exit_status);
  266. }
  267. if(endsamp == startsamp) {
  268. sprintf(errstr,"At this gate level, entire file will be removed.\n");
  269. return(GOAL_FAILED);
  270. }
  271. if((startsplice = startsamp - splicesamps) < 0)
  272. dz->vflag[NO_STT_TRIM] = TRUE;
  273. endsplice = endsamp;
  274. if((endsamp -= splicesamps) <= 0) {
  275. sprintf(errstr,"At this gate level, entire file will be removed.\n");
  276. return(GOAL_FAILED);
  277. }
  278. if(dz->vflag[NO_STT_TRIM])
  279. startsplice = 0;
  280. break;
  281. }
  282. // startseek = startsamp * sizeof(float);
  283. // DEC 2004
  284. dz->ssampsread = 0;
  285. if(((dz->process == TOPNTAIL_CLICKS) && dz->vflag[STT_TRIM])
  286. || ((dz->process != TOPNTAIL_CLICKS) && !dz->vflag[NO_STT_TRIM])) {
  287. if((exit_status = do_startsplice(splicecnt,startsamp,&sampseek,0,dz))<0)
  288. return(exit_status);
  289. } else {
  290. if(sndseekEx(dz->ifd[0],startsamp,0)<0) {
  291. sprintf(errstr,"sndseekEx() failed: A\n");
  292. return(SYSTEM_ERROR);
  293. }
  294. sampseek = startsamp;
  295. }
  296. if(((dz->process == TOPNTAIL_CLICKS) && !dz->vflag[END_TRIM])
  297. || ((dz->process != TOPNTAIL_CLICKS) && dz->vflag[NO_END_TRIM]))
  298. endsamp = endsplice = dz->insams[0];
  299. if((exit_status = advance_to_endsamp(endsamp,&sampseek,0,dz))<0)
  300. return(exit_status);
  301. samps_to_write = endsamp - sampseek;
  302. if(((dz->process == TOPNTAIL_CLICKS) && dz->vflag[END_TRIM])
  303. || ((dz->process != TOPNTAIL_CLICKS) && !dz->vflag[NO_END_TRIM])) {
  304. if((exit_status = do_end_splice(&samps_to_write,splicecnt,0,dz))<0)
  305. return(exit_status);
  306. }
  307. if(samps_to_write > 0) {
  308. if((exit_status = write_samps(obuf,samps_to_write,dz))<0)
  309. return(exit_status);
  310. }
  311. dz->total_samps_written = endsplice - startsplice;
  312. return(FINISHED);
  313. }
  314. /******************************* GET_STARTSAMP *******************************/
  315. int get_startsamp(float *ibuf,int chans,int nbuff,int *startsamp,double gate,double ngate,dataptr dz)
  316. {
  317. int exit_status;
  318. int gotstart = FALSE;
  319. int thisbuff = 0;
  320. int n;
  321. while(!gotstart && thisbuff < nbuff) {
  322. if((exit_status = read_samps(ibuf,dz))<0)
  323. return(exit_status);
  324. for(n = 0;n < dz->ssampsread - 1;n++) {
  325. if(ibuf[n] > gate || ibuf[n] < ngate) {
  326. gotstart = TRUE;
  327. break;
  328. }
  329. }
  330. if(gotstart) {
  331. *startsamp = n + (thisbuff * dz->buflen);
  332. *startsamp = (*startsamp/chans) * chans; /* align to channel group boundary */
  333. break;
  334. }
  335. thisbuff++;
  336. }
  337. if(!gotstart) {
  338. sprintf(errstr,"Entire file is below gate level\n");
  339. return(GOAL_FAILED);
  340. }
  341. return(FINISHED);
  342. }
  343. /******************************* GET_ENDSAMP *******************************/
  344. //RWD based on SECSIZE-aligned
  345. //TW: No, just searching for last sample above gate
  346. int get_endsamp(float *ibuf,int chans,int nbuff,int *endsamp,double gate,double ngate,dataptr dz)
  347. {
  348. int exit_status;
  349. int n;
  350. int gotend = FALSE;
  351. int thisbuff = nbuff - 1; /* buffer that contains last sample */
  352. while(!gotend && thisbuff >= 0) {
  353. if(sndseekEx(dz->ifd[0],thisbuff * dz->buflen,0)<0) {
  354. sprintf(errstr,"sndseek() failed: 1\n");
  355. return(SYSTEM_ERROR);
  356. }
  357. if((exit_status = read_samps(ibuf,dz))<0)
  358. return(exit_status);
  359. for(n = dz->ssampsread - 1;n>=0;n--) {
  360. if(ibuf[n] > gate || ibuf[n] < ngate) {
  361. gotend = TRUE;
  362. break;
  363. }
  364. }
  365. if(gotend) {
  366. *endsamp = n + (thisbuff * dz->buflen);
  367. *endsamp = (*endsamp/chans) * chans; /* align to channel group boundary */
  368. break;
  369. }
  370. thisbuff--;
  371. }
  372. if(!gotend) {
  373. sprintf(errstr,"Entire file is below gate level.\n");
  374. return(GOAL_FAILED);
  375. }
  376. return(FINISHED);
  377. }
  378. /******************************* DO_STARTSPLICE *******************************/
  379. int do_startsplice(int splicecnt,int startsamp,int *sampseek,int input_report,dataptr dz)
  380. {
  381. int exit_status;
  382. int chans = dz->infile->channels;
  383. int k, samps_written;
  384. double aincr, a1;
  385. int n;
  386. int m;
  387. if(sndseekEx(dz->ifd[0],startsamp,0)<0) {
  388. sprintf(errstr,"sndseek() failed: 3\n");
  389. return(SYSTEM_ERROR);
  390. }
  391. // NEW TW June 2004
  392. *sampseek = startsamp;
  393. if((exit_status = read_samps(dz->bigbuf,dz))<0) /* read buffer with additional sector */
  394. return(exit_status);
  395. k = 0;
  396. aincr = 1.0/(double)splicecnt;
  397. a1 = 0.0;
  398. for(n = 0;n < splicecnt;n++) {
  399. for(m = 0; m < chans; m++) {
  400. dz->bigbuf[k] = (float) ((double)dz->bigbuf[k] * a1);
  401. k++;
  402. }
  403. if(k >= dz->ssampsread) {
  404. if(input_report) {
  405. if((exit_status = write_samps_no_report(dz->bigbuf,dz->buflen,&samps_written,dz))<0)
  406. return(exit_status);
  407. } else {
  408. if((exit_status = write_samps(dz->bigbuf,dz->buflen,dz))<0)
  409. return(exit_status);
  410. }
  411. *sampseek += dz->ssampsread;
  412. if((exit_status = read_samps(dz->bigbuf,dz))<0) /*RWD added * */
  413. return(exit_status);
  414. if(dz->ssampsread <=0)
  415. return(FINISHED);
  416. k = 0;
  417. }
  418. a1 += aincr;
  419. }
  420. return(FINISHED);
  421. }
  422. /******************************* ADVANCE_TO_ENDSAMP *******************************/
  423. int advance_to_endsamp(int endsamp,int *sampseek,int input_report,dataptr dz)
  424. {
  425. int exit_status;
  426. int samps_written;
  427. while(endsamp > *sampseek + dz->ssampsread) {
  428. if(dz->ssampsread > 0) {
  429. if(input_report) {
  430. if((exit_status = write_samps_no_report(dz->bigbuf,dz->ssampsread,&samps_written,dz))<0)
  431. return(exit_status);
  432. } else {
  433. if((exit_status = write_samps(dz->bigbuf,dz->ssampsread,dz))<0)
  434. return(exit_status);
  435. }
  436. }
  437. *sampseek += dz->ssampsread;
  438. if((exit_status = read_samps(dz->bigbuf,dz))<0)
  439. return(exit_status);
  440. if(dz->ssampsread ==0) {
  441. return FINISHED;
  442. }
  443. }
  444. return(FINISHED);
  445. }
  446. /******************************* DO_END_SPLICE *******************************/
  447. /*k = nSAMPS*/
  448. int do_end_splice(int *k,int splicecnt,int input_report,dataptr dz)
  449. {
  450. int exit_status;
  451. int chans = dz->infile->channels;
  452. int n, samps_written;
  453. int m;
  454. double aincr = -(1.0/splicecnt);
  455. double a1 = 1.0 + aincr;
  456. for(n = 0;n < splicecnt;n++) {
  457. for(m = 0; m < chans; m++) {
  458. dz->bigbuf[*k] = (float) ((double)dz->bigbuf[*k] * a1);
  459. (*k)++;
  460. }
  461. if(*k >= dz->ssampsread) {
  462. if(dz->ssampsread > 0) {
  463. if(input_report) {
  464. if((exit_status = write_samps_no_report(dz->bigbuf,dz->ssampsread,&samps_written,dz))<0)
  465. return(exit_status);
  466. } else {
  467. if((exit_status = write_samps(dz->bigbuf,dz->ssampsread,dz))<0)
  468. return(exit_status);
  469. }
  470. }
  471. if((exit_status = read_samps(dz->bigbuf,dz))<0)
  472. return(exit_status);
  473. if(dz->ssampsread <=0) {
  474. return(FINISHED);
  475. }
  476. *k = 0;
  477. }
  478. a1 += aincr;
  479. }
  480. return(FINISHED);
  481. }
  482. /******************************* DO_CUTGATE ****************************/
  483. int do_cutgate(dataptr dz)
  484. {
  485. int exit_status;
  486. int n, ccnt = 0;
  487. int outsize, samps_written;
  488. char *thisfilename;
  489. double val;
  490. dz->sbufptr[ENV] = dz->sampbuf[ENV];
  491. fprintf(stdout,"INFO: Extracting envelope.\n");
  492. fflush(stdout);
  493. if((exit_status = ggetenv(dz))<0)
  494. return(exit_status);
  495. switch(dz->mode) {
  496. case(HOUSE_CUTGATE_PREVIEW):
  497. outsize = dz->iparam[CUTGATE_NUMSECS];
  498. if(outsize > 0) {
  499. if((exit_status = write_samps_no_report(dz->sampbuf[ENV],outsize,&samps_written,dz))<0)
  500. return(exit_status);
  501. }
  502. dz->infile->channels = 1;
  503. dz->infile->srate = SR_DEFAULT;
  504. break;
  505. case(HOUSE_CUTGATE):
  506. display_virtual_time(0,dz);
  507. dz->sbufptr[ENV] = dz->sampbuf[ENV];
  508. fprintf(stdout,"INFO: Finding cutpoints.\n");
  509. fflush(stdout);
  510. if(dz->iparam[CUTGATE_SUSTAIN]>0) {
  511. if((exit_status = findcuts2(&ccnt,dz))<0)
  512. return(exit_status);
  513. } else if((exit_status = findcuts(&ccnt,dz))<0)
  514. return(exit_status);
  515. if(ccnt==0) {
  516. sprintf(errstr,"No segments to extract at this gatelevel.\n");
  517. return(GOAL_FAILED);
  518. }
  519. if((exit_status = setup_naming(&thisfilename,dz))<0)
  520. return(exit_status);
  521. fprintf(stdout,"INFO: Cutting file.\n");
  522. fflush(stdout);
  523. // MULTICHAN -->
  524. dz->outchans = dz->infile->channels;
  525. // <-- MULTICHAN
  526. if((exit_status = reset_peak_finder(dz))<0)
  527. return(exit_status);
  528. for(n=0;n<ccnt;n++) {
  529. if (ccnt > 9999) {
  530. fprintf(stdout,"WARNING: More than 9999 segments: Finishing here\n");
  531. fflush(stdout);
  532. free(thisfilename);
  533. return(FINISHED);
  534. }
  535. reset_filedata_counters(dz);
  536. if(sndseekEx(dz->ifd[0],0,0)<0) {
  537. sprintf(errstr,"sndseek() failed.\n");
  538. return(SYSTEM_ERROR);
  539. }
  540. if((exit_status = create_outfile_name(n,thisfilename,dz))<0)
  541. return(exit_status);
  542. if((exit_status = output_cut_sndfile(n,thisfilename,dz))<0)
  543. return(exit_status);
  544. }
  545. free(thisfilename);
  546. fprintf(stdout,"INFO: %d segments extracted.\n",ccnt);
  547. fflush(stdout);
  548. break;
  549. //TW UPDATE : NEW CASE
  550. case(HOUSE_ONSETS):
  551. display_virtual_time(0,dz);
  552. dz->sbufptr[ENV] = dz->sampbuf[ENV];
  553. fprintf(stdout,"INFO: Finding cutpoints.\n");
  554. fflush(stdout);
  555. if((exit_status = find_onset_cuts(&ccnt,dz))<0)
  556. return(exit_status);
  557. if(ccnt==0) {
  558. sprintf(errstr,"No segments to extract at this gatelevel.\n");
  559. return(GOAL_FAILED);
  560. }
  561. for(n=0;n<ccnt;n++) {
  562. val = (double)(dz->lparray[CUTGATE_STIME][n]/dz->infile->channels)/(double)dz->infile->srate;
  563. fprintf(dz->fp,"%.6lf\n",val);
  564. }
  565. fprintf(stdout,"INFO: %d segments extracted.\n",ccnt);
  566. fflush(stdout);
  567. break;
  568. }
  569. return(FINISHED);
  570. }
  571. /******************************** GGETENV ******************************/
  572. int ggetenv(dataptr dz)
  573. {
  574. int exit_status;
  575. int n;
  576. int sampstoget;
  577. float *realend;
  578. display_virtual_time(0,dz);
  579. realend = dz->sampbuf[ENV] + dz->iparam[CUTGATE_NUMSECS];
  580. /* 1ST PASS : WHOLE BUFFERS */
  581. for(n = 0; n < dz->iparam[CUTGATE_NBUFS]; n++) {
  582. if((exit_status = read_samps(dz->bigbuf,dz))<0)
  583. return(exit_status);
  584. readenv(dz->buflen,&(dz->sbufptr[ENV]),dz);
  585. display_virtual_time(dz->total_samps_read,dz);
  586. }
  587. /* 2ND PASS : WHOLE SHRTBLOKS */
  588. sampstoget = dz->iparam[CUTGATE_NSEC] * dz->iparam[CUTGATE_SAMPBLOK];
  589. if((dz->ssampsread = fgetfbufEx(dz->bigbuf, sampstoget,dz->ifd[0],0))!=sampstoget) {
  590. sprintf(errstr,"Sound read anomaly.\n");
  591. if(dz->ssampsread < 0)
  592. return(SYSTEM_ERROR);
  593. return(PROGRAM_ERROR);
  594. }
  595. readenv(sampstoget,&(dz->sbufptr[ENV]),dz);
  596. dz->sbufptr[ENVEND] = dz->sbufptr[ENV]; /* end of data */
  597. while(dz->sbufptr[ENV] < realend + dz->iparam[CUTGATE_WINDOWS]) { /* pad end of buffer with zeroes */
  598. *dz->sbufptr[ENV] = 0;
  599. dz->sbufptr[ENV]++;
  600. }
  601. dz->sbufptr[ENV] = dz->sampbuf[ENV];
  602. display_virtual_time(dz->total_samps_read,dz);
  603. return(FINISHED);
  604. }
  605. /****************************** SEARCHPARS ******************************/
  606. void searchpars(dataptr dz)
  607. {
  608. int searchsize;
  609. dz->iparam[CUTGATE_NUMSECS] = dz->insams[0]/dz->iparam[CUTGATE_SAMPBLOK];
  610. searchsize = dz->iparam[CUTGATE_NUMSECS] * dz->iparam[CUTGATE_SAMPBLOK];
  611. dz->iparam[CUTGATE_NBUFS] = searchsize/dz->buflen; /* no. of whole buffs to search */
  612. dz->iparam[CUTGATE_NSEC] = (searchsize%dz->buflen)/dz->iparam[CUTGATE_SAMPBLOK]; /* no. further secs to search */
  613. return;
  614. }
  615. /************************* READENV *******************************/
  616. void readenv(int samps_to_process,float **env,dataptr dz)
  617. { int d;
  618. for(d=0; d<samps_to_process; d+=dz->iparam[CUTGATE_SAMPBLOK]) {
  619. get_maxsamp(*env,d,dz);
  620. (*env)++;
  621. }
  622. }
  623. /*************************** GET_MAXSAMP ******************************/
  624. void get_maxsamp(float *env,int startsamp,dataptr dz)
  625. {
  626. int i, endsamp = startsamp + dz->iparam[CUTGATE_SAMPBLOK];
  627. double thisenv = 0;
  628. for(i = startsamp; i<endsamp; i++)
  629. thisenv = max(thisenv,fabs(dz->bigbuf[i]));
  630. *env = (float)min(thisenv,F_MAXSAMP); /* avoids overflowing */
  631. }
  632. /**************************** FINDCUTS ********************************
  633. *
  634. * (1)
  635. * (2) If we are NOT inside a sound-to-keep.
  636. * (3) If the level is below the gate level..
  637. * (4) Ignore and continue..
  638. * (5) If the sound is above gate level..
  639. * mark this as (potential) start of a sound-to-keep
  640. * (6) flag sound-to-keep
  641. * (7) set the maximum level in segment to a minimum (0)
  642. * (8) If we are INSIDE a sound-to-keep
  643. * (9) If the sound level drops below gate
  644. * (10) Check that 'dz->iparam[CUTGATE_WINDOWS]' succeeding segments are below gate level..
  645. * (11) If this is true,
  646. * (12) if the maximum level in sound-to-keep exceeded dz->iparam[CUTGATE_THRESH]..
  647. * save the sound start and end times..
  648. * (13) In ANY case, mark that we are NO LONGER in a sound-to-keep.
  649. * If it is NOT true, we are still INSIDE a sound-to-keep..
  650. * (14) If however, the sound is above the gate
  651. * (15) Check level of sound, and readjust maxlevel, if necessary..
  652. */
  653. int findcuts(int *ccnt,dataptr dz)
  654. {
  655. int exit_status, tooshort_segs = 0, tooquiet_segs = 0;
  656. int startsec = 0, endsec;
  657. int inside_sound = FALSE, OK, n;
  658. // float maxlevel = 0, keepit = FALSE;
  659. float maxlevel = 0;
  660. float *bak, *endbak;
  661. int minlen = max(dz->iparam[CUTGATE_SPLEN] * 2,dz->iparam[CUTGATE_MINLEN]);
  662. double gate = dz->param[CUTGATE_GATE] * (double)F_MAXSAMP;
  663. double endgate = dz->param[CUTGATE_ENDGATE] * (double)F_MAXSAMP;
  664. double initlevel = dz->param[CUTGATE_INITLEVEL] * (double)F_MAXSAMP;
  665. double threshold = dz->param[CUTGATE_THRESH] * (double)F_MAXSAMP;
  666. while(dz->sbufptr[ENV]<dz->sbufptr[ENVEND]) {
  667. switch(inside_sound) { /* 1 */
  668. case(FALSE): /* 2 */
  669. if(*(dz->sbufptr[ENV]) <= gate) /* 3 */
  670. break; /* 4 */
  671. if(dz->iparam[CUTGATE_BAKTRAK]) {
  672. bak = dz->sbufptr[ENV];
  673. if((endbak = dz->sbufptr[ENV] - dz->iparam[CUTGATE_BAKTRAK]) < dz->sampbuf[ENV])
  674. endbak = dz->sampbuf[ENV];
  675. while(bak>endbak) {
  676. if(*(bak-1) >= initlevel)
  677. bak--;
  678. else
  679. break;
  680. }
  681. startsec = bak - dz->sampbuf[ENV];
  682. } else
  683. startsec = dz->sbufptr[ENV] - dz->sampbuf[ENV]; /* 5 */
  684. inside_sound = /*1*/TRUE; /* 6 */ /*RWD was 1 */
  685. maxlevel = *(dz->sbufptr[ENV]); /* 7 */
  686. break;
  687. case(TRUE): /* 8 */
  688. if(*(dz->sbufptr[ENV]) <= endgate) { /* 9 */
  689. OK = TRUE;
  690. if(dz->iparam[CUTGATE_WINDOWS]>0) {
  691. for(n=1;n<dz->iparam[CUTGATE_WINDOWS];n++) { /* 10 */
  692. if(*(dz->sbufptr[ENV]+n)>endgate) {
  693. OK = FALSE;
  694. break;
  695. }
  696. }
  697. }
  698. if(OK) { /* 11 */
  699. endsec = dz->sbufptr[ENV] - dz->sampbuf[ENV];
  700. if((endsec - startsec) * dz->iparam[CUTGATE_SAMPBLOK] > minlen) {
  701. if(maxlevel >= threshold) { /* 12 */
  702. if((exit_status = store_cut_positions_in_samples(*ccnt,startsec,endsec,dz))<0)
  703. return(exit_status);
  704. (*ccnt)++;
  705. } else {
  706. tooquiet_segs++;
  707. }
  708. } else {
  709. tooshort_segs++;
  710. }
  711. inside_sound = FALSE; /* 13 */
  712. }
  713. } else { /* 14 */
  714. if(*(dz->sbufptr[ENV]) > maxlevel) /* 15 */
  715. maxlevel = *(dz->sbufptr[ENV]);
  716. }
  717. break;
  718. }
  719. (dz->sbufptr[ENV])++;
  720. }
  721. if(inside_sound) { /* Ensure any significant block at very end is grabbed */
  722. endsec = dz->sbufptr[ENV] - dz->sampbuf[ENV];
  723. if((endsec - startsec) * dz->iparam[CUTGATE_SAMPBLOK] > minlen) {
  724. if(maxlevel >= threshold) { /* 12 */
  725. if((exit_status = store_cut_positions_in_samples(*ccnt,startsec,endsec,dz))<0)
  726. return(exit_status);
  727. (*ccnt)++;
  728. } else {
  729. tooquiet_segs++;
  730. }
  731. } else {
  732. tooshort_segs++;
  733. }
  734. }
  735. if(*ccnt <= 0) {
  736. if(tooshort_segs || tooquiet_segs) {
  737. if(tooshort_segs && tooquiet_segs)
  738. sprintf(errstr,"%d segments shorter than min duration set (or twice splicelen), and %d too quiet.\n",tooshort_segs,tooquiet_segs);
  739. else if(tooquiet_segs)
  740. sprintf(errstr,"%d segments to extract are too quiet (below threshold you set).\n",tooquiet_segs);
  741. else
  742. sprintf(errstr,"%d segments are shorter than minimum duration you set, or than twice splicelen.\n",tooshort_segs);
  743. } else {
  744. sprintf(errstr,"Whole file is below the gate level.\n");
  745. }
  746. return(GOAL_FAILED);
  747. }
  748. return(FINISHED);
  749. }
  750. /******************************* FINDCUTS2 ******************************/
  751. int findcuts2(int *ccnt,dataptr dz)
  752. {
  753. int exit_status, tooshort_segs = 0;
  754. int oldstartsec = 0, startsec, endsec;
  755. int inside_sound = FALSE, OK, n;
  756. /*short maxlevel = 0, keepit = FALSE, *bak, *endbak;*/
  757. //TW UPDATE : prevents WARNING
  758. int keepit = FALSE;
  759. float maxlevel = 0.0f, *bak, *endbak;
  760. int minlen = max(dz->iparam[CUTGATE_SPLEN] * 2,dz->iparam[CUTGATE_MINLEN]);
  761. double gate = dz->param[CUTGATE_GATE] * (double)F_MAXSAMP;
  762. double endgate = dz->param[CUTGATE_ENDGATE] * (double)F_MAXSAMP;
  763. double threshold = dz->param[CUTGATE_THRESH] * (double)F_MAXSAMP;
  764. double initlevel = dz->param[CUTGATE_INITLEVEL] * (double)F_MAXSAMP;
  765. while(dz->sbufptr[ENV]<dz->sbufptr[ENVEND]) {
  766. switch(inside_sound) { /* 1 */
  767. case(FALSE): /* 2 */
  768. if(*(dz->sbufptr[ENV]) <= gate) /* 3 */
  769. break; /* 4 */
  770. if(dz->iparam[CUTGATE_BAKTRAK]) {
  771. bak = dz->sbufptr[ENV];
  772. if((endbak = dz->sbufptr[ENV] - dz->iparam[CUTGATE_BAKTRAK]) < dz->sampbuf[ENV])
  773. endbak = dz->sampbuf[ENV];
  774. while(bak>endbak) {
  775. if(*(bak-1) >= initlevel)
  776. bak--;
  777. else
  778. break;
  779. }
  780. startsec = bak - dz->sampbuf[ENV];
  781. } else
  782. startsec = dz->sbufptr[ENV] - dz->sampbuf[ENV]; /* 5 */
  783. if(keepit && ((endsec = startsec - dz->iparam[CUTGATE_SUSTAIN]) > oldstartsec)) {
  784. if((endsec - oldstartsec) * dz->iparam[CUTGATE_SAMPBLOK] > minlen) {
  785. if((exit_status =
  786. store_cut_positions_in_samples(*ccnt,oldstartsec,startsec - dz->iparam[CUTGATE_SUSTAIN],dz))<0)
  787. return(exit_status);
  788. (*ccnt)++;
  789. } else {
  790. tooshort_segs = 1;
  791. }
  792. }
  793. keepit = FALSE;
  794. oldstartsec = startsec;
  795. inside_sound = /*1*/TRUE; /* 6 */
  796. maxlevel = *(dz->sbufptr[ENV]); /* 7 */
  797. break;
  798. case(TRUE): /* 8 */
  799. if(*(dz->sbufptr[ENV]) <= endgate) { /* 9 */
  800. OK = TRUE;
  801. if(dz->iparam[CUTGATE_WINDOWS]>0) {
  802. for(n=1;n<dz->iparam[CUTGATE_WINDOWS];n++) { /* 10 */
  803. if(*(dz->sbufptr[ENV]+n)>gate) {
  804. OK = FALSE;
  805. break;
  806. }
  807. }
  808. }
  809. if(OK) { /* 11 */
  810. if(maxlevel > threshold) /* 12 */
  811. keepit = TRUE;
  812. else
  813. keepit = FALSE;
  814. inside_sound = FALSE; /* 13 */
  815. }
  816. } else { /* 14 */
  817. if(*(dz->sbufptr[ENV]) > maxlevel) /* 15 */
  818. maxlevel = *(dz->sbufptr[ENV]);
  819. }
  820. break;
  821. }
  822. (dz->sbufptr[ENV])++;
  823. }
  824. endsec = dz->sbufptr[ENVEND] - dz->sampbuf[ENV];
  825. if(keepit && ((endsec - oldstartsec) * dz->iparam[CUTGATE_SAMPBLOK]) > minlen) {
  826. if(maxlevel >= threshold) { /* 12 */
  827. if((exit_status = store_cut_positions_in_samples(*ccnt,oldstartsec,endsec,dz))<0)
  828. return(exit_status);
  829. }
  830. (*ccnt)++;
  831. }
  832. if((*ccnt <= 0) && tooshort_segs) {
  833. sprintf(errstr,"Segments to extract are shorter than minimum duration you set, or than twice splicelen.\n");
  834. return(GOAL_FAILED);
  835. }
  836. return(FINISHED);
  837. }
  838. /******************************* SETUP_NAMING ******************************/
  839. int setup_naming(char **thisfilename,dataptr dz)
  840. {
  841. int innamelen = strlen(dz->wordstor[0]);
  842. int numlen = 5;
  843. if((*thisfilename = (char *)malloc((innamelen + numlen + 1) * sizeof(char)))==NULL) {
  844. sprintf(errstr,"INSUFFICIENT MEMORY for outfilename.\n");
  845. return(MEMORY_ERROR);
  846. }
  847. return(FINISHED);
  848. }
  849. /********************************** CREATE_OUTFILE_NAME ********************************/
  850. int create_outfile_name(int ccnt,char *thisfilename,dataptr dz)
  851. {
  852. //TW REVISED Dec 2002
  853. strcpy(thisfilename,dz->wordstor[0]);
  854. insert_new_number_at_filename_end(thisfilename,ccnt,1);
  855. return(FINISHED);
  856. }
  857. /********************************** OUTPUT_CUT_SNDFILE ********************************/
  858. int output_cut_sndfile(int ccnt,char *filename,dataptr dz)
  859. {
  860. int exit_status;
  861. // int firsttime = TRUE;
  862. int sampseek, startsamp, endsamp, k, samps_to_write, samps_written;
  863. dz->process_type = UNEQUAL_SNDFILE; /* allow sndfile to be created */
  864. if((exit_status = create_sized_outfile(filename,dz))<0) {
  865. fprintf(stdout, "WARNING: Soundfile %s already exists.\n", filename);
  866. fflush(stdout);
  867. dz->process_type = OTHER_PROCESS;
  868. dz->ofd = -1;
  869. if(dz->vflag[STOP_ON_SAMENAME])
  870. return(GOAL_FAILED);
  871. return(FINISHED);
  872. }
  873. startsamp = dz->lparray[CUTGATE_STIME][ccnt];
  874. sampseek = startsamp;
  875. if((exit_status= do_startsplice(dz->iparam[CUTGATE_SPLCNT],startsamp,&sampseek,1,dz))<0)
  876. return(exit_status);
  877. endsamp = dz->lparray[CUTGATE_ETIME][ccnt] - dz->iparam[CUTGATE_SPLEN];
  878. if((exit_status = advance_to_endsamp(endsamp,&sampseek,1,dz))<0)
  879. return(exit_status);
  880. k = endsamp - sampseek;
  881. if((exit_status = do_end_splice(&k,dz->iparam[CUTGATE_SPLCNT],1,dz))<0)
  882. return(exit_status);
  883. if((samps_to_write = k)>0) {
  884. if((exit_status = write_samps_no_report(dz->bigbuf,samps_to_write,&samps_written,dz))<0)
  885. return(exit_status);
  886. }
  887. display_virtual_time(startsamp + dz->total_samps_read,dz);
  888. dz->outfiletype = SNDFILE_OUT; /* allows header to be written */
  889. if((exit_status = headwrite(dz->ofd,dz))<0)
  890. return(exit_status);
  891. dz->process_type = OTHER_PROCESS; /* restore true status */
  892. dz->outfiletype = NO_OUTPUTFILE; /* restore true status */
  893. if((exit_status = reset_peak_finder(dz))<0)
  894. return(exit_status);
  895. if(sndcloseEx(dz->ofd) < 0) {
  896. fprintf(stdout,"WARNING: Can't close output soundfile %s\n",filename);
  897. fflush(stdout);
  898. }
  899. dz->ofd = -1;
  900. return(FINISHED);
  901. }
  902. /********************************** STORE_CUT_POSITIONS_IN_SAMPLES ********************************/
  903. int store_cut_positions_in_samples(int ccnt,int startsec,int endsec,dataptr dz)
  904. {
  905. if(ccnt==0) {
  906. if((dz->lparray[CUTGATE_STIME] = (int *)malloc(sizeof(int)))==NULL
  907. || (dz->lparray[CUTGATE_ETIME] = (int *)malloc(sizeof(int)))==NULL) {
  908. sprintf(errstr,"INSUFFICENT MEMORY to store cut times.\n");
  909. return(MEMORY_ERROR);
  910. }
  911. } else {
  912. if((dz->lparray[CUTGATE_STIME] =
  913. (int *)realloc(dz->lparray[CUTGATE_STIME],(ccnt+1) * sizeof(int)))==NULL
  914. || (dz->lparray[CUTGATE_ETIME] =
  915. (int *)realloc(dz->lparray[CUTGATE_ETIME],(ccnt+1) * sizeof(int)))==NULL) {
  916. sprintf(errstr,"INSUFFICENT MEMORY to store more cut times.\n");
  917. return(MEMORY_ERROR);
  918. }
  919. }
  920. dz->lparray[CUTGATE_STIME][ccnt] = startsec * dz->iparam[CUTGATE_SAMPBLOK];
  921. dz->lparray[CUTGATE_ETIME][ccnt] = endsec * dz->iparam[CUTGATE_SAMPBLOK];
  922. return(FINISHED);
  923. }
  924. /********************************** DO_RECTIFY ********************************/
  925. int do_rectify(dataptr dz)
  926. {
  927. int exit_status;
  928. int n;
  929. float *buf = dz->sampbuf[0], maxsamp, minsamp;
  930. double rectify_shift = dz->param[RECTIFY_SHIFT] * (double)F_MAXSAMP;
  931. if(flteq(rectify_shift,0.0)) {
  932. sprintf(errstr,"NO CHANGE to original sound file.\n");
  933. return(GOAL_FAILED);
  934. }
  935. if(rectify_shift > 0.0) {
  936. fprintf(stdout,"INFO: Finding maximum sample in file.\n");
  937. fflush(stdout);
  938. maxsamp = F_MINSAMP;
  939. while(dz->samps_left > 0) {
  940. if((exit_status = read_samps(buf,dz))<0)
  941. return(exit_status);
  942. for(n= 0;n<dz->ssampsread;n++)
  943. maxsamp = max(maxsamp,buf[n]);
  944. }
  945. if(maxsamp + rectify_shift > (double)F_MAXSAMP) {
  946. sprintf(errstr,"This rectification will distort the sound.\n");
  947. return(GOAL_FAILED);
  948. }
  949. } else {
  950. fprintf(stdout,"INFO: Finding minimum sample in file.\n");
  951. fflush(stdout);
  952. // minsamp = MAXSAMP;
  953. minsamp = F_MAXSAMP;
  954. while(dz->samps_left > 0) {
  955. if((exit_status = read_samps(buf,dz))<0)
  956. return(exit_status);
  957. for(n= 0;n<dz->ssampsread;n++)
  958. minsamp = min(minsamp,buf[n]);
  959. }
  960. if(minsamp + rectify_shift < (double)F_MINSAMP) {
  961. sprintf(errstr,"This rectification will distort the sound.\n");
  962. return(GOAL_FAILED);
  963. }
  964. }
  965. reset_filedata_counters(dz);
  966. if(sndseekEx(dz->ifd[0],0,0)<0) {
  967. sprintf(errstr,"sndseekEx failed.\n");
  968. return(SYSTEM_ERROR);
  969. }
  970. fprintf(stdout,"INFO: Rectifying.\n");
  971. fflush(stdout);
  972. while(dz->samps_left > 0) {
  973. if((exit_status = read_samps(buf,dz))<0)
  974. return(exit_status);
  975. for(n= 0;n<dz->ssampsread;n++)
  976. buf[n] = (float)(buf[n] + rectify_shift);
  977. if(dz->ssampsread > 0) {
  978. if((exit_status = write_exact_samps(buf,dz->ssampsread,dz))<0)
  979. return(exit_status);
  980. }
  981. }
  982. return(FINISHED);
  983. }
  984. //TW FUNCTION NOW REDUNDANT
  985. /********************************** DO_BY_HAND ********************************/
  986. //
  987. //int do_by_hand(dataptr dz)
  988. //{
  989. // int n = 0, all_fixes_done = 0, exit_status;
  990. // int k, last_total_ssampsread = 0;
  991. // double *la = dz->parray[0];
  992. // float *buf = dz->sampbuf[0];
  993. //
  994. // while(dz->samps_left > 0) {
  995. // if((exit_status = read_samps(buf,dz))<0)
  996. // return(exit_status);
  997. // if(!all_fixes_done) {
  998. // while(dz->total_samps_read > *la) {
  999. // k = round(*la++) - last_total_ssampsread;
  1000. /* NOT SHORT, IF BUFS NOT SHORT : 2000 */
  1001. // buf[k] = (float)(*la++);
  1002. // if(la >= dz->parray[1]) {
  1003. // all_fixes_done = 1;
  1004. // break;
  1005. // }
  1006. // }
  1007. // last_total_ssampsread = dz->total_samps_read;
  1008. // }
  1009. // if((exit_status = write_samps(buf,dz->ssampsread,dz))<0)
  1010. // return(exit_status);
  1011. // }
  1012. // return(FINISHED);
  1013. //}
  1014. //
  1015. //TW UPDATE: NEW FUNCTIONS BELOW (updated for flotsams)
  1016. /**************************** FIND_ONSET_CUTS *********************************/
  1017. int find_onset_cuts(int *ccnt,dataptr dz)
  1018. {
  1019. int exit_status, tooshort_segs = 0, tooquiet_segs = 0;
  1020. int startsec = 0, endsec;
  1021. int inside_sound = FALSE, OK, n = 0;
  1022. // short keepit = FALSE;
  1023. float maxlevel = 0;
  1024. float *bak, *endbak, *minpos, *here, minval;
  1025. int minlen = dz->iparam[CUTGATE_MINLEN];
  1026. double gate = dz->param[CUTGATE_GATE] * (double)F_MAXSAMP;
  1027. double endgate = dz->param[CUTGATE_ENDGATE] * (double)F_MAXSAMP;
  1028. double initlevel = dz->param[CUTGATE_INITLEVEL] * (double)F_MAXSAMP;
  1029. double threshold = dz->param[CUTGATE_THRESH] * (double)F_MAXSAMP;
  1030. int envlen = dz->sbufptr[ENVEND] - dz->sbufptr[ENV];
  1031. int ratio = dz->insams[0]/envlen;
  1032. int envstep = envlen/10, envmark = envstep;
  1033. while(dz->sbufptr[ENV]<dz->sbufptr[ENVEND]) {
  1034. switch(inside_sound) { /* 1 */
  1035. case(FALSE): /* 2 */
  1036. if(*(dz->sbufptr[ENV]) <= gate) /* 3 */
  1037. break; /* 4 */
  1038. if(dz->iparam[CUTGATE_BAKTRAK]) {
  1039. bak = dz->sbufptr[ENV];
  1040. if((endbak = dz->sbufptr[ENV] - dz->iparam[CUTGATE_BAKTRAK]) < dz->sampbuf[ENV])
  1041. endbak = dz->sampbuf[ENV];
  1042. while(bak>endbak) {
  1043. if(*(bak-1) > endgate) {
  1044. minval = *bak;
  1045. minpos = bak;
  1046. for(here = bak+1;here <= dz->sbufptr[ENV];here++) {
  1047. if(*here < minval) {
  1048. minval = *here;
  1049. minpos = here;
  1050. }
  1051. }
  1052. bak = minpos;
  1053. break;
  1054. } else if(*(bak-1) >= initlevel)
  1055. bak--;
  1056. else
  1057. break;
  1058. }
  1059. startsec = bak - dz->sampbuf[ENV];
  1060. } else
  1061. startsec = dz->sbufptr[ENV] - dz->sampbuf[ENV]; /* 5 */
  1062. inside_sound = 1; /* 6 */
  1063. maxlevel = *(dz->sbufptr[ENV]); /* 7 */
  1064. break;
  1065. case(TRUE): /* 8 */
  1066. if(*(dz->sbufptr[ENV]) <= endgate) { /* 9 */
  1067. OK = TRUE;
  1068. if(dz->iparam[CUTGATE_WINDOWS]>0) {
  1069. for(n=1;n<dz->iparam[CUTGATE_WINDOWS];n++) { /* 10 */
  1070. if(*(dz->sbufptr[ENV]+n)>endgate) {
  1071. OK = FALSE;
  1072. break;
  1073. }
  1074. }
  1075. }
  1076. if(OK) { /* 11 */
  1077. endsec = dz->sbufptr[ENV] - dz->sampbuf[ENV];
  1078. if((endsec - startsec) * dz->iparam[CUTGATE_SAMPBLOK] > minlen) {
  1079. if(maxlevel >= threshold) { /* 12 */
  1080. if((exit_status = store_startcut_positions_in_samples(*ccnt,startsec,dz))<0)
  1081. return(exit_status);
  1082. (*ccnt)++;
  1083. } else {
  1084. tooquiet_segs = 1;
  1085. }
  1086. } else {
  1087. tooshort_segs = 1;
  1088. }
  1089. inside_sound = FALSE; /* 13 */
  1090. }
  1091. } else { /* 14 */
  1092. if(*(dz->sbufptr[ENV]) > maxlevel) /* 15 */
  1093. maxlevel = *(dz->sbufptr[ENV]);
  1094. }
  1095. break;
  1096. }
  1097. (dz->sbufptr[ENV])++;
  1098. if(++n > envmark) {
  1099. if(sloom) {
  1100. envmark += envstep;
  1101. display_virtual_time(n * ratio,dz);
  1102. }
  1103. }
  1104. }
  1105. if(inside_sound) { /* Ensure any significant block at very end is grabbed */
  1106. endsec = dz->sbufptr[ENV] - dz->sampbuf[ENV];
  1107. if((endsec - startsec) * dz->iparam[CUTGATE_SAMPBLOK] > minlen) {
  1108. if(maxlevel >= threshold) { /* 12 */
  1109. if((exit_status = store_cut_positions_in_samples(*ccnt,startsec,endsec,dz))<0)
  1110. return(exit_status);
  1111. (*ccnt)++;
  1112. } else {
  1113. tooquiet_segs++;
  1114. }
  1115. } else {
  1116. tooshort_segs++;
  1117. }
  1118. }
  1119. if(*ccnt <= 0) {
  1120. if(tooshort_segs || tooquiet_segs) {
  1121. if(tooshort_segs && tooquiet_segs)
  1122. sprintf(errstr,"%d segments shorter than min duration set (or twice splicelen), and %d too quiet.\n",tooshort_segs,tooquiet_segs);
  1123. else if(tooquiet_segs)
  1124. sprintf(errstr,"%d segments to extract are too quiet (below threshold you set).\n",tooquiet_segs);
  1125. else
  1126. sprintf(errstr,"%d segments are shorter than minimum duration you set, or than twice splicelen.\n",tooshort_segs);
  1127. } else {
  1128. sprintf(errstr,"Whole file is below the gate level.\n");
  1129. }
  1130. return(GOAL_FAILED);
  1131. }
  1132. return(FINISHED);
  1133. }
  1134. /********************************** STORE_STARTCUT_POSITIONS_IN_SAMPLES ********************************/
  1135. int store_startcut_positions_in_samples(int ccnt,int startsec,dataptr dz)
  1136. {
  1137. if(ccnt==0) {
  1138. if((dz->lparray[CUTGATE_STIME] = (int *)malloc(sizeof(int)))==NULL) {
  1139. sprintf(errstr,"INSUFFICENT MEMORY to store cut times.\n");
  1140. return(MEMORY_ERROR);
  1141. }
  1142. } else {
  1143. if((dz->lparray[CUTGATE_STIME] =
  1144. (int *)realloc(dz->lparray[CUTGATE_STIME],(ccnt+1) * sizeof(int)))==NULL) {
  1145. sprintf(errstr,"INSUFFICENT MEMORY to store more cut times.\n");
  1146. return(MEMORY_ERROR);
  1147. }
  1148. }
  1149. dz->lparray[CUTGATE_STIME][ccnt] = startsec * dz->iparam[CUTGATE_SAMPBLOK];
  1150. return(FINISHED);
  1151. }
  1152. /********************************** HOUSE_GATE ********************************/
  1153. int house_gate(dataptr dz)
  1154. {
  1155. int exit_status;
  1156. int gotfirst = 0;
  1157. // int zerosgot = 0, finished = 0, cutcount = 0, chans = dz->infile->channels;
  1158. int zerosgot = 0, finished = 0, chans = dz->infile->channels;
  1159. int startsamp = 0, arraysize = BIGARRAY, n, i, j;
  1160. // int samps_to_get = dz->buflen, samps_to_write;
  1161. int samps_to_write;
  1162. int *cutpoint;
  1163. // int total_samps_read = 0, cutcnt = 0, secseek;
  1164. int total_samps_read = 0, cutcnt = 0;
  1165. char *thisfilename;
  1166. int endsamp;
  1167. if((cutpoint = (int *)malloc(arraysize * sizeof(int)))==NULL) {
  1168. sprintf(errstr,"Insufficient memory to store cutting points.\n");
  1169. return(MEMORY_ERROR);
  1170. }
  1171. display_virtual_time(0,dz);
  1172. fprintf(stdout,"INFO: Finding cutpoints.\n");
  1173. fflush(stdout);
  1174. if((exit_status = read_samps(dz->sampbuf[1],dz)) < 0) {
  1175. sprintf(errstr,"Sound read anomaly.\n");
  1176. return(SYSTEM_ERROR);
  1177. }
  1178. total_samps_read += dz->ssampsread;
  1179. display_virtual_time(total_samps_read,dz);
  1180. n = dz->buflen;
  1181. do {
  1182. memcpy((char *)dz->sampbuf[0],(char *)dz->sampbuf[1],dz->buflen * sizeof(float));
  1183. if(dz->ssampsread != dz->buflen)
  1184. finished = 1;
  1185. if(!finished) {
  1186. if((exit_status = read_samps(dz->sampbuf[1],dz)) < 0) {
  1187. sprintf(errstr,"Sound read anomaly.\n");
  1188. return(SYSTEM_ERROR);
  1189. }
  1190. if(dz->ssampsread != dz->buflen) {
  1191. total_samps_read += dz->ssampsread;
  1192. display_virtual_time(total_samps_read,dz);
  1193. }
  1194. }
  1195. n -= dz->buflen;
  1196. if(!finished) {
  1197. endsamp = max(dz->ssampsread,(dz->iparam[GATE_ZEROS] * chans));
  1198. endsamp += dz->buflen;
  1199. } else
  1200. endsamp = dz->ssampsread;
  1201. while(n<endsamp) {
  1202. if(smpflteq(dz->sampbuf[0][n],0.0)) {
  1203. if(!gotfirst) {
  1204. n += chans;
  1205. continue;
  1206. }
  1207. zerosgot++;
  1208. if(zerosgot > dz->iparam[GATE_ZEROS]) {
  1209. n += chans;
  1210. continue;
  1211. }
  1212. else if(zerosgot == dz->iparam[GATE_ZEROS]) {
  1213. cutpoint[cutcnt++] = (startsamp + n - ((dz->iparam[GATE_ZEROS]-1) * chans));
  1214. if(cutcnt >= arraysize) {
  1215. arraysize += BIGARRAY;
  1216. if((cutpoint = (int *)realloc((char *)cutpoint,arraysize * sizeof(int)))==NULL) {
  1217. sprintf(errstr,"Insufficient memory to store cutting points.\n");
  1218. return(MEMORY_ERROR);
  1219. }
  1220. }
  1221. }
  1222. } else {
  1223. if(!gotfirst) {
  1224. cutpoint[cutcnt++] = (startsamp + n);
  1225. gotfirst = 1;
  1226. n += chans;
  1227. continue;
  1228. } else {
  1229. if(zerosgot >= dz->iparam[GATE_ZEROS]) {
  1230. cutpoint[cutcnt++] = (startsamp + n);
  1231. if(cutcnt >= arraysize) {
  1232. arraysize += BIGARRAY;
  1233. if((cutpoint = (int *)realloc((char *)cutpoint,arraysize * sizeof(int)))==NULL) {
  1234. sprintf(errstr,"Insufficient memory to store cutting points.\n");
  1235. return(MEMORY_ERROR);
  1236. }
  1237. }
  1238. }
  1239. zerosgot = 0;
  1240. }
  1241. }
  1242. n += chans;
  1243. }
  1244. startsamp += dz->buflen;
  1245. } while(!finished);
  1246. if(gotfirst) {
  1247. if(zerosgot < dz->iparam[GATE_ZEROS])
  1248. cutpoint[cutcnt++] = dz->insams[0];
  1249. } else {
  1250. sprintf(errstr,"No silent gaps found: no cuts made.\n");
  1251. return(GOAL_FAILED);
  1252. }
  1253. if(!EVEN(cutcnt)) {
  1254. sprintf(errstr,"cut points not paired correctly.\n");
  1255. return(PROGRAM_ERROR);
  1256. }
  1257. cutcnt /= 2;
  1258. if((exit_status = setup_naming(&thisfilename,dz))<0)
  1259. return(exit_status);
  1260. fprintf(stdout,"INFO: Cutting file.\n");
  1261. fflush(stdout);
  1262. // MULTICHAN -->
  1263. dz->outchans = dz->infile->channels;
  1264. // <-- MULTICHAN
  1265. if((exit_status = reset_peak_finder(dz))<0)
  1266. return(exit_status);
  1267. display_virtual_time(0,dz);
  1268. for(n = 0,i= 0,j=1; n < cutcnt; n++,i+=2,j+=2) {
  1269. if (n > 1999) {
  1270. fprintf(stdout,"WARNING: More than 9999 segments: Finishing here\n");
  1271. fflush(stdout);
  1272. free(thisfilename);
  1273. return(FINISHED);
  1274. }
  1275. reset_filedata_counters(dz);
  1276. if((exit_status = create_outfile_name(n,thisfilename,dz))<0)
  1277. return(exit_status);
  1278. dz->process_type = UNEQUAL_SNDFILE; /* allow sndfile to be created */
  1279. if((exit_status = create_sized_outfile(thisfilename,dz))<0) {
  1280. fprintf(stdout, "WARNING: Soundfile %s already exists.\n", thisfilename);
  1281. fflush(stdout);
  1282. dz->process_type = OTHER_PROCESS;
  1283. dz->ofd = -1;
  1284. return(FINISHED);
  1285. }
  1286. sndseekEx(dz->ifd[0],cutpoint[i],0);
  1287. display_virtual_time(cutpoint[i],dz);
  1288. if((exit_status = read_samps(dz->sampbuf[0],dz)) < 0) {
  1289. sprintf(errstr,"Sound read anomaly.\n");
  1290. return(SYSTEM_ERROR);
  1291. }
  1292. samps_to_write = cutpoint[j] - cutpoint[i];
  1293. while(samps_to_write > dz->buflen) {
  1294. if((exit_status = write_samps(dz->sampbuf[0],dz->buflen,dz))<0)
  1295. return(exit_status);
  1296. samps_to_write -= dz->buflen;
  1297. if((exit_status = read_samps(dz->sampbuf[0],dz)) < 0) {
  1298. sprintf(errstr,"Sound read anomaly.\n");
  1299. return(SYSTEM_ERROR);
  1300. }
  1301. }
  1302. if(samps_to_write) {
  1303. if((exit_status = write_samps(dz->sampbuf[0],samps_to_write,dz))<0)
  1304. return(exit_status);
  1305. }
  1306. dz->outfiletype = SNDFILE_OUT; /* allows header to be written */
  1307. if((exit_status = headwrite(dz->ofd,dz))<0)
  1308. return(exit_status);
  1309. dz->process_type = OTHER_PROCESS; /* restore true status */
  1310. dz->outfiletype = NO_OUTPUTFILE; /* restore true status */
  1311. if((exit_status = reset_peak_finder(dz))<0)
  1312. return(exit_status);
  1313. if(sndcloseEx(dz->ofd) < 0) {
  1314. fprintf(stdout,"WARNING: Can't close output soundfile %s\n",thisfilename);
  1315. fflush(stdout);
  1316. }
  1317. dz->ofd = -1;
  1318. }
  1319. display_virtual_time(dz->insams[0],dz);
  1320. free(thisfilename);
  1321. fprintf(stdout,"INFO: %d segments extracted.\n",cutcnt);
  1322. fflush(stdout);
  1323. return(FINISHED);
  1324. }
  1325. /********************************** HOUSE_GATE2 ********************************/
  1326. #define NOTHING_FOUND 0
  1327. #define INTERGLITCH_FOUND 1
  1328. #define MEASURING_GLITCH 2
  1329. #define MEASURING_INTERGLITCH 3
  1330. int house_gate2(dataptr dz)
  1331. {
  1332. int exit_status;
  1333. float *ibuf = dz->sampbuf[0], *filtbuf, *maxsamp = NULL;
  1334. int n, k, f, cnt, z = 0, possible_start = 0;
  1335. int splicelen = dz->iparam[GATE2_SPLEN];
  1336. double spliceratio, spliceincr = 1.0/(double)splicelen, sum, sum2, thissamp;
  1337. int m, j, gotzero, search_state = 0, chans = dz->infile->channels;
  1338. int nonzerosgot = 0, zerosgot = 0,*pos;
  1339. int endcut = 0, startcut = 0, cutcnt, last_total_samps_read, endsplice, startsplice;
  1340. int filtlen = dz->iparam[GATE2_FILT] * chans, filt_index;
  1341. k = (int)ceil((double)dz->insams[0]/(double)(dz->iparam[GATE2_ZEROS] * chans));
  1342. k += 2;
  1343. k *= 2;
  1344. if(k < 0 || ((dz->lparray[0] = (int *)malloc(k * sizeof(int)))==NULL)) {
  1345. sprintf(errstr,"Insufficient memory to store glitch positions.\n");
  1346. return(MEMORY_ERROR);
  1347. }
  1348. if((filtbuf = (float *)malloc(filtlen * sizeof(float)))==NULL) {
  1349. sprintf(errstr,"Insufficient memory to create filter buffer.\n");
  1350. return(MEMORY_ERROR);
  1351. }
  1352. if(dz->vflag[0]) {
  1353. if((maxsamp = (float *)malloc((k/2) * sizeof(float)))==NULL) {
  1354. sprintf(errstr,"No memory to store glitch maxima.\n");
  1355. return(MEMORY_ERROR);
  1356. }
  1357. memset((char *)maxsamp,0,(k/2) * sizeof(float));
  1358. }
  1359. memset((char *)filtbuf,0,filtlen * sizeof(float));
  1360. pos = dz->lparray[0];
  1361. k = 0;
  1362. fprintf(stdout,"INFO: Searching for glitches.\n");
  1363. fflush(stdout);
  1364. if((exit_status = read_samps(ibuf,dz))<0)
  1365. return(exit_status);
  1366. last_total_samps_read = 0;
  1367. sum = 0;
  1368. filt_index = 0;
  1369. cnt = 0;
  1370. while(dz->ssampsread > 0) {
  1371. n = 0;
  1372. while(n<dz->ssampsread) {
  1373. cnt += chans;
  1374. gotzero = 0;
  1375. thissamp = 0.0;
  1376. for(m=0;m < chans ;m++) { /* add samples cyclically to a buffer */
  1377. filtbuf[filt_index++] = ibuf[n+m];
  1378. thissamp += fabs(ibuf[n+m]);
  1379. }
  1380. filt_index %= filtlen; /* cycle around buffer */
  1381. thissamp /= (double)chans; /* average abs size of samples in all channels at this point */
  1382. cnt = min(cnt,filtlen);
  1383. sum = 0.0; /* sum over filt buffer len, or total no of samps read, whichever is smaller */
  1384. for(f = 0;f < cnt;f++)
  1385. sum += fabs(filtbuf[f]);
  1386. sum /= (double)cnt; /* find average abs samp val over last 'filtlen' samps */
  1387. if(sum <= dz->param[GATE2_LEVEL])
  1388. gotzero = 1;
  1389. if(thissamp > dz->param[GATE2_LEVEL]) { /* note abs level of this sample */
  1390. possible_start = n + last_total_samps_read;
  1391. gotzero = 0;
  1392. }
  1393. if(gotzero) {
  1394. nonzerosgot = 0;
  1395. zerosgot++;
  1396. switch(search_state) {
  1397. case(NOTHING_FOUND): /* not yet enough pre-glitch sub-threshold signal */
  1398. if(zerosgot >= dz->iparam[GATE2_ZEROS])
  1399. search_state = INTERGLITCH_FOUND;
  1400. break;
  1401. case(INTERGLITCH_FOUND): /* already got enough pre-glitch sub-threshold signal */
  1402. break;
  1403. case(MEASURING_GLITCH): /* found glitch: mark end, prepare to measure post-glitch */
  1404. endcut = last_total_samps_read + n;
  1405. search_state = MEASURING_INTERGLITCH;
  1406. break;
  1407. case(MEASURING_INTERGLITCH): /* waiting for enough post-glitch, sub-threshold signal */
  1408. if(zerosgot >= dz->iparam[GATE2_ZEROS]) {
  1409. pos[k++] = startcut;
  1410. pos[k++] = endcut;
  1411. z++;
  1412. search_state = INTERGLITCH_FOUND;
  1413. } /* if enough found, also enough preglitch for next glitch */
  1414. break;
  1415. }
  1416. } else {
  1417. nonzerosgot++;
  1418. zerosgot = 0;
  1419. switch(search_state) {
  1420. case(NOTHING_FOUND): /* not yet enough pre-glitch sub-threshold signal */
  1421. break;
  1422. case(INTERGLITCH_FOUND): /* enough signal before threshold, mark start of excision */
  1423. startcut = possible_start;
  1424. if(dz->vflag[0]) {
  1425. f = filt_index - chans;
  1426. maxsamp[z] = 0.0f;
  1427. for(j = n + last_total_samps_read; j >= startcut; j-=chans, f -= chans) {
  1428. if(f < 0) /* use filtbuf to find maxsamp between here & possible_start */
  1429. f += filtlen;
  1430. thissamp = 0.0;
  1431. for(m=0;m < chans ;m++)
  1432. thissamp += fabs(filtbuf[f+m]);
  1433. thissamp /= (double)chans;
  1434. maxsamp[z] = (float)max(thissamp,(double)maxsamp[z]);
  1435. }
  1436. }
  1437. nonzerosgot += (n + last_total_samps_read - possible_start);
  1438. search_state = MEASURING_GLITCH;
  1439. break;
  1440. case(MEASURING_GLITCH): /* measuring possible glitch: if too long, abandon */
  1441. if(dz->vflag[0])
  1442. maxsamp[z] = (float)max((double)maxsamp[z],thissamp);
  1443. if(nonzerosgot > dz->iparam[GATE2_DUR])
  1444. search_state = NOTHING_FOUND;
  1445. break;
  1446. case(MEASURING_INTERGLITCH): /* was waiting for enough postglitch 'ZEROS' but not enough */
  1447. search_state = NOTHING_FOUND;
  1448. break;
  1449. }
  1450. }
  1451. n += chans;
  1452. }
  1453. last_total_samps_read += dz->ssampsread;
  1454. if((exit_status = read_samps(ibuf,dz))<0)
  1455. return(exit_status);
  1456. }
  1457. if(search_state == 2) {
  1458. pos[k++] = startcut;
  1459. pos[k++] = dz->insams[0];
  1460. }
  1461. cutcnt = k;
  1462. fprintf(stdout,"INFO: glitches found = %d\n",k/2);
  1463. fflush(stdout);
  1464. if(dz->vflag[0]) {
  1465. for(n=0,z=0;n<cutcnt;n+=2,z++) {
  1466. k = (pos[n+1] - pos[n])/chans;
  1467. sum = (double)(k * SECS_TO_MS)/(double)dz->infile->srate;
  1468. k = pos[n]/chans;
  1469. sum2 = (double)k/(double)dz->infile->srate;
  1470. fprintf(stdout,"INFO: GLITCH length %.2lf ms : val %f : at (grouped)sample %d : time %lf secs\n",sum,maxsamp[z],k,sum2);
  1471. }
  1472. fflush(stdout);
  1473. }
  1474. if(cutcnt == 0) {
  1475. sprintf(errstr,"None of the sound will be gated.\n");
  1476. return(GOAL_FAILED);
  1477. }
  1478. sndseekEx(dz->ifd[0],0,0);
  1479. reset_filedata_counters(dz);
  1480. fprintf(stdout,"INFO: Gating the file.\n");
  1481. fflush(stdout);
  1482. last_total_samps_read = 0;
  1483. if((exit_status = read_samps(ibuf,dz))<0)
  1484. return(exit_status);
  1485. for(k=0;k < cutcnt;k+=2) {
  1486. startcut = pos[k] - last_total_samps_read;
  1487. endsplice = startcut;
  1488. startcut -= (splicelen * chans);
  1489. if(startcut < 0) {
  1490. sprintf(errstr,"Bad initial cut: program error.\n");
  1491. return(PROGRAM_ERROR);
  1492. }
  1493. endcut = pos[k+1] - last_total_samps_read;
  1494. startsplice = endcut;
  1495. endcut += (splicelen * chans);
  1496. if(endcut > dz->insams[0]) {
  1497. endcut = dz->insams[0];
  1498. n = endcut - startsplice;
  1499. if(n!=0)
  1500. spliceincr = 1.0/(double)(n/chans);
  1501. }
  1502. spliceratio = 1.0;
  1503. n = startcut;
  1504. while(n >= dz->ssampsread) {
  1505. if((exit_status = write_samps(ibuf,dz->ssampsread,dz))<0)
  1506. return(exit_status);
  1507. last_total_samps_read = dz->total_samps_read;
  1508. if((exit_status = read_samps(ibuf,dz))<0)
  1509. return(exit_status);
  1510. n -= dz->buflen;
  1511. endsplice -= dz->buflen;
  1512. startsplice -= dz->buflen;
  1513. endcut -= dz->buflen;
  1514. }
  1515. while(n<endsplice) {
  1516. spliceratio -= spliceincr;
  1517. for(m=0;m<chans;m++)
  1518. ibuf[n+m] = (float)(ibuf[n+m] * spliceratio);
  1519. n += chans;
  1520. if(n >= dz->ssampsread) {
  1521. if((exit_status = write_samps(ibuf,dz->ssampsread,dz))<0)
  1522. return(exit_status);
  1523. last_total_samps_read = dz->total_samps_read;
  1524. if((exit_status = read_samps(ibuf,dz))<0)
  1525. return(exit_status);
  1526. n -= dz->buflen;
  1527. endsplice -= dz->buflen;
  1528. startsplice -= dz->buflen;
  1529. endcut -= dz->buflen;
  1530. }
  1531. }
  1532. while(n < startsplice) {
  1533. ibuf[n++] = 0.0f;
  1534. if(n >= dz->ssampsread) {
  1535. if((exit_status = write_samps(ibuf,dz->ssampsread,dz))<0)
  1536. return(exit_status);
  1537. last_total_samps_read = dz->total_samps_read;
  1538. if((exit_status = read_samps(ibuf,dz))<0)
  1539. return(exit_status);
  1540. n -= dz->buflen;
  1541. startsplice -= dz->buflen;
  1542. endcut -= dz->buflen;
  1543. }
  1544. }
  1545. spliceratio = 0.0;
  1546. while(n < endcut) {
  1547. spliceratio += spliceincr;
  1548. for(m=0;m<chans;m++)
  1549. ibuf[n+m] = (float)(ibuf[n+m] * spliceratio);
  1550. n += chans;
  1551. if(n >= dz->ssampsread) {
  1552. if((exit_status = write_samps(ibuf,dz->ssampsread,dz))<0)
  1553. return(exit_status);
  1554. last_total_samps_read = dz->total_samps_read;
  1555. if((exit_status = read_samps(ibuf,dz))<0)
  1556. return(exit_status);
  1557. n -= dz->buflen;
  1558. endcut -= dz->buflen;
  1559. }
  1560. }
  1561. }
  1562. while(dz->ssampsread > 0) {
  1563. if((exit_status = write_samps(ibuf,dz->ssampsread,dz))<0)
  1564. return(exit_status);
  1565. if((exit_status = read_samps(ibuf,dz))<0)
  1566. return(exit_status);
  1567. }
  1568. return(FINISHED);
  1569. }