Browse Source

initial commit

richarddobson 3 years ago
parent
commit
0d7b0367c1
5 changed files with 1671 additions and 0 deletions
  1. 47 0
      dev/CMakeLists.txt
  2. 19 0
      dev/combine/CMakeLists.txt
  3. 682 0
      dev/combine/ap_combine.c
  4. 686 0
      dev/combine/combine.c
  5. 237 0
      dev/combine/main.c

+ 47 - 0
dev/CMakeLists.txt

@@ -0,0 +1,47 @@
+# RWD development for newsfsys testing
+find_library(ALSA_LIBRARY alsa)
+
+add_subdirectory(cdp2k)
+add_subdirectory(newsfsys)
+add_subdirectory(blur)
+add_subdirectory(cdparams)
+add_subdirectory(cdparams_other)
+add_subdirectory(cdparse)
+add_subdirectory(combine)
+add_subdirectory(distort)
+add_subdirectory(editsf)
+add_subdirectory(env)
+add_subdirectory(extend)
+add_subdirectory(filter)
+add_subdirectory(focus)
+add_subdirectory(formants)
+add_subdirectory(grain)
+add_subdirectory(hfperm)
+add_subdirectory(hilite)
+add_subdirectory(houskeep)
+add_subdirectory(misc)
+add_subdirectory(modify)
+add_subdirectory(morph)
+add_subdirectory(new)
+add_subdirectory(pagrab)
+add_subdirectory(paview)
+add_subdirectory(pitch)
+add_subdirectory(pitchinfo)
+add_subdirectory(pv)
+add_subdirectory(pview)
+add_subdirectory(repitch)
+add_subdirectory(sfutils)
+add_subdirectory(sndinfo)
+add_subdirectory(spec)
+add_subdirectory(specinfo)
+add_subdirectory(standalone)
+add_subdirectory(strange)
+add_subdirectory(stretch)
+add_subdirectory(submix)
+add_subdirectory(synth)
+add_subdirectory(tabedit)
+add_subdirectory(texture)
+add_subdirectory(externals)
+add_subdirectory(standnew)
+add_subdirectory(science)
+

+ 19 - 0
dev/combine/CMakeLists.txt

@@ -0,0 +1,19 @@
+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(combine main.c combine.c ap_combine.c)
+
+target_link_libraries(combine cdp2k sfsys ${EXTRA_LIBRARIES})
+my_install(combine)
+

+ 682 - 0
dev/combine/ap_combine.c

