richarddobson 3 жил өмнө
parent
commit
6d19ebb657

+ 20 - 0
dev/houskeep/CMakeLists.txt

@@ -0,0 +1,20 @@
+if(APPLE)
+  set(CMAKE_C_FLAGS "-O2 -Wall -mmacosx-version-min=10.5 -Dunix")
+else()
+  if(MINGW)
+    set(CMAKE_C_FLAGS "-O2 -Wall -DWIN32")
+  else()
+    set(CMAKE_C_FLAGS "-O2 -Wall -Dlinux -Dunix")
+  endif()
+endif()
+
+link_directories(../cdp2k ../sfsys)
+
+include_directories(../../include)
+
+add_executable(housekeep main.c ap_house.c channels.c clean.c dump.c dupl.c respec.c sort.c)
+
+target_link_libraries(housekeep cdp2k sfsys ${EXTRA_LIBRARIES})
+
+my_install(housekeep)
+

+ 34 - 0
dev/houskeep/Makefiled.osx

@@ -0,0 +1,34 @@
+#
+#	OSX debug makefile for housekeep  � Richard Dobson, CDP Ltd 2014
+#
+
+CC=gcc
+CFLAGS= -g -Wall -mmacosx-version-min=10.5 -Dunix -I ../include -I ../../include
+SFSYS= ../../lib/libsfsys.a
+CDP2K= ../cdp2k/libcdp2kd.a
+PROG=housekeep
+BINS= main.o ap_house.o channels.o clean.o dump.o dupl.o respec.o sort.o 
+.c.o:
+	$(CC) $(CFLAGS) -c $<
+#
+#	targets
+#
+all:	$(PROG)
+
+$(PROG):	$(BINS)
+	$(CC) $(CFLAGS) $(BINS) -o $(PROG) $(CDP2K) $(SFSYS)
+
+clean:
+	rm -f $(PROG)
+	
+veryclean:	clean
+	rm -f *.o
+
+install:	$(PROG)
+	cp $(PROG) ../Release
+
+#
+#	dependencies
+#
+
+

+ 1007 - 0
dev/houskeep/ap_house.c

