/* * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //#ifdef unix #define round(x) lround((x)) //#endif static int eliminate_octave_duplications(dataptr dz); static int check_for_invalid_data(int k,dataptr dz); static void transpose_to_lowest_oct(dataptr dz); static void bublsort_hf(dataptr dz); static void elim_dupls(dataptr dz); static int create_hfpermbufs(dataptr dz); static void establish_waveform(dataptr dz); static int read_delperm_data(char *filename,dataptr dz); static int read_delperm2_data(char *filename,dataptr dz); char warnstr[2400]; /***************************** ESTABLISH_BUFPTRS_AND_EXTRA_BUFFERS **************************/ int establish_bufptrs_and_extra_buffers(dataptr dz) { // 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(HF_PERM1): case(HF_PERM2): dz->extra_bufcnt = 0; dz->bufcnt = 3; break; case(DEL_PERM): case(DEL_PERM2): dz->extra_bufcnt = 0; dz->bufcnt = 4; 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); } 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(HF_PERM1): case(HF_PERM2): dz->array_cnt=1; dz->iarray_cnt=0; dz->larray_cnt=0; dz->ptr_cnt= 0; dz->fptr_cnt = 0; break; case(DEL_PERM): case(DEL_PERM2): dz->array_cnt=3; 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;narray_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;niarray_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;nlarray_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;nptr_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;nfptr_cnt;n++) dz->fptr[n] = NULL; } return(FINISHED); } /****************************** ASSIGN_PROCESS_LOGIC *********************************/ int assign_process_logic(dataptr dz) { switch(dz->process) { case(HF_PERM1): case(HF_PERM2): switch(dz->mode) { case(HFP_SNDOUT): setup_process_logic(WORDLIST_ONLY,UNEQUAL_SNDFILE,SNDFILE_OUT,dz); break; case(HFP_SNDSOUT): setup_process_logic(WORDLIST_ONLY,OTHER_PROCESS, NO_OUTPUTFILE,dz); break; case(HFP_TEXTOUT): setup_process_logic(WORDLIST_ONLY,TO_TEXTFILE, TEXTFILE_OUT,dz); break; case(HFP_MIDIOUT): setup_process_logic(WORDLIST_ONLY,TO_TEXTFILE, TEXTFILE_OUT,dz); break; default: sprintf(errstr,"Unknown mode: assign_process_logic()\n"); return(PROGRAM_ERROR); } break; case(DEL_PERM): setup_process_logic(WORDLIST_ONLY,UNEQUAL_SNDFILE,SNDFILE_OUT,dz); break; case(DEL_PERM2): setup_process_logic(SNDFILES_ONLY,UNEQUAL_SNDFILE,SNDFILE_OUT,dz); break; default: sprintf(errstr,"Unknown process: assign_process_logic()\n"); return(PROGRAM_ERROR); break; } 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; mode = 0; switch(process) { case(HF_PERM1): case(HF_PERM2): exit_status = set_internalparam_data("i",ap); break; case(DEL_PERM): case(DEL_PERM2): exit_status = set_internalparam_data("ii",ap); break; default: sprintf(errstr,"Unknown process in set_legal_internalparam_structure()\n"); return(PROGRAM_ERROR); } return(exit_status); } /********************************************************************************************/ /********************************** FORMERLY IN specialin.c *********************************/ /********************************************************************************************/ /********************** READ_SPECIAL_DATA ************************/ int read_special_data(char *str,dataptr dz) { // int exit_status = FINISHED; aplptr ap = dz->application; switch(ap->special_data) { case(DELPERM): return read_delperm_data(str,dz); case(DELPERM2): return read_delperm2_data(str,dz); default: sprintf(errstr,"Unknown special_data type: read_special_data()\n"); return(PROGRAM_ERROR); } return(FINISHED); /* NOTREACHED */ } /********************************************************************************************/ /********************************** FORMERLY IN preprocess.c ********************************/ /********************************************************************************************/ /****************************** PARAM_PREPROCESS *********************************/ int param_preprocess(dataptr dz) { int exit_status = FINISHED; int octaves_eliminated; double *hf = dz->parray[0]; switch(dz->process) { case(HF_PERM1): dz->iparam[HP1_HFCNT] = dz->numsize; if((exit_status = check_for_invalid_data(HP1_HFCNT,dz))<0) return(exit_status); octaves_eliminated = eliminate_octave_duplications(dz); if(dz->iparam[HP1_HFCNT] < dz->iparam[HP1_MINSET]) { sprintf(errstr,"Minimum size of note set (%d)",dz->iparam[HP1_HFCNT]); if(octaves_eliminated) { sprintf(warnstr," (after octave duplication elimination)"); strcat(errstr,warnstr); } sprintf(warnstr,"\nis less than minimum size specified for chords (%d): cannot proceed.\n",dz->iparam[HP1_MINSET]); strcat(errstr,warnstr); return(DATA_ERROR); } transpose_to_lowest_oct(dz); bublsort_hf(dz); if(hf[dz->iparam[HP1_HFCNT]-1] > (double)dz->iparam[HP1_TOPNOTE]) { sprintf(errstr,"Entered range does not span the given harmonic field\n"); return(DATA_ERROR); } break; case(HF_PERM2): dz->iparam[HP1_HFCNT] = dz->numsize; if((exit_status = check_for_invalid_data(HP1_HFCNT,dz))<0) return(exit_status); elim_dupls(dz); if(dz->iparam[HP1_HFCNT] < dz->iparam[HP1_MINSET]) { sprintf(errstr,"Minimum size of note set (%d)",dz->iparam[HP1_HFCNT]); sprintf(warnstr,"\nis less than minimum size specified for chords (%d): cannot proceed.\n",dz->iparam[HP1_MINSET]); strcat(errstr,warnstr); return(DATA_ERROR); } bublsort_hf(dz); break; case(DEL_PERM2): if((dz->ssampsread = fgetfbufEx(dz->sampbuf[1],dz->insams[0],dz->ifd[0],0)) < 0) { sprintf(errstr,"Can't read samps from input soundfile.\n"); return(SYSTEM_ERROR); } if((exit_status = check_for_invalid_data(DP_NOTECNT,dz))<0) return(exit_status); break; case(DEL_PERM): dz->iparam[DP_NOTECNT] = dz->numsize; if((exit_status = check_for_invalid_data(DP_NOTECNT,dz))<0) return(exit_status); break; default: sprintf(errstr,"Unknown process in param_preprocess()\n"); return(PROGRAM_ERROR); } return(FINISHED); } /********************************************************************************************/ /********************************** FORMERLY IN procgrou.c **********************************/ /********************************************************************************************/ /**************************** GROUCHO_PROCESS_FILE ****************************/ int groucho_process_file(dataptr dz) /* FUNCTIONS FOUND IN PROCESS.C */ { // int exit_status = FINISHED; switch(dz->process) { case(HF_PERM1): case(HF_PERM2): return do_hfperm(dz); case(DEL_PERM): case(DEL_PERM2): return gen_dp_output(dz); default: sprintf(errstr,"Unknown case in process_file()\n"); return(PROGRAM_ERROR); } return(FINISHED); /* NOTREACHED */ } /********************************************************************************************/ /********************************** FORMERLY IN pconsistency.c ******************************/ /********************************************************************************************/ /****************************** CHECK_PARAM_VALIDITY_AND_CONSISTENCY *********************************/ int check_param_validity_and_consistency(dataptr dz) { int exit_status = FINISHED; int temp; switch(dz->process) { case(HF_PERM1): dz->iparam[HP1_BOTNOTE] += MIDDLE_C_MIDI + (dz->iparam[HP1_BOTOCT] * 12); dz->iparam[HP1_TOPNOTE] += MIDDLE_C_MIDI + (dz->iparam[HP1_TOPOCT] * 12); if(dz->iparam[HP1_TOPNOTE] < dz->iparam[HP1_BOTNOTE]) { temp = dz->iparam[HP1_TOPNOTE]; dz->iparam[HP1_TOPNOTE] = dz->iparam[HP1_BOTNOTE]; dz->iparam[HP1_BOTNOTE] = temp; } /* fall thro */ case(HF_PERM2): if(dz->mode == HFP_SNDOUT || dz->mode == HFP_SNDSOUT) { if(BAD_SR(dz->iparam[HP1_SRATE])) { sprintf(errstr,"Invalid sample rate.\n"); return(DATA_ERROR); } dz->infile->channels = 1; dz->infile->srate = dz->iparam[HP1_SRATE]; dz->infile->stype = SAMP_SHORT; dz->iparam[HP1_ELEMENT_SIZE] = (int)round(dz->param[HP1_ELEMENT_SIZE] * dz->infile->srate); dz->iparam[HP1_GAP_SIZE] = (int)round(dz->param[HP1_GAP_SIZE] * dz->infile->srate); dz->iparam[HP1_GGAP_SIZE] = (int)round(dz->param[HP1_GGAP_SIZE] * dz->infile->srate); } if(dz->mode == HFP_SNDOUT) { if((exit_status = create_sized_outfile(dz->outfilename,dz))<0) return(exit_status); } break; case(DEL_PERM): if(BAD_SR(dz->iparam[DP_SRATE])) { sprintf(errstr,"Invalid sample rate.\n"); return(DATA_ERROR); } dz->infile->channels = 1; dz->infile->srate = dz->iparam[DP_SRATE]; dz->infile->stype = SAMP_SHORT; dz->iparam[DP_DUR] = (int)round(dz->param[DP_DUR] * dz->infile->srate); if((exit_status = create_sized_outfile(dz->outfilename,dz))<0) return(exit_status); break; case(DEL_PERM2): dz->iparam[DP_DUR] = (int)(dz->insams[0]); break; } return(FINISHED); } /****************************** HFPERM_CONSISTENCY *********************************/ int hfperm_consistency(dataptr dz) { return(FINISHED); } /********************************************************************************************/ /********************************** FORMERLY IN buffers.c ***********************************/ /********************************************************************************************/ /**************************** ALLOCATE_LARGE_BUFFERS ******************************/ int allocate_large_buffers(dataptr dz) { switch(dz->process) { case(HF_PERM1): case(HF_PERM2): if(dz->mode == HFP_SNDOUT || dz->mode == HFP_SNDSOUT) return create_hfpermbufs(dz); break; case(DEL_PERM): case(DEL_PERM2): return create_hfpermbufs(dz); default: sprintf(errstr,"Unknown program no. in allocate_large_buffers()\n"); return(PROGRAM_ERROR); } return(FINISHED); } /********************************************************************************************/ /********************************** FORMERLY IN cmdline.c ***********************************/ /********************************************************************************************/ int get_process_no(char *prog_identifier_from_cmdline,dataptr dz) { if (!strcmp(prog_identifier_from_cmdline,"hfchords")) dz->process = HF_PERM1; else if(!strcmp(prog_identifier_from_cmdline,"hfchords2")) dz->process = HF_PERM2; else if(!strcmp(prog_identifier_from_cmdline,"delperm")) dz->process = DEL_PERM; else if(!strcmp(prog_identifier_from_cmdline,"delperm2")) dz->process = DEL_PERM2; else { sprintf(errstr,"Unknown program identification string '%s'\n",prog_identifier_from_cmdline); return(USAGE_ONLY); } return(FINISHED); } /********************************************************************************************/ /********************************** FORMERLY IN usage.c *************************************/ /********************************************************************************************/ /******************************** USAGE1 ********************************/ int usage1(void) { sprintf(errstr, "USAGE: hfperm NAME (mode) outfile parameters\n" "\n" "where NAME can be any one of\n" "\n" "hfchords hfchords2 delperm\n" "\n" "OR: hfperm NAME (mode) infile outfile parameters\n" "\n" "where NAME can be any one of\n" "\n" "delperm2\n" "\n" "Type 'hfperm hfchords' for more info on hfperm hfchords option... ETC.\n"); return(USAGE_ONLY); } /******************************** USAGE2 ********************************/ int usage2(char *str) { if(!strcmp(str,"hfchords")) { fprintf(stdout, "GENERATE ALL CHORDS POSSIBLE FROM NOTES IN GIVEN SET, WITHIN GIVEN PITCH RANGE\n" "USING EACH NOTE (OR ITS OCTAVE TRANSPOSITION) ONCE ONLY IN ANY ONE CHORD.\n\n" "USAGE: hfperm hfchords 1 ifil ofil sr nd gd pd min bn bo tn to srt [-m -s -a -o]\n" "OR: hfperm hfchords 2 ifil ofil sr nd gd min bn bo tn to srt [-m -s -a -o]\n" "OR: hfperm hfchords 3-4 ifil ofil sr min bn bo tn to srt [-m -s -a -o]\n" "IFIL text input file of midi note values\n" "MODES: 1 SOUND OUT...Outputs 1 soundfile of all chords.\n" " 2 SOUNDS OUT..Outputs several sndfiles, chords grouped by sort specified\n" " 3 TEXT OUT ...Outputs textfile listing chords described by note names.\n" " 4 MIDI OUT ...Outputs list of chords described by MIDI values.\n" "PARAMETERS: OFIL output filename SR sample rate sound output\n" " ND duration each chord (secs) GD gap btwn chords (secs)\n" " PD gap btwn chord-groups MIN min no. notes to combine\n" "BN bottom note pitchrange, for derived chords (0-11 for C-C#....Bb-B)\n" "BO octave of bottom note (0 = octave upwards from middle C)\n" " TN top note of pitchrange TO octave of top note\n" "SRT 0 root: 1 topnote: 2 pitchclass: 3 chordtype: 4 chordtype(keep 1 of each)\n" " -m generate only chords of min number of notes specified\n" " -s in each group, put smallest span chord first (otherwise it goes last).\n" "-a do final sort by a method other than by chord density\n" " For ROOT or TOP NOTE sort, sort by way intervals stacked inside chord.\n" " For PITCHCLASS SET, sort by size of containing interval, then by density.\n" "-o eliminate chords duplicating-as-a-whole any chord 1 or more 8vas distant.\n"); } else if(!strcmp(str,"hfchords2")) { fprintf(stdout, "GENERATE ALL CHORDS POSSIBLE FROM NOTES IN GIVEN SET.\n\n" "USAGE: hfperm hfchords2 1 ifil ofil sr nd gd pd min srt [-m -s -a -o]\n" "OR: hfperm hfchords2 2 ifil ofil sr nd gd min srt [-m -s -a -o]\n" "OR: hfperm hfchords2 3-4 ifil ofil sr min srt [-m -s -a -o]\n" "IFIL text input file of midi note values\n" "MODES: 1 SOUND OUT...Outputs 1 soundfile of the chords.\n" " 2 SOUNDS OUT..Outputs several sndfiles, chords grouped by sort specified\n" " 3 TEXT OUT ...Outputs textfile listing chords described by note names.\n" " 4 MIDI OUT ...Outputs list of chords described by MIDI values.\n" "PARAMETERS ARE\n" "SRATE sample rate of the sound output\n" "NOTE-DUR duration of each chord generated (secs)\n" "GAP-DUR duration of pauses between chords (secs)\n" "PAUSE-DUR duration of pauses between groups of chords (secs)\n" "MINSET minimum number of input notes to combine\n" "SORT BY 0 root: 1 topnote: 2 pitchclass set:\n" " 3 chord type: 4 chord type (keep 1 of each).\n" "-m generate only chords of min number of notes specified\n" "-s in each group, put smallest span chord first (otherwise it goes last).\n" "-a do final sort by a method other than by chord density\n" " For ROOT or TOP NOTE sort, sort by way intervals stacked inside chord.\n" " For PITCHCLASS SET, sort by size of containing interval, then by density\n" " -o eliminate chords duplicating-as-a-whole any chord 1 or more 8vas distant\n"); } else if(!strcmp(str,"delperm")) { fprintf(stdout, "DELAY AND TRANSFORM EACH INPUT NOTE, CUMULATIVELY.\n\n" "USAGE: hfperm delperm 0 \n" " infile outfile permfile srate initial-notelen cycles-of-perm\n" "PARAMETERS ARE\n" " INFILE text input file of midi note values\n" " PERMFILE pairs of vals: 1st a semitone transpos, 2nd a time multiplier\n" " Sum of all time-multipliers must be 1.0\n" " SRATE sample rate of the sound output\n" " INITIAL-NOTELEN length of each input note, before it is transformed\n" " CYCLES-OF-PERM Number of times the permutation is recursively applied.\n"); } else if(!strcmp(str,"delperm2")) { fprintf(stdout, "DELAY AND TRANSFORM EACH INPUT NOTE, CUMULATIVELY.\n\n" "USAGE: hfperm delperm2 0 \n" " infile outfile permfile cycles-of-perm\n" "PARAMETERS ARE\n" " PERMFILE pairs of vals: 1st a semitone transpos, 2nd a time multiplier\n" " Sum of all time-multipliers must be 1.0\n" " CYCLES-OF-PERM Number of times the permutation is recursively applied.\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); } /************************** ELIMINATE_OCTAVE_DUPLICATIONS **************************/ int eliminate_octave_duplications(dataptr dz) { double *hf = dz->parray[0]; int n, m, k, octaves_eliminated = 0; for(n=0;n< dz->iparam[HP1_HFCNT]-1;n++) { for(m=n+1;m< dz->iparam[HP1_HFCNT];m++) { if(flteq(fmod(hf[n],12.0),fmod(hf[m],12.0))) { octaves_eliminated = 1; k = m; dz->iparam[HP1_HFCNT]--; while(k < dz->iparam[HP1_HFCNT]) { hf[k] = hf[k+1]; k++; } m--; } } } return octaves_eliminated; } /************************** CHECK_FOR_INVALID_DATA **************************/ int check_for_invalid_data(int k,dataptr dz) { double *hf = dz->parray[0]; int *bad, badcnt = 0; int n; if((bad = (int *)malloc(dz->iparam[k] * sizeof(int)))==NULL) return(MEMORY_ERROR); for(n=0;n< dz->iparam[k];n++) { if(hf[n] < MIDIMIN || hf[n] > MIDIMAX) bad[badcnt++] = n; } if(badcnt) { print_outmessage_flush("Invalid midi data in input.....\n"); for(n=0;n < badcnt;n++) { sprintf(errstr,"item %d : value %ld\n",bad[n], round(hf[bad[n]])); print_outmessage_flush(errstr); } sprintf(errstr,"Cannot proceed\n"); return(DATA_ERROR); } return FINISHED; } /**************************** TRANSPOSE_TO_LOWEST_OCT *******************************/ void transpose_to_lowest_oct(dataptr dz) { int n; double *hf = dz->parray[0]; for(n=0;niparam[HP1_HFCNT];n++) { while(hf[n] < (double)dz->iparam[HP1_BOTNOTE]) hf[n] += 12.0; while(hf[n] >= (double)dz->iparam[HP1_BOTNOTE]) hf[n] -= 12.0; hf[n] += 12.0; } } /**************************** BUBLSORT_HF *******************************/ void bublsort_hf(dataptr dz) { int n, m; double temp; double *hf = dz->parray[0]; for(n=0;niparam[HP1_HFCNT]-1;n++) { for(m = n; miparam[HP1_HFCNT]; m++) { if(hf[m] < hf[n]) { temp = hf[n]; hf[n] = hf[m]; hf[m] = temp; } } } } /**************************** ELIM_DUPLS *******************************/ void elim_dupls(dataptr dz) { int n, m, k; double *hf = dz->parray[0]; for(n=0;niparam[HP1_HFCNT]-1;n++) { for(m = n+1; miparam[HP1_HFCNT]; m++) { if(hf[m] == hf[n]) { for(k = m+1; k < dz->iparam[HP1_HFCNT];k++) hf[k-1] = hf[k]; dz->iparam[HP1_HFCNT]--; m--; } } } } /******************************** 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); } /*************************** CREATE_HFPERMBUFS **************************/ int create_hfpermbufs(dataptr dz) { unsigned int presize = 0; //TW ADDED size_t bigbufsize; int fbytesector = F_SECSIZE * sizeof(float); int max_jitter = (int)round((double)HFP_MAXJITTER * (double)MS_TO_SECS * (double)dz->infile->srate); int k = 0; switch(dz->process) { case(HF_PERM1): case(HF_PERM2): k = HP1_ELEMENT_SIZE; break; case(DEL_PERM): case(DEL_PERM2): k = DP_DUR; break; } if(dz->sbufptr == 0 || dz->sampbuf==0) { sprintf(errstr,"buffer pointers not allocated: create_hfpermbufs()\n"); return(PROGRAM_ERROR); } switch(dz->process) { case(HF_PERM1): case(HF_PERM2): presize = (dz->iparam[k] + max_jitter + HFP_TABSIZE + 1) * sizeof(double); break; case(DEL_PERM): presize = ((dz->iparam[k] * 2) + max_jitter + HFP_TABSIZE + 1) * sizeof(double); break; case(DEL_PERM2): presize = ((dz->iparam[k] * 2) + max_jitter) * sizeof(double) + dz->iparam[k] * sizeof(float); break; } //TW CHANGED FOR FLOATS bigbufsize = (size_t) Malloc(-1); if((bigbufsize = (bigbufsize/fbytesector) * fbytesector)<=0) bigbufsize = fbytesector; while((dz->bigbuf = (float *)malloc((size_t)(bigbufsize + presize))) == NULL) { if((bigbufsize -= fbytesector) <= 0) { sprintf(errstr,"INSUFFICIENT MEMORY to create sound buffers.\n"); return(PROGRAM_ERROR); } } dz->buflen = (int)(bigbufsize/sizeof(float)); memset(dz->bigbuf,0,bigbufsize + presize); switch(dz->process) { case(HF_PERM1): case(HF_PERM2): case(DEL_PERM): dz->sbufptr[0] = dz->sampbuf[0] = dz->bigbuf; dz->sbufptr[1] = dz->sampbuf[1] = dz->bigbuf + dz->buflen; dz->sampbuf[2] = (float *)((double *)dz->sampbuf[1] + HFP_TABSIZE + 1); dz->sampbuf[3] = (float *)((double *)dz->sampbuf[2] + dz->iparam[k] + max_jitter); if(dz->process == DEL_PERM) dz->sampbuf[4] = (float *)((double *)dz->sampbuf[3] + dz->iparam[k]); establish_waveform(dz); break; case(DEL_PERM2): dz->sbufptr[0] = dz->sampbuf[0] = dz->bigbuf; dz->sbufptr[1] = dz->sampbuf[1] = dz->bigbuf + dz->buflen; dz->sampbuf[2] = dz->sampbuf[1] + dz->insams[0]; dz->sampbuf[3] = (float *)((double *)dz->sampbuf[2] + dz->iparam[k] + max_jitter); dz->sampbuf[4] = (float *)((double *)dz->sampbuf[3] + dz->iparam[k]); break; } return(FINISHED); } /*************************** ESTABLISH_WAVEFORM ************************** * * Odd harmonics, declining in amplitude 1, 1/2. 1.3, 1/4 etc... */ void establish_waveform(dataptr dz) { int n, partialno, ampdivide; double j, maxval = 0.0, normaliser; double *sintab = (double *)dz->sampbuf[1]; memset((char *)sintab,0,HFP_TABSIZE * sizeof(double)); for(partialno=1,ampdivide=1;partialno<12;partialno+=2,ampdivide++) { for(n=0;n < HFP_TABSIZE; n++) { j = sin(TWOPI * partialno * (double)n/(double)HFP_TABSIZE)/(double)ampdivide; *sintab += j; maxval = max(maxval,fabs(*sintab)); sintab++; } j = sin(TWOPI * partialno * (double)n/(double)HFP_TABSIZE)/(double)ampdivide; *sintab += j; maxval = max(maxval,fabs(*sintab)); sintab = (double *)dz->sampbuf[1]; } normaliser = 1.0/maxval; for(n=0;n < HFP_TABSIZE; n++) *sintab++ *= normaliser; } /************************** READ_DELPERM_DATA ********************************/ int read_delperm_data(char *filename,dataptr dz) { int n = 0, k, valcnt = 0; char temp[200], *p; double *val; // int is_transpos = TRUE; double dursum = 0.0; int arraysize = BIGARRAY; if((dz->fp = fopen(filename,"r"))==NULL) { sprintf(errstr,"Cannot open datafile %s\n",filename); return(DATA_ERROR); } if((val = (double *)malloc(arraysize * sizeof(double)))==NULL) { sprintf(errstr,"No memory for permutation data.\n"); return(MEMORY_ERROR); } while(fgets(temp,200,dz->fp)!=NULL) { p = temp; while(strgetfloat(&p,&(val[valcnt]))) { if(++valcnt > arraysize) { arraysize += BIGARRAY; if((val = (double *)realloc((char *)val,arraysize * sizeof(double)))==NULL) { sprintf(errstr,"Out of memory loading permutation data.\n"); return(MEMORY_ERROR); } } } } if(valcnt < arraysize) { if((val = (double *)realloc((char *)val,valcnt * sizeof(double)))==NULL) { sprintf(errstr,"Squeezing permutation data.\n"); return(MEMORY_ERROR); } } if(ODD(valcnt)) { sprintf(errstr,"Permutation data incorrectly paired.\n"); return(DATA_ERROR); } valcnt /= 2; if((dz->parray[1] = (double *)malloc(valcnt * sizeof(double)))==NULL) { sprintf(errstr,"No memory for transposition data.\n"); return(MEMORY_ERROR); } if((dz->parray[2] = (double *)malloc(valcnt * sizeof(double)))==NULL) { sprintf(errstr,"No memory for transposition data.\n"); return(MEMORY_ERROR); } for(n=0,k=0;nparray[1][n] = val[k++]) < dz->application->min_special || dz->parray[1][n] > dz->application->max_special) { sprintf(errstr,"Transposition value %lf out of range, in permutation data.\n",dz->parray[1][n]); return(DATA_ERROR); } if((dz->parray[2][n] = val[k++]) < dz->application->min_special2 || dz->parray[2][n] > dz->application->max_special2) { sprintf(errstr,"Duration multiplier value %lf out of range, in permutation data.\n",dz->parray[2][n]); return(DATA_ERROR); } dursum += dz->parray[2][n]; } if(!flteq(dursum,1.0)) { sprintf(errstr,"Duration multipliers in permutation data do not sum to 1.0.\n"); return(DATA_ERROR); } free(val); if(fclose(dz->fp)<0) { fprintf(stdout,"WARNING: Failed to close input textfile %s.\n",filename); fflush(stdout); } dz->iparam[DP_PERMCNT] = valcnt; return(FINISHED); } /************************** READ_DELPERM2_DATA ********************************/ int read_delperm2_data(char *filename,dataptr dz) { int n = 0, k, valcnt = 0/*, linecnt = 0*/; char temp[200], *p; double *val; // int is_transpos = TRUE; double dursum = 0.0; int arraysize = BIGARRAY; if((dz->fp = fopen(filename,"r"))==NULL) { sprintf(errstr,"Cannot open datafile %s\n",filename); return(DATA_ERROR); } if((val = (double *)malloc(arraysize * sizeof(double)))==NULL) { sprintf(errstr,"No memory for permutation data.\n"); return(MEMORY_ERROR); } while(fgets(temp,200,dz->fp)!=NULL) { p = temp; while(strgetfloat(&p,&(val[valcnt]))) { if(++valcnt > arraysize) { arraysize += BIGARRAY; if((val = (double *)realloc((char *)val,arraysize * sizeof(double)))==NULL) { sprintf(errstr,"Out of memory loading permutation data.\n"); return(MEMORY_ERROR); } } } /* if(!linecnt) { if((dz->parray[0] = (double *)malloc(valcnt * sizeof(double)))==NULL) { sprintf(errstr,"No memory for midi transposition data data.\n"); return(MEMORY_ERROR); } dz->iparam[DP_NOTECNT] = valcnt; memcpy((char *)dz->parray[0],(char *)val,valcnt * sizeof(double)); linecnt++; valcnt = 0; continue; } */ } if(valcnt < arraysize) { if((val = (double *)realloc((char *)val,valcnt * sizeof(double)))==NULL) { sprintf(errstr,"Squeezing permutation data.\n"); return(MEMORY_ERROR); } } if(ODD(valcnt)) { sprintf(errstr,"Permutation data incorrectly paired.\n"); return(DATA_ERROR); } valcnt /= 2; if((dz->parray[1] = (double *)malloc(valcnt * sizeof(double)))==NULL) { sprintf(errstr,"No memory for transposition data.\n"); return(MEMORY_ERROR); } if((dz->parray[2] = (double *)malloc(valcnt * sizeof(double)))==NULL) { sprintf(errstr,"No memory for duration multiplier data.\n"); return(MEMORY_ERROR); } for(n=0,k=0;nparray[1][n] = val[k++]) < dz->application->min_special || dz->parray[1][n] > dz->application->max_special) { sprintf(errstr,"Transposition value %lf out of range, in permutation data.\n",dz->parray[1][n]); return(DATA_ERROR); } if((dz->parray[2][n] = val[k++]) < dz->application->min_special2 || dz->parray[2][n] > dz->application->max_special2) { sprintf(errstr,"Duration multiplier value %lf out of range, in permutation data.\n",dz->parray[2][n]); return(DATA_ERROR); } dursum += dz->parray[2][n]; } if(!flteq(dursum,1.0)) { sprintf(errstr,"Duration multipliers in permutation data do not sum to 1.0. (%lf)\n",dursum); return(DATA_ERROR); } free(val); if(fclose(dz->fp)<0) { fprintf(stdout,"WARNING: Failed to close input textfile %s.\n",filename); fflush(stdout); } dz->iparam[DP_PERMCNT] = valcnt; return(FINISHED); }