|
@@ -0,0 +1,1674 @@
|
|
|
|
|
+/*
|
|
|
|
|
+ * 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);
|
|
|
|
|
+}
|
|
|
|
|
+
|