@@ -0,0 +1,1007 @@
+/*
+ * 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
+ *
+ */
+/* RWD 14-20: removed usage refs to 'dump' and 'recover' */
+
+
+/* floatsam version TW */
+#include <stdio.h>
+#include <stdlib.h>
+#include <structures.h>
+#include <cdpmain.h>
+#include <tkglobals.h>
+#include <pnames.h>
+#include <house.h>
+#include <processno.h>
+#include <modeno.h>
+#include <globcon.h>
+#include <logic.h>
+#include <filetype.h>
+#include <mixxcon.h>
+#include <flags.h>
+#include <speccon.h>
+#include <arrays.h>
+#include <special.h>
+#include <formants.h>
+#include <sfsys.h>
+#include <osbind.h>
+#include <string.h>
+#include <math.h>
+#include <srates.h>
+#include <flags.h>
+//TW UPDATE
+#include "sfdump.h"
+
+#if defined unix || defined __GNUC__
+#define round(x) lround((x))
+#endif
+
+static int batchexpand_consistency(dataptr dz);
+static int read_batchexpand_params(char *filename,dataptr dz);
+static int create_bakup_sndbufs(dataptr dz);
+
+/***************************************************************************************/
+/****************************** FORMERLY IN aplinit.c **********************************/
+/***************************************************************************************/
+
+/***************************** ESTABLISH_BUFPTRS_AND_EXTRA_BUFFERS **************************/
+
+int establish_bufptrs_and_extra_buffers(dataptr dz)
+{
+	int exit_status;
+//	int is_spec = FALSE;
+	dz->extra_bufcnt = -1;	/* ENSURE EVERY CASE HAS A PAIR OF ENTRIES !! */
+	dz->bptrcnt = 0;
+	dz->bufcnt  = 0;
+	switch(dz->process) {
+	case(HOUSE_COPY):
+		switch(dz->mode) {
+		case(COPYSF):			dz->extra_bufcnt = 0;	dz->bufcnt = 1;		break;
+		case(DUPL):				dz->extra_bufcnt = 0;	dz->bufcnt = 1;		break;
+		default:
+			sprintf(errstr,"Unknown mode for HOUSE_COPY in establish_bufptrs_and_extra_buffers()\n");
+			return(PROGRAM_ERROR);
+		}
+		break;
+	case(HOUSE_DEL):			dz->extra_bufcnt = 0;	dz->bufcnt = 0;							break;
+	case(HOUSE_CHANS):
+		switch(dz->mode) {
+		case(HOUSE_CHANNEL):
+		case(HOUSE_CHANNELS):	dz->extra_bufcnt = 0;	dz->bufcnt = MAX_SNDFILE_OUTCHANS;		break;
+		case(HOUSE_ZCHANNEL):	dz->extra_bufcnt = 0;	dz->bufcnt = MAX_SNDFILE_OUTCHANS;		break;
+		case(STOM):				dz->extra_bufcnt = 0;	dz->bufcnt = MAX_SNDFILE_OUTCHANS;		break;
+		default:				dz->extra_bufcnt = 0;	dz->bufcnt = 2;							break;
+		}
+		break;
+	case(HOUSE_BUNDLE):			dz->extra_bufcnt = 0;	dz->bufcnt = 0;							break;
+	case(HOUSE_SORT):			dz->extra_bufcnt = 0;	dz->bufcnt = 0;							break;
+	case(HOUSE_SPEC):
+		switch(dz->mode) {
+		case(HOUSE_RESAMPLE):	dz->extra_bufcnt = 0;	dz->bufcnt = 5;							break;
+		case(HOUSE_CONVERT):	dz->extra_bufcnt = 0;	dz->bufcnt = 1;	dz->bptrcnt = 1;		break;
+		case(HOUSE_REPROP):		dz->extra_bufcnt = 0;	dz->bufcnt = 1;							break;
+		}
+		break;
+	case(HOUSE_EXTRACT):
+		switch(dz->mode) {
+		case(HOUSE_CUTGATE):		 dz->extra_bufcnt = 0;	dz->bufcnt = 2;						break;
+		case(HOUSE_CUTGATE_PREVIEW): dz->extra_bufcnt = 0;	dz->bufcnt = 2;						break;
+		case(HOUSE_TOPNTAIL):		 dz->extra_bufcnt = 0;	dz->bufcnt = 2;						break;
+		case(HOUSE_RECTIFY):		 dz->extra_bufcnt = 0;	dz->bufcnt = 1;						break;
+		case(HOUSE_BYHAND):		 	 dz->extra_bufcnt = 0;	dz->bufcnt = 1;						break;
+		case(HOUSE_ONSETS):		 	 dz->extra_bufcnt = 0;	dz->bufcnt = 2;						break;
+		default:
+			sprintf(errstr,"Unknown case for HOUSE_EXTRACT in establish_bufptrs_and_extra_buffers()\n");
+			return(PROGRAM_ERROR);
+		}
+		break;
+	case(TOPNTAIL_CLICKS):		dz->extra_bufcnt = 0;	dz->bufcnt = 2;							break;
+	case(HOUSE_BAKUP):			
+	case(HOUSE_GATE):			dz->extra_bufcnt = 0;	dz->bufcnt = 2;							break;
+	case(HOUSE_GATE2):			dz->extra_bufcnt = 0;	dz->bufcnt = 1;							break;
+	case(BATCH_EXPAND):
+	case(HOUSE_DISK):			dz->extra_bufcnt = 0;	dz->bufcnt = 0;							break;
+	default:
+		sprintf(errstr,"Unknown program type [%d] in establish_bufptrs_and_extra_buffers()\n",dz->process);
+		return(PROGRAM_ERROR);
+	}
+
+	if(dz->extra_bufcnt < 0) {
+		sprintf(errstr,"bufcnts have not been set: establish_bufptrs_and_extra_buffers()\n");
+		return(PROGRAM_ERROR);
+	}
+	else if((dz->process==HOUSE_SPEC && dz->mode==HOUSE_CONVERT) || dz->process==INFO_DIFF) {
+		if((exit_status = establish_spec_bufptrs_and_extra_buffers(dz))<0)
+			return(exit_status);
+	}
+	return establish_groucho_bufptrs_and_extra_buffers(dz);
+}
+
+/***************************** SETUP_INTERNAL_ARRAYS_AND_ARRAY_POINTERS **************************/
+
+int setup_internal_arrays_and_array_pointers(dataptr dz)
+{
+	int n;		 
+	dz->ptr_cnt    = -1;		/* base constructor...process */
+	dz->array_cnt  = -1;
+	dz->iarray_cnt = -1;
+	dz->larray_cnt = -1;
+	switch(dz->process) {
+	case(HOUSE_COPY):	   dz->array_cnt=0; dz->iarray_cnt=0; dz->larray_cnt=0; dz->ptr_cnt= 0; dz->fptr_cnt = 0; break;
+	case(HOUSE_DEL):       dz->array_cnt=0; dz->iarray_cnt=0; dz->larray_cnt=0; dz->ptr_cnt= 0; dz->fptr_cnt = 0; break;
+	case(HOUSE_CHANS):     dz->array_cnt=0; dz->iarray_cnt=0; dz->larray_cnt=0; dz->ptr_cnt= 0; dz->fptr_cnt = 0; break;
+	case(HOUSE_BUNDLE):	   dz->array_cnt=0; dz->iarray_cnt=0; dz->larray_cnt=0; dz->ptr_cnt= 0; dz->fptr_cnt = 0; break;
+	case(HOUSE_SORT):	   dz->array_cnt=0; dz->iarray_cnt=0; dz->larray_cnt=0; dz->ptr_cnt= 0; dz->fptr_cnt = 0; break;
+	case(HOUSE_SPEC):
+		switch(dz->mode) {
+		case(HOUSE_RESAMPLE): dz->array_cnt=0; dz->iarray_cnt=0; dz->larray_cnt=0; dz->ptr_cnt=6; dz->fptr_cnt=0; break;
+		default:			  dz->array_cnt=0; dz->iarray_cnt=0; dz->larray_cnt=0; dz->ptr_cnt=0; dz->fptr_cnt=0; break;
+		}
+		break;		
+	case(HOUSE_EXTRACT):
+		switch(dz->mode) {
+		case(HOUSE_CUTGATE): dz->array_cnt=0; dz->iarray_cnt=0; dz->larray_cnt=2; dz->ptr_cnt=0; dz->fptr_cnt= 0; break;
+		case(HOUSE_ONSETS):  dz->array_cnt=0; dz->iarray_cnt=0; dz->larray_cnt=1; dz->ptr_cnt=0; dz->fptr_cnt= 0; break;
+		case(HOUSE_BYHAND):  dz->array_cnt=2; dz->iarray_cnt=0; dz->larray_cnt=0; dz->ptr_cnt=0; dz->fptr_cnt= 0; break;
+		default:		   dz->array_cnt=0; dz->iarray_cnt=0; dz->larray_cnt=0; dz->ptr_cnt= 0; dz->fptr_cnt = 0; break;
+		}
+		break;
+	case(TOPNTAIL_CLICKS): dz->array_cnt=0; dz->iarray_cnt=0; dz->larray_cnt=0; dz->ptr_cnt= 0; dz->fptr_cnt = 0; break;
+	case(HOUSE_BAKUP):	   dz->array_cnt=0; dz->iarray_cnt=0; dz->larray_cnt=0; dz->ptr_cnt= 0; dz->fptr_cnt = 0; break;
+	case(HOUSE_GATE):	   dz->array_cnt=0; dz->iarray_cnt=0; dz->larray_cnt=0; dz->ptr_cnt= 0; dz->fptr_cnt = 0; break;
+	case(HOUSE_GATE2):	   dz->array_cnt=0; dz->iarray_cnt=0; dz->larray_cnt=1; dz->ptr_cnt= 0; dz->fptr_cnt = 0; break;
+	case(BATCH_EXPAND):
+	case(HOUSE_DISK):	   dz->array_cnt=0; dz->iarray_cnt=0; dz->larray_cnt=0; dz->ptr_cnt= 0; dz->fptr_cnt = 0; break;
+	}
+
+/*** WARNING ***
+ANY APPLICATION DEALING WITH A NUMLIST INPUT: MUST establish AT LEAST 1 double array: i.e. dz->array_cnt = at least 1
+**** WARNING ***/
+
+
+	if(dz->array_cnt < 0 || dz->iarray_cnt < 0 || dz->larray_cnt < 0 || dz->ptr_cnt < 0 || dz->fptr_cnt < 0) {
+		sprintf(errstr,"array_cnt not set in setup_internal_arrays_and_array_pointers()\n");	   
+		return(PROGRAM_ERROR);
+	}
+
+	if(dz->array_cnt > 0) {  
+		if((dz->parray  = (double **)malloc(dz->array_cnt * sizeof(double *)))==NULL) {
+			sprintf(errstr,"INSUFFICIENT MEMORY for internal double arrays.\n");
+			return(MEMORY_ERROR);
+		}
+		for(n=0;n<dz->array_cnt;n++)
+			dz->parray[n] = NULL;
+	}
+	if(dz->iarray_cnt > 0) {
+		if((dz->iparray = (int     **)malloc(dz->iarray_cnt * sizeof(int *)))==NULL) {
+			sprintf(errstr,"INSUFFICIENT MEMORY for internal int arrays.\n");
+			return(MEMORY_ERROR);
+		}
+		for(n=0;n<dz->iarray_cnt;n++)
+			dz->iparray[n] = NULL;
+	}
+	if(dz->larray_cnt > 0) {	  
+		if((dz->lparray = (int    **)malloc(dz->larray_cnt * sizeof(int *)))==NULL) {
+			sprintf(errstr,"INSUFFICIENT MEMORY for internal long arrays.\n");
+			return(MEMORY_ERROR);
+		}
+		for(n=0;n<dz->larray_cnt;n++)
+			dz->lparray[n] = NULL;
+	}
+	if(dz->ptr_cnt > 0)   {  	  
+		if((dz->ptr    	= (double  **)malloc(dz->ptr_cnt  * sizeof(double *)))==NULL) {
+			sprintf(errstr,"INSUFFICIENT MEMORY for internal pointer arrays.\n");
+			return(MEMORY_ERROR);
+		}
+		for(n=0;n<dz->ptr_cnt;n++)
+			dz->ptr[n] = NULL;
+	}
+	if(dz->fptr_cnt > 0)   {  	  
+		if((dz->fptr = (float  **)malloc(dz->fptr_cnt * sizeof(float *)))==NULL) {
+			sprintf(errstr,"INSUFFICIENT MEMORY for internal float-pointer arrays.\n");
+			return(MEMORY_ERROR);
+		}
+		for(n=0;n<dz->fptr_cnt;n++)
+			dz->fptr[n] = NULL;
+	}
+	return(FINISHED);
+}
+
+/****************************** ASSIGN_PROCESS_LOGIC *********************************/
+
+int assign_process_logic(dataptr dz)
+{						 
+	switch(dz->process) {
+	case(HOUSE_COPY):
+		switch(dz->mode) {
+		case(COPYSF):		setup_process_logic(ALL_FILES,			EQUAL_SNDFILE,		SNDFILE_OUT,	dz);	break;
+		case(DUPL):
+			if(!sloom)
+				setup_process_logic(SNDFILES_ONLY,		OTHER_PROCESS,		NO_OUTPUTFILE,	dz);
+			else
+				setup_process_logic(ALL_FILES,			EQUAL_SNDFILE,		SNDFILE_OUT,	dz);
+			break;
+		default:
+			sprintf(errstr,"Unknown mode for HOUSE_COPY in assign_process_logic()\n");
+			return(PROGRAM_ERROR);
+		}
+		break;
+	case(HOUSE_DEL):		setup_process_logic(NO_FILE_AT_ALL,		OTHER_PROCESS,		NO_OUTPUTFILE,	dz);	break;
+	case(HOUSE_CHANS):		
+		switch(dz->mode) {
+		case(HOUSE_CHANNEL):	setup_process_logic(SNDFILES_ONLY,	UNEQUAL_SNDFILE,	NO_OUTPUTFILE,	dz);	break;
+		case(HOUSE_CHANNELS):	setup_process_logic(SNDFILES_ONLY,	UNEQUAL_SNDFILE,	NO_OUTPUTFILE,	dz);	break;
+		case(HOUSE_ZCHANNEL):	setup_process_logic(SNDFILES_ONLY,	UNEQUAL_SNDFILE,	SNDFILE_OUT,	dz);	break;
+		case(STOM):				setup_process_logic(SNDFILES_ONLY,	UNEQUAL_SNDFILE,	SNDFILE_OUT,	dz);	break;
+		case(MTOS):				setup_process_logic(SNDFILES_ONLY,	UNEQUAL_SNDFILE,	SNDFILE_OUT,	dz);	break;
+		default:
+			sprintf(errstr,"Unknown mode for HOUSE_CHANS in assign_process_logic()\n");
+			return(PROGRAM_ERROR);
+		}
+		break;
+	case(HOUSE_BUNDLE):			setup_process_logic(ANY_NUMBER_OF_ANY_FILES,TO_TEXTFILE,		TEXTFILE_OUT,	dz);	break;
+	case(HOUSE_SORT):			setup_process_logic(WORDLIST_ONLY,			OTHER_PROCESS,		NO_OUTPUTFILE,	dz);	break;
+	case(HOUSE_SPEC):			
+		switch(dz->mode) {
+		case(HOUSE_REPROP):		setup_process_logic(SNDFILES_ONLY,	EQUAL_SNDFILE,		SNDFILE_OUT,	dz);	break;
+		default:				setup_process_logic(SNDFILES_ONLY,	UNEQUAL_SNDFILE,	SNDFILE_OUT,	dz);	break;
+		}
+		break;
+	case(HOUSE_EXTRACT):
+		switch(dz->mode) {
+		case(HOUSE_CUTGATE):		 setup_process_logic(SNDFILES_ONLY,	OTHER_PROCESS,	 NO_OUTPUTFILE,	dz);	break;
+		case(HOUSE_ONSETS):			 setup_process_logic(SNDFILES_ONLY,	TO_TEXTFILE,	 TEXTFILE_OUT,	dz);	break;
+		case(HOUSE_CUTGATE_PREVIEW): setup_process_logic(SNDFILES_ONLY, UNEQUAL_SNDFILE, SNDFILE_OUT,	dz);	break;
+		case(HOUSE_TOPNTAIL):		 setup_process_logic(SNDFILES_ONLY,	UNEQUAL_SNDFILE, SNDFILE_OUT,	dz);	break;
+		case(HOUSE_RECTIFY):		 setup_process_logic(SNDFILES_ONLY,	EQUAL_SNDFILE,	 SNDFILE_OUT,	dz);	break;
+		case(HOUSE_BYHAND):		 	 setup_process_logic(SNDFILES_ONLY,	EQUAL_SNDFILE,	 SNDFILE_OUT,	dz);	break;
+		}
+		break;
+	case(TOPNTAIL_CLICKS):  setup_process_logic(SNDFILES_ONLY,	UNEQUAL_SNDFILE, SNDFILE_OUT,	dz);			break;
+	case(HOUSE_BAKUP):		setup_process_logic(ONE_OR_MANY_SNDFILES,	UNEQUAL_SNDFILE, SNDFILE_OUT,	dz);	break;
+	case(HOUSE_GATE):		setup_process_logic(SNDFILES_ONLY,			OTHER_PROCESS,	 NO_OUTPUTFILE,	dz);	break;
+	case(HOUSE_GATE2):		setup_process_logic(SNDFILES_ONLY,			EQUAL_SNDFILE,	 SNDFILE_OUT,	dz);	break;
+	case(HOUSE_DISK):			
+		setup_process_logic(ALL_FILES,		SCREEN_MESSAGE,		NO_OUTPUTFILE,	dz);	
+		break;
+	case(BATCH_EXPAND):	    setup_process_logic(ANY_NUMBER_OF_ANY_FILES, TO_TEXTFILE,	TEXTFILE_OUT,	dz);	break;
+	default:
+		sprintf(errstr,"Unknown process: assign_process_logic()\n");
+		return(PROGRAM_ERROR);
+		break;
+	}
+	if(dz->has_otherfile) {
+		switch(dz->input_data_type) {
+		case(ALL_FILES):
+		case(TWO_SNDFILES):
+		case(SNDFILE_AND_ENVFILE):
+		case(SNDFILE_AND_BRKFILE):
+		case(SNDFILE_AND_UNRANGED_BRKFILE):
+		case(SNDFILE_AND_DB_BRKFILE):
+			break;
+		case(MANY_SNDFILES):
+			if(dz->process==INFO_TIMELIST)
+				break;
+			/* fall thro */
+		default:
+			sprintf(errstr,"Most processes accepting files with different properties\n"
+						   "can only take 2 sound infiles.\n");
+			return(PROGRAM_ERROR);
+		}
+	}
+	return(FINISHED);
+}
+
+/***************************** SET_LEGAL_INFILE_STRUCTURE **************************
+ *
+ * Allows 2nd infile to have different props to first infile.
+ */
+
+void set_legal_infile_structure(dataptr dz)
+{
+	switch(dz->process) {
+	default:
+		dz->has_otherfile = FALSE;
+		break;
+	}
+}
+
+/***************************************************************************************/
+/****************************** FORMERLY IN internal.c *********************************/
+/***************************************************************************************/
+
+/****************************** SET_LEGAL_INTERNALPARAM_STRUCTURE *********************************/
+
+int set_legal_internalparam_structure(int process,int mode,aplptr ap)
+{
+	int exit_status = FINISHED;
+	switch(process) {
+	case(HOUSE_COPY):   	exit_status = set_internalparam_data("",ap); 		break;
+	case(HOUSE_DEL):   		exit_status = set_internalparam_data("",ap); 		break;
+	case(HOUSE_CHANS):   	exit_status = set_internalparam_data("",ap); 		break;
+	case(HOUSE_BUNDLE):		exit_status = set_internalparam_data("",ap); 		break;
+	case(HOUSE_SORT):   	exit_status = set_internalparam_data("i",ap); 		break;
+	case(HOUSE_SPEC):
+		switch(mode) {
+		case(HOUSE_RESAMPLE):exit_status = set_internalparam_data("00iiii",ap);	break;
+		default:			 exit_status = set_internalparam_data("",ap); 		break;
+		}
+		break;															 /*w	  sp*/
+	case(HOUSE_EXTRACT):   												 /*i	  lc*/
+		switch(mode) {													 /*n	  nt*/
+		case(HOUSE_CUTGATE): exit_status = set_internalparam_data(         "iiiiiii",ap);	break;
+		case(HOUSE_ONSETS):  exit_status = set_internalparam_data(         "iiiiiii",ap);	break;
+case(HOUSE_CUTGATE_PREVIEW): exit_status = set_internalparam_data("00000000iiiiiii",ap);	break;
+	   case(HOUSE_TOPNTAIL): exit_status = set_internalparam_data("ii",ap);					break;
+		case(HOUSE_RECTIFY): exit_status = set_internalparam_data("",ap);					break;
+		case(HOUSE_BYHAND):  exit_status = set_internalparam_data("",ap);					break;
+		}
+		break;
+	case(TOPNTAIL_CLICKS):	exit_status = set_internalparam_data("",ap);			break;
+	case(HOUSE_BAKUP):   	
+	case(HOUSE_GATE):   	
+	case(HOUSE_GATE2):
+	case(BATCH_EXPAND):
+	case(HOUSE_DISK):   	exit_status = set_internalparam_data("",ap); 					break;
+	default:
+		sprintf(errstr,"Unknown process in set_legal_internalparam_structure()\n");
+		return(PROGRAM_ERROR);
+	}
+	return(exit_status);		
+}
+
+/********************************************************************************************/
+/********************************** FORMERLY IN specialin.c *********************************/
+/********************************************************************************************/
+
+/********************** READ_SPECIAL_DATA ************************/
+
+int read_special_data(char *str,dataptr dz)	   
+{
+//	int exit_status = FINISHED;
+	aplptr ap = dz->application;
+
+	switch(ap->special_data) {
+	case(SNDFILENAME):				return read_new_filename(str,dz);
+	case(BATCH):					return read_batchexpand_params(str,dz);
+	case(BY_HAND):	
+// TW ADDED : ensures back-compatibility, but blocks essentially 16-bit (& now redundant) process
+		sprintf(errstr,"THIS PROCESS IS NO LONGER AVAILABLE.");
+		return(GOAL_FAILED);
+	default:
+		sprintf(errstr,"Unknown special_data type: read_special_data()\n");
+		return(PROGRAM_ERROR);
+	}
+	return(FINISHED);	/* NOTREACHED */
+}
+
+/********************************************************************************************/
+/********************************** FORMERLY IN preprocess.c ********************************/
+/********************************************************************************************/
+
+/****************************** PARAM_PREPROCESS *********************************/
+
+int param_preprocess(dataptr dz)	
+{
+//	int exit_status = FINISHED;
+
+	switch(dz->process) {
+	case(HOUSE_COPY):
+	case(HOUSE_DEL):
+	case(HOUSE_BUNDLE):
+	case(HOUSE_EXTRACT):
+	case(TOPNTAIL_CLICKS):
+	case(HOUSE_BAKUP):
+	case(HOUSE_GATE):
+	case(HOUSE_DISK):
+	case(BATCH_EXPAND):
+		break;
+	case(HOUSE_CHANS):
+		switch(dz->mode) {
+		case(HOUSE_CHANNELS):
+		case(STOM):
+		case(MTOS):
+			break;
+		default:
+			if(dz->iparam[CHAN_NO] > dz->infile->channels) {
+				sprintf(errstr,"There is no channel %d in the input file\n",dz->iparam[CHAN_NO]);
+				return(DATA_ERROR);
+			}
+			break;
+		}
+		break;
+	case(HOUSE_GATE2):
+		dz->iparam[GATE2_DUR]    = max(1,(int)round(dz->param[GATE2_DUR] * MS_TO_SECS * (double)dz->infile->srate));
+		dz->iparam[GATE2_ZEROS]  = max(1,(int)round(dz->param[GATE2_ZEROS] * MS_TO_SECS * (double)dz->infile->srate));
+		dz->iparam[GATE2_SPLEN]  = max(1,(int)round(dz->param[GATE2_SPLEN] * MS_TO_SECS * (double)dz->infile->srate));
+		dz->iparam[GATE2_FILT]   = max(1,(int)round(dz->param[GATE2_FILT] * MS_TO_SECS * (double)dz->infile->srate));
+		if(dz->iparam[GATE2_SPLEN] * 2 > dz->iparam[GATE2_ZEROS]) {
+			sprintf(errstr,"Splicelength must be no more than half as long as minimum duration of 'silence' around glitch.\n");
+			return(DATA_ERROR);
+		}
+		break;
+	case(HOUSE_SPEC): return FINISHED;
+	case(HOUSE_SORT): return sort_preprocess(dz);
+	default:
+		sprintf(errstr,"PROGRAMMING PROBLEM: Unknown process in param_preprocess()\n");
+		return(PROGRAM_ERROR);
+	}
+	return(FINISHED);
+}
+
+/********************************************************************************************/
+/********************************** FORMERLY IN procgrou.c **********************************/
+/********************************************************************************************/
+
+/**************************** GROUCHO_PROCESS_FILE ****************************/
+
+int groucho_process_file(dataptr dz)   /* FUNCTIONS FOUND IN PROCESS.C */
+{	
+//	int exit_status = FINISHED;
+
+	switch(dz->process) {
+	case(HOUSE_COPY):		return do_duplicates(dz);
+	case(HOUSE_DEL):		return do_deletes(dz);
+	case(HOUSE_CHANS):		return do_channels(dz);
+	case(HOUSE_BUNDLE):		return do_bundle(dz);
+	case(HOUSE_SORT):		return do_file_sorting(dz);
+	case(HOUSE_SPEC):		return do_respecification(dz);
+	case(TOPNTAIL_CLICKS):
+	case(HOUSE_EXTRACT):	return process_clean(dz);
+//TW UPDATES (replacing bracketed-out code - DUMP & RECOVER have now been abandoned)
+	case(HOUSE_GATE):		return house_gate(dz);
+	case(HOUSE_GATE2):		return house_gate2(dz);
+	case(HOUSE_BAKUP):		return house_bakup(dz);
+
+	case(HOUSE_DISK):		return check_available_diskspace(dz);
+	case(BATCH_EXPAND):		return batch_expand(dz);
+	default:
+		sprintf(errstr,"Unknown case in process_file()\n");
+		return(PROGRAM_ERROR);
+	}
+	return(FINISHED);	/* NOTREACHED */
+}
+
+/********************************************************************************************/
+/********************************** FORMERLY IN pconsistency.c ******************************/
+/********************************************************************************************/
+
+/****************************** CHECK_PARAM_VALIDITY_AND_CONSISTENCY *********************************/
+
+int check_param_validity_and_consistency(dataptr dz)
+{
+//	int exit_status = FINISHED;
+	handle_pitch_zeros(dz);
+	switch(dz->process) {
+	case(TOPNTAIL_CLICKS):
+	case(HOUSE_EXTRACT):	return pconsistency_clean(dz);
+	case(BATCH_EXPAND):		return batchexpand_consistency(dz);
+	}
+	return(FINISHED);
+}
+
+/********************************************************************************************/
+/********************************** FORMERLY IN buffers.c ***********************************/
+/********************************************************************************************/
+
+/**************************** ALLOCATE_LARGE_BUFFERS ******************************/
+
+int allocate_large_buffers(dataptr dz)
+{
+	switch(dz->process) {
+	case(HOUSE_COPY):	 
+		if(!(dz->mode == COPYSF && dz->infile->filetype == WORDLIST))
+			return create_sndbufs(dz);
+		break;
+	case(HOUSE_CHANS):	 return create_sndbufs(dz);
+	case(HOUSE_SPEC):	 return create_respec_buffers(dz);
+//TW UPDATES (replacing bracketed-out code - DUMP & RECOVER have now been abandoned)
+	case(HOUSE_BAKUP):	 return create_bakup_sndbufs(dz);
+	case(HOUSE_GATE2):
+	case(HOUSE_GATE): 	 return create_sndbufs(dz); 
+
+	case(HOUSE_EXTRACT): 
+		switch(dz->mode) {
+		case(HOUSE_RECTIFY):
+		case(HOUSE_BYHAND):	return create_sndbufs(dz);
+		default:			return create_clean_buffers(dz);
+		}
+		break;
+	case(TOPNTAIL_CLICKS): return create_clean_buffers(dz);
+	case(HOUSE_BUNDLE):
+	case(HOUSE_DEL):
+	case(HOUSE_SORT):
+	case(HOUSE_DISK):
+	case(BATCH_EXPAND):
+		break;
+	default:
+		sprintf(errstr,"Unknown program no. in allocate_large_buffers()\n");
+		return(PROGRAM_ERROR);
+	}
+	return(FINISHED);
+}
+
+/********************************************************************************************/
+/********************************** FORMERLY IN cmdline.c ***********************************/
+/********************************************************************************************/
+
+int get_process_no(char *prog_identifier_from_cmdline,dataptr dz)
+{
+	if     (!strcmp(prog_identifier_from_cmdline,"copy"))			dz->process = HOUSE_COPY;
+	else if(!strcmp(prog_identifier_from_cmdline,"remove"))			dz->process = HOUSE_DEL;
+	else if(!strcmp(prog_identifier_from_cmdline,"chans"))			dz->process = HOUSE_CHANS;
+	else if(!strcmp(prog_identifier_from_cmdline,"bundle"))			dz->process = HOUSE_BUNDLE;
+	else if(!strcmp(prog_identifier_from_cmdline,"sort"))			dz->process = HOUSE_SORT;
+	else if(!strcmp(prog_identifier_from_cmdline,"respec"))			dz->process = HOUSE_SPEC;
+	else if(!strcmp(prog_identifier_from_cmdline,"extract"))		dz->process = HOUSE_EXTRACT;
+//TW UPDATES (replacing bracketed-out code - DUMP & RECOVER have now been abandoned)
+	else if(!strcmp(prog_identifier_from_cmdline,"bakup"))			dz->process = HOUSE_BAKUP;
+	else if(!strcmp(prog_identifier_from_cmdline,"gate"))			dz->process = HOUSE_GATE;
+
+	else if(!strcmp(prog_identifier_from_cmdline,"disk"))			dz->process = HOUSE_DISK;
+	else if(!strcmp(prog_identifier_from_cmdline,"batchexpand"))	dz->process = BATCH_EXPAND;
+	else if(!strcmp(prog_identifier_from_cmdline,"endclicks"))		dz->process = TOPNTAIL_CLICKS;
+	else if(!strcmp(prog_identifier_from_cmdline,"deglitch"))		dz->process = HOUSE_GATE2;
+	else {
+		sprintf(errstr,"Unknown program identification string '%s'\n",prog_identifier_from_cmdline);
+		return(USAGE_ONLY);
+	}
+	return FINISHED;
+}
+
+/********************************************************************************************/
+/********************************** FORMERLY IN usage.c *************************************/
+/********************************************************************************************/
+
+/******************************** USAGE1 ********************************/
+
+int usage1(void)
+{
+	sprintf(errstr,
+	"USAGE: housekeep NAME (mode) infile(s) (outfile) (parameters)\n"
+	"\n"
+	"where NAME can be any one of\n"
+	"\n"
+	"extract  copy   remove   chans   respec   bundle   sort   disk\n"
+//TW UPDATES
+	"bakup    gate    batchexpand    endclicks    deglitch\n"
+
+	"\n"
+	"Type 'housekeep chans'  for more info on housekeep chans option... ETC.\n");
+	return(USAGE_ONLY);
+}
+
+/******************************** USAGE2 ********************************/
+
+int usage2(char *str)
+{
+	if(!strcmp(str,"copy")) {
+    	fprintf(stdout,
+		"MAKE COPIES OF THE INFILE\n\n"
+		"USAGE: housekeep copy 1 infile outfile\n"
+		"OR:    housekeep copy 2 infile count [-i]\n"
+		"MODES ARE\n"
+		"1) COPY ONCE\n" 
+		"2) COPY MANY\n"
+		"         Produces N copies of infile X, with names X_001,X_002...\n"
+		"         COUNT is number of duplicates to produce.\n"
+		"     -i  ignore existing duplicates (don't overwrite them).\n"
+		"         default, process halts on discovering a pre-existing file.\n");
+
+	} else if(!strcmp(str,"remove")) {
+    	fprintf(stdout,
+		"REMOVE EXISTING COPIES OF A FILE \n\n"
+		"USAGE: housekeep remove filename [-a]\n\n"
+		"         Deletes any copies of filename X, having names X_001,X_002...\n"
+		"         No checks are made that these ARE COPIES of file X!!\n"
+		"     -a  Program checks all names in numbered sequence.\n"
+		"         In standard case, once a numbered file is missing,\n"
+		"         program checks for %d more named files before halting.\n"
+		"         Setting -a flag forces program to search for all possible\n"
+		"         duplicate filenames. This may take some time.\n",COPYDEL_OVERMAX);
+
+	} else if(!strcmp(str,"chans")) {
+    	fprintf(stdout,
+		"EXTRACT OR CONVERT CHANNELS OF SOUNDFILE.\n\n"
+		"USAGE: housekeep chans 1 infile channo\n"
+		"OR:    housekeep chans 2 infile \n"
+		"OR:    housekeep chans 3 infile outfile channo\n"
+		"OR:    housekeep chans 4 infile outfile [-p]\n"
+		"OR:    housekeep chans 5 infile outfile\n\n"
+		"MODES ARE\n"
+		"1) EXTRACT A CHANNEL\n"
+		"         channo is channel to extract\n" 
+		"         outfile is named inname_c1 (for channel 1) etc.\n"
+		"2) EXTRACT ALL CHANNELS\n"
+		"         outfiles are named inname_c1 (for channel 1) etc.\n"
+		"3) ZERO ONE CHANNEL\n"
+		"         channo is channel to zero\n" 
+		"         mono file goes to just one side of stereo outfile.\n"
+		"         multichannel files have one channel zeroed out.\n"
+		"4) MIX DOWN TO MONO\n"
+		"         -p inverts phase of 2nd stereo channel before mixing.\n" 
+		"         (phase inversion has no effect with non-stereo files).\n" 
+		"5) MONO TO STEREO\n"
+		"         Creates a 2-channel equivalent of mono infile.\n"); 
+	} else if(!strcmp(str,"bundle")) {
+    	fprintf(stdout,
+		"LIST FILENAMES IN TEXTFILE FOR SORTING, OR MIXDUMMY.\n\n"
+		"USAGE: housekeep bundle mode infile [infile2....] outtextfile\n\n"
+		"MODES ARE\n"
+		"1) BUNDLE ALL ENTERED FILES\n"
+		"2) BUNDLE ALL NON-TEXT FILES ENTERED\n"
+		"3) BUNDLE ALL NON-TEXT FILES OF SAME TYPE AS FIRST NON-TEXT FILE\n"
+		"           e.g. all sndfiles, or all analysis files....\n"
+		"4) AS (3), BUT ONLY FILES WITH SAME PROPERTIES\n"
+		"5) AS (4), BUT IF FILE1 IS SNDFILE, FILES WITH SAME CHAN COUNT ONLY\n");
+	} else if(!strcmp(str,"sort")) {
+    	fprintf(stdout,
+		"SORT FILES LISTED IN A TEXTFILE.\n\n"
+		"USAGE: housekeep sort 1   listfile\n"
+		"OR:    housekeep sort 2-3 listfile small large step [-l]\n"
+		"OR:    housekeep sort 4   listfile [-l]\n"
+		"OR:    housekeep sort 5   listfile\n"
+		"LISTFILE is a textfile, a list of names of files to be sorted.\n\n"
+		"MODES ARE\n"
+		"1) SORT BY FILETYPE\n"
+		"      Sorts files into different types.\n"
+		"      Lists appropriate filenames in textfiles with extensions.. \n"
+		"      .mot  mono sndfiles           .stt  stereo sndfiles\n"
+		"      .qtt  4-channel sndfiles      .ant  analysis files\n"
+		"      .pct  binary pitchdata files  .fot  binary formant files\n"
+		"      .ent  binary envelope files   .trt  binary transposition files\n"
+		"      .ott  any other files\n"
+		"2) SORT BY SRATE\n"
+		"      Sorts any soundfiles to different sampling rates.\n"
+		"      Lists appropriate filenames in textfiles with extensions.. \n"
+		"      .24  for 24000            .44  for 44100              ETC\n"
+		"3) SORT BY DURATION\n"
+		"      Sorts any soundfiles to different lengths.\n"
+		"      If the listfile is 'list' or 'list.xxx' sorted file is 'list.len'.\n"
+		"      SMALL is max size of smallest files. (secs)\n"
+		"      LARGE is min size of largest files. (secs)\n"
+		"      STEP  is size-steps between file types. (secs)\n"
+		"      -l causes file durations not to be written to outfile.\n"
+		"4) SORT BY LOG DURATION\n"
+		"      The same, except STEP is duration ratio between file types.\n"
+		"      -l causes file durations not to be written to outfile.\n"
+		"5) SORT INTO DURATION ORDER\n"
+		"      Sorts any sndfiles into duration order.\n"
+		"      If the listfile is 'list' or 'list.xxx' sorted file is 'list.len'.\n"
+		"      -l causes file durations not to be written to outfile.\n"
+		"6) FIND ROGUES\n"
+		"      Sort out any non- or invalid soundfiles.\n");
+	} else if(!strcmp(str,"respec")) {
+    	fprintf(stdout, 
+    	"ALTER THE SPECIFICATION OF A SOUNDFILE.\n\n"
+    	"USAGE: housekeep respec 1 infile outfile new_samplerate\n"
+		"OR:    housekeep respec 2 infile outfile\n"
+		"OR:    housekeep respec 3 infile outfile [-ssrate] [-cchannels]\n"
+		"MODES ARE\n\n"
+		"1) RESAMPLE  at some different sampling rate.\n"
+		"           New sampling rate must be one of...\n"
+		"           96000,88200,48000,24000,44100,22050,32000,16000\n\n"
+		"2) CONVERT FROM INTEGER TO FLOAT SAMPLES, OR VICE VERSA\n\n"
+		"3) CHANGE PROPERTIES OF SOUND: (USE WITH CAUTION!!)\n"
+        "      SRATE is the new sample rate to impose.\n"
+		"           NB: this does NOT RESAMPLE the data.\n"
+		"           Simply causes original data to be read at different srate.\n"
+		"           Sound has same no of samples, but different duration,\n"
+		"           and will appear to be transposed in pitch.\n"
+        "      CHANNELS is the new channel count to impose.\n"
+		"           NB: this does NOT RECHANNEL the data.\n"
+		"           Hence e.g. a stereo file will appear twice as long.\n"
+		);
+	} else if(!strcmp(str,"extract")) {
+//TW further reformatted: fits on one screen
+		fprintf(stdout,
+		"USAGE: housekeep extract \n"
+		"       1 inf [-ggate] [-sS] [-eE] [-tT] [-hH] [-bB] [-iI] [-lL] [-wW] [-n]\n"
+    	"OR:    2 inf outf             OR: 3 inf outf [-ggate] [-ssplice] [-b] [-e]\n"
+    	"OR:    4 inf outf shift       OR: 5 inf outf valsfile\n"
+    	"OR:    6 inf gate endgate threshold baktrak initlevel minsize gatewin\n"
+		"MODE 1) CUT OUT & KEEP SIGNIFICANT EVENTS FROM INPUT SNDFILE.\n"
+		"-g  GATE level (G) above which sounds accepted : Range:0-1 (default 0).\n"
+		"-s  SPLICE LENGTH in mS (default 15mS)\n"
+		"-e  END-CUTOFF level (E) below which END of sound cut.(If 0, defaults to GATE).\n"
+		"-t  THRESHOLD (T) If segment level never exceeds threshold,not kept(default 0)\n"
+		"-h  HOLD sound till S sectors BEFORE START of next segment.(default 0)\n"
+		"-b  KEEP B sects prior to gate-on, if level there > I (see below). Max B is %d.\n"
+		"-i  INITIAL level (I). Use with -b flag.\n"
+		"-l  Min LENGTH of events to keep (secs).\n"
+		"-w  GATE_WINDOW Gates off only if level < gate for W+1 sectors. (default 0).\n"
+		"-n  STOP if NAME of EXISTING sndfile generated. Default: ignore and continue.\n"
+		"MODE 2) PREVIEW: make envel as 'sound'. View to get params for CUT OUT & KEEP.\n"
+		"MODE 3) TOP AND TAIL: REMOVE LOW LEVEL SIGNAL FROM START & END OF SOUND.\n"
+		" GATE   level ABOVE which signal accepted : (Range 0-1 : default 0).\n"
+		" SPLICE length in mS (default 15mS) : -b Don't trim start : -e Don't trim end.\n"
+		"MODE 4) RECTIFY: SHIFT ENTIRE SIGNAL TO ELIMINATE DC DRIFT.\n"
+		"MODE 5) MODIFY 'BY HAND'. This process is no longer available.\n"
+		"MODE 6) GET ONSET TIMES:gate,end-cutoff,thresh,keep,init-lvl,minlen,gate-windw.\n",CUTGATE_MAXBAKTRAK);
+	} else if(!strcmp(str,"endclicks")) {
+		fprintf(stdout,
+		"REMOVE CLICKS FROM START OR END OF FILE.\n\n"
+		"USAGE: housekeep endclicks infile outfile gate splicelen [-b] [-e]\n"
+		"GATE   level ABOVE which signal accepted : (Range 0-1).\n"
+		"SPLICE length in mS\n"
+		"-b     Trim start\n"
+		"-e     Trim end.\n");
+	} else if(!strcmp(str,"bakup")) {
+		fprintf(stdout,
+		"CONCATENATE SOUNDFILES IN ONE BAKUP FILE, WITH SILENCES BETWEEN\n\n"
+     	"USAGE: housekeep bakup infile1 [infile2 ...] outfile\n\n");
+	} else if(!strcmp(str,"gate")) {
+		fprintf(stdout,
+		"CUT FILE AT ZERO AMPLITUDE POINTS.\n\n"
+		"USAGE: housekeep gate infile outfile [-zzerocnt]\n"
+  		"\n"
+		"zerocnt: number of consecutive zero samples (per channel)\n"
+		"         to indicate a silent gap in sound, where it can be cut.\n");
+
+	} else if(!strcmp(str,"disk")) {
+    	fprintf(stdout,
+		"DISPLAY AVAILABLE SPACE ON DISK.\n\n"
+		"USAGE: housekeep disk anyinfile\n\n"
+		"If a sndfile is used, its samplerate will govern space calculations.\n");
+	} else if(!strcmp(str,"batchexpand")) {
+    	fprintf(stdout,
+		"EXPAND AN EXISTING BATCHFILE.\n\n"
+		"USAGE: housekeep batchexpand mode batch snd1 [snd2 ...] datafile ic oc pc\n\n"
+		"BATCH      a batchfile, which uses same kind of param in one of its columns.\n"
+		"SND1,2...  any number of soundfiles\n"
+		"IC  is column in batchfile containing input file.\n"
+		"OC  is column in batchfile containing  output file.\n"
+		"PC  is column in batchfile containing parameter to be replaced.\n"
+		"DATAFILE  of param values where 1st param applies to 1st sndfile, 2nd param to 2nd.\n"
+		"New batchfile created, modelled on original........\n"
+		"IN MODE 1:\n"
+		"a) Existing batchfile has only 1 input file.\n"
+		"b) Same sequence of operations applied to each in-sndfile using each new param.\n"
+		"(So a 3 line file, with 3 sound inputs, becomes a 9-line file)\n"
+		"IN MODE 2:\n"
+		"a) Existing batchfile can operate on different soundfiles.\n"
+		"Soundfiles in orig batchfile replaced by chosen files, and using new params.\n"
+		"(So a 3 line file, with 3 sound inputs, becomes a 3-line file)\n");
+	} else if(!strcmp(str,"deglitch")) {
+    	fprintf(stdout,
+		"ATTEMPT TO DEGLITCH A SOUND.\n\n"
+		"USAGE: housekeep deglitch inf outf glitch sil thresh splice window [-s]\n\n"
+		"GLITCH maximum duration (ms) of any glitches to find.\n"
+		"SIL    minimum duration (ms) of 'silence' on either side of glitch.\n"
+		"THRESH maximum level of 'silence' on either side of glitch.\n"
+		"SPLICE splicelength (ms) to cutout glitch. Must be < half SILDUR)\n"
+		"       with THRESH 0 use SPLICE 0. Otherwise SPLICE 0 makes clicks.\n"
+		"WINDOW windowlen (ms) in which to search for glitches, & 'silence'.\n"
+		"        very short windows may mistake parts of waveform for 'silence'.\n"
+		"        Use larger windows to see larger features.\n"
+		"-s     See details of (possible) glitches found.\n");
+	} else
+		fprintf(stdout,"Unknown option '%s'\n",str);
+	return(USAGE_ONLY);
+}
+
+/******************************** USAGE3 ********************************/
+
+int usage3(char *str1,char *str2)
+{
+	if(!strcmp(str1,"remove"))		
+		return(CONTINUE);
+	else if(!strcmp(str1,"disk"))		
+		return(CONTINUE);
+//TW NEW CASE
+	else if(!strcmp(str1,"gate"))		
+		return(CONTINUE);
+
+	else
+		sprintf(errstr,"Insufficient parameters on command line.\n");
+	return(USAGE_ONLY);
+}
+
+/******************************** INNER_LOOP (redundant)  ********************************/
+
+int inner_loop
+(int *peakscore,int *descnt,int *in_start_portion,int *least,int *pitchcnt,int windows_in_buf,dataptr dz)
+{
+	return(FINISHED);
+}
+
+/******************************** READ_BATCHEXPAND_PARAMS ********************************/
+
+int read_batchexpand_params(char *filename,dataptr dz)
+{
+	FILE *fp;
+	int cnt = 0;
+	char temp[200], *p, *q;
+
+	if((fp = fopen(filename,"r"))==NULL) {
+		sprintf(errstr,	"Can't open file %s to read data.\n",filename);
+		return(DATA_ERROR);
+	}
+	while(fgets(temp,200,fp)!=NULL) {
+		p = temp;
+		while(get_word_from_string(&p,&q)) {
+			if((dz->wordstor[dz->all_words] = (char *)malloc((strlen(q) + 1) * sizeof(char)))==NULL) {
+				sprintf(errstr,"INSUFFICIENT MEMORY for wordstor %d\n",dz->all_words+1);
+				return(MEMORY_ERROR);
+			}
+			strcpy(dz->wordstor[dz->all_words],q);
+			dz->all_words++;
+			cnt++;
+			if(cnt > dz->itemcnt) {
+				sprintf(errstr,"NUMBER OF DATA PARAMETERS is greater than NUMBER OF INPUT SOUNDFILES\n");
+				return(DATA_ERROR);
+			}
+		}
+	}			
+	if(cnt < dz->itemcnt) {
+		sprintf(errstr,"NUMBER OF DATA PARAMETERS is less than NUMBER OF INPUT SOUNDFILES\n");
+		return(DATA_ERROR);
+	}
+	return(FINISHED);
+}
+
+//TW UPDATE : NEW FUNCTION (modified for flotsams)
+/*************************** CREATE_BAKUP_SNDBUFS **************************/
+
+int create_bakup_sndbufs(dataptr dz)
+{
+	int n;
+	int insert_samps, insert_secs;
+	size_t bigbufsize;
+    int framesize = F_SECSIZE * dz->infile->channels;
+	
+	insert_samps = dz->infile->srate * dz->infile->channels;	/* 1 second in samps */
+	insert_samps = (int)round(BAKUP_GAP * insert_samps);
+	if((insert_secs = insert_samps/framesize) * framesize != insert_samps)
+		insert_secs++;
+	insert_samps = insert_secs * framesize;
+	if(dz->sbufptr == 0 || dz->sampbuf == 0) {
+		sprintf(errstr,"buffer pointers not allocated: create_bakup_sndbufs()\n");
+		return(PROGRAM_ERROR);
+	}
+	bigbufsize = (size_t) Malloc(-1);
+	bigbufsize /= dz->bufcnt;
+	dz->buflen = (int)(bigbufsize/sizeof(float));
+	if((dz->buflen = (dz->buflen/framesize) * framesize)<=insert_samps) {
+		dz->buflen  = insert_samps;
+	}
+	if((dz->bigbuf = (float *)malloc((size_t)(dz->buflen * sizeof(float) * dz->bufcnt))) == NULL) {
+		sprintf(errstr,"INSUFFICIENT MEMORY to create sound buffers.\n");
+		return(PROGRAM_ERROR);
+	}
+	for(n=0;n<dz->bufcnt;n++)
+		dz->sbufptr[n] = dz->sampbuf[n] = dz->bigbuf + (dz->buflen * n);
+	dz->sampbuf[n] = dz->bigbuf + (dz->buflen * n);
+	return(FINISHED);
+}
+
+/****************************** BATCHEXPAND_CONSISTENCY *********************************/
+
+int batchexpand_consistency(dataptr dz)
+{
+	int n, entrycnt, basecnt;
+	char paramval[200], infname[200];
+	if (dz->iparam[BE_INFILE] >= dz->iparam[BE_OUTFILE]) {
+		sprintf(errstr,"Infile and Outfile column numbers are inconsistent.\n");
+		return(DATA_ERROR);
+	}
+	if (dz->iparam[BE_OUTFILE] >= dz->iparam[BE_PARAM]) {
+		sprintf(errstr,"Outfile and Param column numbers are inconsistent.\n");
+		return(DATA_ERROR);
+	}
+	entrycnt = dz->wordcnt[0];
+	if(entrycnt < 5) {
+		sprintf(errstr,"First file is not a batchfile.\n");
+		return(DATA_ERROR);
+	}
+	if(entrycnt < dz->iparam[BE_INFILE]) {
+		sprintf(errstr,"Batchfile has insufficient columns to correspond to Infile column number.\n");
+		return(DATA_ERROR);
+	}
+	if(entrycnt < dz->iparam[BE_OUTFILE]) {
+		sprintf(errstr,"Batchfile has insufficient columns to correspond to Outfile column number.\n");
+		return(DATA_ERROR);
+	}
+	if(entrycnt < dz->iparam[BE_PARAM]) {
+		sprintf(errstr,"Batchfile has insufficient columns to correspond to Parameter column number.\n");
+		return(DATA_ERROR);
+	}
+	dz->iparam[BE_INFILE]--;
+	dz->iparam[BE_OUTFILE]--;
+	dz->iparam[BE_PARAM]--;
+	if(dz->mode==ONE_PARAM) {
+		strcpy(paramval,dz->wordstor[BE_PARAM]);
+		strcpy(infname,dz->wordstor[BE_INFILE]);
+	}
+	basecnt = entrycnt;
+	for(n = 1; n < dz->linecnt; n++) {
+		if(entrycnt != dz->wordcnt[n]) {
+			sprintf(errstr,"First file is not a batchfile.\n");
+			return(DATA_ERROR);
+		}
+		if(dz->mode==ONE_PARAM && (strcmp(paramval,dz->wordstor[BE_PARAM + basecnt]))) {
+			sprintf(errstr,"Specified batchfile parameter is not the same in all lines of the original batchfile\n");
+			return(DATA_ERROR);
+		}
+		if(dz->mode==ONE_PARAM && (strcmp(infname,dz->wordstor[BE_INFILE + basecnt]))) {
+			sprintf(errstr,"Infile is not the same in all lines of the original batchfile\n");
+			return(DATA_ERROR);
+		}
+		basecnt += entrycnt;
+	}
+	return(FINISHED);
+}
+
+/******************************** READ_INDIVIDUAL_SAMPLE_VALUES ********************************/
+
+int read_individual_sample_values(char *filename,dataptr dz)
+{
+	FILE *fp;
+	int cnt = 0;
+	char temp[200], *p;
+	double val;
+	double lasttime = 0.0, *la;
+
+	if((fp = fopen(filename,"r"))==NULL) {
+		sprintf(errstr,	"Can't open file %s to read data.\n",filename);
+		return(DATA_ERROR);
+	}
+	if((la = (double *)malloc(sizeof(int)))==NULL) {
+		sprintf(errstr,"INSUFFICIENT_MEMORY to store sample value information.\n");
+		return(MEMORY_ERROR);
+	}
+	while(fgets(temp,200,fp)!=NULL) {
+		p = temp;
+		while(get_float_from_within_string(&p,&val)) {
+			if(cnt > 0) {
+				if((la = (double*)realloc((char *)la,(cnt+1) * sizeof(double)))==NULL) {
+					sprintf(errstr,"INSUFFICIENT_MEMORY to store sample value information.\n");
+					return(MEMORY_ERROR);
+				}
+			}
+			la[cnt] = (double)val;
+			if(EVEN(cnt)) {
+				if(cnt == 0)
+					lasttime = la[cnt];
+				else if(la[cnt] <= lasttime) {
+					sprintf(errstr,"Sample positions not in ascending order.\n");
+					return(DATA_ERROR);
+				}
+			} else {
+				if((la[cnt] < (double)MINSAMP) || (la[cnt] > (double)MAXSAMP)) {
+					sprintf(errstr,"Sample value %lf is out of range (%lf to %lf).\n",
+					la[cnt],(double)MINSAMP,(double)MAXSAMP);
+					return(DATA_ERROR);
+				}
+			}
+			cnt++;
+		}
+	}
+	if(ODD(cnt)) {
+		sprintf(errstr,"Data values not paired correctly.\n");
+		return(DATA_ERROR);
+	}
+	dz->parray[0] = la;
+	dz->parray[1] = la + cnt;
+	return(FINISHED);
+}