@@ -0,0 +1,682 @@
+/*
+ * 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 <cdpmain.h>
+#include <tkglobals.h>
+#include <pnames.h>
+#include <combine.h>
+#include <processno.h>
+#include <modeno.h>
+#include <globcon.h>
+#include <logic.h>
+#include <filetype.h>
+#include <mixxcon.h>
+#include <speccon.h>
+#include <flags.h>
+#include <arrays.h>
+#include <formants.h>
+#include <sfsys.h>
+#include <osbind.h>
+#include <string.h>
+#include <math.h>
+#include <srates.h>
+
+/********************************************************************************************/
+/********************************** FORMERLY IN preprocess.c ********************************/
+/********************************************************************************************/
+
+static int  force_file_zero_to_be_largest_file(dataptr dz);
+static int  mean_preprocess(dataptr dz);
+static void integer_swap(int *a,int *b);
+static int allocate_specleaf_buffer(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) {
+//TW NEW CASE
+	case(MAKE2):
+
+	case(MAKE):	      		dz->extra_bufcnt =  0; dz->bptrcnt = 4; 	is_spec = TRUE;		break;
+	case(SUM):	      		dz->extra_bufcnt =  0; dz->bptrcnt = 4; 	is_spec = TRUE;		break;
+	case(DIFF):	      		dz->extra_bufcnt =  0; dz->bptrcnt = 4; 	is_spec = TRUE;		break;
+	case(LEAF):       		dz->extra_bufcnt =  0; dz->bptrcnt = 4; 	is_spec = TRUE;		break;
+	case(MAX):	      		dz->extra_bufcnt =  0; dz->bptrcnt = 4; 	is_spec = TRUE;		break;
+	case(MEAN):       		dz->extra_bufcnt =  3; dz->bptrcnt = 4; 	is_spec = TRUE;		break;	/* TW August 19 */
+	case(CROSS):      		dz->extra_bufcnt =  0; dz->bptrcnt = 4; 	is_spec = TRUE;		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);
+	}
+	if(is_spec)
+		return establish_spec_bufptrs_and_extra_buffers(dz);
+	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) {
+//TW NEW CASE
+	case(MAKE2):
+	case(MAKE):    	dz->array_cnt = 0; dz->iarray_cnt = 0; dz->larray_cnt = 0; dz->ptr_cnt = 0; dz->fptr_cnt = 0;	break;
+	case(SUM):	  	dz->array_cnt = 0; dz->iarray_cnt = 0; dz->larray_cnt = 0; dz->ptr_cnt = 0; dz->fptr_cnt = 0;	break;
+	case(DIFF):	  	dz->array_cnt = 0; dz->iarray_cnt = 0; dz->larray_cnt = 0; dz->ptr_cnt = 0; dz->fptr_cnt = 0;	break;
+	case(LEAF):	  	dz->array_cnt = 0; dz->iarray_cnt = 0; dz->larray_cnt = 0; dz->ptr_cnt = 0; dz->fptr_cnt = 0;	break;
+	case(MAX): 	  	dz->array_cnt = 0; dz->iarray_cnt = 0; dz->larray_cnt = 0; dz->ptr_cnt = 0; dz->fptr_cnt = 0;	break;
+	case(MEAN):   	dz->array_cnt = 0; dz->iarray_cnt = 2; dz->larray_cnt = 0; dz->ptr_cnt = 0; dz->fptr_cnt = 0;	break;
+	case(CROSS):  	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(MAKE):			setup_process_logic(PITCH_AND_FORMANTS,   	PITCH_TO_ANAL,		ANALFILE_OUT,	dz);	break;
+//TW NEW CASE
+	case(MAKE2):		setup_process_logic(PFE,   					PITCH_TO_ANAL,		ANALFILE_OUT,	dz);	break;
+	case(SUM):			setup_process_logic(TWO_ANALFILES,		  	MAX_ANALFILE,		ANALFILE_OUT,	dz);	break;
+	case(DIFF):		  	setup_process_logic(TWO_ANALFILES,		  	EQUAL_ANALFILE,		ANALFILE_OUT,	dz);	break;
+	case(LEAF):		  	setup_process_logic(MANY_ANALFILES,		  	MIN_ANALFILE,		ANALFILE_OUT,	dz);	break;
+	case(MAX):		  	setup_process_logic(MANY_ANALFILES,		  	MAX_ANALFILE,		ANALFILE_OUT,	dz);	break;
+	case(MEAN):		  	setup_process_logic(TWO_ANALFILES,		  	MIN_ANALFILE,		ANALFILE_OUT,	dz);	break;
+	case(CROSS):	  	setup_process_logic(TWO_ANALFILES,		  	MIN_ANALFILE,		ANALFILE_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) {
+//TW NEW CASE
+	case(MAKE2):
+	case(MAKE):       	return(FINISHED);
+	case(SUM):		  	return(FINISHED);
+	case(DIFF):		  	return(FINISHED);
+	case(LEAF):		  	return(FINISHED);
+	case(MAX):		  	return(FINISHED);
+	case(MEAN):		  	exit_status = set_internalparam_data("ii",ap);					break;
+	case(CROSS):	  	return(FINISHED);
+	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;
+//TW AVOIDS WARNING
+	//str = str;
+
+	switch(ap->special_data) {
+	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)	
+{
+	switch(dz->process) {
+	case(MAX):			return force_file_zero_to_be_largest_file(dz);
+	case(MEAN):			return mean_preprocess(dz);
+
+//TW NEW CASE
+	case(MAKE2):
+	case(MAKE):	case(SUM):	case(DIFF):	case(LEAF):	case(CROSS):		
+		return(FINISHED);
+	default:
+		sprintf(errstr,"PROGRAMMING PROBLEM: Unknown process in param_preprocess()\n");
+		return(PROGRAM_ERROR);
+	}
+	return(FINISHED);	/* NOTREACHED */
+}
+
+/********************** FORCE_FILE_ZERO_TO_BE_LARGEST_FILE **********************/
+
+int force_file_zero_to_be_largest_file(dataptr dz)
+{
+	int maxsize = dz->insams[0];
+	int maxfile = 0, n, k;
+	for(n=1;n<dz->infilecnt;n++) {
+		if(dz->insams[n] > maxsize) {
+			maxsize = dz->insams[n];
+			maxfile = n;
+		}
+	}
+	if(n!=0) {		/* Force file zero to be largest file */
+		k = dz->ifd[0];
+		dz->ifd[0] = dz->ifd[maxfile];
+		dz->ifd[maxfile] = k;
+		k = dz->insams[0];
+		dz->insams[0] = dz->insams[maxfile];
+		dz->insams[maxfile] = k;
+	}
+	return(FINISHED);
+}
+
+/************************** MEAN_PREPROCESS ******************************/
+
+int mean_preprocess(dataptr dz)
+{
+	int exit_status;
+	if(dz->zeroset) {
+		sprintf(errstr,"zeroset flag set: Needed unset for later use: mean_preprocess()\n");
+		return(PROGRAM_ERROR);
+	}
+	if((dz->iparray[MEAN_LOC1] = (int *)malloc(dz->clength * sizeof(int)))==NULL
+	|| (dz->iparray[MEAN_LOC2] = (int *)malloc(dz->clength * sizeof(int)))==NULL) {
+		sprintf(errstr,"INSUFFICIENT MEMORY for mean location arrays.\n");
+		return(MEMORY_ERROR);
+	}
+	if((exit_status = get_channel_corresponding_to_frq(&(dz->iparam[MEAN_BOT]),dz->param[MEAN_LOF],dz))<0)
+		return(exit_status);
+	if((exit_status = get_channel_corresponding_to_frq(&(dz->iparam[MEAN_TOP]),dz->param[MEAN_HIF],dz))<0)
+		return(exit_status);
+	if(dz->iparam[MEAN_TOP] < dz->iparam[MEAN_BOT])
+		integer_swap(&(dz->iparam[MEAN_TOP]),&(dz->iparam[MEAN_BOT]));
+	if(dz->iparam[MEAN_TOP] - dz->iparam[MEAN_BOT] + 1 < dz->iparam[MEAN_CHAN])
+		/* Reducing chans parameter to fit into frq limits. */
+		dz->iparam[MEAN_CHAN] = dz->iparam[MEAN_TOP] - dz->iparam[MEAN_BOT] + 1;
+	dz->iparam[MEAN_TOP] *= 2; /* CONVERT FROM CHANNEL-NO TO FLOAT-NO IN BUFFER */
+	dz->iparam[MEAN_BOT] *= 2;
+	dz->iparam[MEAN_TOP] += 2; /* INCLUSIVE LOOP LIMIT */
+	dz->iparam[MEAN_TOP] = min(dz->iparam[MEAN_TOP],dz->wanted);
+	return(FINISHED);
+}
+
+/***************************** INTEGER_SWAP **************************/
+
+void integer_swap(int *a,int *b)
+{
+	int k;
+	k  = *a;
+	*a = *b;
+	*b = k;
+}
+
+/***************************** 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);
+}
+
+/***************** SKIP_OR_SPECIAL_OPERATION_ON_WINDOW_ZERO ************/
+
+int skip_or_special_operation_on_window_zero(dataptr dz)
+{
+	return(FALSE);
+}
+
+/********************************************************************************************/
+/********************************** FORMERLY IN procspec.c **********************************/
+/********************************************************************************************/
+
+/**************************** SPEC_PROCESS_FILE ****************************/
+
+int spec_process_file(dataptr dz)
+{	
+	dz->total_windows = 0;
+
+	display_virtual_time(0L,dz);
+
+	switch(dz->process) {
+//TW NEW CASE
+	case(MAKE2):
+	case(MAKE):		return specmake(dz);		   
+	case(SUM):		return outer_twofileinput_loop(dz);
+	case(DIFF):		return outer_twofileinput_loop(dz);
+	case(LEAF):		return specleaf(dz);
+	case(MAX):		return specmax(dz);
+	case(MEAN):		return outer_twofileinput_loop(dz);
+	case(CROSS):	return outer_twofileinput_loop(dz);
+	default:
+		sprintf(errstr,"Unknown process in procspec()\n");
+		return(PROGRAM_ERROR);
+	}
+	return(FINISHED);	/* NOTREACHED */
+}
+
+/**************************** OUTER_TWOFILEINPUT_LOOP ***************************/
+
+int outer_twofileinput_loop(dataptr dz)
+{
+	int exit_status;
+	int windows_to_process, windows_in_buf, samps_read, samps_to_write, wc, got;
+	int file_to_keep = 0, finished = 0, stop_at_end_of_shortest_file = 0;
+	int stop_at_end_of_process = 0;
+	dz->time = 0.0f;
+	switch(dz->process) {
+	case(CROSS):
+	case(MEAN):
+		windows_to_process = min(dz->insams[0],dz->insams[1])/dz->wanted;
+		stop_at_end_of_shortest_file = 1;
+		break;
+	case(SUM):
+		windows_to_process = min(dz->insams[0],dz->insams[1])/dz->wanted;
+		file_to_keep = get_longer_file(dz);
+		break;
+	case(DIFF):
+		windows_to_process = min(dz->insams[0],dz->insams[1])/dz->wanted;
+		if(dz->insams[0] > dz->insams[1])
+			file_to_keep = 1;
+		break;
+	default:
+		sprintf(errstr,"unknown case in outer_twofileinput_loop()\n");
+		return(PROGRAM_ERROR);
+	}
+   	while(!finished) {
+
+		if((exit_status = read_both_files(&windows_in_buf,&got,dz))<0)
+			return(exit_status);
+		samps_to_write = got;
+ 		for(wc=0; wc<windows_in_buf; wc++) {
+			if(dz->total_windows==0) {
+				if((exit_status = skip_or_special_operation_on_window_zero(dz))<0)
+				 	return(exit_status);
+				if(exit_status==TRUE) {
+					if((exit_status = advance_one_2fileinput_window(dz))<0)
+						return(exit_status);
+					continue;
+				}
+			}
+			if((exit_status = read_values_from_all_existing_brktables((double)dz->time,dz))<0)
+				return(exit_status);
+			switch(dz->process) {
+			case(CROSS):  
+				if((exit_status = speccross(dz))<0)
+					return(exit_status);
+				break;
+			case(DIFF):	  
+				if((exit_status = specdiff(dz))<0)
+					return(exit_status);
+				break;
+			case(MEAN):   
+				if((exit_status = specmean(dz))<0)
+					return(exit_status);
+				break;
+			case(SUM):	  
+				if((exit_status = specsum(dz))<0)
+					return(exit_status);
+				break;
+			default:
+				sprintf(errstr,"unknown process in outer_twofileinput_loop()\n");
+				return(PROGRAM_ERROR);
+			}
+			if((exit_status = advance_one_2fileinput_window(dz))<0)
+				return(exit_status);
+			if(dz->total_windows >= windows_to_process) {
+				if((exit_status = keep_excess_samps_from_correct_file(&samps_to_write,file_to_keep,got,wc,dz))<0)
+					return(exit_status);
+				finished = 1;
+				break;
+			}
+		}
+		if(samps_to_write > 0) { 
+			if((exit_status = write_samps(dz->bigfbuf,samps_to_write,dz))<0)
+				return(exit_status);
+		}
+	}
+	if(!stop_at_end_of_process && !stop_at_end_of_shortest_file) {
+		if((exit_status = read_either_file(&samps_read,file_to_keep,dz))<0)
+			return(exit_status);
+		while(samps_read > 0) {
+			if((exit_status = write_samps(dz->bigfbuf,samps_read,dz))<0)
+				return(exit_status);
+			if((exit_status = read_either_file(&samps_read,file_to_keep,dz))<0)
+				return(exit_status);
+		}
+	}
+	return(FINISHED);
+}
+
+/********************************************************************************************/
+/********************************** FORMERLY IN pconsistency.c ******************************/
+/********************************************************************************************/
+
+/****************************** CHECK_PARAM_VALIDITY_AND_CONSISTENCY *********************************/
+
+int check_param_validity_and_consistency(dataptr dz)
+{
+	return(FINISHED);
+}
+
+/********************************************************************************************/
+/********************************** FORMERLY IN buffers.c ***********************************/
+/********************************************************************************************/
+
+/**************************** ALLOCATE_LARGE_BUFFERS ******************************/
+
+int allocate_large_buffers(dataptr dz)
+{
+	switch(dz->process) {
+	case(SUM):		case(DIFF):
+	case(MAX):		case(MEAN):		case(CROSS):	
+		return allocate_double_buffer(dz);
+	case(LEAF):		
+		return allocate_specleaf_buffer(dz);
+	case(MAKE):		
+//TW NEW CASE
+	case(MAKE2):		
+		return allocate_analdata_plus_formantdata_buffer(dz);
+	default:
+		sprintf(errstr,"Unknown program no. in allocate_large_buffers()\n");
+		return(PROGRAM_ERROR);
+	}
+	return(FINISHED);	/* NOTREACHED */
+}
+
+/********************************************************************************************/
+/********************************** FORMERLY IN cmdline.c ***********************************/
+/********************************************************************************************/
+
+int get_process_no(char *prog_identifier_from_cmdline,dataptr dz)
+{
+	if     (!strcmp(prog_identifier_from_cmdline,"make"))  	   		dz->process = MAKE;
+//TW NEW CASE
+	else if(!strcmp(prog_identifier_from_cmdline,"make2"))  	   	dz->process = MAKE2;
+	else if(!strcmp(prog_identifier_from_cmdline,"sum"))  	   		dz->process = SUM;
+	else if(!strcmp(prog_identifier_from_cmdline,"diff"))  	   		dz->process = DIFF;
+	else if(!strcmp(prog_identifier_from_cmdline,"interleave"))  	dz->process = LEAF;
+	else if(!strcmp(prog_identifier_from_cmdline,"max"))  	   		dz->process = MAX;
+	else if(!strcmp(prog_identifier_from_cmdline,"mean"))  	   		dz->process = MEAN;
+	else if(!strcmp(prog_identifier_from_cmdline,"cross"))     		dz->process = CROSS;
+	else {
+		sprintf(errstr,"Unknown program identification string '%s'\n",prog_identifier_from_cmdline);
+		return(USAGE_ONLY);
+	}
+//TW UPDATE
+	return(FINISHED);
+}
+
+/********************************************************************************************/
+/********************************** FORMERLY IN usage.c *************************************/
+/********************************************************************************************/
+
+/******************************** USAGE1 ********************************/
+
+int usage1(void)
+{
+	sprintf(errstr,
+	"\nCOMBINATION OF SPECTRAL FILES\n\n"
+	"USAGE: combine NAME (mode) infile (infile2...) outfile parameters: \n"
+	"\n"
+	"where NAME can be any one of\n"
+	"\n"
+//TW ADDED NEW CASE
+	"make    make2    sum    diff    interleave    max    mean    cross\n\n"
+	"Type 'combine make' for more info on combine make..ETC.\n");
+
+	return(USAGE_ONLY);
+}
+
+/******************************** USAGE2 ********************************/
+
+int usage2(char *str)
+{
+	if(!strcmp(str,"make")) {
+		sprintf(errstr,
+		"combine make pitchfile formantfile outfile\n\n"
+		"GENERATE SPECTRUM FROM PITCH & FORMANT DATA ONLY.\n\n"
+		"pitchfile   is a binary pitchdata file\n" 
+		"formantfile is a binary formantdata file\n" 
+		"outfile     is an analysis file which can be resynthesized with PVOC\n"
+		"\n"
+//TW temporary cmdline restriction
+		"** Do not use output filenames which end in '1'\n");
+//TW NEW CASE
+	} else if(!strcmp(str,"make2")) {
+		sprintf(errstr,
+		"combine make2 pitchfile formantfile envfile outfile\n\n"
+		"GENERATE SPECTRUM FROM PITCH, FORMANT AND ENVELOPE DATA ONLY.\n\n"
+		"pitchfile   is a binary pitchdata file\n" 
+		"formantfile is a binary formantdata file\n" 
+		"envfile     is a binary envelope file derived from an ANALYSIS file\n" 
+		"outfile     is an analysis file which can be resynthesized with PVOC\n");
+
+} else if(!strcmp(str,"sum")) {
+		sprintf(errstr,
+		"combine sum infile infile2 outfile [-ccrossover]\n\n"
+		"FIND SUM OF TWO SPECTRA.\n\n"
+		"-c  CROSSOVER is amount of 2nd spectrum added to 1st (range 0 to 1)\n\n"
+		"crossover may vary over time.\n");
+	} else if(!strcmp(str,"diff")) {
+		sprintf(errstr,
+		"combine diff infile infile2 outfile [-ccrossover] [-a]\n\n"
+		"FIND DIFFERENCE OF TWO SPECTRA.\n\n"
+		"-c  CROSSOVER is amount of 2nd spectrum subtracted from 1st (range 0 to 1)\n"
+		"-a  retains any subzero amplitudes produced (Default: sets these to zero).\n\n"
+		"crossover may vary over time.\n");
+	} else if(!strcmp(str,"interleave")) {
+		sprintf(errstr,
+		"combine interleave infile infile2 [infile3 ....] outfile leafsize\n\n"
+		"INTERLEAVE WINDOWS FROM INFILES, LEAFSIZE WINDOWS PER LEAF.\n");
+	} else if(!strcmp(str,"max")) {
+		sprintf(errstr,
+		"combine max infile infile2 [infile3 ....] outfile\n\n"
+		"IN EACH ANALYSIS CHANNEL, IN EACH WINDOW, TAKE MAX VAL AMONGST INPUT FILES.\n");
+	} else if(!strcmp(str,"mean")) {
+		sprintf(errstr,
+		"combine mean mode infile infile2 outfile [-llofrq] [-hhifrq] [-cchans] [-z]\n\n"
+		"GENERATE SPECTRAL 'MEAN' OF 2 SOUNDS.\n\n"
+		"LOFRQ 	is low freq limit of channels to look at.\n"
+		"HIFRQ 	is high freq limit of channels to look at.\n"
+		"CHANS	no. of significant channels to compare..Default: All within range.\n"
+		"-z   	Zeroes channels OUTSIDE frq range specified.\n\n"
+		"MODES are...\n"
+		"(1) mean channel amp of 2 files :  mean of two pitches\n"
+		"(2) mean channel amp of 2 files :  mean of two frqs\n"
+		"(3) channel amp from file1      :  mean of two pitches\n"
+		"(4) channel amp from file1      :  mean of two frqs\n"
+		"(5) channel amp from file2      :  mean of two pitches\n"
+		"(6) channel amp from file2      :  mean of two frqs\n"
+		"(7) max channel amp of 2 files  :  mean of two pitches\n"
+		"(8) max channel amp of 2 files  :  mean of two frqs\n");
+	} else if(!strcmp(str,"cross")) {
+		sprintf(errstr,
+		"combine cross infile infile2 outfile [-iinterp]\n\n"
+		"REPLACE SPECTRAL AMPLITUDES OF 1st FILE WITH THOSE OF 2nd.\n\n"
+		"-i	INTERP is degree of replacement.\n\n"
+		"    interp may vary over time.\n");
+	} else
+		sprintf(errstr,"Unknown option '%s'\n",str);
+	return(USAGE_ONLY);
+}
+
+/******************************** USAGE3 ********************************/
+
+int usage3(char *str1,char *str2)
+{
+	sprintf(errstr,"Insufficient parameters on command line.\n");
+	return(USAGE_ONLY);
+}
+
+/**************************** ALLOCATE_SPECLEAF_BUFFER ******************************/
+
+int allocate_specleaf_buffer(dataptr dz)
+{
+	unsigned int buffersize;
+	if(dz->bptrcnt <= 0) {
+		sprintf(errstr,"bufptr not established in allocate_specleaf_buffer()\n");
+		return(PROGRAM_ERROR);
+	}
+	buffersize = dz->wanted * dz->iparam[LEAF_SIZE];
+	dz->buflen = buffersize;
+	buffersize += 1;
+	if((dz->bigfbuf	= (float*) malloc(buffersize * sizeof(float)))==NULL) {  
+		sprintf(errstr,"INSUFFICIENT MEMORY for sound buffers.\n");
+		return(MEMORY_ERROR);
+	}
+	dz->big_fsize = dz->buflen;
+	dz->bigfbuf[dz->big_fsize] = 0.0f;	/* safety value */
+	return(FINISHED);
+}
+

+ 686 - 0
dev/combine/combine.c

@@ -0,0 +1,686 @@
+/*
+ * 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>
+//TW UPDATE
+#include <processno.h>
+#include <modeno.h>
+#include <arrays.h>
+#include <flags.h>
+#include <combine.h>
+#include <cdpmain.h>
+#include <formants.h>
+#include <speccon.h>
+#include <sfsys.h>
+#include <osbind.h>
+#include <string.h>
+#include <combine.h>
+
+static int  setup_channel_mifdrqs(dataptr dz);
+static int  check_formant_buffer(dataptr dz);
+static int  preset_channels(dataptr dz);
+static int  write_pitched_window(double fundamental,double *amptotal,dataptr dz);
+//TW UPDATES + AVOID WARNING
+static int  write_unpitched_window(double *amptotal,dataptr dz);
+static int  write_silent_window(dataptr dz);
+
+static int  normalise_in_file(double normaliser,dataptr dz);
+static int  do_specmax(dataptr dz);
+static int  if_loud_enough_to_go_in_list_put_in_list(float *ampstore,int *locstore,float val,int location,dataptr dz);
+static int  generate_mean_values(int *loc1, int *loc2,dataptr dz);
+static int  pichwise_mean_of_frqs(double *outfrq,double frq1,double frq2);
+//TW UPDATE
+static int read_envel_from_envfile(float **env,float **envend,int *envlen,int fileno,dataptr dz);
+
+/****************************** SPECMAKE ****************************
+ *
+ * Construct an analfile, from pitchfile and formantdata only.
+ */
+
+int specmake(dataptr dz)
+{
+#define MAXANALAMP	(1.0)
+
+	int exit_status;
+	double normaliser, amptotal, thisfrq, maxamptotal = 0.0;
+
+//TW UPDATE
+	float *env = NULL, *envend;
+	int envlen;
+
+	if(dz->process==MAKE2) {
+		if((exit_status = read_envel_from_envfile(&env,&envend,&envlen,2,dz))<0)
+			return(exit_status);
+		dz->wlength = min(dz->wlength,envlen);
+	}
+
+	dz->wanted      = dz->infile->origchans;	/* to reconstruct an analfile !! */
+
+	if((exit_status = setup_formant_params(dz->ifd[1],dz))<0)
+		return(exit_status);
+	dz->flbufptr[1] = dz->flbufptr[2] + dz->descriptor_samps;
+	if((exit_status = setup_channel_mifdrqs(dz))<0)
+		return(exit_status);
+	if((exit_status = check_formant_buffer(dz))<0)
+		return(exit_status);
+	dz->flbufptr[0] = dz->bigfbuf;
+ 	while(dz->total_windows < dz->wlength){
+		amptotal = 0.0;
+		if((exit_status = preset_channels(dz))<0)
+			return(exit_status);
+		if((thisfrq = dz->pitches[dz->total_windows])>0.0) {
+			if((exit_status = write_pitched_window(thisfrq,&amptotal,dz))<0)
+				return(exit_status);
+//TW UPDATE
+		} else if(flteq(thisfrq,NOT_SOUND)) {
+			amptotal = 0.0;
+			if((exit_status = write_silent_window(dz))<0)
+				return(exit_status);
+		} else {
+//TW AVOID WARNING
+			if((exit_status = write_unpitched_window(&amptotal,dz))<0)
+				return(exit_status);
+			if(dz->process==MAKE2) 
+				normalise(env[dz->total_windows],amptotal,dz);
+		}
+
+		if(amptotal > maxamptotal)
+			maxamptotal = amptotal;
+		if((dz->flbufptr[0] += dz->wanted) >= dz->flbufptr[2]) {
+			if((exit_status = write_exact_samps(dz->bigfbuf,dz->buflen,dz))<0)
+				return(exit_status);
+			dz->flbufptr[0] = dz->bigfbuf;
+		}
+		if((exit_status = move_along_formant_buffer(dz))<0)
+			return(exit_status);
+		if(exit_status!=CONTINUE)
+			break;
+		dz->total_windows++;
+	}
+	if(dz->flbufptr[0] != dz->bigfbuf) {
+		if((exit_status = write_samps(dz->bigfbuf,(dz->flbufptr[0] - dz->bigfbuf),dz))<0)
+			return(exit_status);
+	}
+//TW UPDATE
+	if(dz->process!=MAKE2) {
+		if(maxamptotal > MAXANALAMP)
+			normaliser = MAXANALAMP/maxamptotal;
+		else
+			normaliser = 1.0;
+		if((exit_status = normalise_in_file(normaliser,dz))<0)
+			return(exit_status);
+	}
+	dz->specenvamp = NULL;	/* prevent SUPERFREE from attempting to free this pointer */
+	return(FINISHED);
+}
+
+/*************************** SETUP_CHANNEL_MIFDRQS ********************/
+
+int setup_channel_mifdrqs(dataptr dz)
+{
+	int cc;
+	double thisfrq = 0.0;
+	for(cc=0;cc<dz->clength;cc++) {
+		dz->freq[cc] = (float)thisfrq;	/* Set up midfrqs of PVOC channels */
+		thisfrq += dz->chwidth;
+	}
+	return(FINISHED);
+}
+
+/*************************** CHECK_FORMANT_BUFFER ********************/
+
+int check_formant_buffer(dataptr dz)
+{
+	if(dz->flbufptr[1] >= dz->flbufptr[3]) {
+		if(fgetfbufEx(dz->flbufptr[2],dz->buflen2,dz->ifd[1],0)<0) {
+			sprintf(errstr,"data miscount in check_formant_buffer()\n");
+			return(SYSTEM_ERROR);
+		}
+		dz->flbufptr[1] = dz->flbufptr[2];
+	}
+	return(FINISHED);
+}
+
+/*************************** PRESET_CHANNELS ********************/
+
+int preset_channels(dataptr dz)
+{
+	int vc, cc;
+	for(cc = 0, vc = 0; cc < dz->clength; cc++, vc+=2) {
+		dz->flbufptr[0][AMPP] = 0.0f;
+		dz->flbufptr[0][FREQ] = dz->freq[cc];
+	}
+	return(FINISHED);
+}
+
+/*************************** WRITE_PITCHED_WINDOW ********************/
+
+int write_pitched_window(double fundamental,double *amptotal,dataptr dz)
+{
+	int exit_status;
+	double thisamp, thisfrq = fundamental;
+	int n = 1, vc, cc;
+	dz->specenvamp = dz->flbufptr[1];
+	while(thisfrq < dz->nyquist) {
+		if((exit_status = get_channel_corresponding_to_frq(&cc,thisfrq,dz))<0)
+			return(exit_status);
+		vc = cc * 2;
+		if((exit_status = getspecenvamp(&thisamp,thisfrq,0,dz))<0)
+			return(exit_status);
+		if(thisamp  > dz->flbufptr[0][vc]) {
+			*amptotal -= dz->flbufptr[0][vc];
+			dz->flbufptr[0][AMPP] = (float)thisamp;
+			dz->flbufptr[0][FREQ] = (float)thisfrq;
+			*amptotal += thisamp;
+		}
+		n++;
+		thisfrq = fundamental * (double)n;
+	}
+	return(FINISHED);
+}
+
+/********************************** NORMALISE_IN_FILE ***********************************/
+
+int normalise_in_file(double normaliser,dataptr dz)
+{
+	int exit_status;
+	int vc;
+	int bufcnt = 0;
+	int total_samps_to_write = dz->total_samps_written;
+	int samps_to_write;
+	float *bufend;
+//TW NEW MECHANISM writes renormalised vals from original file created (tempfile) into true outfile
+// true outfile gets the name the user originally input
+//seek eliminated
+	if(sndcloseEx(dz->ifd[0]) < 0) {
+		sprintf(errstr, "WARNING: Can't close input soundfile\n");
+		return(SYSTEM_ERROR);
+	}
+	dz->ifd[0] = -1;
+	if(sndcloseEx(dz->ofd) < 0) {
+		sprintf(errstr, "WARNING: Can't close output soundfile\n");
+		return(SYSTEM_ERROR);
+	}
+	dz->ofd = -1;
+	if((dz->ifd[0] = sndopenEx(dz->outfilename,0,CDP_OPEN_RDWR)) < 0) {	   /*RWD Nov 2003, was RDONLY */
+		sprintf(errstr,"Failure to reopen file %s for renormalisation.\n",dz->outfilename);
+		return(SYSTEM_ERROR);
+	}
+	sndseekEx(dz->ifd[0],0,0);
+	if((exit_status = create_sized_outfile(dz->wordstor[0],dz))<0) {
+		sprintf(errstr,"Failure to create file %s for renormalisation.\n",dz->wordstor[0]);
+		return(exit_status);
+	}
+	if((exit_status = reset_peak_finder(dz)) < 0)
+		return exit_status;
+	dz->total_samps_written = 0;
+	fprintf(stdout,"INFO: Normalising.\n");
+	fflush(stdout);
+	while(total_samps_to_write>0) {
+		if(fgetfbufEx(dz->bigfbuf,dz->buflen,dz->ifd[0],0)<0) {
+			sprintf(errstr,"Sound read error.\n");
+			close_and_delete_tempfile(dz->outfilename,dz);
+			return(SYSTEM_ERROR);
+		}
+		dz->flbufptr[0]  = dz->bigfbuf;
+		samps_to_write  = min(dz->buflen,total_samps_to_write);
+		bufend = dz->flbufptr[0] + samps_to_write;
+		while(dz->flbufptr[0] < bufend) {
+			for(vc = 0;vc < dz->wanted; vc+=2)
+				dz->flbufptr[0][AMPP] = (float)(dz->flbufptr[0][AMPP] * normaliser);
+			dz->flbufptr[0] += dz->wanted;
+		}
+		if(samps_to_write>=dz->buflen) {
+			if((exit_status = write_exact_samps(dz->bigfbuf,samps_to_write,dz))<0) {
+				close_and_delete_tempfile(dz->outfilename,dz);
+				return(exit_status);
+			}
+		} else if(samps_to_write > 0) {
+			if((exit_status = write_samps(dz->bigfbuf,samps_to_write,dz))<0) {
+				close_and_delete_tempfile(dz->outfilename,dz);
+				return(exit_status);
+			}
+		}
+		total_samps_to_write -= samps_to_write;
+		bufcnt++;
+	}	
+	close_and_delete_tempfile(dz->outfilename,dz);
+	return(FINISHED);
+}
+
+/*************************** SPECSUM ***********************/
+
+int specsum(dataptr dz)
+{
+	int vc;
+	switch(dz->vflag[SUM_IS_CROSS]) {
+	case(TRUE):
+		for(vc = 0; vc < dz->wanted; vc += 2)
+			dz->flbufptr[0][vc] = (float)(dz->flbufptr[0][vc] + (dz->param[SUM_CROSS] * dz->flbufptr[1][vc]));
+		break;
+	case(FALSE):
+		for(vc = 0; vc < dz->wanted; vc += 2)
+			dz->flbufptr[0][vc] = (float)(dz->flbufptr[0][vc] + dz->flbufptr[1][vc]);
+		break;
+	default:
+		sprintf(errstr,"unknown case in specsum()\n");
+		return(PROGRAM_ERROR);				 
+	}
+	return(FINISHED);
+}
+
+/*************************** SPECDIFF ***********************/
+
+int specdiff(dataptr dz)
+{
+	int vc;
+	switch(dz->vflag[DIFF_SUBZERO]) {
+	case(FALSE):
+		switch(dz->vflag[DIFF_IS_CROSS]) {
+		case(FALSE):
+			for(vc = 0; vc < dz->wanted; vc += 2)
+				dz->flbufptr[0][vc] = (float)max(0.0,dz->flbufptr[0][vc] - dz->flbufptr[1][vc]);
+			break;
+		case(TRUE):
+			for(vc = 0; vc < dz->wanted; vc += 2)
+				dz->flbufptr[0][vc] = (float)max(0.0,dz->flbufptr[0][vc] - (dz->flbufptr[1][vc] * dz->param[DIFF_CROSS]));
+			break;
+		}
+		break;
+	case(TRUE):
+		switch(dz->vflag[DIFF_IS_CROSS]) {
+		case(FALSE):
+			for(vc = 0; vc < dz->wanted; vc += 2)
+				dz->flbufptr[0][vc] = (float)(dz->flbufptr[0][vc] - dz->flbufptr[1][vc]);
+			break;
+		case(TRUE):
+			for(vc = 0; vc < dz->wanted; vc += 2)
+				dz->flbufptr[0][vc] = (float)(dz->flbufptr[0][vc] - (dz->flbufptr[1][vc] * dz->param[DIFF_CROSS]));
+			break;
+		}
+		break;
+	}
+	return(FINISHED);
+}
+
+/**************************** SPECLEAF ****************************/
+
+int specleaf(dataptr dz)
+{
+	int  exit_status;
+	int  n;
+	int samps_read, minsams = dz->insams[0];
+	for(n=1;n<dz->infilecnt;n++)
+		minsams = min(minsams,dz->insams[n]);
+	dz->wlength = minsams/dz->wanted;
+	while(dz->total_windows < dz->wlength) {
+		for(n = 0;n < dz->infilecnt;n++) {
+			if((samps_read = fgetfbufEx(dz->bigfbuf,dz->buflen,dz->ifd[n],0))<=0) {
+				if(samps_read<0) {
+					sprintf(errstr,"Sound read error.\n");
+					return(SYSTEM_ERROR);
+				} else {
+					sprintf(errstr,"Accounting problem: specleaf()\n");
+					return(PROGRAM_ERROR);
+				}
+			}
+			if((exit_status = write_samps(dz->bigfbuf,dz->buflen,dz))<0)
+				return(exit_status);
+			if((dz->total_windows += dz->iparam[LEAF_SIZE]) >= dz->wlength)
+				break;
+		}
+	}
+	return(FINISHED);
+}
+
+/***************************** SPECMAX ***********************
+ *
+ * NB file0 is always the largest.
+ */
+
+int specmax(dataptr dz)
+{
+	int exit_status;
+	int n, m, windows_in_buf, windows_read, samps_read, samps_to_write;
+	int windows_to_process = dz->wlength; 
+	while(windows_to_process) {
+		if((samps_read = fgetfbufEx(dz->bigfbuf,dz->buflen,dz->ifd[0],0))<=0) {
+			if(samps_read<0) {
+				sprintf(errstr,"Sound read error.\n");
+				return(SYSTEM_ERROR);
+			} else {
+				sprintf(errstr,"Buffer accounting problem: specmax()\n");
+				return(PROGRAM_ERROR);
+			}
+		}
+		windows_read = samps_read/dz->wanted;
+		samps_to_write = samps_read;
+		for(n=1;n<dz->infilecnt;n++) {
+			if((samps_read = fgetfbufEx(dz->flbufptr[2],dz->buflen,dz->ifd[n],0))>0) {
+				windows_in_buf = samps_read/dz->wanted;
+				dz->flbufptr[0] = dz->bigfbuf;
+				dz->flbufptr[1] = dz->flbufptr[2];
+				for(m=0;m<windows_in_buf;m++) {
+					if((exit_status = do_specmax(dz))<0)
+						return(exit_status);
+					dz->flbufptr[0] += dz->wanted;
+					dz->flbufptr[1] += dz->wanted;
+				}
+			}
+		}
+		if(samps_to_write > 0) {
+			if((exit_status = write_samps(dz->bigfbuf,samps_to_write,dz))<0)
+				return(exit_status);
+		}
+		windows_to_process -= windows_read;
+	}
+	return(FINISHED);
+}
+
+/****************** DO_SPECMAX *********************/
+
+int do_specmax(dataptr dz)
+{
+	int vc;
+
+	for(vc=0;vc<dz->wanted;vc+=2) {
+		if(dz->flbufptr[1][AMPP] > dz->flbufptr[0][AMPP]) {
+			dz->flbufptr[0][AMPP] = dz->flbufptr[1][AMPP];
+			dz->flbufptr[0][FREQ] = dz->flbufptr[1][FREQ];
+		}
+	}
+	return(FINISHED);
+}
+
+/****************** SPECMEAN *********************/
+
+int specmean(dataptr dz)
+{
+	int exit_status;
+	int vc, cc;
+	int *loc1 = dz->iparray[MEAN_LOC1];
+	int *loc2 = dz->iparray[MEAN_LOC2];
+	/* SUBZERO ALL LOUDEST-VALS TO BE USED IN THIS PASS */
+	rectify_window(dz->flbufptr[0],dz);
+	rectify_window(dz->flbufptr[1],dz);
+	for(cc = 0; cc < dz->clength; cc++) {
+		dz->windowbuf[1][cc] = -1.0f;
+		dz->windowbuf[2][cc] = -1.0f;
+	}
+	if(dz->vflag[MEAN_ZEROED]) {	/* zero out-of-range channels */
+		for(vc = 0; vc < dz->iparam[MEAN_BOT];vc += 2)
+			dz->flbufptr[0][AMPP] = 0.0f;
+		for(vc = dz->iparam[MEAN_TOP]; vc < dz->wanted; vc += 2)
+			dz->flbufptr[0][AMPP] = 0.0f;
+		return(FINISHED);
+	}
+	for(vc = dz->iparam[MEAN_BOT]; vc < dz->iparam[MEAN_TOP]; vc += 2) {
+		if((exit_status = if_loud_enough_to_go_in_list_put_in_list(dz->windowbuf[1],loc1,dz->flbufptr[0][vc],vc,dz))<0)
+			return(exit_status);
+		if((exit_status = if_loud_enough_to_go_in_list_put_in_list(dz->windowbuf[2],loc2,dz->flbufptr[1][vc],vc,dz))<0)
+			return(exit_status);
+		dz->windowbuf[0][AMPP] = 0.0f;	/* initialise each output to zero amp */
+		dz->windowbuf[0][FREQ] = dz->flbufptr[0][FREQ];
+	}
+	return generate_mean_values(loc1,loc2,dz);	   /* SWITCH AMPLITUDES */
+}
+
+/****************************** IF_LOUD_ENOUGH_TO_GO_IN_LIST_PUT_IN_LIST ******************************/
+
+int if_loud_enough_to_go_in_list_put_in_list(float *ampstore,int *locstore,float val,int location,dataptr dz)
+{
+	int n = 0;
+	if(val < 0.0)				/* eliminate any subzero amplitudes */
+		return(FINISHED);
+	while(ampstore[n] >= val) {	/* Move along until stored vals are less than input val */
+		if(++n >= dz->clength)
+			return(FINISHED);
+	}
+	if(n < dz->clength-1) {		/* If ness, shuffle existing vals */
+		memmove((char *)(ampstore + n),(char *)(ampstore + n + 1),(dz->clength - n - 1) * sizeof(float));
+		memmove((char *)(locstore + n),(char *)(locstore + n + 1),(dz->clength - n - 1) * sizeof(int));
+	}
+	ampstore[n] = val;			/* Store new value */
+	locstore[n] = location;		/* store its location in original buffer */
+	return(FINISHED);
+}
+	
+
+/*************************** GENERATE_MEAN_VALUES ****************************/
+
+int generate_mean_values(int *loc1, int *loc2,dataptr dz)
+{
+	int exit_status;
+	double newfrq, newamp;
+	int j, n, a, b;
+	n = 0;
+	while(n < dz->clength && dz->windowbuf[1][n] >= 0.0 && dz->windowbuf[2][n] >= 0.0) {
+		a = loc1[n];
+		b = loc2[n];
+		switch(dz->mode) {
+		case(MEAN_AMP_AND_PICH):
+			newamp = (dz->flbufptr[0][a] + dz->flbufptr[1][b])/2.0;
+			a++;	
+			b++;
+			if((exit_status = pichwise_mean_of_frqs
+			(&newfrq,fabs((double)dz->flbufptr[0][a]),fabs((double)dz->flbufptr[1][b])))<0)
+				return(exit_status);
+			break;
+		case(MEAN_AMP_AND_FRQ):
+			newamp = (dz->flbufptr[0][a] + dz->flbufptr[1][b])/2.0;
+			a++;
+			b++;
+			newfrq = (fabs(dz->flbufptr[0][a]) + fabs(dz->flbufptr[1][b]))/2.0;
+			break;
+		case(AMP1_MEAN_PICH):
+			newamp = dz->flbufptr[0][a];
+			a++;
+			b++;
+			if((exit_status = pichwise_mean_of_frqs
+			(&newfrq,fabs((double)dz->flbufptr[0][a]),fabs((double)dz->flbufptr[1][b])))<0)
+				return(exit_status);
+			break;
+		case(AMP1_MEAN_FRQ):
+			newamp = dz->flbufptr[0][a];
+			a++;
+			b++;
+			newfrq = (fabs(dz->flbufptr[0][a]) + fabs(dz->flbufptr[1][b]))/2.0;
+			break;
+		case(AMP2_MEAN_PICH):
+			newamp = dz->flbufptr[1][b];
+			a++;
+			b++;
+			if((exit_status = pichwise_mean_of_frqs
+			(&newfrq,fabs((double)dz->flbufptr[0][a]),fabs((double)dz->flbufptr[1][b])))<0)
+				return(exit_status);
+			break;
+		case(AMP2_MEAN_FRQ):
+			newamp = dz->flbufptr[1][b];
+			a++;
+			b++;
+			newfrq = (fabs(dz->flbufptr[0][a]) + fabs(dz->flbufptr[1][b]))/2.0;
+			break;
+		case(MAXAMP_MEAN_PICH):
+			newamp = max(dz->flbufptr[0][a],dz->flbufptr[1][b]);
+			a++;
+			b++;
+			if((exit_status = pichwise_mean_of_frqs
+			(&newfrq,fabs((double)dz->flbufptr[0][a]),fabs((double)dz->flbufptr[1][b])))<0)
+				return(exit_status);
+			break;
+		case(MAXAMP_MEAN_FRQ):
+			newamp = max(dz->flbufptr[0][a],dz->flbufptr[1][b]);
+			a++;
+			b++;
+			newfrq = (fabs(dz->flbufptr[0][a]) + fabs(dz->flbufptr[1][b]))/2.0;
+			break;
+		default:
+			sprintf(errstr,"unknown program mode in generate_mean_values()\n");
+			return(PROGRAM_ERROR);
+		}		
+		j = (int)((newfrq + dz->halfchwidth)/dz->chwidth); /* TRUNCATE */ /*FIND APPROP CHAN */
+
+		if(j < dz->infile->channels) {
+			j *= 2;
+
+			if(newamp > dz->windowbuf[0][j]) {
+				dz->windowbuf[0][j++] = (float)newamp;
+				dz->windowbuf[0][j]   = (float)newfrq;
+			}
+		}
+		n++;
+	}
+	for(j = dz->iparam[MEAN_BOT]; j < dz->iparam[MEAN_TOP]; j++) 
+		dz->flbufptr[0][j] = dz->windowbuf[0][j];
+	return(FINISHED);
+}
+
+/****************************** PICHWISE_MEAN_OF_FRQS ******************************/
+
+int pichwise_mean_of_frqs(double *outfrq,double frq1,double frq2)
+{
+	double half_of_interval_in_octaves;
+	if(frq1 == 0.0)	 {
+		*outfrq = frq2;
+		return(FINISHED);
+	}
+	if(frq2 == 0.0)	 {
+		*outfrq = frq1;
+		return(FINISHED);
+	}
+	half_of_interval_in_octaves = (LOG2(frq2/frq1))/2.0;
+	*outfrq = pow(2.0,half_of_interval_in_octaves) * frq1;
+	return(FINISHED);
+}
+
+/************************* SPECCROSS ***************************/
+
+int speccross(dataptr dz)
+{
+	int vc;
+	double valdiff;
+	switch(dz->vflag[CROSS_INTP]) {
+	case(CROS_FULL):
+		for(vc = 0; vc < dz->wanted; vc += 2)
+			dz->flbufptr[0][vc] = dz->flbufptr[1][vc];
+		break;
+	case(CROS_INTERP):
+		for(vc = 0; vc < dz->wanted; vc += 2) {
+			valdiff            = dz->flbufptr[1][vc] - dz->flbufptr[0][vc];
+			valdiff           *= dz->param[CROS_INTP];
+			dz->flbufptr[0][vc] = (float)(dz->flbufptr[0][vc] + valdiff);
+		}
+		break;
+	default:
+		sprintf(errstr,"Unknown flag value in speccross()\n");
+		return(PROGRAM_ERROR);
+	}
+	return(FINISHED);
+}
+
+//TW NEW UPDATE CODE BELOW
+/*************************** WRITE_UNPITCHED_WINDOW ********************/
+
+#define NOISEBASEX	(0.5)
+
+//TW AVOID WARNING
+int write_unpitched_window(double *amptotal,dataptr dz)
+{
+	int exit_status;
+	double thisamp, basefrq = 0.0, thisfrq;
+	double rand_offset;
+	double noisrange = 1.0 - NOISEBASEX;
+	int n = 1, vc, cc;
+	int ccnt =  dz->wanted/2;
+	n = 1;
+	while(n <= ccnt) {
+		rand_offset = (drand48() - (.5)) * dz->chwidth;
+		thisfrq = basefrq + rand_offset;
+		if(thisfrq < 0.0 || thisfrq > dz->nyquist)	
+			continue;
+		if((exit_status = get_channel_corresponding_to_frq(&cc,thisfrq,dz))<0)
+			return(exit_status);
+		vc = cc * 2;
+		if((exit_status = getspecenvamp(&thisamp,thisfrq,0,dz))<0)
+			return(exit_status);
+		if(thisamp  > dz->flbufptr[0][vc]) {
+			*amptotal -= dz->flbufptr[0][vc];
+			dz->flbufptr[0][AMPP] = (float)(thisamp * (drand48() * noisrange));
+			dz->flbufptr[0][FREQ] = (float)thisfrq;
+			*amptotal += thisamp;
+		}
+		basefrq += dz->chwidth;
+		n++;
+	}
+	return(FINISHED);
+}
+
+/*************************** WRITE_SILENT_WINDOW ********************/
+
+int write_silent_window(dataptr dz)
+{
+	int vc, cc;
+	double thisfrq = 0.0;
+	for(cc=0, vc =0; cc < dz->clength; cc++, vc += 2) {
+		dz->flbufptr[0][AMPP] = (float)0.0;
+		dz->flbufptr[0][FREQ] = (float)thisfrq;
+		thisfrq += dz->chwidth;
+	}
+	return(FINISHED);
+}
+
+/*************************** READ_ENVEL_FROM_ENVFILE **************************/
+
+int read_envel_from_envfile(float **env,float **envend,int *envlen,int fileno,dataptr dz)
+{
+	int samps_to_read, secs_to_read;
+	
+	*envlen = dz->insams[fileno];
+	if(((secs_to_read = dz->insams[fileno]/F_SECSIZE)*F_SECSIZE)!=dz->insams[fileno])
+		secs_to_read++;
+	samps_to_read = secs_to_read * F_SECSIZE;	
+	if((*env = (float *)malloc((size_t)(samps_to_read * sizeof(float))))==NULL) {
+		sprintf(errstr,"INSUFFICIENT MEMORY for envelope array.\n");
+		return(MEMORY_ERROR);
+	}
+	if(fgetfbufEx(*env,samps_to_read,dz->ifd[fileno],0) < 0) {
+		sprintf(errstr,"fgetfbufEx() Anomaly in read_envel_from_envfile()\n");
+		return(SYSTEM_ERROR);
+	}		
+	if((*env = (float *)realloc(*env,(size_t)(dz->insams[fileno] * sizeof(float))))==NULL) {
+		sprintf(errstr,"INSUFFICIENT MEMORY to reallocate envelope array.\n");
+		return(MEMORY_ERROR);
+	}
+	*envend = *env + *envlen;
+	return(FINISHED);
+}
+
+

+ 237 - 0
dev/combine/main.c

@@ -0,0 +1,237 @@
+/*
+ * 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 <combine.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 <stdlib.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 = 1;
+/* extern */ int is_converted_to_stereo = -1;
+const char* cdp_version = "7.1.0";
+
+/**************************************** MAIN *********************************************/
+
+int main(int argc,char *argv[])
+{
+	int exit_status;
+	//FILE *fp   = NULL;
+	dataptr dz = 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 */
+//TW UPDATE
+	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);
+	}
+
+						  /* INITIAL CHECK OF CMDLINE DATA */
+	if(!sloom) {
+		if((exit_status = make_initial_cmdline_check(&argc,&argv))<0) {
+			print_messages_and_close_sndfiles(exit_status,is_launched,dz);
+			return(FAILED);
+		}
+					  /* GET PRE_DATA, ALLOCATE THE APPLICATION, CHECK FOR EXTRA INFILES */
+		cmdline    = argv;
+		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()      */
+	/* MARCH 1999 */
+			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((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->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);
+		}
+		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;
+
+	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 = spec_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);
+}
+