|
|
@@ -0,0 +1,1143 @@
|
|
|
+/*
|
|
|
+ * 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 <pitch.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>
|
|
|
+
|
|
|
+#ifndef HUGE
|
|
|
+#define HUGE 3.40282347e+38F
|
|
|
+#endif
|
|
|
+
|
|
|
+/********************************************************************************************/
|
|
|
+/********************************** FORMERLY IN pconsistency.c ******************************/
|
|
|
+/********************************************************************************************/
|
|
|
+
|
|
|
+static int check_viability_and_compatibility_of_shiftp_params(dataptr dz);
|
|
|
+static int sub_check_shiftp(dataptr dz);
|
|
|
+
|
|
|
+/********************************************************************************************/
|
|
|
+/********************************** FORMERLY IN preprocess.c ********************************/
|
|
|
+/********************************************************************************************/
|
|
|
+
|
|
|
+#define SCALEFUDGE (3.0)
|
|
|
+static int tune_preprocess(dataptr dz);
|
|
|
+static int convert_params_for_tune(dataptr dz);
|
|
|
+static int pick_preprocess(dataptr dz);
|
|
|
+static int adjust_parameters_for_specpick(dataptr dz);
|
|
|
+static int mark_chosen_channels_in_bitflags(dataptr dz);
|
|
|
+static int chan_containing_partial(int *botpchan,double *lastchtop,int *chan,double partial,dataptr dz);
|
|
|
+
|
|
|
+/********************************************************************************************/
|
|
|
+/********************************** FORMERLY IN specialin.c *********************************/
|
|
|
+/********************************************************************************************/
|
|
|
+
|
|
|
+static int generate_template_frqs(char *str,int datatype,dataptr dz);
|
|
|
+static int get_input_frqs(char *str,int datatype,double **fundamentals, double **harmonics,int *infrqcnt,dataptr dz);
|
|
|
+static int generate_template(double *fundamentals, double *harmonics, int infrqcnt, dataptr dz);
|
|
|
+static int getnextfrq(double *minfrq,double *fundamentals,double *harmonics,int infrqcnt);
|
|
|
+static int chordget(char *str,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(ALT): dz->extra_bufcnt = 0; dz->bptrcnt = 1; is_spec = TRUE; break;
|
|
|
+ case(OCT): dz->extra_bufcnt = 0; dz->bptrcnt = 1; is_spec = TRUE; break;
|
|
|
+ case(SHIFTP): dz->extra_bufcnt = 0; dz->bptrcnt = 1; is_spec = TRUE; break;
|
|
|
+ case(TUNE): dz->extra_bufcnt = 0; dz->bptrcnt = 1; is_spec = TRUE; break;
|
|
|
+ case(PICK): dz->extra_bufcnt = 0; dz->bptrcnt = 1; is_spec = TRUE; break;
|
|
|
+ case(MULTRANS): dz->extra_bufcnt = 1; dz->bptrcnt = 1; is_spec = TRUE; break;
|
|
|
+ case(CHORD): dz->extra_bufcnt = 1; dz->bptrcnt = 1; 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) {
|
|
|
+ case(ALT): dz->array_cnt = 0; dz->iarray_cnt = 0; dz->larray_cnt = 0; dz->ptr_cnt = 0; dz->fptr_cnt = 0; break;
|
|
|
+ case(OCT): dz->array_cnt = 0; dz->iarray_cnt = 0; dz->larray_cnt = 0; dz->ptr_cnt = 0; dz->fptr_cnt = 0; break;
|
|
|
+ case(SHIFTP): dz->array_cnt = 0; dz->iarray_cnt = 0; dz->larray_cnt = 0; dz->ptr_cnt = 0; dz->fptr_cnt = 0; break;
|
|
|
+ case(TUNE): dz->array_cnt = 0; dz->iarray_cnt =1; dz->larray_cnt = 0; dz->ptr_cnt = 0; dz->fptr_cnt = 0; break;
|
|
|
+ case(PICK): dz->array_cnt = 0; dz->iarray_cnt = 0; dz->larray_cnt =1; dz->ptr_cnt = 0; dz->fptr_cnt = 0; break;
|
|
|
+ case(MULTRANS): dz->array_cnt = 0; dz->iarray_cnt = 0; dz->larray_cnt = 0; dz->ptr_cnt = 0; dz->fptr_cnt = 0; break;
|
|
|
+ case(CHORD): 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(ALT): setup_process_logic(ANAL_WITH_PITCHDATA, EQUAL_ANALFILE, ANALFILE_OUT, dz); break;
|
|
|
+ case(OCT): setup_process_logic(ANAL_WITH_PITCHDATA, EQUAL_ANALFILE, ANALFILE_OUT, dz); break;
|
|
|
+ case(SHIFTP): setup_process_logic(ANALFILE_ONLY, EQUAL_ANALFILE, ANALFILE_OUT, dz); break;
|
|
|
+ case(TUNE): setup_process_logic(ANALFILE_ONLY, EQUAL_ANALFILE, ANALFILE_OUT, dz); break;
|
|
|
+ case(PICK): setup_process_logic(ANALFILE_ONLY, EQUAL_ANALFILE, ANALFILE_OUT, dz); break;
|
|
|
+ case(MULTRANS): setup_process_logic(ANALFILE_ONLY, EQUAL_ANALFILE, ANALFILE_OUT, dz); break;
|
|
|
+ case(CHORD): setup_process_logic(ANALFILE_ONLY, EQUAL_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) {
|
|
|
+ case(ALT): return(FINISHED);
|
|
|
+ case(OCT): return(FINISHED);
|
|
|
+ case(SHIFTP): exit_status = set_internalparam_data("idddddd",ap); break;
|
|
|
+ case(TUNE): return(FINISHED);
|
|
|
+ case(PICK): exit_status = set_internalparam_data("ii",ap); break;
|
|
|
+ case(MULTRANS): return(FINISHED);
|
|
|
+ case(CHORD): 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)
|
|
|
+{
|
|
|
+ aplptr ap = dz->application;
|
|
|
+
|
|
|
+ switch(ap->special_data) {
|
|
|
+ case(FRQ_OR_FRQSET):
|
|
|
+ case(PITCH_OR_PITCHSET): return generate_template_frqs(str,(int)ap->special_data,dz);
|
|
|
+
|
|
|
+ case(SEMIT_TRANSPOS_SET): return chordget(str,dz);
|
|
|
+ default:
|
|
|
+ sprintf(errstr,"Unknown special_data type: read_special_data()\n");
|
|
|
+ return(PROGRAM_ERROR);
|
|
|
+ }
|
|
|
+ return(FINISHED); /* NOTREACHED */
|
|
|
+}
|
|
|
+
|
|
|
+/**************************** GENERATE_TEMPLATE_FRQS ****************************/
|
|
|
+
|
|
|
+int generate_template_frqs(char *str,int datatype,dataptr dz) /* 'datatype' has to be PITCH_OR_PITCHSET or FRQ_OR_FRQSET */
|
|
|
+{
|
|
|
+ double *fundamentals, *harmonics;
|
|
|
+ int infrqcnt;
|
|
|
+ int exit_status;
|
|
|
+ if((exit_status = get_input_frqs(str,datatype,&fundamentals,&harmonics,&infrqcnt,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ if((exit_status = generate_template(fundamentals,harmonics,infrqcnt,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ free(fundamentals);
|
|
|
+ free(harmonics);
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/**************************** GET_INPUT_FRQS ****************************/
|
|
|
+
|
|
|
+int get_input_frqs(char *str,int datatype,double **fundamentals, double **harmonics,int *infrqcnt,dataptr dz)
|
|
|
+{
|
|
|
+ double dummy = 0.0, mididummy = 0.0;
|
|
|
+ FILE *fp;
|
|
|
+ int n, is_numeric = 0;
|
|
|
+ int arraysize = BIGARRAY;
|
|
|
+ char temp[200], *p;
|
|
|
+
|
|
|
+ *infrqcnt = 0;
|
|
|
+
|
|
|
+ if(!sloom) {
|
|
|
+//TW NEW CONVENTION ON numeric filenames
|
|
|
+ if(!value_is_numeric(str) && file_has_invalid_startchar(str)) {
|
|
|
+ sprintf(errstr,"Filename has invalid start-character [%s]\n",str);
|
|
|
+ return(USER_ERROR);
|
|
|
+ }
|
|
|
+ if(value_is_numeric(str)) {
|
|
|
+ if(sscanf(str,"%lf",&dummy)!=1) {
|
|
|
+ sprintf(errstr,"Invalid frq or pitch data: get_input_frqs()\n");
|
|
|
+ return(DATA_ERROR);
|
|
|
+ }
|
|
|
+ is_numeric = 1;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if(str[0]==NUMERICVAL_MARKER) {
|
|
|
+ str++;
|
|
|
+ if(strlen(str)<=0 || sscanf(str,"%lf",&dummy)!=1) {
|
|
|
+ sprintf(errstr,"Invalid frq or pitch data: get_input_frqs()\n");
|
|
|
+ return(DATA_ERROR);
|
|
|
+ }
|
|
|
+ is_numeric = 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(is_numeric) {
|
|
|
+ if(datatype == PITCH_OR_PITCHSET) {
|
|
|
+ mididummy = dummy;
|
|
|
+ dummy = miditohz(dummy);
|
|
|
+ }
|
|
|
+ if(dummy <= 0.0 || dummy >= dz->nyquist) {
|
|
|
+ if(datatype == PITCH_OR_PITCHSET) {
|
|
|
+ sprintf(errstr,"Input midi value %lf in file %s is outside frq range (>0 - %.0lf[nyquist])\n",
|
|
|
+ mididummy,str,dz->nyquist);
|
|
|
+ } else {
|
|
|
+ sprintf(errstr,"Input frq value %lf in file %s is outside frq range (>0 - %.0lf[nyquist])\n",
|
|
|
+ dummy,str,dz->nyquist);
|
|
|
+ }
|
|
|
+ return(USER_ERROR);
|
|
|
+ }
|
|
|
+ if((*fundamentals = (double *)malloc(sizeof(double)))==NULL) {
|
|
|
+ sprintf(errstr,"INSUFFICIENT MEMORY to store fundamentals.\n");
|
|
|
+ return(MEMORY_ERROR);
|
|
|
+ }
|
|
|
+ (*fundamentals)[(*infrqcnt)++] = (float)dummy;
|
|
|
+ } else {
|
|
|
+ if((fp = fopen(str,"r"))==NULL) {
|
|
|
+ sprintf(errstr,"Cannot open file %s to read template.\n",str);
|
|
|
+ return(DATA_ERROR);
|
|
|
+ }
|
|
|
+ if((*fundamentals = (double *)malloc(arraysize * sizeof(double)))==NULL) {
|
|
|
+ sprintf(errstr,"INSUFFICIENT MEMORY to store fundamentals.\n");
|
|
|
+ return(MEMORY_ERROR);
|
|
|
+ }
|
|
|
+ while(fgets(temp,200,fp)!=NULL) {
|
|
|
+ p = temp;
|
|
|
+ while(get_float_from_within_string(&p,&dummy)) {
|
|
|
+ switch(datatype) {
|
|
|
+ case(PITCH_OR_PITCHSET):
|
|
|
+ mididummy = dummy;
|
|
|
+ dummy = miditohz(dummy);
|
|
|
+ /* fall thro */
|
|
|
+ case(FRQ_OR_FRQSET):
|
|
|
+ if(dummy <= 0.0 || dummy >= dz->nyquist) {
|
|
|
+ if(datatype == PITCH_OR_PITCHSET) {
|
|
|
+ sprintf(errstr,"Input midi value %lf in file %s is outside frq range (>0 - %.0lf[nyquist])\n",
|
|
|
+ mididummy,str,dz->nyquist);
|
|
|
+ } else {
|
|
|
+ sprintf(errstr,"Input frq value %lf in file %s is outside frq range (>0 - %.0lf[nyquist])\n",
|
|
|
+ dummy,str,dz->nyquist);
|
|
|
+ }
|
|
|
+ return(USER_ERROR);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ (*fundamentals)[*infrqcnt] = (float)dummy;
|
|
|
+ if(++(*infrqcnt)>=arraysize) {
|
|
|
+ arraysize += BIGARRAY;
|
|
|
+ if((*fundamentals = (double *)realloc((char *)(*fundamentals),arraysize*sizeof(double)))==NULL) {
|
|
|
+ sprintf(errstr,"INSUFFICIENT MEMORY to reallocate fundamentals store.\n");
|
|
|
+ return(MEMORY_ERROR);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(*infrqcnt==0) {
|
|
|
+ sprintf(errstr,"No data found in frq template file %s\n",str);
|
|
|
+ return(DATA_ERROR);
|
|
|
+ }
|
|
|
+ if((*fundamentals = (double *)realloc((char *)(*fundamentals),(*infrqcnt) * sizeof(double)))==NULL) {
|
|
|
+ sprintf(errstr,"INSUFFICIENT MEMORY to reallocate fundamentals store.\n");
|
|
|
+ return(MEMORY_ERROR);
|
|
|
+ }
|
|
|
+ if(fclose(fp)<0) {
|
|
|
+ fprintf(stdout,"WARNING: Failed to close input textfile %s.\n",str);
|
|
|
+ fflush(stdout);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if((*harmonics = (double *)malloc((*infrqcnt) * sizeof(double)))==NULL) {
|
|
|
+ sprintf(errstr,"INSUFFICIENT MEMORY to store harmonics.\n");
|
|
|
+ return(MEMORY_ERROR);
|
|
|
+ }
|
|
|
+ for(n=0;n<(*infrqcnt);n++)
|
|
|
+ (*harmonics)[n] = (*fundamentals)[n];
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/**************************** GENERATE_TEMPLATE *************************/
|
|
|
+
|
|
|
+int generate_template(double *fundamentals, double *harmonics, int infrqcnt, dataptr dz)
|
|
|
+{
|
|
|
+ int exit_status;
|
|
|
+ int n;
|
|
|
+ double lastchtop, thischtop, thisfrq;
|
|
|
+ for(n=0;n<infrqcnt;n++) {
|
|
|
+ if(fundamentals[n]>=dz->nyquist) {
|
|
|
+ sprintf(errstr,"Input frq %d = %lf >= nyquist[%.0lf].\n",n+1,fundamentals[n],dz->nyquist);
|
|
|
+ return(DATA_ERROR);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ lastchtop = 0.0;
|
|
|
+ thischtop = dz->chwidth/2.0;
|
|
|
+ if((exit_status = getnextfrq(&thisfrq,fundamentals,harmonics,infrqcnt))<0)
|
|
|
+ return(exit_status);
|
|
|
+ if((exit_status = float_array(&(dz->frq_template),dz->clength))<0)
|
|
|
+ return(exit_status);
|
|
|
+ for(n=0;n<dz->clength;n++) {
|
|
|
+ while(thisfrq < lastchtop) {
|
|
|
+ if((exit_status = getnextfrq(&thisfrq,fundamentals,harmonics,infrqcnt))<0)
|
|
|
+ return(exit_status);
|
|
|
+ }
|
|
|
+ if(thisfrq > thischtop)
|
|
|
+ dz->frq_template[n] = (float)(-1.0);
|
|
|
+ else
|
|
|
+ dz->frq_template[n] = (float)thisfrq;
|
|
|
+ lastchtop = thischtop;
|
|
|
+ if((thischtop += dz->chwidth) > dz->nyquist)
|
|
|
+ thischtop = dz->nyquist;
|
|
|
+ }
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/***************************** GETNEXTFRQ *****************************/
|
|
|
+
|
|
|
+int getnextfrq(double *minfrq,double *fundamentals,double *harmonics,int infrqcnt)
|
|
|
+{
|
|
|
+ int minptr = 0, n;
|
|
|
+ *minfrq = HUGE;
|
|
|
+ for(n=0;n<infrqcnt;n++) {
|
|
|
+ if(harmonics[n] < *minfrq) { /* FIND CURRENT MIN FRQ IN ARRAY harmonics[] */
|
|
|
+ *minfrq = harmonics[n];
|
|
|
+ minptr = n;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ harmonics[minptr] += fundamentals[minptr]; /* INCREMENT MIN VALUE TO NEXT APPROPRIATE HARMONIC */
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/*************************** CHORDGET ******************************/
|
|
|
+
|
|
|
+int chordget(char *str,dataptr dz)
|
|
|
+{
|
|
|
+ FILE *fp;
|
|
|
+ double val;
|
|
|
+ int arraysize = BIGARRAY;
|
|
|
+ char temp[200], *q;
|
|
|
+ if((dz->transpos = (float *)malloc(arraysize * sizeof(float)))==NULL) {
|
|
|
+ sprintf(errstr,"INSUFFICIENT MEMORY for transposition array.\n");
|
|
|
+ return(MEMORY_ERROR);
|
|
|
+ }
|
|
|
+ if(!sloom) {
|
|
|
+//TW NEW CONVENTION on numeric filenames
|
|
|
+ if(!value_is_numeric(str) && file_has_invalid_startchar(str)) {
|
|
|
+ sprintf(errstr,"Cannot read parameter value [%s]\n",str);
|
|
|
+ return(USER_ERROR);
|
|
|
+ }
|
|
|
+//TW REVISED Dec 2002
|
|
|
+ if(value_is_numeric(str)) {
|
|
|
+ sprintf(errstr,"This process takes chord-data in a FILE only.\n");
|
|
|
+ return(DATA_ERROR);
|
|
|
+ }
|
|
|
+ if((fp = fopen(str,"r"))==NULL) {
|
|
|
+ sprintf(errstr,"Can't open text file %s to read.\n",str);
|
|
|
+ return(DATA_ERROR);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if(str[0] == NUMERICVAL_MARKER) {
|
|
|
+//TW THis Check should be redundant: trapped by Sound Loom
|
|
|
+ sprintf(errstr,"This process takes chord-data in a FILE only.\n");
|
|
|
+ return(DATA_ERROR);
|
|
|
+ } else if((fp = fopen(str,"r"))==NULL) {
|
|
|
+ sprintf(errstr,"Can't open text file %s to read.\n",str);
|
|
|
+ return(DATA_ERROR);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ while(fgets(temp,200,fp)==temp) {
|
|
|
+ q = temp;
|
|
|
+ while(get_float_from_within_string(&q,&val)) {
|
|
|
+ val *= OCTAVES_PER_SEMITONE; /* CONVERT SEMITONES TO OCTAVES */
|
|
|
+ val = pow(2.0,val); /* CONVERT OCTAVES TO FRQ RATIO */
|
|
|
+ if(val <= MIN_TRANSPOS || val > MAX_TRANSPOS) {
|
|
|
+ sprintf(errstr,"transposition out of range (frq ratio %lf to %lf)\n",
|
|
|
+ LOG2(MIN_TRANSPOS) * SEMITONES_PER_OCTAVE,LOG2(MAX_TRANSPOS) * SEMITONES_PER_OCTAVE);
|
|
|
+ return(DATA_ERROR);
|
|
|
+ }
|
|
|
+ dz->transpos[dz->itemcnt] = (float)val;
|
|
|
+ if(++dz->itemcnt >= arraysize) {
|
|
|
+ arraysize += BIGARRAY;
|
|
|
+ if((dz->transpos = (float *)realloc((char *)dz->transpos,arraysize * sizeof(float)))==NULL) {
|
|
|
+ sprintf(errstr,"INSUFFICIENT MEMORY to reallocate transposition array.\n");
|
|
|
+ return(MEMORY_ERROR);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(dz->itemcnt == 0) {
|
|
|
+ sprintf(errstr,"No data in file %s\n",str);
|
|
|
+ return(DATA_ERROR);
|
|
|
+ }
|
|
|
+ if((dz->transpos = (float *)realloc((char *)dz->transpos,dz->itemcnt * sizeof(float)))==NULL) {
|
|
|
+ sprintf(errstr,"INSUFFICIENT MEMORY to reallocate transposition array.\n");
|
|
|
+ return(MEMORY_ERROR);
|
|
|
+ }
|
|
|
+ if(fclose(fp)<0) {
|
|
|
+ fprintf(stdout,"WARNING: Failed to close input textfile %s.\n",str);
|
|
|
+ fflush(stdout);
|
|
|
+ }
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+/********************************************************************************************/
|
|
|
+/********************************** FORMERLY IN preprocess.c ********************************/
|
|
|
+/********************************************************************************************/
|
|
|
+
|
|
|
+/****************************** PARAM_PREPROCESS *********************************/
|
|
|
+
|
|
|
+int param_preprocess(dataptr dz)
|
|
|
+{
|
|
|
+ int check;
|
|
|
+
|
|
|
+ switch(dz->process) {
|
|
|
+ case(OCT): return initialise_specenv(&check,dz);
|
|
|
+ case(SHIFTP): return adjust_params_and_setup_internal_params_for_shiftp(dz);
|
|
|
+ case(TUNE): return tune_preprocess(dz);
|
|
|
+ case(PICK): return pick_preprocess(dz);
|
|
|
+
|
|
|
+ case(ALT): case(MULTRANS): case(CHORD):
|
|
|
+ return(FINISHED);
|
|
|
+ default:
|
|
|
+ sprintf(errstr,"PROGRAMMING PROBLEM: Unknown process in param_preprocess()\n");
|
|
|
+ return(PROGRAM_ERROR);
|
|
|
+ }
|
|
|
+ return(FINISHED); /* NOTREACHED */
|
|
|
+}
|
|
|
+
|
|
|
+/************ ADJUST_PARAMS_AND_SETUP_INTERNAL_PARAMS_FOR_SHIFTP *************/
|
|
|
+
|
|
|
+int adjust_params_and_setup_internal_params_for_shiftp(dataptr dz)
|
|
|
+{
|
|
|
+ int exit_status;
|
|
|
+ double frq;
|
|
|
+ frq = dz->param[SHIFTP_FFRQ] + dz->chwidth/2.0;
|
|
|
+ dz->iparam[SHIFTP_FDCNO] = (int)floor(frq/dz->chwidth);
|
|
|
+ dz->param[SHIFTP_S1L1] = dz->param[SHIFTP_SHF1] - 1.0;
|
|
|
+ dz->param[SHIFTP_1LS1] = 1.0 - dz->param[SHIFTP_SHF1];
|
|
|
+ if(dz->mode == P_SHFT_UP_AND_DN) {
|
|
|
+ dz->param[SHIFTP_S2L1] = dz->param[SHIFTP_SHF2] - 1.0;
|
|
|
+ dz->param[SHIFTP_1LS2] = 1.0 - dz->param[SHIFTP_SHF2];
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ dz->param[SHIFTP_S2L1] = 0.0;
|
|
|
+ dz->param[SHIFTP_1LS2] = 0.0;
|
|
|
+ }
|
|
|
+ dz->param[SHIFTP_NS1] = dz->param[SHIFTP_SHF1];
|
|
|
+ if(dz->mode == P_SHFT_UP_AND_DN)
|
|
|
+ dz->param[SHIFTP_NS2] = dz->param[SHIFTP_SHF2];
|
|
|
+ else
|
|
|
+ dz->param[SHIFTP_NS2] = 0.0;
|
|
|
+ if(dz->vflag[SHP_IS_DEPTH] && dz->brksize[SHIFTP_DEPTH]==0) {
|
|
|
+ if((exit_status = reset_shiftps_according_to_depth_value(dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ }
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/************************ RESET_SHIFTPS_ACCORDING_TO_DEPTH_VALUE ****************************/
|
|
|
+
|
|
|
+int reset_shiftps_according_to_depth_value(dataptr dz)
|
|
|
+{
|
|
|
+ switch(dz->mode) {
|
|
|
+ case(6):
|
|
|
+ if(dz->param[SHIFTP_SHF2] > 1.0)
|
|
|
+ dz->param[SHIFTP_NS2] = (dz->param[SHIFTP_S2L1] * dz->param[SHIFTP_DEPTH]) + 1.0;
|
|
|
+ else
|
|
|
+ dz->param[SHIFTP_NS2] = 1.0 - (dz->param[SHIFTP_1LS2] * dz->param[SHIFTP_DEPTH]);
|
|
|
+ default:
|
|
|
+ if(dz->param[SHIFTP_SHF1] > 1.0)
|
|
|
+ dz->param[SHIFTP_NS1] = (dz->param[SHIFTP_S1L1] * dz->param[SHIFTP_DEPTH]) + 1.0;
|
|
|
+ else
|
|
|
+ dz->param[SHIFTP_NS1] = 1.0 - (dz->param[SHIFTP_1LS1] * dz->param[SHIFTP_DEPTH]);
|
|
|
+ }
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/************************** TUNE_PREPROCESS ******************************/
|
|
|
+
|
|
|
+int tune_preprocess(dataptr dz)
|
|
|
+{
|
|
|
+ int exit_status;
|
|
|
+ if((exit_status = convert_params_for_tune(dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ if((dz->iparray[TUNE_LOUD] = (int *)malloc(dz->wanted * sizeof(int)))==NULL) {
|
|
|
+ sprintf(errstr,"INSUFFICIENT MEMORY for loudness array.\n");
|
|
|
+ return(MEMORY_ERROR);
|
|
|
+ }
|
|
|
+ return setup_ring(dz);
|
|
|
+}
|
|
|
+
|
|
|
+/************ CONVERT_PARAMS_FOR_TUNE *************/
|
|
|
+
|
|
|
+int convert_params_for_tune(dataptr dz)
|
|
|
+{
|
|
|
+ double *p;
|
|
|
+ int n;
|
|
|
+ if(dz->brksize[TUNE_CLAR]==0)
|
|
|
+ dz->param[TUNE_CLAR] = 1.0 - dz->param[TUNE_CLAR];
|
|
|
+ else {
|
|
|
+ p = dz->brk[TUNE_CLAR] + 1;
|
|
|
+ for(n = 0;n<dz->brksize[TUNE_CLAR];n++) {
|
|
|
+ *p = 1.0 - *p;
|
|
|
+ p += 2;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/************************** PICK_PREPROCESS ******************************/
|
|
|
+
|
|
|
+int pick_preprocess(dataptr dz)
|
|
|
+{
|
|
|
+ int exit_status;
|
|
|
+ if((exit_status = adjust_parameters_for_specpick(dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ if((exit_status = setup_internal_bitflags(PICK_BFLG,PICK_LONGPOW2,PICK_DIVMASK,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ return mark_chosen_channels_in_bitflags(dz);
|
|
|
+}
|
|
|
+
|
|
|
+/************ ADJUST_PARAMETERS_FOR_SPECPICK *************/
|
|
|
+
|
|
|
+int adjust_parameters_for_specpick(dataptr dz)
|
|
|
+{
|
|
|
+ /* Make perceived clarity grow linearly with entered val: PICK */
|
|
|
+
|
|
|
+ double *p;
|
|
|
+ int n;
|
|
|
+ if(dz->brksize[PICK_CLAR] == 0) {
|
|
|
+ dz->param[PICK_CLAR] = 1.0 - dz->param[PICK_CLAR];
|
|
|
+ dz->param[PICK_CLAR] = pow(dz->param[PICK_CLAR],SCALEFUDGE);
|
|
|
+ } else {
|
|
|
+ p = dz->brk[PICK_CLAR] + 1;
|
|
|
+ for(n=0; n < dz->brksize[PICK_CLAR]; n++) {
|
|
|
+ *p = 1.0 - *p;
|
|
|
+ *p = pow(*p,SCALEFUDGE);
|
|
|
+ p += 2;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/***************************** MARK_CHOSEN_CHANNELS_IN_BITFLAGS *************/
|
|
|
+
|
|
|
+int mark_chosen_channels_in_bitflags(dataptr dz)
|
|
|
+{
|
|
|
+ int exit_status;
|
|
|
+ int n=1, chan;
|
|
|
+ int mask;
|
|
|
+ int botpchan = 0;
|
|
|
+ double lastchtop = dz->chwidth/2.0;
|
|
|
+ double partial = dz->param[PICK_FUND];
|
|
|
+ do {
|
|
|
+ if((exit_status = chan_containing_partial(&botpchan,&lastchtop,&chan,partial,dz))<0) {
|
|
|
+ sprintf(errstr,"Problem with partial->channel calculation: mark_chosen_channels_in_bitflags()\n");
|
|
|
+ return(PROGRAM_ERROR);
|
|
|
+ }
|
|
|
+ mask = 1; /* set bitflag */
|
|
|
+ dz->lparray[PICK_BFLG][(chan>>dz->iparam[PICK_LONGPOW2])]
|
|
|
+ |= (mask <<= (chan & dz->iparam[PICK_DIVMASK]));
|
|
|
+ switch(dz->mode) {
|
|
|
+ case(PIK_HARMS): n++; partial = dz->param[PICK_FUND] * (double)n; break;
|
|
|
+ case(PIK_OCTS): partial = partial * 2.0; break;
|
|
|
+ case(PIK_ODD_HARMS): n+=2; partial = dz->param[PICK_FUND] * (double)n; break;
|
|
|
+ case(PIK_LINEAR): partial += dz->param[PICK_LIN]; break;
|
|
|
+ case(PIK_DISPLACED_HARMS): n++; partial = (dz->param[PICK_FUND]
|
|
|
+ * (double)n) + dz->param[PICK_LIN];
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ sprintf(errstr,"Programing Problem: Unknown mode in mark_chosen_channels_in_bitflags()\n");
|
|
|
+ return(PROGRAM_ERROR);
|
|
|
+ }
|
|
|
+ } while(partial < dz->nyquist);
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/************************** CHAN_CONTAINING_PARTIAL *************************/
|
|
|
+
|
|
|
+int chan_containing_partial(int *botpchan,double *lastchtop,int *chan,double partial,dataptr dz)
|
|
|
+{
|
|
|
+ int n;
|
|
|
+ double chtop;
|
|
|
+ chtop = *lastchtop;
|
|
|
+ for(n=*botpchan; n<=dz->clength ;n++) {
|
|
|
+ if(partial < chtop) {
|
|
|
+ *botpchan = n;
|
|
|
+ *lastchtop = chtop;
|
|
|
+ *chan = n;
|
|
|
+ return(FINISHED);
|
|
|
+ }
|
|
|
+ chtop += dz->chwidth;
|
|
|
+ }
|
|
|
+ return(GOAL_FAILED);
|
|
|
+}
|
|
|
+
|
|
|
+/********************************************************************************************/
|
|
|
+/********************************** 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) {
|
|
|
+ case(ALT): return outer_loop(dz);
|
|
|
+ case(OCT): return outer_loop(dz);
|
|
|
+ case(SHIFTP): return outer_loop(dz);
|
|
|
+ case(TUNE): return outer_loop(dz);
|
|
|
+ case(PICK): return outer_loop(dz);
|
|
|
+ case(MULTRANS): return outer_loop(dz);
|
|
|
+ case(CHORD): return outer_loop(dz);
|
|
|
+ default:
|
|
|
+ sprintf(errstr,"Unknown process in procspec()\n");
|
|
|
+ return(PROGRAM_ERROR);
|
|
|
+ }
|
|
|
+ return(FINISHED); /* NOTREACHED */
|
|
|
+}
|
|
|
+
|
|
|
+/**************************** INNER_LOOP ****************************/
|
|
|
+
|
|
|
+int inner_loop
|
|
|
+(int *peakscore,int *descnt,int *in_start_portion,int *least,int *pitchcnt,int windows_in_buf,dataptr dz)
|
|
|
+{
|
|
|
+ int exit_status;
|
|
|
+ int local_zero_set = FALSE;
|
|
|
+ int wc;
|
|
|
+ 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) {
|
|
|
+ dz->flbufptr[0] += dz->wanted;
|
|
|
+ dz->total_windows++;
|
|
|
+ dz->time = (float)(dz->time + dz->frametime);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if((exit_status = read_values_from_all_existing_brktables((double)dz->time,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+
|
|
|
+ switch(dz->process) {
|
|
|
+ case(ALT): exit_status = specalt(pitchcnt,dz); break;
|
|
|
+ case(OCT): exit_status = specoct(dz); break;
|
|
|
+ case(CHORD): exit_status = specchord(dz); break;
|
|
|
+ case(MULTRANS): exit_status = specchord2(dz); break;
|
|
|
+ case(PICK): exit_status = specpick(dz); break;
|
|
|
+ case(SHIFTP): exit_status = specshiftp(dz); break;
|
|
|
+ case(TUNE): exit_status = spectune(dz); break;
|
|
|
+ default:
|
|
|
+ sprintf(errstr,"unknown process in inner_loop()\n");
|
|
|
+ return(PROGRAM_ERROR);
|
|
|
+ }
|
|
|
+ if(exit_status<0)
|
|
|
+ return(exit_status);
|
|
|
+ dz->flbufptr[0] += dz->wanted;
|
|
|
+ dz->total_windows++;
|
|
|
+ dz->time = (float)(dz->time + dz->frametime);
|
|
|
+ }
|
|
|
+ if(!dz->zeroset && local_zero_set==TRUE) {
|
|
|
+ fprintf(stdout,"WARNING: Zero-amp spectral window(s) encountered: orig window(s) substituted.\n");
|
|
|
+ fflush(stdout);
|
|
|
+ dz->zeroset = TRUE;
|
|
|
+ }
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/***************** SKIP_OR_SPECIAL_OPERATION_ON_WINDOW_ZERO ************/
|
|
|
+
|
|
|
+int skip_or_special_operation_on_window_zero(dataptr dz)
|
|
|
+{
|
|
|
+ int vc;
|
|
|
+ switch(dz->process) {
|
|
|
+ case(CHORD): case(OCT): case(MULTRANS):
|
|
|
+ switch(dz->process) {
|
|
|
+ case(CHORD):
|
|
|
+ case(MULTRANS):
|
|
|
+ for(vc = 0; vc < dz->wanted; vc += 2)
|
|
|
+ dz->windowbuf[0][FREQ] = dz->flbufptr[0][FREQ];
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ return(TRUE);
|
|
|
+ }
|
|
|
+ return(FALSE);
|
|
|
+}
|
|
|
+
|
|
|
+/********************************************************************************************/
|
|
|
+/********************************** FORMERLY IN pconsistency.c ******************************/
|
|
|
+/********************************************************************************************/
|
|
|
+
|
|
|
+/****************************** CHECK_PARAM_VALIDITY_AND_CONSISTENCY *********************************/
|
|
|
+
|
|
|
+int check_param_validity_and_consistency(dataptr dz)
|
|
|
+{
|
|
|
+ handle_pitch_zeros(dz);
|
|
|
+ switch(dz->process) {
|
|
|
+ case(SHIFTP): return check_viability_and_compatibility_of_shiftp_params(dz);
|
|
|
+ }
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/***************** CHECK_VIABILITY_AND_COMPATIBILITY_OF_SHIFTP_PARAMS ******************/
|
|
|
+
|
|
|
+int check_viability_and_compatibility_of_shiftp_params(dataptr dz)
|
|
|
+{
|
|
|
+ int exit_status;
|
|
|
+ double thistime = 0.0;
|
|
|
+ if(dz->vflag[SHP_IS_DEPTH]) {
|
|
|
+ if((exit_status = check_depth_vals(SHIFTP_DEPTH,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ }
|
|
|
+ if(dz->brksize[SHIFTP_FFRQ] || dz->brksize[SHIFTP_SHF1] || dz->brksize[SHIFTP_SHF2]) {
|
|
|
+ while(thistime < dz->duration + dz->frametime) {
|
|
|
+ if((exit_status = read_values_from_all_existing_brktables(thistime,dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ if((exit_status = sub_check_shiftp(dz))<0)
|
|
|
+ return(exit_status);
|
|
|
+ thistime += dz->frametime;
|
|
|
+ }
|
|
|
+ return(FINISHED);
|
|
|
+ }
|
|
|
+ return sub_check_shiftp(dz);
|
|
|
+}
|
|
|
+
|
|
|
+/*********************** SUB_CHECK_SHIFTP ***********************/
|
|
|
+
|
|
|
+int sub_check_shiftp(dataptr dz)
|
|
|
+{
|
|
|
+ double frq = dz->param[SHIFTP_FFRQ] + dz->chwidth/2.0;
|
|
|
+ int fdcno = (int)floor(frq/dz->chwidth);
|
|
|
+ switch(dz->mode) {
|
|
|
+ case(P_SHFT_UP_AND_DN):
|
|
|
+ dz->param[SHIFTP_SHF1] *= OCTAVES_PER_SEMITONE;
|
|
|
+ dz->param[SHIFTP_SHF1] = pow(2.0,dz->param[SHIFTP_SHF1]);
|
|
|
+ dz->param[SHIFTP_SHF2] *= OCTAVES_PER_SEMITONE;
|
|
|
+ dz->param[SHIFTP_SHF2] = pow(2.0,dz->param[SHIFTP_SHF2]);
|
|
|
+
|
|
|
+ if(dz->param[SHIFTP_SHF1] > 1.0
|
|
|
+ && round((double)(dz->clength-1)/dz->param[SHIFTP_SHF1]) < fdcno) {
|
|
|
+ sprintf(errstr,"Shift above frq split is too great to work.\n");
|
|
|
+ return(DATA_ERROR);
|
|
|
+ }
|
|
|
+ if(dz->param[SHIFTP_SHF1] <= 1.0
|
|
|
+ && round((double)(dz->clength-1)*dz->param[SHIFTP_SHF1]) <= fdcno) {
|
|
|
+ sprintf(errstr,"Shift above frq split is too great to work.\n");
|
|
|
+ return(DATA_ERROR);
|
|
|
+ }
|
|
|
+ if(dz->param[SHIFTP_SHF2] > dz->param[SHIFTP_FFRQ]/SPEC_MINFRQ) {
|
|
|
+ sprintf(errstr,"Shift below frq split is too great to work.\n");
|
|
|
+ return(DATA_ERROR);
|
|
|
+ }
|
|
|
+ if(dz->param[SHIFTP_SHF2] <= 1.0
|
|
|
+ && (1.0/dz->param[SHIFTP_SHF2]) >= dz->param[SHIFTP_FFRQ]/SPEC_MINFRQ) {
|
|
|
+ sprintf(errstr,"Shift below frq split is too great to work.\n");
|
|
|
+ return(DATA_ERROR);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case(P_SHFT_DN):
|
|
|
+ dz->param[SHIFTP_SHF1] *= OCTAVES_PER_SEMITONE;
|
|
|
+ dz->param[SHIFTP_SHF1] = pow(2.0,dz->param[SHIFTP_SHF1]);
|
|
|
+ if(dz->param[SHIFTP_SHF1] > 1.0
|
|
|
+ && round((double)(dz->clength-1)/dz->param[SHIFTP_SHF1]) < fdcno) {
|
|
|
+ sprintf(errstr,"Shift incompatible with frqsplit.\n");
|
|
|
+ return(DATA_ERROR);
|
|
|
+ }
|
|
|
+ if(dz->param[SHIFTP_SHF1] <= 1.0
|
|
|
+ && round((double)(dz->clength-1)*dz->param[SHIFTP_SHF1]) < fdcno) {
|
|
|
+ sprintf(errstr,"Shift incompatible with frqsplit.\n");
|
|
|
+ return(DATA_ERROR);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case(P_SHFT_UP):
|
|
|
+ dz->param[SHIFTP_SHF1] *= OCTAVES_PER_SEMITONE;
|
|
|
+ dz->param[SHIFTP_SHF1] = pow(2.0,dz->param[SHIFTP_SHF1]);
|
|
|
+ if(dz->param[SHIFTP_SHF1] > 1.0
|
|
|
+ && round((double)(dz->clength-1)/dz->param[SHIFTP_SHF1]) < fdcno) {
|
|
|
+ sprintf(errstr,"Shift incompatible with frqsplit.\n");
|
|
|
+ return(DATA_ERROR);
|
|
|
+ }
|
|
|
+ if(dz->param[SHIFTP_SHF1] <= 1.0
|
|
|
+ && round((double)(dz->clength-1)*dz->param[SHIFTP_SHF1]) <= fdcno) {
|
|
|
+ sprintf(errstr,"Shift incompatible with frqsplit.\n");
|
|
|
+ return(DATA_ERROR);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ return(FINISHED);
|
|
|
+}
|
|
|
+
|
|
|
+/********************************************************************************************/
|
|
|
+/********************************** FORMERLY IN buffers.c ***********************************/
|
|
|
+/********************************************************************************************/
|
|
|
+
|
|
|
+/**************************** ALLOCATE_LARGE_BUFFERS ******************************/
|
|
|
+
|
|
|
+int allocate_large_buffers(dataptr dz)
|
|
|
+{
|
|
|
+ switch(dz->process) {
|
|
|
+ case(ALT): case(OCT): case(SHIFTP):
|
|
|
+ case(TUNE): case(PICK): case(MULTRANS):
|
|
|
+ case(CHORD):
|
|
|
+ return allocate_single_buffer(dz);
|
|
|
+ }
|
|
|
+ sprintf(errstr,"Unknown program no. in allocate_large_buffers()\n");
|
|
|
+ return(PROGRAM_ERROR);
|
|
|
+}
|
|
|
+
|
|
|
+/********************************************************************************************/
|
|
|
+/********************************** FORMERLY IN cmdline.c ***********************************/
|
|
|
+/********************************************************************************************/
|
|
|
+
|
|
|
+int get_process_no(char *prog_identifier_from_cmdline,dataptr dz)
|
|
|
+{
|
|
|
+ if (!strcmp(prog_identifier_from_cmdline,"altharms")) dz->process = ALT;
|
|
|
+ else if(!strcmp(prog_identifier_from_cmdline,"octmove")) dz->process = OCT;
|
|
|
+ else if(!strcmp(prog_identifier_from_cmdline,"transp")) dz->process = SHIFTP;
|
|
|
+ else if(!strcmp(prog_identifier_from_cmdline,"tune")) dz->process = TUNE;
|
|
|
+ else if(!strcmp(prog_identifier_from_cmdline,"pick")) dz->process = PICK;
|
|
|
+ else if(!strcmp(prog_identifier_from_cmdline,"chord")) dz->process = MULTRANS;
|
|
|
+ else if(!strcmp(prog_identifier_from_cmdline,"chordf")) dz->process = CHORD;
|
|
|
+ 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,
|
|
|
+ "\nPITCH OPERATIONS ON A SPECTRAL FILE\n\n"
|
|
|
+ "USAGE: pitch NAME (mode) infile outfile parameters: \n"
|
|
|
+ "\n"
|
|
|
+ "where NAME can be any one of\n"
|
|
|
+ "\n"
|
|
|
+ "altharms octmove transp tune pick chordf chord\n\n"
|
|
|
+ "Type 'pitch altharms' for more info on pitch altharms..ETC.\n");
|
|
|
+ return(USAGE_ONLY);
|
|
|
+}
|
|
|
+
|
|
|
+/******************************** USAGE2 ********************************/
|
|
|
+
|
|
|
+int usage2(char *str)
|
|
|
+{
|
|
|
+ if(!strcmp(str,"altharms")) {
|
|
|
+ fprintf(stdout,
|
|
|
+ "pitch altharms mode infile pitchfile outfile [-x]\n"
|
|
|
+ "\n"
|
|
|
+ "DELETE ALTERNATE HARMONICS\n"
|
|
|
+ "\n"
|
|
|
+ "MODES :-\n"
|
|
|
+ "1 delete odd harmonics.\n"
|
|
|
+ " Usually produces octave up transposition with no formant change.\n"
|
|
|
+ "2 delete even harmonics.\n"
|
|
|
+ "-x alternative spectral reconstruction.\n\n"
|
|
|
+ "PITCHFILE must be derived from infile\n");
|
|
|
+ } else if(!strcmp(str,"octmove")) {
|
|
|
+ fprintf(stdout,
|
|
|
+ "pitch octmove 1-2 infile pitchfile outfile [-i] transposition\n"
|
|
|
+ "pitch octmove 3 infile pitchfile outfile [-i] transposition bassboost\n"
|
|
|
+ "\n"
|
|
|
+ "OCTAVE TRANSPOSE WITHOUT FORMANT SHIFT\n"
|
|
|
+ "\n"
|
|
|
+ "MODES :-\n"
|
|
|
+ "1 transpose up.\n"
|
|
|
+ "2 transpose down.\n"
|
|
|
+ "3 transpose down, with bass-reinforcement.\n"
|
|
|
+ "\n"
|
|
|
+ "PITCHFILE must be derived from infile.\n"
|
|
|
+ "transposition an integer transposition-ratio: 2 is 8va, 3 is 12th etc.\n"
|
|
|
+ " as in harmonic series.\n"
|
|
|
+ "bassboost bass reinforcement: values >=0.0\n"
|
|
|
+ "-i quicksearch for formants (less accurate).\n"
|
|
|
+ "\n"
|
|
|
+ "bassboost may vary over time.\n");
|
|
|
+ } else if(!strcmp(str,"transp")) { /* SHIFTP */
|
|
|
+ fprintf(stdout,
|
|
|
+ "pitch transp 1-3 infile outfile frq_split [-ddepth]\n"
|
|
|
+ "pitch transp 4-5 infile outfile frq_split transpos [-ddepth]\n"
|
|
|
+ "pitch transp 6 infile outfile frq_split transpos1 transpos2 [-ddepth]\n"
|
|
|
+ "\n"
|
|
|
+ "SHIFT PITCH OF (PART OF) SPECTRUM\n"
|
|
|
+ "\n"
|
|
|
+ "MODES :-\n"
|
|
|
+ "1 Octave transpose up, above freq_split.\n"
|
|
|
+ "2 Octave transpose down, below freq_split.\n"
|
|
|
+ "3 Octave transpose up and down.\n"
|
|
|
+ "4 Pitch transpose up, above freq_split.\n"
|
|
|
+ "5 Pitch transpose down, below freq_split.\n"
|
|
|
+ "6 Pitch transpose up and down.\n"
|
|
|
+ "\n"
|
|
|
+ "frq_split is frequency above or below which transposition takes place.\n"
|
|
|
+ "transpos is transposition above or below freq_split.\n"
|
|
|
+ "transpos1 is transposition above freq_split. (semitones)\n"
|
|
|
+ "transpos2 is transposition below freq_split. (semitones)\n"
|
|
|
+ "depth transposition effect on source (from 0(no effect) to 1(full effect))\n"
|
|
|
+ "\n"
|
|
|
+ "depth,frq_split,transpos1 & transpos2 can vary over time.\n");
|
|
|
+ } else if(!strcmp(str,"tune")) {
|
|
|
+ fprintf(stdout,
|
|
|
+ "pitch tune mode infile outfile pitch_template\n"
|
|
|
+ " [-ffocus] [-cclarity] [-ttrace] [-bbcut] \n"
|
|
|
+ "\n"
|
|
|
+ "REPLACE SPECTRAL FRQS BY HARMONICS OF SPECIFIED PITCH(ES)\n"
|
|
|
+ "\n"
|
|
|
+ "MODES :-\n"
|
|
|
+ "1 enter pitch_template data as frq (in Hz).\n"
|
|
|
+ "2 enter pitch_template data as (possibly fractional) MIDI values.\n"
|
|
|
+ "\n"
|
|
|
+ "pitch_template a value, or a textfile containing values (as hz or midi).\n"
|
|
|
+ "\n"
|
|
|
+ "-f FOCUS determines degree of focusing of partial pitches onto template.\n"
|
|
|
+ " (range 0-1: val or brkpnt file: default 1).\n"
|
|
|
+ "-c CLARITY determines degree to which non-template partials are suppressed.\n"
|
|
|
+ " (range 0-1: val or brkpnt file: default 0).\n"
|
|
|
+ "-t TRACE specifies no. of (window_by_window) most prominent channels\n"
|
|
|
+ " to be replaced by template frqs.\n"
|
|
|
+ "-b Ignore frqs below BCUT, Bass cutoff frq.\n"
|
|
|
+ "\n"
|
|
|
+ "All parameters may vary over time.\n");
|
|
|
+ } else if(!strcmp(str,"pick")) {
|
|
|
+ fprintf(stdout,
|
|
|
+ "pitch pick 1-3 infile outfile fundamental [-cclarity]\n"
|
|
|
+ "pitch pick 4-5 infile outfile fundamental frqstep [-cclarity]\n"
|
|
|
+ "\n"
|
|
|
+ "ONLY RETAIN CHANNELS WHICH MIGHT HOLD SPECIFIED PARTIALS\n"
|
|
|
+ "\n"
|
|
|
+ "MODES :-\n"
|
|
|
+ "1 Harmonic Series.\n"
|
|
|
+ "2 Octaves.\n"
|
|
|
+ "3 Odd partials of harmonic series only.\n"
|
|
|
+ "4 Partials are successive linear steps (each of frqstep) from 'fundamental'.\n"
|
|
|
+ "5 Add linear displacement (frqstep) to harmonic partials over fundamental.\n"
|
|
|
+ "\n"
|
|
|
+ "fundamental Fundamental frequency of harmonic series, (or of calculation).\n"
|
|
|
+ "frqstep Frequency step to be added to another frequency.\n"
|
|
|
+ "clarity extent to which data in other channels is suppressed.\n"
|
|
|
+ " Range 0-1: Default 1.\n"
|
|
|
+ "\n"
|
|
|
+ "clarity may vary over time.\n");
|
|
|
+ } else if(!strcmp(str,"chordf")) {
|
|
|
+ fprintf(stdout,
|
|
|
+ "pitch chordf infile outfile -fN|-pN [-i] transpose_file [-bbot] [-ttop] [-x]\n"
|
|
|
+ "\n"
|
|
|
+ "TRANSPOSED VERSIONS OF SPECTRUM SUPERIMPOSED WITHIN EXISTING SPECTRAL ENVELOPE\n"
|
|
|
+ "\n"
|
|
|
+ "-f extract spectral envelope linear-freqwise, using N chans per point.\n"
|
|
|
+ "-p extract spectral envelope linear-pitchwise, using N bands per octave.\n"
|
|
|
+ " (recommeded value 1.0)\n"
|
|
|
+ "-i quicksearch for formants (less accurate).\n"
|
|
|
+ "\n"
|
|
|
+ "transpose_file is file of (possibly fractional) semitone transposition values.\n"
|
|
|
+ "\n"
|
|
|
+ "-b BOT = bottom frq, below which data is filtered out.\n"
|
|
|
+ "-t TOP = top frq, above which data is filtered out.\n"
|
|
|
+ "-x Fuller spectrum.\n"
|
|
|
+ "\n"
|
|
|
+ "top frq and bottom frq may vary over time.\n"
|
|
|
+ "\n");
|
|
|
+ } else if(!strcmp(str,"chord")) {
|
|
|
+ fprintf(stdout,
|
|
|
+ "pitch chord infile outfile transpose_file [-bbot] [-ttop] [-x]\n"
|
|
|
+ "\n"
|
|
|
+ "TRANSPOSED VERSIONS OF SOUND SUPERIMPOSED ON ORIGINAL\n"
|
|
|
+ "\n"
|
|
|
+ "transpose_file is file of (possibly fractional) semitone transposition values.\n"
|
|
|
+ "\n"
|
|
|
+ "-t TOP = top frq, above which data is filtered out.\n"
|
|
|
+ "-b BOT = bottom frq, below which data is filtered out.\n"
|
|
|
+ "-x Fuller spectrum.\n"
|
|
|
+ "\n"
|
|
|
+ "top frq and bottom frq may vary over time.\n"
|
|
|
+ "\n");
|
|
|
+ } else
|
|
|
+ fprintf(stdout,"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);
|
|
|
+}
|
|
|
+
|