+ 385 - 0
dev/houskeep/channels.c

@@ -0,0 +1,385 @@
+/*
+ * 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*/
+#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 <logic.h>
+#include <pnames.h>
+#include <flags.h>
+#include <sfsys.h>
+
+#include <string.h>
+/**
+#include <filetype.h>
+#include <limits.h>
+#include <math.h>
+**/
+
+/* mainfuncs.c */
+extern void dz2props(dataptr dz, SFPROPS* props);
+
+
+/*********************************** DO_CHANNELS ****************************/
+/* RWD NB changes to ensure outfile is created with correct chan count. */
+/* need full set of oufile props in dz, so we NEVER use dz-infile to spec the outfile! */
+/* TODO: support n_channels, e.g. for zero, channel etc */
+
+int do_channels(dataptr dz)
+{
+	int exit_status;
+	int chans = dz->infile->channels, start_chan = 0, end_chan = 0;
+	double maxoutsum, maxinval, sum, normaliser = 0.0;
+//TW REVISION Dec 2002
+//	char *outfilename, *outfilenumber;
+	char *outfilename;
+	char prefix[] = "_c";
+	int namelen;
+	int prefixlen = strlen(prefix);
+	int infilesize, outfilesize;
+	int k, m, n, j;
+	float *buf = dz->bigbuf;
+	int not_zeroed = 0, zeroed = 0, totlen;
+
+	switch(dz->mode) {
+	case(HOUSE_CHANNEL):
+		dz->iparam[CHAN_NO]--;	/* change to internal numbering */
+		break;
+	case(HOUSE_ZCHANNEL):
+		dz->iparam[CHAN_NO]--;	/* change to internal numbering */
+		zeroed     =  dz->iparam[CHAN_NO];
+		not_zeroed = !dz->iparam[CHAN_NO];
+		break;
+	}
+	switch(dz->mode) {
+	case(HOUSE_CHANNEL):
+	case(HOUSE_CHANNELS):
+		dz->buflen *= chans;				/* read chan * (contiguous) buffers */
+// FEB 2010 TW
+//		if(!sloom) {
+//			namelen = strlen(dz->wordstor[0]);
+//			q = dz->wordstor[0];
+//			r = dz->wordstor[0] + namelen;
+//			p = r - 1;
+//			while((*p != '\\') && (*p != '/') && (*p != ':')) {
+//				p--	;
+//				if(p < dz->wordstor[0])
+//					break;
+//			}
+//			if(p > dz->wordstor[0]) {
+//				p++;
+//				while(p <= r)
+//					*q++ = *p++;
+//			}
+//		}
+		namelen   = strlen(dz->wordstor[0]);
+		if(!sloom)
+// FEB 2010 TW
+			totlen = namelen + prefixlen + 20;
+		else
+// FEB 2010 TW
+			totlen = namelen + 20;
+		if((outfilename = (char *)malloc(totlen * sizeof(char)))==NULL) {
+			sprintf(errstr,"INSUFFICIENT MEMORY for outfile name.\n");
+			return(MEMORY_ERROR);
+		}
+		switch(dz->mode) {
+		case(HOUSE_CHANNEL):
+			dz->tempsize = dz->insams[0]/chans;	/* total outfile size */
+			start_chan = dz->iparam[CHAN_NO];
+			end_chan   = dz->iparam[CHAN_NO]+1;
+			break;
+		case(HOUSE_CHANNELS):
+			dz->tempsize = dz->insams[0]/dz->infile->channels;
+			start_chan = 0;
+			end_chan   = dz->infile->channels;
+			break;
+		}	
+		dz->process_type = EQUAL_SNDFILE;	/* allow sndfile(s) to be created */
+		/*RWD: GRRR! */
+		dz->infile->channels = MONO;		/* force outfile(s) to be mono    */
+		infilesize  = dz->insams[0];
+		outfilesize = dz->insams[0]/chans;
+		for(k=start_chan,j=0;k<end_chan;k++,j++) {
+			if(sndseekEx(dz->ifd[0],0,0)<0) {
+				sprintf(errstr,"sndseek failed.\n");
+				return(SYSTEM_ERROR);
+			}
+			dz->total_samps_written = 0;
+			dz->samps_left = dz->insams[0];
+			dz->total_samps_read = 0;	/* NB total_samps_read NOT reset */
+			strcpy(outfilename,dz->wordstor[0]);
+			if(!sloom) {
+				insert_new_chars_at_filename_end(outfilename,prefix);
+				insert_new_number_at_filename_end(outfilename,k+1,0);
+			} else
+				insert_new_number_at_filename_end(outfilename,j,1);
+			dz->insams[0] = outfilesize;   /* creates smaller outfile */
+			if((exit_status = create_sized_outfile(outfilename,dz))<0) {
+				sprintf(errstr,"Cannot open output file %s\n", outfilename);
+				dz->insams[0] = infilesize;
+				free(outfilename);
+				return(DATA_ERROR);
+			}
+			dz->insams[0] = infilesize;		/* restore true value */
+			while(dz->samps_left) {
+				if((exit_status = read_samps(buf,dz))<0) {
+					free(outfilename);
+					return(exit_status);
+				}
+				for(n=k,m=0;n<dz->ssampsread;n+=chans,m++)
+					buf[m] = buf[n];
+				if(dz->ssampsread > 0) {
+					if((exit_status = write_exact_samps(buf,dz->ssampsread/chans,dz))<0) {
+						free(outfilename);
+						return(exit_status);
+					}
+				}
+			}
+			dz->outfiletype  = SNDFILE_OUT;			/* allows header to be written  */
+			/* RWD: will eliminate this eventually */
+			if((exit_status = headwrite(dz->ofd,dz))<0) {
+				free(outfilename);
+				return(exit_status);
+			}
+			if(k < end_chan - 1) {
+				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",outfilename);
+					fflush(stdout);
+				}
+				/*free(outfilename);*/ /*RWD 25:9:2001 used again! */
+				dz->ofd = -1;
+			}
+		}
+		break;
+	case(HOUSE_ZCHANNEL):
+	case(STOM):
+	case(MTOS):
+		switch(chans) {
+		case(MONO): 
+			switch(dz->mode) {
+			case(HOUSE_ZCHANNEL):
+				/*RWD*/
+				dz->outfile->channels = 2;
+
+				dz->tempsize = dz->insams[0] * 2;	break;	/* total output size */
+			case(STOM):
+				sprintf(errstr,"This file is already mono!!\n");	return(GOAL_FAILED);
+			case(MTOS):
+				/*RWD*/
+				dz->outfile->channels = 2;
+
+				dz->tempsize = dz->insams[0] * 2;	break;	/* total output size */
+			
+			}
+			break;
+		case(STEREO): 
+			dz->buflen *= chans;	/* read chans * (contiguous) buffers */
+			switch(dz->mode) {
+			case(HOUSE_ZCHANNEL):				
+				/*RWD*/
+				dz->outfile->channels = 2;
+
+				dz->tempsize = dz->insams[0];		break;	/* total output size */
+			case(STOM):
+				/*RWD*/
+				dz->outfile->channels = 1;
+				
+				dz->tempsize = dz->insams[0]/2;		break;	/* total output size */
+			case(MTOS): sprintf(errstr,"This file is already stereo!!\n");	return(GOAL_FAILED);
+			}
+			break;
+		default:
+			switch(dz->mode) {
+			case(MTOS):
+				sprintf(errstr,"This process does not work with multichannel files!!\n");	return(GOAL_FAILED);
+				break;
+			case(STOM):	// MULTICHAN APPLICATION FOR MAKING THUMBNAILS
+				dz->buflen *= chans;	/* read chans * (contiguous) buffers */
+				dz->outfile->channels = 1;
+				break;
+			case(HOUSE_ZCHANNEL):
+				dz->buflen *= chans;	/* read chans * (contiguous) buffers */
+				dz->outfile->channels = dz->infile->channels;
+				break;
+			}
+			break;
+		}
+		/*RWD NOW, we can create the outfile! */
+		/*RWD April 2005 need this for wave-ex */
+		if(dz->outfile->channels > 2 || dz->infile->stype > SAMP_FLOAT){
+			SFPROPS props, inprops;
+			dz2props(dz,&props);			
+			props.chans = dz->outfile->channels;
+			props.srate = dz->infile->srate;
+			/* RWD: always need to hack it one way or another!*/
+
+			if(dz->ifd && dz->ifd[0] >=0) {
+				if(snd_headread(dz->ifd[0], &inprops)){
+					/* if we receive an old WAVE 24bit file, want to write new wave-ex one! */
+					if(inprops.chformat == STDWAVE)
+						props.chformat = MC_STD;
+					else
+						props.chformat = inprops.chformat;
+				}
+			}
+#ifdef _DEBUG
+			printf("DEBUG: writing WAVE_EX outfile\n");
+#endif
+			dz->ofd = sndcreat_ex(dz->outfilename,-1,&props,SFILE_CDP,CDP_CREATE_NORMAL); 
+			if(dz->ofd < 0){
+				sprintf(errstr,"Cannot open output file %s : %s\n", dz->outfilename,sferrstr());
+				return(DATA_ERROR);
+			}
+		}
+		else
+		//create outfile here, now we have required format info	
+			dz->ofd = sndcreat_formatted(dz->outfilename,-1,dz->infile->stype,dz->outfile->channels,
+									dz->infile->srate,									
+									CDP_CREATE_NORMAL);
+//TW ADDED, for peak chunk
+		dz->outchans = dz->outfile->channels;
+		establish_peak_status(dz);
+		if(dz->ofd < 0)
+			return DATA_ERROR;
+
+
+// MULTICHAN APPLICATION FOR MAKING THUMBNAILS -->
+		if(dz->mode == STOM && chans > 2) {
+			maxoutsum = 0.0;
+			maxinval = 0.0;
+			while(dz->samps_left) {
+				if((exit_status = read_samps(buf,dz))<0) {
+					return(exit_status);
+				}
+				for(n=0;n< dz->ssampsread;n+=chans) {
+					sum = 0.0;
+					for(m=0;m < chans;m++) {
+						maxinval = max(maxinval,fabs(buf[n+m]));
+						sum += buf[n+m];
+					}
+					maxoutsum = max(maxoutsum,fabs(sum));
+				}
+			}
+			normaliser = maxinval/maxoutsum;
+			sndseekEx(dz->ifd[0],0,0);
+			reset_filedata_counters(dz);
+		}
+// <-- MULTICHAN APPLICATION FOR MAKING THUMBNAILS
+
+		while(dz->samps_left) {
+			if((exit_status = read_samps(buf,dz))<0) {
+				return(exit_status);
+			}
+			if(dz->ssampsread > 0) {
+				switch(chans) {
+				case(MONO): 
+					switch(dz->mode) {
+					case(HOUSE_ZCHANNEL):
+						for(n=dz->ssampsread-MONO,m=(dz->ssampsread*STEREO)-STEREO;n>=0;n--,m-=2) {
+							buf[m+zeroed]     = (float)0;
+							buf[m+not_zeroed] = buf[n];														   
+						}
+						if((exit_status = write_samps(buf,dz->ssampsread * STEREO,dz))<0)
+							return(exit_status);
+						break;
+					case(MTOS):
+						for(n=dz->ssampsread-MONO,m=(dz->ssampsread*STEREO)-STEREO,k=m+1;n>=0;n--,m-=2,k-=2) {
+							buf[m] = buf[n];
+							buf[k] = buf[n];
+						}
+						if((exit_status = write_samps(buf,dz->ssampsread * STEREO,dz))<0)
+							return(exit_status);
+						break;
+					}		
+					break;
+				case(STEREO): 
+					switch(dz->mode) {
+					case(HOUSE_ZCHANNEL):
+						for(n=dz->iparam[CHAN_NO];n< dz->ssampsread;n+=2)
+							buf[n] = (float)0;
+						if((exit_status = write_samps(buf,dz->ssampsread,dz))<0) {
+							return(exit_status);
+						}
+						break;
+					case(STOM):
+						if(dz->vflag[CHAN_INVERT_PHASE]) {
+							for(n=0,m=0;n< dz->ssampsread;n+=2,m++)
+								buf[m] = (float)((buf[n] - buf[n+1])/2.0);
+						} else {
+							for(n=0,m=0;n< dz->ssampsread;n+=2,m++)
+								buf[m] = (float)((buf[n] + buf[n+1])/2.0);
+						}
+						if((exit_status = write_samps(buf,dz->ssampsread/2,dz))<0) {
+							return(exit_status);
+						}
+						break;
+					}
+					break;
+				default:		// HOUSE_ZCHANNEL
+					switch(dz->mode) {
+					case(HOUSE_ZCHANNEL):
+						for(n=dz->iparam[CHAN_NO];n< dz->ssampsread;n+=dz->infile->channels)
+							buf[n] = (float)0;
+						if((exit_status = write_samps(buf,dz->ssampsread,dz))<0) {
+							return(exit_status);
+						}
+						break;
+					case(STOM):	// MULTICHAN APPLICATION FOR MAKING THUMBNAILS
+						for(n=0,m=0;n< dz->ssampsread;n+=chans,m++) {
+							sum = 0.0;
+							for(k=0;k < chans;k++)
+								sum += buf[n+k];
+							sum *= normaliser;
+							buf[m] = (float)sum;
+						}
+						if((exit_status = write_samps(buf,dz->ssampsread/chans,dz))<0) {
+							return(exit_status);
+						}
+						break;
+					}
+					break;
+
+				}
+			}
+		}
+		switch(dz->mode) {
+		case(HOUSE_ZCHANNEL):	dz->infile->channels = dz->outfile->channels;	break;
+		case(STOM):				dz->infile->channels = MONO;  	break;
+		case(MTOS):			 	dz->infile->channels = STEREO;	break;
+		}
+		break;
+	}
+	return(FINISHED);
+}

+ 1674 - 0
dev/houskeep/clean.c

@@ -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);
+}
+

+ 114 - 0
dev/houskeep/dump.c

@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 1983-2013 Trevor Wishart and Composers Desktop Project Ltd
+ * http://www.trevorwishart.co.uk
+ * http://www.composersdesktop.com
+ *
+ This file is part of the CDP System.
+
+    The CDP System is free software; you can redistribute it
+    and/or modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    The CDP System is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with the CDP System; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+    02111-1307 USA
+ *
+ */
+
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <structures.h>
+#include <tkglobals.h>
+#include <pnames.h>
+#include <globcon.h>
+#include <cdpmain.h>
+#include <house.h>
+#include <modeno.h>
+#include <sfsys.h>
+#include <memory.h>
+#include "sfdump.h"
+
+/*************************** HOUSE_BAKUP ******************************/
+
+int house_bakup(dataptr dz) 
+{
+	int n, exit_status;
+	int samps_to_write, secs_to_write, insert_samps, insert_secs;
+	int spare_samps, tail, spare_samps_in_secs, samps_written = 0;
+	float *buf = dz->bigbuf;
+	
+	insert_samps = dz->infile->srate * dz->infile->channels;	/* 1 second in samples */
+	insert_samps = (int)round(BAKUP_GAP * insert_samps);
+	if((insert_secs = insert_samps/F_SECSIZE) * F_SECSIZE != insert_samps)
+		insert_secs++;
+	insert_samps = insert_secs * F_SECSIZE;
+
+	dz->tempsize = 0;
+	for(n=0;n<dz->infilecnt;n++)
+		dz->tempsize += dz->insams[n];
+
+	for(n=0;n<dz->infilecnt;n++) {
+		sndseekEx(dz->ifd[n],0,0);
+		dz->samps_left = dz->insams[n];
+		spare_samps = 0;
+		while(dz->samps_left > 0) {
+			memset((char *)dz->bigbuf,0,dz->buflen * sizeof(float));
+			if((dz->ssampsread = fgetfbufEx(buf,dz->buflen,dz->ifd[n],0)) < 0) {
+				sprintf(errstr,"Can't read samples from input soundfile %d\n",n+1);
+				return(SYSTEM_ERROR);
+			}
+			dz->samps_left -= dz->ssampsread;
+
+			samps_to_write = dz->ssampsread;	/* Default (full input buff) write all of it */
+			spare_samps = dz->buflen - dz->ssampsread;
+			if(spare_samps) {					/* with partially full input buff  */
+				tail = spare_samps % F_SECSIZE;
+				spare_samps_in_secs = spare_samps - tail;
+				if(spare_samps_in_secs >= insert_samps) {	/* If empty part of buf exceeds silence-insert-dur */				
+					samps_to_write = dz->ssampsread + tail + insert_samps;	/* write ALL silence from buftail */
+					if(((samps_to_write/F_SECSIZE) * F_SECSIZE) != samps_to_write) {
+						sprintf(errstr,"Error in program file-write logic.\n");
+						return(PROGRAM_ERROR);
+					}
+				} else {
+					samps_to_write = dz->buflen;		/* Else, write some of silence from tail of buffer */
+					if((exit_status = write_samps(buf,samps_to_write,dz)) < 0)
+						return(exit_status);
+					dz->total_samps_written += samps_written;
+					display_virtual_time(dz->total_samps_written,dz);
+					memset((char *)dz->bigbuf,0,dz->buflen * sizeof(float));	
+					samps_to_write = insert_samps - spare_samps;
+					if((secs_to_write = samps_to_write/F_SECSIZE) * F_SECSIZE != samps_to_write)
+						secs_to_write++;					/* rounding up to whole number of sectors */
+					samps_to_write = secs_to_write * F_SECSIZE;
+				}
+			}
+			if(samps_to_write > 0) {
+				if((exit_status = write_samps(buf, samps_to_write,dz)) < 0)
+					return(exit_status);
+			}
+			dz->total_samps_written += samps_written;
+			display_virtual_time(dz->total_samps_written,dz);
+		}
+		if(spare_samps == 0) {		/* in event of last file write EXACTLY fitting into read buffer */
+			memset((char *)dz->bigbuf,0,dz->buflen * sizeof(float));	
+			if(insert_samps > 0) {
+				if((exit_status = write_samps(buf, insert_samps,dz)) < 0)
+					return(exit_status);
+			}
+			dz->total_samps_written += samps_written;
+			display_virtual_time(dz->total_samps_written,dz);
+		}
+	}
+	return FINISHED;
+}
+

+ 431 - 0
dev/houskeep/dupl.c

@@ -0,0 +1,431 @@
+/*
+ * Copyright (c) 1983-2013 Trevor Wishart and Composers Desktop Project Ltd
+ * http://www.trevorwishart.co.uk
+ * http://www.composersdesktop.com
+ *
+ This file is part of the CDP System.
+
+    The CDP System is free software; you can redistribute it
+    and/or modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    The CDP System is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with the CDP System; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+    02111-1307 USA
+ *
+ */
+
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <structures.h>
+#include <tkglobals.h>
+#include <globcon.h>
+#include <cdpmain.h>
+#include <house.h>
+#include <modeno.h>
+#include <pnames.h>
+#include <filetype.h>
+#include <flags.h>
+#include <logic.h>
+#include <limits.h>
+
+#include <sfsys.h>
+#include <osbind.h>     /*RWD*/
+
+#include <string.h>
+#include <math.h>
+
+static int  check_available_space(dataptr dz);
+static int  copy_textfile(dataptr dz);
+
+extern unsigned int superzargo;
+
+/************************************ DO_DUPLICATES ********************************/
+
+int do_duplicates(dataptr dz)
+{
+    int exit_status;
+    int n, start, end;
+    int old_ofd;
+    int namelen, numlen;
+    char *outfilename;
+//TW REVISION Dec 2002
+    char prefix_units[]     = "_00";
+    char prefix_tens[]      = "_0";
+    char prefix_hundreds[]  = "_";
+    char *p, *q, *r;
+
+    numlen  = 4;
+    switch(dz->mode) {
+    case(COPYSF):
+        if(dz->infile->filetype==WORDLIST)
+            return copy_textfile(dz);
+        dz->tempsize = dz->insams[0];
+        switch(dz->infile->filetype) {
+        case(PITCHFILE):
+            if((exit_status = write_exact_samps(dz->pitches,dz->insams[0],dz))<0)
+                return(exit_status);
+            break;
+        case(TRANSPOSFILE):
+            if((exit_status = write_exact_samps(dz->transpos,dz->insams[0],dz))<0)
+                return(exit_status);
+            break;
+        default:
+            while(dz->samps_left) {
+                if((exit_status = read_samps(dz->sampbuf[0],dz))<0)
+                    return(exit_status);
+                if(dz->ssampsread > 0) {
+                    if((exit_status = write_exact_samps(dz->sampbuf[0],dz->ssampsread,dz))<0)
+                        return(exit_status);
+                } else if(dz->total_samps_read == 0) {
+                    sprintf(errstr,"Failure to read samples from input file.\n");
+                    return(SYSTEM_ERROR);
+                }
+            }
+            if(dz->infile->filetype == ENVFILE)
+                dz->outfile->window_size = dz->infile->window_size;
+            break;
+        }
+        break;
+    case(DUPL):
+        if(!sloom) {
+            namelen = strlen(dz->wordstor[0]);
+            q = dz->wordstor[0];
+            r = dz->wordstor[0] + namelen;
+            p = r - 1;
+            while((*p != '\\') && (*p != '/') && (*p != ':')) {
+                p-- ;
+                if(p < dz->wordstor[0])
+                    break;
+            }
+            if(p > dz->wordstor[0]) {
+                p++;
+                while(p <= r)
+                    *q++ = *p++;
+            }
+        }
+        namelen = strlen(dz->wordstor[0]);      
+        superzargo = 0; /* timer-base */
+        old_ofd = dz->ofd;
+        if((exit_status = check_available_space(dz))<0)
+            return(exit_status);
+//TW ????
+        if(!sloom)
+            dz->ofd = -1;
+        else
+            dz->ofd = old_ofd;
+        if((dz->tempsize = dz->insams[0] * dz->iparam[COPY_CNT])<0)
+            dz->tempsize = INT_MAX; /* ERROR was LONG_MAX **** Overflows **** */
+
+        if(sloom) {
+            namelen--;                                  /* Drop the 0 at end of name */
+            start = 0;
+            end = dz->iparam[COPY_CNT];
+        } else {
+            start = 1;
+            end = dz->iparam[COPY_CNT] + 1;
+        }
+        for(n=start;n<end;n++) {
+            if(sndseekEx(dz->ifd[0],0,0)<0) {
+                sprintf(errstr,"sndseek() failed.\n");
+                return(SYSTEM_ERROR);
+            }
+            reset_filedata_counters(dz);
+            if((outfilename = (char *)malloc((namelen + numlen + 1) * sizeof(char)))==NULL) {
+                sprintf(errstr,"INSUFFICIENT MEMORY for outfilename.\n");
+                return(MEMORY_ERROR);
+            }               
+            strcpy(outfilename,dz->wordstor[0]);
+
+            if(!sloom) {
+                if(n<10)
+//TW REVISION Dec 2002
+                    insert_new_chars_at_filename_end(outfilename,prefix_units);
+                else if(n<100)
+                    insert_new_chars_at_filename_end(outfilename,prefix_tens);
+                else if(n<1000)
+                    insert_new_chars_at_filename_end(outfilename,prefix_hundreds);
+                else {
+                    sprintf(errstr,"Too many duplicates.\n");
+                    return(PROGRAM_ERROR);
+                }
+                insert_new_number_at_filename_end(outfilename,n,0);
+            } else {
+                insert_new_number_at_filename_end(outfilename,n,1);
+            }
+            dz->process_type = EQUAL_SNDFILE;   /* allow sndfile to be created */
+            if(!sloom || n>0) {
+                if((exit_status = create_sized_outfile(outfilename,dz))<0) {
+                    if(!sloom) {
+                        if(dz->vflag[IGNORE_COPIES]) {
+                            fprintf(stdout, "INFO: Soundfile %s already exists\n", outfilename);
+                            fflush(stdout);
+                            free(outfilename);
+                            dz->process_type = OTHER_PROCESS;
+                            dz->ofd = -1;
+                            continue;
+                        }
+                        else {
+                            sprintf(errstr, "Soundfile %s already exists: Made %d duplicates only.\n",outfilename,n-1);
+                            free(outfilename);
+                            dz->process_type = OTHER_PROCESS;
+                            dz->ofd = -1;
+                            return(GOAL_FAILED);
+                        }
+                    } else {
+                        dz->process_type = OTHER_PROCESS;
+                        dz->ofd = -1;
+                        return(SYSTEM_ERROR);
+                    }
+                }                           
+            }
+            dz->process_type = OTHER_PROCESS;
+            while(dz->samps_left) {
+                if((exit_status = read_samps(dz->sampbuf[0],dz))<0)
+                    return(exit_status);
+                if(dz->ssampsread > 0) {
+                    if((exit_status = write_exact_samps(dz->sampbuf[0],dz->ssampsread,dz))<0)
+                        return(exit_status);
+                }
+            }
+            dz->process_type = EQUAL_SNDFILE;       /* allows header to be written  */
+            dz->outfiletype  = SNDFILE_OUT;         /* allows header to be written  */
+            if((exit_status = headwrite(dz->ofd,dz))<0) {
+                free(outfilename);
+                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",outfilename);
+                fflush(stdout);
+            }
+            free(outfilename);
+            dz->ofd = -1;
+        }
+        break;
+    default:
+        sprintf(errstr,"Unknown case in do_duplicates()\n");
+        return(PROGRAM_ERROR);
+    }
+    return(FINISHED);
+}
+
+/************************************ DO_DELETES ********************************/
+
+int do_deletes(dataptr dz)
+{
+    char *outfilename;
+    int n;
+    char prefix_units[]     = "_00";
+    char prefix_tens[]      = "_0";
+    char prefix_hundreds[]  = "_";
+    int namelen = strlen(dz->wordstor[0]);
+    int numlen  = 4, unopen, removed;
+    unopen = 0;
+    removed = 0;
+    for(n=1;n<=MAXDUPL;n++) {
+        if((!dz->vflag[ALL_COPIES]) && unopen >= COPYDEL_OVERMAX)
+            break;
+        if((outfilename = (char *)malloc((namelen + numlen + 1) * sizeof(char)))==NULL) {
+            sprintf(errstr,"INSUFFICIENT MEMORY for outfilename.\n");
+            return(MEMORY_ERROR);
+        }               
+        strcpy(outfilename,dz->wordstor[0]);
+//TW COMMENT: program not available on Sound Loom
+//TW REVISIONs Dec 2002 : to do with sending filename extension in cmdline
+        if(!sloom) {
+            if(n<10)
+                insert_new_chars_at_filename_end(outfilename,prefix_units);
+            else if(n<100)
+                insert_new_chars_at_filename_end(outfilename,prefix_tens);
+            else if(n<1000)
+                insert_new_chars_at_filename_end(outfilename,prefix_hundreds);
+            else {
+                sprintf(errstr,"Too many duplicates.\n");
+                return(PROGRAM_ERROR);
+            }
+        }
+        insert_new_number_at_filename_end(outfilename,n,0);
+        if((dz->ofd = sndopenEx(outfilename,0,CDP_OPEN_RDONLY)) < 0) {   /*RWD don't need sndopenex... */
+            unopen++;
+            dz->ofd = -1;
+            continue;
+        }
+        if(sndunlink(dz->ofd) < 0) {
+            fprintf(stdout,"WARNING: Can't set output soundfile %s for deletion.\n",outfilename);
+            fflush(stdout);
+            dz->ofd = -1;               
+            free(outfilename);
+        }
+        if(sndcloseEx(dz->ofd) < 0) {
+            fprintf(stdout,"WARNING: Can't close output soundfile %s\n",outfilename);
+            fflush(stdout);
+            dz->ofd = -1;               
+            free(outfilename);
+        }
+        removed++;
+        free(outfilename);
+        dz->ofd = -1;
+    }
+    fprintf(stdout,"INFO: %d duplicate files removed.\n",removed);
+    fflush(stdout);
+    return(FINISHED);
+}
+
+/************************************ CHECK_AVAILABLE_SPACE ********************************/
+
+int check_available_space(dataptr dz)
+{
+    unsigned int slots;
+    int outfilesize;
+
+    outfilesize = getdrivefreespace("temp") / sizeof(float);
+    slots = outfilesize/dz->insams[0];
+    if(slots < (unsigned int)dz->iparam[COPY_CNT]) {
+        sprintf(errstr,"Insufficient space on disk to create %d copies.\n"
+                       "You have space for %d copies.\n",dz->iparam[COPY_CNT],slots);
+        return(GOAL_FAILED);
+    }
+    return(FINISHED);
+}
+
+/************************************ CHECK_AVAILABLE_DISKSPACE ********************************/
+/* used for HOUSE DISK only */
+
+#define LEAVESPACE  (10*1024)       /* file space that must be left */
+#define DEFAULT_SRATE (44100)
+
+int check_available_diskspace(dataptr dz)
+{
+    double secs, mins, hrs;
+    int srate;
+    unsigned int outsamps = 0, orig_outsamps;
+    int m, k, kk, spacecnt;
+    char temp[800];
+    unsigned int freespace = getdrivefreespace("temp") - LEAVESPACE;
+
+    switch(dz->infile->filetype) {
+    case(SNDFILE):  srate = dz->infile->srate;  break;
+    default:        srate = DEFAULT_SRATE;      break;
+    }
+    sprintf(errstr,"AVAILABLE DISK SPACE (at sample rate %d)\n",srate);
+    sprintf(temp,"%d",freespace);
+    strcat(errstr,temp);
+    spacecnt = 13 - strlen(temp);
+    for(k=0;k<spacecnt;k++)        /* did have ; at end */
+        strcat(errstr," ");
+    strcat(errstr,"bytes\n");
+    splice_multiline_string(errstr,"INFO:");
+    fflush(stdout);
+    kk = 0;
+    while (kk < 4) {
+        errstr[0] = ENDOFSTR;
+        switch(kk) {
+        case(0): outsamps = freespace/2;    break;
+        case(1): outsamps = freespace/3;    break;
+        case(2): outsamps = freespace/4;    break;
+        case(3): outsamps = freespace/sizeof(float);    break;
+        }
+        sprintf(temp,"%d",outsamps);
+        strcat(errstr,temp);
+        spacecnt = 13 - strlen(temp);
+        for(k=0;k<spacecnt;k++)     /* did have ; at end */
+            strcat(errstr," ");
+        switch(kk) {
+        case(0): strcat(errstr,"16-bit samples\n"); break;
+        case(1): strcat(errstr,"24-bit samples\n"); break;
+        case(2): strcat(errstr,"32-bit samples\n"); break;
+        case(3): strcat(errstr,"float  samples\n"); break;
+        }
+        orig_outsamps = outsamps;
+        for(m=MONO;m<=STEREO;m++) {
+            switch(m) {
+            case(MONO):
+                outsamps = orig_outsamps;
+                sprintf(temp,"IN MONO    : ");
+                strcat(errstr,temp);
+                break;
+            case(STEREO):
+                outsamps /= 2;
+                sprintf(temp,"IN STEREO : ");
+                strcat(errstr,temp);
+                break;
+            }
+            secs  = (double)outsamps/srate;
+            mins  = floor(secs/60.0);
+            secs -= mins * 60.0;
+            hrs   = floor(mins/60.0);
+            mins -= hrs * 60.0;
+            if(hrs > 0.0) {
+                sprintf(temp,"%.0lf",hrs);
+                strcat(errstr,temp);
+                spacecnt = 3 - strlen(temp);
+                for(k=0;k<spacecnt;k++)
+                    strcat(errstr," ");
+                strcat(errstr,"hours ");
+            } else {
+                for(k=0;k<4 + (int)strlen("hours");k++)
+                    strcat(errstr," ");
+            }
+            if(mins > 0.0) {
+                sprintf(temp,"%.0lf",mins);
+                strcat(errstr,temp);
+                spacecnt = 3 - strlen(temp);
+                for(k=0;k<spacecnt;k++)
+                    strcat(errstr," ");
+                strcat(errstr,"mins ");
+            } else {
+                for(k=0;k<4 + (int)strlen("mins");k++)
+                    strcat(errstr," ");
+            }
+            sprintf(temp,"%.3lf",secs);
+            strcat(errstr,temp);
+            spacecnt = 7 - strlen(temp);
+            for(k=0;k<spacecnt;k++)
+                strcat(errstr," ");
+            strcat(errstr,"secs\n");
+        }
+        splice_multiline_string(errstr,"INFO:");
+        fflush(stdout);
+        kk++;
+    }
+    return FINISHED;
+}
+
+/************************************ COPY_TEXTFILE ********************************/
+
+int copy_textfile(dataptr dz)
+{
+    char temp[200];
+    int k = 0, n, m, thiswordcnt;
+    for(n=0;n<dz->linecnt;n++) {
+        thiswordcnt = dz->wordcnt[n];
+        for(m=0;m < thiswordcnt;m++) {
+            if(m == 0) {
+                //sprintf(temp,dz->wordstor[k++]); /* RWD 07 2010: bad use of sprintf */
+                strcpy(temp,dz->wordstor[k++]);
+            } else {
+                strcat(temp," ");
+                strcat(temp,dz->wordstor[k++]);
+            }
+        }
+        strcat(temp,"\n");
+        if(fputs(temp,dz->fp)<0) {
+            sprintf(errstr,"Failed to write line %d to outfile.\n",n);
+            return(SYSTEM_ERROR);
+        }
+    }
+    return(FINISHED);
+}

+ 250 - 0
dev/houskeep/main.c

@@ -0,0 +1,250 @@
+/*
+ * Copyright (c) 1983-2013 Trevor Wishart and Composers Desktop Project Ltd
+ * http://www.trevorwishart.co.uk
+ * http://www.composersdesktop.com
+ *
+ This file is part of the CDP System.
+
+    The CDP System is free software; you can redistribute it
+    and/or modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    The CDP System is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with the CDP System; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+    02111-1307 USA
+ *
+ */
+
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <structures.h>
+#include <tkglobals.h>
+#include <house.h>
+#include <filetype.h>
+#include <processno.h>
+#include <modeno.h>
+#include <formants.h>
+#include <cdpmain.h>
+#include <special.h>
+#include <logic.h>
+#include <globcon.h>
+#include <cdpmain.h>
+#include <sfsys.h>
+#include <ctype.h>
+#include <string.h>
+
+char errstr[2400];
+
+/*extern*/ int  sloom = 0;
+/*extern*/ int  sloombatch = 0;
+/*extern*/ int anal_infiles = 0;
+/*extern*/ int is_converted_to_stereo = -1;
+const char* cdp_version = "7.1.1";
+
+/**************************************** MAIN *********************************************/
+
+int main(int argc,char *argv[])
+{
+    int exit_status;
+    dataptr dz = NULL;
+//  char *special_data_string = NULL;
+    char **cmdline;
+    int  cmdlinecnt;
+    aplptr ap;
+    int *valid = NULL;
+    int is_launched = FALSE;
+    int  validcnt;
+
+    if(argc==2 && (strcmp(argv[1],"--version") == 0)) {
+        fprintf(stdout,"%s\n",cdp_version);
+        fflush(stdout);
+        return 0;
+    }
+                        /* CHECK FOR SOUNDLOOM */
+    if((sloom = sound_loom_in_use(&argc,&argv)) > 1) {
+        sloom = 0;
+        sloombatch = 1;
+    }
+
+    if(!sloom) {
+        if((exit_status = allocate_and_initialise_validity_flags(&valid,&validcnt))<0) {
+            print_messages_and_close_sndfiles(exit_status,is_launched,dz);
+            return(FAILED);
+        }
+    }
+
+    if(sflinit("cdp")){
+        sfperror("cdp: initialisation\n");
+        return(FAILED);
+    }
+
+                          /* SET UP THE PRINCIPLE DATASTRUCTURE */
+    if((exit_status = establish_datastructure(&dz))<0) {
+        print_messages_and_close_sndfiles(exit_status,is_launched,dz);
+        return(FAILED);
+    }
+
+    if(!sloom) {
+                              /* INITIAL CHECK OF CMDLINE DATA */
+        if((exit_status = make_initial_cmdline_check(&argc,&argv))<0) {
+            print_messages_and_close_sndfiles(exit_status,is_launched,dz);
+            return(FAILED);
+        }
+        cmdline    = argv;  /* GET PRE_DATA, ALLOCATE THE APPLICATION, CHECK FOR EXTRA INFILES */
+        cmdlinecnt = argc;
+        if((exit_status = get_process_and_mode_from_cmdline(&cmdlinecnt,&cmdline,dz))<0) {
+            print_messages_and_close_sndfiles(exit_status,is_launched,dz);
+            return(FAILED);
+        }       
+        if((exit_status = setup_particular_application(dz))<0) {
+            print_messages_and_close_sndfiles(exit_status,is_launched,dz);
+            return(FAILED);
+        }
+        if((exit_status = count_and_allocate_for_infiles(cmdlinecnt,cmdline,dz))<0) {
+            print_messages_and_close_sndfiles(exit_status,is_launched,dz);
+            return(FAILED);
+        }
+    } else {
+        if((exit_status = parse_tk_data(argc,argv,&cmdline,&cmdlinecnt,dz))<0) {    /* includes setup_particular_application()      */
+            exit_status = print_messages_and_close_sndfiles(exit_status,is_launched,dz);/* and cmdlinelength check = sees extra-infiles */
+            return(exit_status);         
+        }
+    }
+    ap = dz->application;
+
+/*********************************************************************************************************************
+       cmdline[0]                         2 vals                              ACTIVE         
+TK      (infile) (more-infiles) (outfile) (flag val) (formantsqksrch) (special) params  options   variant-params  flags
+CMDLINE (infile) (more-infiles) (outfile) (formants) (formantsqksrch) (special) params  POSSIBLY  POSSIBLY      POSSIBLY
+                                          1 val
+*********************************************************************************************************************/
+
+    if(dz->process!=HOUSE_DEL) {
+        if((exit_status = parse_infile_and_hone_type(cmdline[0],valid,dz))<0) {
+            print_messages_and_close_sndfiles(exit_status,is_launched,dz);
+            return(FAILED);
+        }
+    }
+
+    if((exit_status = setup_param_ranges_and_defaults(dz))<0) {
+        print_messages_and_close_sndfiles(exit_status,is_launched,dz);
+        return(FAILED);
+    }
+
+                    /* OPEN FIRST INFILE AND STORE DATA, AND INFORMATION, APPROPRIATELY */
+
+    if(dz->process!=HOUSE_DEL) {
+        /*RWD 9:2001 there was only one & below */
+        if(dz->process!=HOUSE_BUNDLE  && dz->input_data_type!=NO_FILE_AT_ALL) {
+            if((exit_status = open_first_infile(cmdline[0],dz))<0) {    
+                print_messages_and_close_sndfiles(exit_status,is_launched,dz);  
+                return(FAILED);
+            }
+        }
+        if(!sloom) {
+            if((dz->process==HOUSE_SORT || (dz->process==HOUSE_COPY && dz->mode==COPYSF && dz->infile->filetype==WORDLIST))) {
+                if(dz->process==HOUSE_SORT) 
+                    dz->all_words--;
+                if (setup_file_outname_where_ness(cmdline[0],dz)<0) {
+                    print_messages_and_close_sndfiles(exit_status,is_launched,dz);  
+                    return(FAILED);      /* stores name of inlistfile at END of list of names of sndfiles */
+                }
+            }
+        }
+
+
+        cmdlinecnt--;
+        cmdline++;
+    
+    }
+
+/*********************************************************************************************************************
+        cmdline[0]                 2 vals                              ACTIVE        
+TK      (more-infiles) (outfile) (flag val) (formantsqksrch) (special) params  options   variant-params  flags
+CMDLINE (more-infiles) (outfile) (formants) (formantsqksrch) (special) params  POSSIBLY  POSSIBLY         POSSIBLY
+                                   1 val
+*********************************************************************************************************************/
+
+    if((exit_status = handle_extra_infiles(&cmdline,&cmdlinecnt,dz))<0) {
+        print_messages_and_close_sndfiles(exit_status,is_launched,dz);      
+        return(FAILED);
+    }
+
+/*********************************************************************************************************************
+        cmdline[0]    2                                 ACTIVE       
+TK      (outfile) (flag val) (formantsqksrch) (special) params  options   variant-params  flags
+CMDLINE (outfile) (formants) (formantsqksrch) (special) params  POSSIBLY  POSSIBLY         POSSIBLY
+                      1
+*********************************************************************************************************************/
+
+    if((exit_status = handle_outfile(&cmdlinecnt,&cmdline,is_launched,dz))<0) {
+        print_messages_and_close_sndfiles(exit_status,is_launched,dz);
+        return(FAILED);
+    }
+
+/****************************************************************************************
+        cmdline[0]                             ACTIVE        
+TK      (flag val) (formantsqksrch) (special) params  options   variant-params  flags
+CMDLINE (formants) (formantsqksrch) (special) params  POSSIBLY  POSSIBLY        POSSIBLY
+*****************************************************************************************/
+
+    if((exit_status = handle_formants(&cmdlinecnt,&cmdline,dz))<0) {
+        print_messages_and_close_sndfiles(exit_status,is_launched,dz);
+        return(FAILED);
+    }
+    if((exit_status = handle_formant_quiksearch(&cmdlinecnt,&cmdline,dz))<0) {
+        print_messages_and_close_sndfiles(exit_status,is_launched,dz);
+        return(FAILED);
+    }
+    if((exit_status = handle_special_data(&cmdlinecnt,&cmdline,dz))<0) {
+        print_messages_and_close_sndfiles(exit_status,is_launched,dz);
+        return(FAILED);
+    }
+ 
+/****************************************************************************************
+        cmdline[0]                          
+TK      active_params   options         variant-params  flags
+CMDLINE active_params   POSSIBLY        POSSIBLY        POSSIBLY
+*****************************************************************************************/
+
+    if((exit_status = read_parameters_and_flags(&cmdline,&cmdlinecnt,dz))<0) {
+        print_messages_and_close_sndfiles(exit_status,is_launched,dz);
+        return(FAILED);
+    }
+
+    if((exit_status = check_param_validity_and_consistency(dz))<0) {
+        print_messages_and_close_sndfiles(exit_status,is_launched,dz);
+        return(FAILED);
+    }
+
+    is_launched = TRUE;
+    /*RWD OCT 2001: NB: we need to validate rq srate before allocating buffers! */
+    if((exit_status = allocate_large_buffers(dz))<0){
+        print_messages_and_close_sndfiles(exit_status,is_launched,dz);
+        return(FAILED);
+    }
+    if((exit_status = param_preprocess(dz))<0){
+        print_messages_and_close_sndfiles(exit_status,is_launched,dz);
+        return(FAILED);
+    }
+    if((exit_status = groucho_process_file(dz))<0) {
+        print_messages_and_close_sndfiles(exit_status,is_launched,dz);
+        return(FAILED);
+    }
+    if((exit_status = complete_output(dz))<0) {
+        print_messages_and_close_sndfiles(exit_status,is_launched,dz);
+        return(FAILED);
+    }
+    exit_status = print_messages_and_close_sndfiles(FINISHED,is_launched,dz);
+    free(dz);
+    return(SUCCEEDED);
+}

+ 557 - 0
dev/houskeep/respec.c

@@ -0,0 +1,557 @@
+/*
+ * Copyright (c) 1983-2013 Trevor Wishart and Composers Desktop Project Ltd
+ * http://www.trevorwishart.co.uk
+ * http://www.composersdesktop.com
+ *
+ This file is part of the CDP System.
+
+    The CDP System is free software; you can redistribute it
+    and/or modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    The CDP System is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with the CDP System; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+    02111-1307 USA
+ *
+ */
+
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <structures.h>
+#include <tkglobals.h>
+#include <pnames.h>
+#include <globcon.h>
+#include <cdpmain.h>
+#include <house.h>
+#include <modeno.h>
+#include <sfsys.h>
+#include <filetype.h>
+#include <srates.h>
+#include <flags.h>
+
+#ifdef unix
+#define round(x) lround((x))
+#endif
+
+static int 	  create_convert_buffer(dataptr dz);
+static int	  create_reprop_buffer(dataptr dz);
+static int 	  do_convert_process(dataptr dz);
+static int	  reprop_process(dataptr dz);
+static void   strip_dir(char *str);
+static int	  create_cubic_spline_bufs(dataptr dz);
+static int	  cubic_spline(dataptr dz);
+
+/****************************** CREATE_RESPEC_BUFFERS ****************************/
+
+int create_respec_buffers(dataptr dz)
+{
+	switch(dz->mode) {
+	case(HOUSE_RESAMPLE):	return create_cubic_spline_bufs(dz);
+	case(HOUSE_CONVERT):	return create_convert_buffer(dz);
+	case(HOUSE_REPROP):		return create_reprop_buffer(dz);
+	}
+	return(FINISHED);
+}
+
+/***************************** DO_RESPECIFICATION ******************************/
+
+int do_respecification(dataptr dz)
+{
+	switch(dz->mode) {
+	case(HOUSE_RESAMPLE):	return cubic_spline(dz);
+	case(HOUSE_CONVERT):	return do_convert_process(dz);
+	case(HOUSE_REPROP):		return reprop_process(dz);
+	}
+	return(FINISHED);
+}
+
+/***************************** CREATE_CONVERT_BUFFER ******************************/
+
+int create_convert_buffer(dataptr dz)
+{
+	int bigbufsize;
+	int factor = (sizeof(short) + sizeof(float))/sizeof(short);
+
+	bigbufsize = (int) (long)Malloc(-1);
+	dz->buflen = bigbufsize/sizeof(float) / factor;
+	if((dz->bigbuf = (float *)malloc((size_t)
+		(dz->buflen * factor * sizeof(float))))==NULL) {
+		sprintf(errstr,"Insufficient memory for sound.\n");
+		return(MEMORY_ERROR);
+	}
+	dz->sampbuf[0]  = dz->bigbuf;
+   	dz->flbufptr[0] = (float *)(dz->sampbuf[0] + dz->buflen); 
+	return(FINISHED);
+}
+
+/***************************** CREATE_REPROP_BUFFER ******************************/
+
+int create_reprop_buffer(dataptr dz)
+{
+	size_t bigbufsize;
+	bigbufsize = (size_t)Malloc(-1);
+	dz->buflen = (int)(bigbufsize / sizeof(float));
+	
+	if((dz->bigbuf = (float *)malloc(dz->buflen* sizeof(float)))==NULL) {
+		sprintf(errstr,"Insufficient memory for sound.\n");
+		return(MEMORY_ERROR);
+	}
+	dz->sampbuf[0]  = dz->bigbuf;
+	return(FINISHED);
+}
+
+/************************** REPROP_PROCESS **************************/
+//RWD.1.99  modified to check that the iparams are active
+//RWD.1.99  modified to check that the iparams are active
+/*RWD Oct 2001: but does not support 24bit files, etc.... yet; need new cmdline flags for that */
+int reprop_process(dataptr dz)
+{
+	int intype;
+	SFPROPS props = {0};
+	int exit_status;
+//TW modified: as infile->stype is now merely a flag for SOUND v NOT-SOUND DATA
+	if(dz->infile->filetype != SNDFILE){
+		sprintf(errstr,"This process only works with soundfiles.\n");
+		return(DATA_ERROR);
+	}
+	if(!snd_headread(dz->ifd[0],&props)) {
+		fprintf(stdout,"Failure to read sample type\n");
+		fflush(stdout);
+		return(DATA_ERROR);
+	}
+	switch(props.samptype) {
+	case (2):  /* FLOAT32 */	intype = SAMP_SHORT;	break;
+	case (1):  /* SHORT16 */	intype = SAMP_FLOAT;	break;
+	default:
+		sprintf(errstr,"This process only works with 16-bit or floating-point soundfiles.\n");
+		return(DATA_ERROR);
+	}
+	if(dz->iparam[HSPEC_SRATE]==dz->infile->srate
+	&& dz->iparam[HSPEC_CHANS]==dz->infile->channels
+	&& dz->iparam[HSPEC_TYPE] == intype) {
+		sprintf(errstr,"NO CHANGE to input file.\n");
+		return(GOAL_FAILED);
+	}
+	/*RWD oct 2001: NB refuses 9-ch B-format files! */
+	if((dz->iparam[HSPEC_CHANS] > 0) && (
+		dz->iparam[HSPEC_CHANS] != 1 
+		&& dz->iparam[HSPEC_CHANS] != 2
+		&& dz->iparam[HSPEC_CHANS] != 4
+		&& dz->iparam[HSPEC_CHANS] != 6
+		&& dz->iparam[HSPEC_CHANS] != 8
+		&& dz->iparam[HSPEC_CHANS] != 16
+		)) {
+    	sprintf(errstr,"\nInvalid channel count [%d]",dz->iparam[HSPEC_CHANS]);
+		return(DATA_ERROR);
+	}
+	if((dz->iparam[HSPEC_SRATE] > 0) && (!IS_LOSR(dz->iparam[HSPEC_SRATE]) && !IS_HISR(dz->iparam[HSPEC_SRATE]))) {
+    	sprintf(errstr,"\nInvalid sample rate [%d]",dz->iparam[HSPEC_SRATE]);
+		return(DATA_ERROR);
+	}
+
+	if(dz->iparam[HSPEC_TYPE] >= SAMP_SHORT &&   (dz->iparam[HSPEC_TYPE]!=SAMP_SHORT
+	&& dz->iparam[HSPEC_TYPE]!=SAMP_FLOAT)) {
+    	sprintf(errstr,"\nInvalid sample type [%d]",dz->iparam[HSPEC_TYPE]);
+		return(DATA_ERROR);
+	}
+	//RWD only update if the value is legal!
+	if(dz->iparam[HSPEC_TYPE] >= SAMP_SHORT)
+		dz->infile->stype    = dz->iparam[HSPEC_TYPE];
+	if(dz->iparam[HSPEC_SRATE] > 0)
+		dz->infile->srate    = dz->iparam[HSPEC_SRATE];
+	if(dz->iparam[HSPEC_CHANS] > 0)
+		dz->infile->channels = dz->iparam[HSPEC_CHANS];
+
+	
+	dz->ofd = sndcreat_formatted(dz->outfilename,-1,dz->infile->stype,dz->infile->channels,
+									dz->infile->srate,CDP_CREATE_NORMAL);
+//TW ADDED : for peak chunk
+	dz->outchans = dz->infile->channels;
+	establish_peak_status(dz);
+	//test!
+	dz->outfilesize = 0;
+	if(dz->ofd < 0)	{
+		sprintf(errstr,"Unable to open outfile %s\n",dz->outfilename);
+		return SYSTEM_ERROR;
+	}
+
+	while(dz->samps_left) {		
+		if((exit_status = read_samps(dz->sampbuf[0],dz))<0)
+			return(exit_status);	
+		if(dz->ssampsread > 0) {
+			if((exit_status = write_exact_samps(dz->sampbuf[0],dz->ssampsread,dz))<0)
+				return(exit_status);
+		}
+	}
+	return(FINISHED);
+}
+
+/************************** DO_CONVERT_PROCESS **************************/
+
+int do_convert_process(dataptr dz)
+{
+	int exit_status;
+	float *fbuf = dz->flbufptr[0];
+	SFPROPS props = {0};
+	int outtype;		/*RWD*/
+
+//TW dz->infile->stype now merely flags whether we have a soundfile
+	if(dz->infile->filetype != SNDFILE){
+		sprintf(errstr,"This process only works with soundfiles.\n");
+		return(DATA_ERROR);
+	}
+	if(!snd_headread(dz->ifd[0],&props)) {
+		fprintf(stdout,"Failure to read sample type\n");
+		fflush(stdout);
+		return(DATA_ERROR);
+	}
+	switch(props.samptype) {
+	case (2):  /* FLOAT32 */	outtype = SAMP_SHORT;	break;
+	case (1):  /* SHORT16 */	outtype = SAMP_FLOAT;	break;
+	default:
+		sprintf(errstr,"This process only works with 16-bit or floating-point soundfiles.\n");
+		return(DATA_ERROR);
+	}
+
+	dz->ofd = sndcreat_formatted(dz->outfilename,-1,
+		outtype,dz->infile->channels,
+									dz->infile->srate,CDP_CREATE_NORMAL);	
+	if(dz->ofd < 0)	{
+		sprintf(errstr,"Unable to open outfile %s\n",dz->outfilename);
+		return SYSTEM_ERROR;
+	}
+	dz->outchans = dz->infile->channels;
+	establish_peak_status(dz);
+	dz->tempsize = dz->insams[0];
+	while(dz->samps_left){
+		if((exit_status = read_samps(fbuf,dz))<0)
+			return(exit_status);
+		if(dz->ssampsread) {
+			if((exit_status = write_samps(fbuf,dz->ssampsread,dz)) < 0)
+				return exit_status;
+		}
+	}
+	return(FINISHED);
+}
+
+/********************** BATCH_EXPAND ****************************/
+ 
+int batch_expand(dataptr dz)
+{
+	int	   total_wordcnt = 0;
+	int    n, m, k, linelen = dz->wordcnt[0];
+	char   temp[200], temp2[200], temp3[10];
+	char   **fname_wordstor = dz->wordstor + (dz->all_words - (dz->itemcnt * 2));
+	char   **param_wordstor = dz->wordstor + (dz->all_words - dz->itemcnt);
+	int	    fq;
+
+	if(dz->infilecnt - 1 <= 0) {
+		sprintf(errstr,"No sound files entered.\n");
+		return(DATA_ERROR);
+	}
+	switch(dz->mode) {
+	case(ONE_PARAM):
+		for(k = 0; k < dz->itemcnt; k++) {
+			total_wordcnt = 0;
+			for(n=0;n< dz->linecnt;n++) {
+				for(m=0;m<linelen;m++) {
+					if(m==0) {
+						strcpy(temp,dz->wordstor[total_wordcnt]);
+					} else if(total_wordcnt % linelen == dz->iparam[BE_INFILE]) {
+						strcat(temp," ");
+						strcat(temp,fname_wordstor[k]);
+					} else if(total_wordcnt % linelen == dz->iparam[BE_OUTFILE]) {
+					strcpy(temp3,"_b");
+					sprintf(temp2,"%d",n);
+					strcat(temp3,temp2);
+					strcpy(temp2,fname_wordstor[k]);
+					strip_dir(temp2);
+					insert_new_chars_at_filename_end(temp2,temp3);
+					strcat(temp," ");
+					strcat(temp,temp2);
+						if((fq = sndopenEx(temp,0,CDP_OPEN_RDONLY)) >= 0) {
+							sndcloseEx(fq);
+							fq = -1;
+							sprintf(errstr,"File %s already exists: cannot use as outname in batchfile\n",temp);
+							return(DATA_ERROR);
+						}
+					} else if(total_wordcnt % linelen == dz->iparam[BE_PARAM]) {
+						strcat(temp," ");
+						strcat(temp,param_wordstor[k]);
+					} else {
+						strcat(temp," ");
+						strcat(temp,dz->wordstor[total_wordcnt]);
+					}
+					total_wordcnt++;
+				}
+				strcat(temp,"\n");
+				if(fputs(temp,dz->fp)<0) {
+					sprintf(errstr,"Failed to copy of original batchfile line %d to output file.\n",n+1);
+					return(SYSTEM_ERROR);
+				}
+			}
+		}
+		break;		
+	case(MANY_PARAMS):
+		total_wordcnt = 0;
+		for(n=0,k=0;n< dz->linecnt;n++,k++) {
+			if (k >= dz->itemcnt)
+				break;	
+			for(m=0;m<linelen;m++) {
+				if(m==0) {
+					/*sprintf*/strcpy(temp,dz->wordstor[total_wordcnt]); // RWD 07 2010 see above
+				} else if(total_wordcnt % linelen == dz->iparam[BE_INFILE]) {
+					strcat(temp," ");
+					strcat(temp,fname_wordstor[k]);
+				} else if(total_wordcnt % linelen == dz->iparam[BE_OUTFILE]) {
+					strcpy(temp2,fname_wordstor[k]);
+					insert_new_chars_at_filename_end(temp2,"_b");
+					strcat(temp," ");
+					strcat(temp,temp2);
+					if((fq = sndopenEx(temp,0,CDP_OPEN_RDONLY)) >= 0) {
+						sndcloseEx(fq);
+						fq = -1;
+						sprintf(errstr,"File %s already exists: cannot use as outname in batchfile\n",temp);
+						return(DATA_ERROR);
+					}
+				} else if(total_wordcnt % linelen == dz->iparam[BE_PARAM]) {
+					strcat(temp," ");
+					strcat(temp,param_wordstor[k]);
+				} else {
+					strcat(temp," ");
+					strcat(temp,dz->wordstor[total_wordcnt]);
+				}
+				total_wordcnt++;
+			}
+			strcat(temp,"\n");
+			if(fputs(temp,dz->fp)<0) {
+				sprintf(errstr,"Failed to print new batchfile line %d to output file.\n",n+1);
+				return(SYSTEM_ERROR);
+			}
+		}
+		break;
+	}
+	return FINISHED;
+}
+
+/********************** STRIP_DIR ****************************/
+ 
+void strip_dir(char *str)
+{
+	char *p, *q, *r = str;
+	q = str + strlen(str);
+	p = q - 1;
+	while(p > str) {
+		if(*p == '/') {
+			p++;
+			while(p <= q)
+				*r++ = *p++;
+			return;
+		}
+		p--;
+	}
+}
+
+/********************** CREATE_CUBIC_SPLINE_BUFS ****************************/
+ 
+int create_cubic_spline_bufs(dataptr dz)
+{
+	int dblratio = sizeof(double)/sizeof(float);
+	int dbl_buflen;
+	int k, chans = dz->infile->channels;
+	int dbl_chans = chans * dblratio;
+	size_t bigbuf_bigsize, bigbufsize;
+	int fsecsize = SECSIZE/sizeof(float);
+	int framesize = fsecsize * dz->infile->channels;
+
+	bigbuf_bigsize = ((size_t) Malloc(-1))/sizeof(float);
+	bigbufsize = (bigbuf_bigsize/framesize) * framesize;
+	if(bigbufsize <= 0)
+		bigbufsize = framesize;
+	k = (3 * dblratio) + 2;
+	bigbuf_bigsize = bigbufsize * k;
+	bigbuf_bigsize  += fsecsize;
+	bigbuf_bigsize  += (chans * dblratio * 3);
+	if((dz->bigbuf = (float *)malloc((size_t)(bigbuf_bigsize * sizeof(float)))) == NULL) {
+		sprintf(errstr,"INSUFFICIENT MEMORY to create sound buffers.\n");
+		return(MEMORY_ERROR);
+	}
+	memset((char *)dz->bigbuf,0,bigbuf_bigsize * sizeof(float));
+	/* NB: wraparound points for both samples and derivatives are thus zeroed */
+	dz->buflen = (int) bigbufsize;
+	dbl_buflen = dz->buflen * dblratio;
+	/* sampbuf[0] has chans samps store at start to read wraparound points */
+	dz->sampbuf[0] = dz->bigbuf + fsecsize;
+	dz->sampbuf[1] = dz->sampbuf[0] + dz->buflen;
+	/* sampbufs[2][3][4] have additional chans samps store at start,and are doubles buffers */
+	dz->sampbuf[2] = dz->sampbuf[1] + dz->buflen + dbl_chans;
+	dz->sampbuf[3] = dz->sampbuf[2] + dbl_buflen + dbl_chans;
+	dz->sampbuf[4] = dz->sampbuf[3] + dbl_buflen + dbl_chans;
+	return(FINISHED);
+}
+
+/********************** CUBIC_SPLINE ****************************/
+ 
+int cubic_spline(dataptr dz)
+{
+	int exit_status;
+	int chans = dz->infile->channels;	
+	int fsecsize = SECSIZE/sizeof(float);
+		/* Input and Output and Derivatives buffers */
+	float *ibuf = dz->sampbuf[0], *obuf = dz->sampbuf[1];
+	double *y2 = (double *)dz->sampbuf[2];
+	double *u  = (double *)dz->sampbuf[3];
+	double *y3 = (double *)dz->sampbuf[4];
+		/* constants used in calculation */
+	double incr = (double)dz->infile->srate/(double)dz->iparam[HSPEC_SRATE];
+	double sig = 0.5;
+	double sig_less_one = sig - 1.0;
+		/* flags used in calculation */
+	int all_read = 0, start = 1;
+		/* other variables */
+	double d = 0.0, p;
+	int n,m,k,obufcnt = 0, samps_to_process;
+	double kk, hi, lo, hidif, lodif, x1, x2, x3, x4;
+	int lochan, hichan;
+	double samp;
+	int inlo, inhi; 
+	dz->tempsize = round((double)dz->insams[0]/incr);
+		/* setup wraparound pointers */
+	//create outfile here, now we have required format info	
+	if((dz->ofd = sndcreat_formatted(dz->outfilename,-1,dz->infile->stype,dz->infile->channels,
+									/*dz->infile->srate*/
+									dz->iparam[HSPEC_SRATE],
+									CDP_CREATE_NORMAL)) < 0) {
+		sprintf(errstr,"Unable to open outfile %s\n",dz->outfilename);
+		return SYSTEM_ERROR;
+	}
+	dz->outchans = dz->infile->channels;
+	establish_peak_status(dz);
+
+	k = dz->buflen - fsecsize - chans;
+	dz->sbufptr[0] = dz->sampbuf[0] - chans;
+	dz->sbufptr[1] = dz->sampbuf[0] + k;
+	dz->ptr[0] = y2 - chans;
+	dz->ptr[1] = y2 + k;
+	dz->ptr[2] = u  - chans;
+	dz->ptr[3] = u  + k;
+	dz->ptr[4] = y3 - chans;
+	dz->ptr[5] = y3 + k;
+
+	while(dz->samps_left > 0) {
+		/* Read samps, leaving overlapping samps at end of buffer to do wraparound calculations */		
+		
+		if((exit_status = read_samps(ibuf,dz))<0)
+			return(exit_status);
+		if(dz->total_samps_read < dz->insams[0]) {
+// APRIL 2005
+//			sfseek(dz->ifd[0],(dz->total_samps_read - fsecsize) * sizeof(float),0);
+			sndseekEx(dz->ifd[0],dz->total_samps_read - fsecsize,0);
+
+			samps_to_process = dz->ssampsread - fsecsize;
+			dz->total_samps_read -= fsecsize;
+			dz->samps_left += fsecsize;
+		} else {
+			all_read = 1;
+			k = dz->ssampsread;
+				/* if at end of data, add buffering zeros after end */
+			for(n=0;n<chans;n++) {
+				dz->sampbuf[0][k] = 0.0f;
+				k++;
+			}
+			samps_to_process = dz->ssampsread; 
+		}
+			/* CALCULATE 2nd DERIVATIVE : STAGE 1 */
+		for(n=0;n<samps_to_process;n+= chans) {
+			for(m = 0;m <chans; m++) {
+				k = n + m;
+				p = sig * y2[k-chans] + 2.0;
+				y2[k] = sig_less_one/p;
+//				u[k]  = (ibuf[k+chans] - ibuf[k]) - (ibuf[k] - ibuf[k-chans]);
+				u[k]  = (round(32767 * ibuf[k+chans]) - round(32767 * ibuf[k])) - (round(32767 * ibuf[k]) - round(32767 * ibuf[k-chans]));
+				x1 = (6.0 * u[k])/2.0;
+				x2 = sig * u[k-chans];
+				u[k]  = (x1 - x2)/p;
+			}
+		}
+		if(all_read) {	/* add "natural spline" end vals of 2nd derivative */
+			for(m = 0;m <chans; m++)
+				y2[n+m] = 0.0;
+		}
+			/* CALCULATE 2nd DERIVATIVE : STAGE 2 */
+		for(n = samps_to_process-chans;n >= 0;n -= chans) {
+			for(m = 0;m <chans; m++) {
+				k = n + m;
+				y3[k] = (y2[k] * y2[k+chans]) + u[k];
+			}
+		}
+			/* DO SPLINE */
+		k = samps_to_process/chans;
+		kk = (double)k;
+		if(start) {
+			for(m=0;m<chans;m++)
+				obuf[m] = ibuf[m];
+			obufcnt = chans;
+			start = 0;
+		}
+		for(;;) {
+			d += incr;			/* Advance re-read pointer in buffer */
+			if(d >= kk) {
+				d -= incr;
+				d -= kk;		/* if at end of input buffer, reset pointer, and break */
+				break;
+			}
+			lo = floor(d);		/* find buffer indices of samples above and below pointer */
+			hi = lo + 1.0;
+			hidif = hi - d;
+			lodif = d - lo;
+			lochan = (int)lo * chans;
+			hichan = (int)hi * chans;
+			for(m=0;m<chans;m++) {
+				n = obufcnt + m;
+				inlo = lochan + m; 
+				inhi = hichan + m; 
+								/* DO SPLINE */
+//				x1 = (hidif * ibuf[inlo]) + (lodif * ibuf[inhi]);	
+				x1 = (hidif * round(32767 * ibuf[inlo])) + (lodif * round(32767 * ibuf[inhi]));	
+				x2 = ((hidif * hidif * hidif) - hidif) * y3[inlo];
+				x3 = ((lodif * lodif * lodif) - lodif) * y3[inhi];
+				x4 = (x2 + x3)/6.0;
+//				samp = x1 + x4;
+				samp = ((int)round(x1 + x4)/32767.0);
+				if(samp > 1.0)
+					samp = 1.0;
+				if(samp < -1.0)
+					samp = -1.0;
+				obuf[n] = (float)samp;
+			}
+			obufcnt += chans;
+			if(obufcnt >= dz->buflen) {
+				if((exit_status = write_samps(obuf,dz->buflen,dz))<0)
+					return(exit_status);
+				obufcnt = 0;
+			}
+		}
+		if(!all_read) {    /* do wrap-around points for input & derivatives */
+			memcpy((char *)dz->sbufptr[0],(char *)dz->sbufptr[1],chans * sizeof(float));
+			memcpy((char *)dz->ptr[0],(char *)dz->ptr[1],chans * sizeof(double));
+			memcpy((char *)dz->ptr[2],(char *)dz->ptr[3],chans * sizeof(double));
+			memcpy((char *)dz->ptr[4],(char *)dz->ptr[5],chans * sizeof(double));
+		}	
+	}
+	if(obufcnt > 0) {
+		if((exit_status = write_samps(obuf,obufcnt,dz))<0)
+			return(exit_status);
+	}
+	return FINISHED;
+}

+ 1286 - 0
dev/houskeep/sort.c

@@ -0,0 +1,1286 @@
+/*
+ * 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
+ *
+ */
+
+
+
+/* RWD floats version */
+#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 <flags.h>
+#include <filetype.h>
+#include <sfsys.h>
+#include <string.h>
+/**
+#include <logic.h>
+#include <limits.h>
+#include <math.h>
+**/
+
+#define MAXTYPES (512)
+
+#define	IS_MONO		(1)
+#define	IS_STEREO	(2)
+#define	IS_QUAD		(3)
+#define	IS_ANAL		(4)
+#define	IS_PITCH	(5)
+#define	IS_TRANSPOS	(6)
+#define	IS_FMNT		(7)
+#define	IS_ENV		(8)
+
+static int  compare_properties_for_bundling(fileptr fp1,infileptr fp2);
+		    
+static int  read_and_sort_properties(char *infilename,dataptr dz);
+static int  do_srates(char *infilename,char *thisfilename,
+			char **file48,char **file44,char **file32,char **file24,char **file22,char **file16,
+			int *is_file48,int *is_file44,int *is_file32,int *is_file24,int *is_file2,int *is_file16,
+			FILE **fp48,FILE **fp44,FILE **fp32,FILE **fp24,FILE **fp22,FILE **fp16,dataptr dz);
+static void do_rogues(char *infilename,int *a_srate,dataptr dz);
+static int  read_srate(char *infilename,dataptr dz);
+static int  read_channels(char *infilename,dataptr dz);
+static void get_length(char *infilename,dataptr dz);
+static int  do_lenths(char *infilename,char *thisfilename,char **namestore,char ***lstore,
+			int *namestoresize,int *lcnt,double *sortlens,dataptr dz);
+static int  create_lfile(char *infilename,char **otherfile,char ***lstore,double *sortlens,int *lcnt,dataptr dz);
+static int  create_ofile(char *infilename,char **otherfile,int cnt,
+			char ***lstore,double *lenstore,int *posstore,dataptr dz);
+static int  do_types(char *infilename, char *thisfilename,char **monofile,char **stereofile,char **quadfile,
+			char **analfile,char **pitchfile, char **transfile,char **formantfile,char **envfile,char **otherfile,
+			int *is_mono_list,int *is_stereo_list,int *is_quad_list,int *is_anal_list,int *is_pitch_list,
+			int *is_trans_list,int *is_fmnt_list,int *is_env_list,int *is_other_list,
+			FILE **fpm,FILE **fps,FILE **fpa,FILE **fpp,FILE **fpt,FILE **fpf,FILE **fpe,FILE **fpo,FILE **fpq,dataptr dz);
+//TW REVISED
+static int  output_lenths(char *infilename,char **otherfile,
+			char ***lstore,double *sortlens,int *lcnt,dataptr dz);
+static void output_srates(int is_file48,int is_file44,int is_file32,int is_file24,int is_file22,int is_file16,
+		   	char *file48,char *file44,char *file32,char *file24,char *file22,char *file16);
+static void output_types(char *infilename,int is_mono_list,int is_stereo_list,int is_quad_list,
+			int is_anal_list,int is_pitch_list,
+			int is_trans_list,int is_fmnt_list,int is_env_list,int is_other_list,
+			char *monofile,char *stereofile,char *quadfile,char *analfile,char *pitchfile,char *transfile,
+			char *formantfile,char *envfile,char *otherfile);
+static void strip_extension(char *filename);
+static int  do_order(char *infilename,char *thisfilename,char **namestore,double **lenstore,int **posstore,
+			char ****lstore,int *fileno,int *namestoresize,dataptr dz);
+static int  output_order(char *infilename,char **otherfile,
+			int *posstore,double *lenstore,char ***lstore,int cnt,dataptr dz);
+static int  read_special_type(dataptr dz);
+static int  filename_extension_is_not_sound(char *filename);
+
+int outfcnt = 0;
+
+/************************** DO_BUNDLE *****************************/
+
+int do_bundle(dataptr dz)
+{
+	int exit_status;
+	int got_sndfile = FALSE, n, OK;
+	int filetype = dz->infile->filetype;
+	fileptr fp1 = dz->infile;
+	double maxamp, maxloc;
+	int maxrep;
+	int getmax = 0, getmaxinfo = 0;
+	infileptr ifp;
+	if((ifp = (infileptr)malloc(sizeof(struct filedata)))==NULL) {
+		sprintf(errstr,"INSUFFICIENT MEMORY to store data on files.\n");
+		return(MEMORY_ERROR);
+	}
+
+	for(n=0;n<dz->infilecnt;n++) {
+		if(!strcmp(dz->wordstor[n],dz->wordstor[dz->all_words-1])) {
+			sprintf(errstr,"Name of out-listfile [%s] cannot be included in the listing!!\n",dz->wordstor[n]);
+			return(DATA_ERROR);
+		}
+	}
+	if(!is_a_text_input_filetype(filetype))
+		got_sndfile = TRUE;
+	if(got_sndfile || dz->mode==BUNDLE_ALL) {
+		sprintf(errstr,"BUNDLED %s\n",dz->wordstor[0]);
+		print_outmessage(errstr);
+		fprintf(dz->fp,"%s\n",dz->wordstor[0]);
+	}
+	for(n=1;n<dz->infilecnt;n++) {
+		for(;;) {
+			OK = FALSE;
+			if(dz->mode==BUNDLE_ALL) {
+				OK = TRUE;					  /* list any file */
+				break;
+			} else if((dz->ifd[n] = sndopenEx(dz->wordstor[n],0,CDP_OPEN_RDONLY)) < 0)
+				break;						  /* else if non-text file, break */
+			if(dz->mode==BUNDLE_NONTEXT) {
+				OK = TRUE;					  /* if any non-text file OK, break */
+				break;				
+			}
+			if(!got_sndfile) {
+				got_sndfile = TRUE;
+				if((exit_status = readhead(ifp,dz->ifd[n],dz->wordstor[n],&maxamp,&maxloc,&maxrep,getmax,getmaxinfo))<0)
+					return(exit_status);
+				filetype = ifp->filetype;
+				copy_to_fileptr(ifp,fp1);
+				OK = TRUE;					  /* 1st non-text file is always OK, break */
+				break;
+			}
+			if((exit_status = readhead(ifp,dz->ifd[n],dz->wordstor[n],&maxamp,&maxloc,&maxrep,getmax,getmaxinfo))<0)
+				return(exit_status);
+			if(ifp->filetype!=filetype) /* If files NOT of same type, break */
+				break;	
+			if(dz->mode==BUNDLE_TYPE) {
+				OK = TRUE;					  /* if any file of same type OK, break */
+				break;
+			}
+			if(compare_properties_for_bundling(fp1,ifp)==CONTINUE)
+				break;					  	/* if properties incompatible, break */
+			if(dz->mode==BUNDLE_SRATE) {
+				OK = TRUE;					/* if any file with same props OK, break */
+				break;
+			}								/* if files have same chancnt, set OK for BUNDLE_CHAN */
+			if(fp1->channels==ifp->channels)
+				OK = TRUE;				
+			break;	
+		}
+		if(OK) {
+			sprintf(errstr,"BUNDLED %s\n",dz->wordstor[n]);
+			print_outmessage(errstr);
+			fprintf(dz->fp,"%s\n",dz->wordstor[n]);
+		}
+	}
+	fflush(stdout);
+	free(ifp);
+	return(FINISHED);
+}
+
+/************************** COMPARE_PROPERTIES_FOR_BUNDLING *****************************/
+
+int compare_properties_for_bundling(fileptr fp1,infileptr fp2)
+{
+	switch(fp1->filetype) {
+ 	case(PITCHFILE):	/* compare properties not in analfiles */
+	case(FORMANTFILE):
+	case(TRANSPOSFILE):
+		if(fp2->origchans != fp1->origchans)
+			return(CONTINUE);
+		/* fall thro */ 
+	case(ANALFILE):	/* compare properties common to all float files except envfiles */
+		if(fp2->origstype != fp1->origstype)
+			return(CONTINUE);
+		if(fp2->origrate != fp1->origrate)
+			return(CONTINUE);
+		if(fp2->arate != fp1->arate)
+			return(CONTINUE);
+		if(fp2->Mlen != fp1->Mlen)
+			return(CONTINUE);
+		if(fp2->Dfac != fp1->Dfac)
+			return(CONTINUE);
+		/* fall thro */ 
+	case(SNDFILE):
+// TW MOVED THIS HERE : June 2004
+		if(fp2->channels != fp1->channels)
+			return(CONTINUE);
+		if(fp2->srate != fp1->srate)
+			return(CONTINUE);
+		if(fp2->stype != fp1->stype)
+			return(CONTINUE);
+		break;
+	case(ENVFILE):
+		if(fp2->window_size != fp1->window_size)
+			return(CONTINUE);
+		break;
+	default:
+		sprintf(errstr,"Inaccessible case in compare_properties_for_bundling()\n");
+		return(PROGRAM_ERROR);
+	}
+	return(FINISHED);
+}
+
+/**************************** DO_FILE_SORTING *****************************/
+
+int do_file_sorting(dataptr dz)
+{
+	int exit_status;
+	int  n;
+	int a_srate = 0;
+	double sum;
+	int  infilecnt = dz->all_words-1;
+	int  fileno = 0, namestoresize = 0;
+	char *filename = dz->wordstor[infilecnt];	/* name of input list file */
+	char *monofile=NULL,     *stereofile = NULL, *analfile = NULL, *quadfile = NULL;
+	char *pitchfile = NULL,  *transfile = NULL,  *formantfile = NULL;
+	char *envfile = NULL,    *otherfile  = NULL, *namestore  = NULL;
+	int  *posstore   = NULL;
+	int  *lcnt       = NULL;
+	char ***lstore   = NULL;
+ 	double *lenstore = NULL;
+ 	double *sortlens = NULL;
+#ifdef NOTDEF
+    char *file48 = ENDOFSTR, *file44 = ENDOFSTR, *file32 = ENDOFSTR;
+    char *file24 = ENDOFSTR, *file22 = ENDOFSTR, *file16 = ENDOFSTR;
+#else
+    char *file48 = NULL, *file44 = NULL, *file32 = NULL;
+    char *file24 = NULL, *file22 = NULL, *file16 = NULL;
+#endif
+	int is_file48=FALSE, is_file44=FALSE, is_file32=FALSE, is_file24=FALSE, is_file22=FALSE, is_file16=FALSE;
+	int is_mono_list=FALSE,  is_stereo_list=FALSE,is_quad_list=FALSE, is_anal_list=FALSE,is_pitch_list=FALSE;
+	int is_trans_list=FALSE, is_fmnt_list=FALSE,  is_env_list=FALSE, is_other_list=FALSE;
+	FILE *fp48 = NULL, *fp44 = NULL, *fp32 = NULL, *fp24 = NULL, *fp22 = NULL, *fp16 = NULL, 
+	    *fpm = NULL, *fps = NULL, *fpa = NULL, *fpp = NULL, *fpt = NULL, *fpf = NULL, *fpe = NULL, *fpo = NULL, *fpq = NULL;
+	char *p;
+	int done_errmsg = 0;
+
+	switch(dz->mode) {
+	case(BY_DURATION):	
+	case(BY_LOG_DUR):	
+		if((lcnt = (int *)malloc((dz->iparam[SORT_LENCNT]+1) * sizeof(int)))==NULL) {
+			sprintf(errstr,"INSUFFICIENT MEMORY for lcnt store.\n");
+			return(MEMORY_ERROR);
+		}
+		if((sortlens  = (double *)malloc(dz->iparam[SORT_LENCNT] * sizeof(double)))==NULL) {
+			sprintf(errstr,"INSUFFICIENT MEMORY for lens store.\n");
+			return(MEMORY_ERROR);
+		}
+		sum = dz->param[SORT_SMALL];
+		for(n=0;n<dz->iparam[SORT_LENCNT];n++) {
+			lcnt[n] = 0;				
+			sortlens[n] = sum;
+			if(dz->mode==BY_LOG_DUR)
+				sum *= dz->param[SORT_STEP];
+			else
+				sum += dz->param[SORT_STEP];
+		}
+		lcnt[dz->iparam[SORT_LENCNT]] = 0;
+		sortlens[dz->iparam[SORT_LENCNT]-1] = dz->param[SORT_LARGE];
+		dz->iparam[SORT_LENCNT]++;
+		/* fall thro */
+	case(IN_DUR_ORDER):	
+	   	if((lstore = (char ***)malloc((dz->iparam[SORT_LENCNT]+1) * sizeof(char **)))==NULL) {
+			sprintf(errstr,"INSUFFICIENT MEMORY for length store.\n");
+			return(MEMORY_ERROR);
+		}
+		for(n=0;n<dz->iparam[SORT_LENCNT]+1;n++) {
+// AVOID realloc
+			if((lstore[n] = (char **)malloc(infilecnt * sizeof(char *)))==NULL) {
+				sprintf(errstr,"INSUFFICIENT MEMORY for length store %d.\n",n+1);
+				return(MEMORY_ERROR);
+			}
+		}
+		break;
+	}
+	strip_extension(filename);
+	if(sloom && (dz->mode == BY_FILETYPE || dz->mode == BY_SRATE)) {
+		p = filename + strlen(filename) - 1;		/* Strip trailing zero from generic tempfilename */
+		*p = ENDOFSTR;
+	}
+	for(n=0;n<infilecnt;n++) {
+		if(!strcmp(dz->wordstor[infilecnt],dz->wordstor[n])) {
+			sprintf(errstr,"The name of the listfile cannot be included in the listing!!\n");
+			return(DATA_ERROR);
+		}
+	}
+// AVOID realloc
+	for(n=0;n<infilecnt;n++)
+		namestoresize += strlen(dz->wordstor[n]) + 1;
+	if((namestore = (char *)malloc(namestoresize * sizeof(char)))==NULL) {
+		sprintf(errstr,"INSUFFICIENT MEMORY for name store.\n");
+		return(MEMORY_ERROR);
+	}
+	namestoresize = 0;
+	for(n=0;n<infilecnt;n++) {
+	    if((dz->ifd[0] = sndopenEx(dz->wordstor[n],0,CDP_OPEN_RDONLY)) < 0) 	{
+			if(dz->mode!=BY_FILETYPE)  {
+				if(!done_errmsg) {
+					sprintf(errstr,"Some files are NOT soundfiles.\n");
+					print_outmessage_flush(errstr);
+					done_errmsg = 1;
+				}
+			}
+			dz->ifd[0] = -1;
+			continue;
+		} else if((dz->mode!=BY_FILETYPE) && filename_extension_is_not_sound(dz->wordstor[n])) {
+			if(!done_errmsg) {
+				sprintf(errstr,"Some files are NOT soundfiles.\n");
+				print_outmessage_flush(errstr);
+				done_errmsg = 1;
+			}
+			continue;
+		}
+		switch(dz->mode) {
+		case(BY_SRATE):		
+			if((exit_status = do_srates(filename,dz->wordstor[n],&file48,&file44,&file32,&file24,&file22,&file16,
+			&is_file48,&is_file44,&is_file32,&is_file24,&is_file22,&is_file16,
+			&fp48,&fp44,&fp32,&fp24,&fp22,&fp16,dz))<0)
+				return(exit_status);
+			break;
+		case(BY_DURATION):	
+		case(BY_LOG_DUR):	
+			if((exit_status = do_lenths(filename,dz->wordstor[n],&namestore,lstore,&namestoresize,lcnt,sortlens,dz))<0)
+				return(exit_status);
+			break;
+		case(IN_DUR_ORDER):	
+			if((exit_status = do_order
+			(filename,dz->wordstor[n],&namestore,&lenstore,&posstore,&lstore,&fileno,&namestoresize,dz))<0)
+				return(exit_status);
+			break;
+		case(BY_FILETYPE):	
+			if((exit_status = do_types(filename,dz->wordstor[n],
+			&monofile,&stereofile,&quadfile,&analfile,&pitchfile,&transfile,&formantfile,&envfile,&otherfile,
+			&is_mono_list,&is_stereo_list,&is_quad_list,&is_anal_list,
+			&is_pitch_list,&is_trans_list,&is_fmnt_list,&is_env_list,&is_other_list,
+			&fpm,&fps,&fpa,&fpp,&fpt,&fpf,&fpe,&fpo,&fpq,dz))<0)
+				return(exit_status);
+			break;
+		case(FIND_ROGUES):	
+			do_rogues(dz->wordstor[n],&a_srate,dz);
+			break;
+		}
+
+		if(dz->ifd[0]!=-1 && sndcloseEx(dz->ifd[0])<0)
+			fprintf(stdout,"WARNING: Failed to close sndfile %s.\n",dz->wordstor[n]);
+		dz->ifd[0] = -1;
+	}
+	switch(dz->mode) {
+	case(BY_LOG_DUR):
+	case(BY_DURATION):	
+		if((exit_status = output_lenths(filename,&otherfile,lstore,sortlens,lcnt,dz))<0)
+			return(exit_status);
+		break;
+ 	case(BY_SRATE):		
+ 		output_srates(is_file48,is_file44,is_file32,is_file24,is_file22,is_file16,
+		file48,	file44,file32,file24,file22,file16);						
+		break;
+ 	case(IN_DUR_ORDER):	
+ 		if((exit_status = output_order(filename,&otherfile,posstore,lenstore,lstore,fileno,dz))<0)
+			return(exit_status);
+ 		break;
+	case(BY_FILETYPE):	
+		output_types(filename,is_mono_list,is_stereo_list,is_quad_list,
+		is_anal_list,is_pitch_list,is_trans_list,is_fmnt_list,is_env_list,
+		is_other_list,monofile,stereofile,quadfile,analfile,pitchfile,
+		transfile,formantfile,envfile,otherfile);							
+		break;
+
+	}
+	fflush(stdout);
+	return(FINISHED);
+}
+
+/********************* READ_AND_SORT_PROPERTIES **********************/
+
+int read_and_sort_properties(char *infilename,dataptr dz)
+{
+	int ttype = IS_MONO, exit_status;
+	double maxamp, maxloc;
+	int maxrep;
+	int getmax = 0, getmaxinfo = 0;
+	infileptr ifp;
+	if((ifp = (infileptr)malloc(sizeof(struct filedata)))==NULL) {
+		sprintf(errstr,"INSUFFICIENT MEMORY to store data on files.\n");
+		return(MEMORY_ERROR);
+	}
+	if((exit_status = readhead(ifp,dz->ifd[0],infilename,&maxamp,&maxloc,&maxrep,getmax,getmaxinfo))<0)
+		return(exit_status);
+	copy_to_fileptr(ifp,dz->infile);
+
+	if(dz->infile->filetype != SNDFILE)	{
+		switch(dz->infile->filetype) {
+		case(PITCHFILE):	return(IS_PITCH);
+		case(TRANSPOSFILE):	return(IS_TRANSPOS);
+		case(FORMANTFILE):	return(IS_FMNT);
+		case(ENVFILE):		return(IS_ENV);
+		case(ANALFILE):		return(IS_ANAL);
+		default:
+			sprintf(errstr,"This program only works with sound files or CDP-derived files.\n");
+			return(DATA_ERROR);
+		}
+    }
+	if(dz->infile->channels==2)
+		ttype = IS_STEREO;
+	else if(dz->infile->channels==4)
+		ttype = IS_QUAD;
+ 	else if(dz->infile->channels != 1) {
+		sprintf(errstr,"Program accepts sndfiles which are mono, stereo or quad, only.\n");
+		return(DATA_ERROR);
+    }
+    return(ttype);
+}
+
+/********************* DO_SRATES *********************/ 
+
+int do_srates(char *infilename,char *thisfilename,
+char **file48,char **file44,char **file32,char **file24,char **file22,char **file16,
+int *is_file48,int *is_file44,int *is_file32,int *is_file24,int *is_file22,int *is_file16,
+FILE **fp48,FILE **fp44,FILE **fp32,FILE **fp24,FILE **fp22,FILE **fp16,dataptr dz)
+{
+	char temp[4];
+	switch(read_srate(thisfilename,dz)) {
+	case(48):		
+		if(!*is_file48) {
+			if((*file48 = (char *)malloc((strlen(infilename)+5) * sizeof(char)))==NULL) {
+				sprintf(errstr,"INSUFFICIENT MEMORY from srate 48000 filename.\n");
+				return(MEMORY_ERROR);
+			}
+			strcpy(*file48,infilename);
+			if(sloom) {
+				sprintf(temp,"%d",outfcnt);
+				strcat(*file48,temp);				
+				outfcnt++;
+			} else
+				strcat(*file48,".48");				
+			if((*fp48 = fopen(*file48,"w"))==NULL) {
+				sprintf(errstr,"Cannot open file '%s' to write list of 48000 files.\n",*file48);
+				return(SYSTEM_ERROR);
+			}
+			*is_file48 = TRUE;
+		}
+		fprintf(*fp48,"%s\n",thisfilename);
+		break;
+	case(44):		
+		if(!*is_file44) {
+			if((*file44 = (char *)malloc((strlen(infilename)+5) * sizeof(char)))==NULL) {
+				sprintf(errstr,"INSUFFICIENT MEMORY from srate 44100 filename.\n");
+				return(MEMORY_ERROR);
+			}
+			strcpy(*file44,infilename);
+			if(sloom) {
+				sprintf(temp,"%d",outfcnt);
+				strcat(*file44,temp);				
+				outfcnt++;
+			} else
+				strcat(*file44,".44");				
+			if((*fp44 = fopen(*file44,"w"))==NULL) {
+				sprintf(errstr,"Cannot open file '%s' to write list of 44100 files.\n",*file44);
+				return(SYSTEM_ERROR);
+			}
+			*is_file44 = TRUE;
+		}
+		fprintf(*fp44,"%s\n",thisfilename);
+		break;
+	case(32):			
+		if(!*is_file32) {
+			if((*file32 = (char *)malloc((strlen(infilename)+5) * sizeof(char)))==NULL) {
+				sprintf(errstr,"INSUFFICIENT MEMORY from srate 32000 filename.\n");
+				return(MEMORY_ERROR);
+			}
+			strcpy(*file32,infilename);
+			if(sloom) {
+				sprintf(temp,"%d",outfcnt);
+				strcat(*file32,temp);				
+				outfcnt++;
+			} else
+				strcat(*file32,".32");
+			if((*fp32 = fopen(*file32,"w"))==NULL) {
+				sprintf(errstr,"Cannot open file '%s' to write list of 32000 files.\n",*file32);
+				return(SYSTEM_ERROR);
+			}
+			*is_file32 = TRUE;
+		}
+		fprintf(*fp32,"%s\n",thisfilename);
+		break;
+	case(24):			
+		if(!*is_file24) {
+			if((*file24 = (char *)malloc((strlen(infilename)+5) * sizeof(char)))==NULL) {
+				sprintf(errstr,"INSUFFICIENT MEMORY from srate 24000 filename.\n");
+				return(MEMORY_ERROR);
+			}
+			strcpy(*file24,infilename);
+			if(sloom) {
+				sprintf(temp,"%d",outfcnt);
+				strcat(*file24,temp);				
+				outfcnt++;
+			} else
+				strcat(*file24,".24");				
+			if((*fp24 = fopen(*file24,"w"))==NULL) {
+				sprintf(errstr,"Cannot open file '%s' to write list of 24000 files.\n",*file24);
+				return(SYSTEM_ERROR);
+			}
+			*is_file24 = TRUE;
+		}
+		fprintf(*fp24,"%s\n",thisfilename);
+		break;
+	case(22):			
+		if(!*is_file22) {
+			if((*file22 = (char *)malloc((strlen(infilename)+5) * sizeof(char)))==NULL) {
+				sprintf(errstr,"INSUFFICIENT MEMORY from srate 22050 filename.\n");
+				return(MEMORY_ERROR);
+			}
+			strcpy(*file22,infilename);
+			if(sloom) {
+				sprintf(temp,"%d",outfcnt);
+				strcat(*file22,temp);				
+				outfcnt++;
+			} else
+				strcat(*file22,".22");				
+			if((*fp22 = fopen(*file22,"w"))==NULL) {
+				sprintf(errstr,"Cannot open file '%s' to write list of 22050 files.\n",*file22);
+				return(SYSTEM_ERROR);
+			}
+			*is_file22 = TRUE;
+		}
+		fprintf(*fp22,"%s\n",thisfilename);
+		break;
+	case(16):		
+		if(!*is_file16) {
+			if((*file16 = (char *)malloc((strlen(infilename)+5) * sizeof(char)))==NULL) {
+				sprintf(errstr,"INSUFFICIENT MEMORY from srate 16000 filename.\n");
+				return(MEMORY_ERROR);
+			}
+			strcpy(*file16,infilename);
+			if(sloom) {
+				sprintf(temp,"%d",outfcnt);
+				strcat(*file16,temp);				
+				outfcnt++;
+			} else
+				strcat(*file16,".16");				
+			if((*fp16 = fopen(*file16,"w"))==NULL) {
+				sprintf(errstr,"Cannot open file '%s' to write list of 16000 files.\n",*file16);
+				return(SYSTEM_ERROR);
+			}
+			*is_file16 = TRUE;
+		}
+		fprintf(*fp16,"%s\n",thisfilename);
+		break;
+	default:
+		sprintf(errstr,"Ignoring file '%s'\n",thisfilename);
+		print_outmessage_flush(errstr);
+		break;		 
+	}
+	return(FINISHED);
+}
+
+/********************* DO_ROGUES **********************/
+
+void do_rogues(char *infilename,int *a_srate,dataptr dz)
+{
+	if(read_special_type(dz)<0)
+		return;
+	if(read_srate(infilename,dz)<0)
+		return;
+	if(*a_srate==0)
+		*a_srate = dz->infile->srate;
+	else if(*a_srate!= dz->infile->srate) {
+		sprintf(errstr,"%s has different sampling rate [%d] to earlier file [%d]\n",
+		infilename,dz->infile->srate,*a_srate);
+		print_outmessage_flush(errstr);
+		return;
+	}
+	if(read_channels(infilename,dz)<0)
+		return;
+	get_length(infilename,dz);
+}
+
+/********************* READ_SRATE **********************/
+
+int read_srate(char *infilename,dataptr dz)
+{
+	int k;
+//TW CHANGED
+//  if(sfgetprop(dz->ifd[0], "sample rate", (char *)&dz->infile->srate, sizeof(int)) < 0) {
+    if(sndgetprop(dz->ifd[0], "sample rate", (char *)&dz->infile->srate, sizeof(int)) < 0) {
+		fprintf(stdout,"WARNING: Can't read sample rate from input soundfile %s\n",infilename);
+		return(-1);
+    }
+	k = (int)(dz->infile->srate/1000);
+    return(k);
+}
+
+/********************* READ_SPECIAL_TYPE **********************/
+
+int read_special_type(dataptr dz)
+{
+	int pppp = 0;
+//TW CHANGED TO sndgetprop THROUGHOUT
+    if(sndgetprop(dz->ifd[0], "is an envelope", (char *)&pppp, sizeof(int)) >=0) {
+		sprintf(errstr,"%s is an envelope file\n",snd_getfilename(dz->ifd[0]));
+		print_outmessage_flush(errstr);
+		return(-1);
+	}
+    if(sndgetprop(dz->ifd[0], "is a pitch file", (char *)&pppp, sizeof(int)) >=0) {
+		sprintf(errstr,"%s is a pitch file\n",snd_getfilename(dz->ifd[0]));
+		print_outmessage_flush(errstr);
+		return(-1);
+	}
+    if(sndgetprop(dz->ifd[0], "is a transpos file", (char *)&pppp, sizeof(int)) >=0) {
+		sprintf(errstr,"%s is a transposition file\n",snd_getfilename(dz->ifd[0]));
+		print_outmessage_flush(errstr);
+		return(-1);
+	}
+    if(sndgetprop(dz->ifd[0], "is a formant file", (char *)&pppp, sizeof(int)) >=0)	{
+		sprintf(errstr,"%s is a formant file\n",snd_getfilename(dz->ifd[0]));
+		print_outmessage_flush(errstr);
+		return(-1);
+	}
+    return(0);
+}
+
+/********************* READ_CHANNELS **********************/
+
+int read_channels(char *infilename,dataptr dz)
+{
+	int channels;
+//TW CHANGED 
+    if(sndgetprop(dz->ifd[0], "channels", (char *)&channels, sizeof(int)) < 0) {
+		fprintf(stdout,"WARNING: Can't read channels from input soundfile %s\n",infilename);
+		return(-1);
+    }
+	if(channels!=1 && channels!=2 && channels != 4) {
+		fprintf(stdout,"WARNING: Invalid channel count [%d] from input soundfile %s\n",channels,infilename);
+		return(-1);
+    }
+    return(0);
+}
+
+/********************* GET_LENGTH **********************/
+
+void get_length(char *infilename,dataptr dz)
+{
+	if((dz->insams[0] = sndsizeEx(dz->ifd[0]))<0) {
+		fprintf(stdout, "WARNING: Can't read size of input file %s.\n",infilename);
+		return;
+	}
+	if(dz->insams[0] <=0)
+		fprintf(stdout, "WARNING: No data in file %s.\n",infilename);
+}
+
+/********************* DO_LENTHS *********************/ 
+
+int do_lenths(char *infilename,char *thisfilename,char **namestore,char ***lstore,int *namestoresize,
+				int *lcnt,double *sortlens,dataptr dz)
+{
+	int exit_status;
+	int	k, thislen;
+	double d;
+	char *namestoreend;
+	if((exit_status = read_and_sort_properties(thisfilename,dz))<0)
+		return(exit_status);
+	if((dz->insams[0] = sndsizeEx(dz->ifd[0]))<0) {
+		sprintf(errstr, "Can't read size of input file %s.\n",infilename);
+		return(PROGRAM_ERROR);
+	}
+	d = (double)(dz->insams[0]/dz->infile->channels)/(double)dz->infile->srate;
+	for(k=0;k<dz->iparam[SORT_LENCNT]-1;k++) {
+		if(d<sortlens[k])
+			break;
+	}
+	thislen = strlen(thisfilename)+1;
+	namestoreend = *namestore + *namestoresize;
+	*namestoresize += thislen;
+	strcpy(namestoreend,thisfilename);
+	lstore[k][lcnt[k]] = namestoreend;
+	lcnt[k]++;
+	return(FINISHED);
+}
+
+/********************* CREATE_LFILE *********************/
+
+int create_lfile(char *infilename,char **otherfile,char ***lstore,double *sortlens,int *lcnt,dataptr dz)
+{
+	int n, m;
+	FILE *fpo;
+	if((*otherfile = (char *)malloc((strlen(infilename)+5) * sizeof(char)))==NULL) {
+		sprintf(errstr,"INSUFFICIENT MEMORY from otherfile name.\n");
+		return(MEMORY_ERROR);
+	}
+	strcpy(*otherfile,infilename);
+	if(!sloom)
+		strcat(*otherfile,".len");
+	if((fpo = fopen(*otherfile,"w"))==NULL) {
+		sprintf(errstr,"Cannot open file %s to write data\n",*otherfile);
+		return(SYSTEM_ERROR);
+	}
+	for(n=0;n<dz->iparam[SORT_LENCNT]-1;n++) {
+		if(lcnt[n]) {
+			if(dz->vflag[DONT_SHOW_DURS]) {
+				fprintf(fpo,   "\n");
+				sprintf(errstr,"\n");
+				print_outmessage(errstr);
+			}else {
+				fprintf(fpo,   "\n%d Files <= %.3lf secs\n",lcnt[n],sortlens[n]);
+				sprintf(errstr,"%d Files <= %.3lf secs\n",lcnt[n],sortlens[n]);
+				print_outmessage(errstr);
+			} for(m=0;m<lcnt[n];m++) {
+				fprintf(fpo,   "%s\n",lstore[n][m]);
+				sprintf(errstr,"%s\n",lstore[n][m]);
+				print_outmessage(errstr);
+			}
+		}
+	}
+	fflush(stdout);
+	if(lcnt[n]) {
+		if(dz->vflag[DONT_SHOW_DURS]) {
+			fprintf(fpo,   "\n");
+			sprintf(errstr,"\n");
+			print_outmessage(errstr);
+		} else {
+			fprintf(fpo,   "\n%d Files > %.3lf secs\n",lcnt[n],sortlens[n-1]);
+			sprintf(errstr,"%d Files > %.3lf secs\n",lcnt[n],sortlens[n-1]);
+			print_outmessage(errstr);
+		}
+		for(m=0;m<lcnt[n];m++) {
+			fprintf(fpo   ,"%s\n",lstore[n][m]);
+			sprintf(errstr,"%s\n",lstore[n][m]);
+			print_outmessage(errstr);
+		}
+	}
+	fflush(stdout);
+	if(fclose(fpo)<0) {
+		fprintf(stdout,"WARNING: Failed to close output textfile.\n");
+		fflush(stdout);
+	} 
+	return(FINISHED);
+}
+
+/********************* CREATE_OFILE *********************/
+
+int create_ofile(char *infilename,char **otherfile,int cnt,char ***lstore,double *lenstore,int *posstore,dataptr dz)
+{
+	int n, m;
+	int spacesize = 32, thisspace;
+	char *p;
+	FILE *fpo;
+	if((*otherfile = (char *)malloc((strlen(infilename)+5) * sizeof(char)))==NULL) {
+		sprintf(errstr,"INSUFFICIENT MEMORY from otherfile name.\n");
+		return(MEMORY_ERROR);
+	}
+	strcpy(*otherfile,infilename);
+	if(!sloom)
+		strcat(*otherfile,".len");
+	if((fpo = fopen(*otherfile,"w"))==NULL) {
+		sprintf(errstr,"Cannot open file %s to write data\n",*otherfile);
+		return(SYSTEM_ERROR);
+	}
+	if(dz->vflag[DONT_SHOW_DURS]) {
+		for(n=0;n<cnt;n++) {
+			fprintf(fpo,   "%s\n",lstore[0][posstore[n]]);
+			sprintf(errstr,"%s\n",lstore[0][posstore[n]]);
+			print_outmessage(errstr);
+		}
+	} else {
+		for(n=0;n<cnt;n++) {
+
+			sprintf(errstr,"%.6lf secs",lenstore[n]);
+			thisspace = spacesize - strlen(errstr);
+			for(m=0;m<thisspace;m++)
+				strcat(errstr," ");
+			p = errstr + strlen(errstr);
+			sprintf(p,"%s\n",lstore[0][posstore[n]]);
+			fprintf(fpo,"%s",errstr);
+			print_outmessage(errstr);
+		}
+	}
+	fflush(stdout);
+	if(fclose(fpo)<0) {
+		fprintf(stdout,"WARNING: Failed to close output textfile.\n");
+		fflush(stdout);
+	}
+	return(FINISHED);
+}
+
+/********************* DO_TYPES *********************/
+
+int do_types(char *infilename, char *thisfilename,char **monofile,char **stereofile,char **quadfile,
+			char **analfile,char **pitchfile, char **transfile,char **formantfile,char **envfile,char **otherfile,
+			int *is_mono_list,int *is_stereo_list,int *is_quad_list,int *is_anal_list,int *is_pitch_list,
+			int *is_trans_list,int *is_fmnt_list,int *is_env_list,int *is_other_list,
+			FILE **fpm,FILE **fps,FILE **fpa,FILE **fpp,FILE **fpt,FILE **fpf,
+			FILE **fpe,FILE **fpo,FILE **fpq,dataptr dz)
+{
+	char temp[4];
+	if(dz->ifd[0]==-1) {
+		if(!*is_other_list) {
+			if((*otherfile = (char *)malloc((strlen(infilename)+5) * sizeof(char)))==NULL) {
+				sprintf(errstr,"INSUFFICIENT MEMORY from forman file name.\n");
+				return(MEMORY_ERROR);
+			}
+			strcpy(*otherfile,infilename);
+			if(sloom) {
+				sprintf(temp,"%d",outfcnt);
+				strcat(*otherfile,temp);				
+				outfcnt++;
+			} else
+				strcat(*otherfile,".ott");				
+			if((*fpo = fopen(*otherfile,"w"))==NULL) {
+				sprintf(errstr,"Cannot open file '%s' to write list of other data files.\n",*otherfile);
+				return(SYSTEM_ERROR);
+			}
+			*is_other_list = TRUE;
+		}
+		fprintf(*fpo,"%s\n",thisfilename);
+		return(FINISHED);
+	}
+	switch(read_and_sort_properties(thisfilename,dz)) {
+	case(IS_MONO):			/* Mono   sndfile */
+		if(!*is_mono_list) {
+			if((*monofile = (char *)malloc((strlen(infilename)+5) * sizeof(char)))==NULL) {
+				sprintf(errstr,"INSUFFICIENT MEMORY from monofile name.\n");
+				return(MEMORY_ERROR);
+			}
+			strcpy(*monofile,infilename);
+			if(sloom) {
+				sprintf(temp,"%d",outfcnt);
+				strcat(*monofile,temp);				
+				outfcnt++;
+			} else
+				strcat(*monofile,".mot");				
+			if((*fpm = fopen(*monofile,"w"))==NULL) {
+				sprintf(errstr,"Cannot open file '%s' to write list of mono files.\n",*monofile);
+				return(SYSTEM_ERROR);
+			}
+			*is_mono_list = TRUE;
+		}
+		fprintf(*fpm,"%s\n",thisfilename);
+		break;
+	case(IS_STEREO):		/* Stereo sndfile */
+		if(!*is_stereo_list) {
+			if((*stereofile = (char *)malloc((strlen(infilename)+5) * sizeof(char)))==NULL) {
+				sprintf(errstr,"INSUFFICIENT MEMORY from stereofile name.\n");
+				return(MEMORY_ERROR);
+			}
+			strcpy(*stereofile,infilename);
+			if(sloom) {
+				sprintf(temp,"%d",outfcnt);
+				strcat(*stereofile,temp);				
+				outfcnt++;
+			} else
+				strcat(*stereofile,".stt");				
+			if((*fps = fopen(*stereofile,"w"))==NULL) {
+				sprintf(errstr,"Cannot open file '%s' to write list of stereo files.\n",*stereofile);
+				return(SYSTEM_ERROR);
+			}
+			*is_stereo_list = TRUE;
+		}
+		fprintf(*fps,"%s\n",thisfilename);
+		break;
+	case(IS_QUAD):		/* Quad sndfile */
+		if(!*is_quad_list) {
+			if((*quadfile = (char *)malloc((strlen(infilename)+5) * sizeof(char)))==NULL) {
+				sprintf(errstr,"INSUFFICIENT MEMORY from quadfile name.\n");
+				return(MEMORY_ERROR);
+			}
+			strcpy(*quadfile,infilename);
+			if(sloom) {
+				sprintf(temp,"%d",outfcnt);
+				strcat(*quadfile,temp);				
+				outfcnt++;
+			} else
+				strcat(*quadfile,".qdt");				
+			if((*fpq = fopen(*quadfile,"w"))==NULL) {
+				sprintf(errstr,"Cannot open file '%s' to write list of quad files.\n",*quadfile);
+				return(SYSTEM_ERROR);
+			}
+			*is_quad_list = TRUE;
+		}
+		fprintf(*fpq,"%s\n",thisfilename);
+		break;
+	case(IS_ANAL):			/* Analysis file */
+		if(!*is_anal_list) {
+			if((*analfile = (char *)malloc((strlen(infilename)+5) * sizeof(char)))==NULL) {
+				sprintf(errstr,"INSUFFICIENT MEMORY from analfile name.\n");
+				return(MEMORY_ERROR);
+			}
+			strcpy(*analfile,infilename);
+			if(sloom) {
+				sprintf(temp,"%d",outfcnt);
+				strcat(*analfile,temp);				
+				outfcnt++;
+			} else
+				strcat(*analfile,".ant");				
+			if((*fpa = fopen(*analfile,"w"))==NULL) {
+				sprintf(errstr,"Cannot open file '%s' to write list of analysis files.\n",*analfile);
+				return(SYSTEM_ERROR);
+			}
+			*is_anal_list = TRUE;
+		}
+		fprintf(*fpa,"%s\n",thisfilename);
+		break;
+	case(IS_PITCH):			/* Pitch data file */
+		if(!*is_pitch_list) {
+			if((*pitchfile = (char *)malloc((strlen(infilename)+5) * sizeof(char)))==NULL) {
+				sprintf(errstr,"INSUFFICIENT MEMORY from pitchfile name.\n");
+				return(MEMORY_ERROR);
+			}
+			strcpy(*pitchfile,infilename);
+			if(sloom) {
+				sprintf(temp,"%d",outfcnt);
+				strcat(*pitchfile,temp);				
+				outfcnt++;
+			} else
+				strcat(*pitchfile,".pct");				
+			if((*fpp = fopen(*pitchfile,"w"))==NULL) {
+				sprintf(errstr,"Cannot open file '%s' to write list of pitchdata files.\n",*pitchfile);
+				return(SYSTEM_ERROR);
+			}
+			*is_pitch_list = TRUE;
+		}
+		fprintf(*fpp,"%s\n",thisfilename);
+		break;
+	case(IS_TRANSPOS):			/* Transposition data file */
+		if(!*is_trans_list) {
+			if((*transfile = (char *)malloc((strlen(infilename)+5) * sizeof(char)))==NULL) {
+				sprintf(errstr,"INSUFFICIENT MEMORY from transposition file name.\n");
+				return(MEMORY_ERROR);
+			}
+			strcpy(*transfile,infilename);
+			if(sloom) {
+				sprintf(temp,"%d",outfcnt);
+				strcat(*transfile,temp);				
+				outfcnt++;
+			} else
+				strcat(*transfile,".trt");				
+			if((*fpt = fopen(*transfile,"w"))==NULL) {
+				sprintf(errstr,"Cannot open file '%s' to write list of transposition data files.\n",*transfile);
+				return(SYSTEM_ERROR);
+			}
+			*is_trans_list = TRUE;
+		}
+		fprintf(*fpt,"%s\n",thisfilename);
+		break;
+	case(IS_FMNT):			/* Formant Data file */
+		if(!*is_fmnt_list) {
+			if((*formantfile = (char *)malloc((strlen(infilename)+5) * sizeof(char)))==NULL) {
+				sprintf(errstr,"INSUFFICIENT MEMORY from forman file name.\n");
+				return(MEMORY_ERROR);
+			}
+			strcpy(*formantfile,infilename);
+			if(sloom) {
+				sprintf(temp,"%d",outfcnt);
+				strcat(*formantfile,temp);				
+				outfcnt++;
+			} else
+				strcat(*formantfile,".fot");				
+			if((*fpf = fopen(*formantfile,"w"))==NULL) {
+				sprintf(errstr,"Cannot open file '%s' to write list of formant data files.\n",*formantfile);
+				return(SYSTEM_ERROR);
+			}
+			*is_fmnt_list = TRUE;
+		}
+		fprintf(*fpf,"%s\n",thisfilename);
+		break;
+	case(IS_ENV):			/* Formant Data file */
+		if(!*is_env_list) {
+			if((*envfile = (char *)malloc((strlen(infilename)+5) * sizeof(char)))==NULL) {
+				sprintf(errstr,"INSUFFICIENT MEMORY from other file name.\n");
+				return(MEMORY_ERROR);
+			}
+			strcpy(*envfile,infilename);
+			if(sloom) {
+				sprintf(temp,"%d",outfcnt);
+				strcat(*envfile,temp);				
+				outfcnt++;
+			} else
+				strcat(*envfile,".ett");				
+			if((*fpe = fopen(*envfile,"w"))==NULL) {
+				sprintf(errstr,"Cannot open file '%s' to write list of formant data files.\n",*envfile);
+				return(SYSTEM_ERROR);
+			}
+			*is_env_list = TRUE;
+		}
+		fprintf(*fpe,"%s\n",thisfilename);
+		break;
+	default:
+		sprintf(errstr,"Unknown case in do_types()\n");
+		return(PROGRAM_ERROR);
+	}
+	return(FINISHED);
+}
+
+/********************* OUTPUT_LENTHS *********************/
+//TW REVISED
+int output_lenths(char *infilename,char **otherfile,char ***lstore,double *sortlens,int *lcnt,dataptr dz)
+{
+	int  exit_status;
+	int n, sum = 0;
+	for(n=0;n<dz->iparam[SORT_LENCNT];n++)
+		sum += lcnt[n];
+	if(sum==0) {
+		sprintf(errstr,"NO VALID FILES FOUND.\n");
+		print_outmessage(errstr);
+	} else {
+		if((exit_status = create_lfile(infilename,otherfile,lstore,sortlens,lcnt,dz))<0)
+			return(exit_status);
+//TW UPDATE
+		if(!sloom && !sloombatch)
+			fprintf(stdout,"\nCREATED SORT FILE '%s'\n",*otherfile);
+		else {
+			fprintf(stdout,"INFO: \n");
+			fprintf(stdout,"INFO: CREATED SORT FILE '%s'\n",*otherfile);
+		}
+	}
+	fflush(stdout);
+ 	return(FINISHED);
+ }
+
+/********************* OUTPUT_SRATES *********************/
+
+void output_srates(int is_file48,int is_file44,int is_file32,int is_file24,int is_file22,int is_file16,
+				   char *file48,char *file44,char *file32,char *file24,char *file22,char *file16)
+{
+	if(!is_file48 && !is_file44 && !is_file32 
+	&& !is_file24 && !is_file22 && !is_file16) {
+		sprintf(errstr,"NO SORT FILES CREATED.\n");
+		print_outmessage(errstr);
+	} else {
+//TW UPDATE
+		if(!sloom && !sloombatch)
+			fprintf(stdout,"\nCREATED SORT FILES....\n");
+		else {
+			fprintf(stdout,"INFO: \n");
+			fprintf(stdout,"INFO: CREATED SORT FILES....\n");
+		}
+//TW UPDATE
+		if(!sloom && !sloombatch) {
+			if(is_file48)   		fprintf(stdout,"%s\n",file48);
+			if(is_file44)   		fprintf(stdout,"%s\n",file44);
+			if(is_file32)   		fprintf(stdout,"%s\n",file32);
+			if(is_file24)   		fprintf(stdout,"%s\n",file24);
+			if(is_file22)   		fprintf(stdout,"%s\n",file22);
+			if(is_file16)   		fprintf(stdout,"%s\n",file16);
+		} else {
+			if(is_file48)   		fprintf(stdout,"INFO: %s LISTING FILES OF SAMPLE RATE 48000\n",file48);
+			if(is_file44)   		fprintf(stdout,"INFO: %s LISTING FILES OF SAMPLE RATE 44100\n",file44);
+			if(is_file32)   		fprintf(stdout,"INFO: %s LISTING FILES OF SAMPLE RATE 32000\n",file32);
+			if(is_file24)   		fprintf(stdout,"INFO: %s LISTING FILES OF SAMPLE RATE 24000\n",file24);
+			if(is_file22)   		fprintf(stdout,"INFO: %s LISTING FILES OF SAMPLE RATE 22050\n",file22);
+			if(is_file16)   		fprintf(stdout,"INFO: %s LISTING FILES OF SAMPLE RATE 16000\n",file16);
+		}
+	}
+	fflush(stdout);
+}
+
+/********************* OUTPUT_TYPES *********************/
+
+void output_types(char *infilename,int is_mono_list,int is_stereo_list,int is_quad_list,
+				int is_anal_list,int is_pitch_list,
+				int is_trans_list,int is_fmnt_list,int is_env_list,int is_other_list,
+				char *monofile,char *stereofile,char *quadfile,char *analfile,char *pitchfile,char *transfile,
+				char *formantfile,char *envfile,char *otherfile)
+{
+	if(!is_mono_list && !is_stereo_list && !is_quad_list && !is_anal_list 
+	&& !is_pitch_list && !is_trans_list && !is_fmnt_list && !is_env_list) {
+		if(!is_other_list) {
+			sprintf(errstr,"NO SORT FILES CREATED.\n");
+			print_outmessage(errstr);
+		} else {
+			sprintf(errstr,"NO VALID FILES FOUND : see '%s.ott' for files recognised.\n",infilename);
+			print_outmessage(errstr);
+		}			
+	} else {
+//TW UPDATE
+		if(!sloom && !sloombatch)
+			fprintf(stdout,"\nCREATED SORT FILES....\n");
+		else {
+			fprintf(stdout,"INFO: \n");
+			fprintf(stdout,"INFO: CREATED SORT FILES....\n");
+		}
+
+//TW UPDATE
+		if(!sloom && !sloombatch) {
+			if(is_mono_list)  	fprintf(stdout,"%s\n",monofile);		
+			if(is_stereo_list)	fprintf(stdout,"%s\n",stereofile);		
+			if(is_quad_list)  	fprintf(stdout,"%s\n",quadfile);		
+			if(is_anal_list)  	fprintf(stdout,"%s\n",analfile);		
+			if(is_pitch_list) 	fprintf(stdout,"%s\n",pitchfile);			
+			if(is_trans_list) 	fprintf(stdout,"%s\n",transfile);			
+			if(is_fmnt_list)  	fprintf(stdout,"%s\n",formantfile);	
+			if(is_env_list)   	fprintf(stdout,"%s\n",envfile);
+			if(is_other_list) 	fprintf(stdout,"%s\n",otherfile);
+		} else {
+			if(is_mono_list)  	fprintf(stdout,"INFO: %s of MONO SNDFILES.\n",monofile);		
+			if(is_stereo_list)	fprintf(stdout,"INFO: %s of STEREO SNDFILES.\n",stereofile);		
+			if(is_quad_list)  	fprintf(stdout,"INFO: %s of QUAD SNDFILES.\n",quadfile);		
+			if(is_anal_list)  	fprintf(stdout,"INFO: %s of ANALYSIS FILES.\n",analfile);		
+			if(is_pitch_list) 	fprintf(stdout,"INFO: %s of BINARY PITCH FILES.\n",pitchfile);			
+			if(is_trans_list) 	fprintf(stdout,"INFO: %s of BINARY TRANSPOSITION FILES.\n",transfile);			
+			if(is_fmnt_list)  	fprintf(stdout,"INFO: %s of FORMANT FILES.\n",formantfile);	
+			if(is_env_list)   	fprintf(stdout,"INFO: %s of BINARY ENVELOPE FILES.\n",envfile);
+			if(is_other_list) 	fprintf(stdout,"INFO: %s of TEXT FILES.\n",otherfile);
+		}
+	}
+	fflush(stdout);
+}
+
+/********************* STRIP_EXTENSION *********************/
+
+void strip_extension(char *filename)
+{
+	char *p;
+	int OK = 0;
+	p = filename + strlen(filename) - 1;
+	while(*p!='.') {
+		if(--p==filename) {
+			OK = TRUE;
+			break;
+		}
+	}
+	if(!OK)
+		*p = ENDOFSTR;
+}
+
+/********************* TEST_LENVALS *********************/
+
+int sort_preprocess(dataptr dz)
+{
+//	int cnt = 0;
+	double sum, lastsum;
+	switch(dz->mode) {
+	case(BY_DURATION):
+	case(BY_LOG_DUR):
+		dz->iparam[SORT_LENCNT] = 0;
+		if(flteq(dz->param[SORT_SMALL],dz->param[SORT_LARGE])) {
+			sprintf(errstr,"Parameters for durations are the same: can't proceed.\n");
+			return(DATA_ERROR);
+		}
+		if(dz->param[SORT_LARGE] < dz->param[SORT_SMALL]) {
+			fprintf(stdout,"WARNING: Duration parameters inverted: swapping them round.\n");
+			swap(&(dz->param[SORT_LARGE]),&(dz->param[SORT_SMALL]));
+		}
+		sum = dz->param[SORT_SMALL];
+		do {
+			lastsum = sum;
+			if(++dz->iparam[SORT_LENCNT] > MAXTYPES) {
+				sprintf(errstr,"Over %d length types: too many!!\n",MAXTYPES);
+				return(GOAL_FAILED);
+			}
+			if(dz->mode==BY_LOG_DUR)
+				sum *= dz->param[SORT_STEP];
+			else
+				sum += dz->param[SORT_STEP];
+		} while(sum < dz->param[SORT_LARGE]);
+		if(!flteq(lastsum,dz->param[SORT_LARGE])) {
+			if(++dz->iparam[SORT_LENCNT] > MAXTYPES) {
+				sprintf(errstr,"Over %d length types: too many!!\n",MAXTYPES);
+				return(GOAL_FAILED);
+			}
+		}
+		break;
+	}
+	return(FINISHED);
+}
+
+/********************* DO_ORDER *********************/ 
+
+int do_order(char *infilename,char *thisfilename,char **namestore,double **lenstore,int **posstore,
+			char ****lstore,int *fileno,int *namestoresize,dataptr dz)
+{
+	int  exit_status;
+	int n, m, thislen;
+	double d;
+	char *namestoreend;
+	if((exit_status = read_and_sort_properties(thisfilename,dz))<0)
+		return(exit_status);
+	if((dz->insams[0] = sndsizeEx(dz->ifd[0]))<0) {
+		sprintf(errstr, "Can't read size of input file %s.\n",infilename);
+		return(PROGRAM_ERROR);
+	}
+	d = (double)(dz->insams[0]/dz->infile->channels)/(double)dz->infile->srate;
+	thislen = strlen(thisfilename)+1;
+	namestoreend = *namestore + *namestoresize;
+	*namestoresize += thislen;
+	strcpy(namestoreend,thisfilename);
+
+	(*lstore)[0][*fileno] = namestoreend;
+	if(*fileno) {
+		for(n = 0;n < *fileno; n++)	{
+			if(d <= (*lenstore)[n])
+				break;
+		}
+		if(((*posstore) = (int    *)realloc((char *)(*posstore),((*fileno)+1) * sizeof(int   )))==NULL) {
+			sprintf(errstr,"INSUFFICIENT MEMORY to reallocate posstore.\n");
+			return(MEMORY_ERROR);
+		}
+		if(((*lenstore) = (double *)realloc((char *)(*lenstore),((*fileno)+1) * sizeof(double)))==NULL) {
+			sprintf(errstr,"INSUFFICIENT MEMORY to reallocate lenstore.\n");
+			return(MEMORY_ERROR);
+		}
+		if(n != *fileno) {
+			for(m = *fileno; m > n; m--) {
+				(*lenstore)[m] = (*lenstore)[m-1];
+				(*posstore)[m] = (*posstore)[m-1];
+			}
+		}
+
+	} else {
+		if(((*lenstore) = (double *)malloc(sizeof(double))) == NULL) {
+			sprintf(errstr,"INSUFFICIENT MEMORY for lenstore.\n");
+			return(MEMORY_ERROR);
+		}
+		if(((*posstore) = (int    *)malloc(sizeof(int))) == NULL) {
+			sprintf(errstr,"INSUFFICIENT MEMORY for posstore.\n");
+			return(MEMORY_ERROR);
+		}
+		n = 0;
+	}		
+	(*lenstore)[n] = d;
+	(*posstore)[n] = *fileno;
+	(*fileno)++;
+	return(FINISHED);
+}
+
+/********************* OUTPUT_ORDER *********************/
+
+int output_order(char *infilename,char **otherfile,int *posstore,double *lenstore,char ***lstore,int cnt,dataptr dz)
+{
+	int exit_status;
+	if(cnt==0) {
+		sprintf(errstr,"NO VALID FILES FOUND.\n");
+		print_outmessage(errstr);
+	} else {
+		if((exit_status = create_ofile(infilename,otherfile,cnt,lstore,lenstore,posstore,dz))<0)
+			return(exit_status);
+//TW UPDATE
+		if(!sloom && !sloombatch)
+			fprintf(stdout,"\nCREATED LENGTH-ORDERED FILE '%s'\n",*otherfile);
+		else {
+			fprintf(stdout,"INFO: \n");
+			fprintf(stdout,"INFO: CREATED LENGTH-ORDERED FILE '%s'\n",*otherfile);
+		}
+	}
+ 	fflush(stdout);
+	return(FINISHED);
+ }
+
+/********************* FILENAME_EXTENSION_IS_NOT_SOUND *********************/
+
+int filename_extension_is_not_sound(char *filename)
+{
+	char *q = filename;
+	char *p = filename + strlen(filename);
+	while(p > q) {
+		p--;
+		if(*p == '.') {
+			if(!strcmp(p,".evl")
+			|| !strcmp(p,".frq")
+			|| !strcmp(p,".trn")
+			|| !strcmp(p,".ana")
+			|| !strcmp(p,".for")) {
+				return 1;
+			}
+		}
+	}
+	return 0;
+}
+