| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117 |
- /*
- * Copyright (c) 1983-2023 Trevor Wishart and Composers Desktop Project Ltd
- * http://www.trevorwishart.co.uk
- * http://www.composersdesktop.com
- *
- This file is part of the CDP System.
- The CDP System is free software; you can redistribute it
- and/or modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
- The CDP System is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public
- License along with the CDP System; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA
- *
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <memory.h>
- #include <sfsys.h>
- #include <osbind.h>
- #include <ctype.h>
- #include <structures.h>
- #include <pnames.h>
- #include <processno.h>
- #include <flags.h>
- #include <modeno.h>
- #include <cdpmain.h>
- #include <globcon.h>
- #include <tkglobals.h>
- #include <logic.h>
- #include <math.h>
- #include <hfperm.h>
- #if defined unix || defined __GNUC__
- #define round(x) lround((x))
- #endif
- #define BY_STACKING (0)
- #define BY_DENSITY (1)
- #define SMALLEST_FIRST (0)
- #define LARGEST_FIRST (1)
- #define ROOT (0)
- #define TOPNOTE (1)
- #define KEEP_OCT_EQUIVS (0)
- #define ELIMINATE_OCT_EQUIVS (1)
- #define ROLLOFF (0.66)
- static int generate_perms(double ***combo,int **combolen,int *combocnt,dataptr dz);
- static int set_element(int element_no,int total_elements,int field_cnt,int *element,
- double ***combo,int **combolen,int *combocnt);
- static int store_combo(double ***combo,int *combocnt,int **combolen,int *element,int total_elements);
- static void substitute_midivals_in_perms(double **combo,int *combolen,int combocnt,dataptr dz);
- static int generate_hfsets(int combocnt,double **combo,int *combolen,
- double ***hfset,int **hfsetlen,int *hfsetcnt,dataptr dz);
- static int transpose_element(int element_no,double *thiscombo,int thiscombolen,double *origval,
- double ***hfset,int **hfsetlen,int *hfsetcnt,dataptr dz);
- static int store_transposition(double ***hfset,int **hfsetlen,int *hfsetcnt,double *thiscombo,int thiscombolen);
- static int sort_hfsets(double **hfset,int *hfsetlen,int *hfsetcnt,int *grping,dataptr dz);
- static int gen_output(int hfsetcnt,double **hfset,int *hfsetlen,int *grping,dataptr dz);
- static int gen_outputs(int hfsetcnt,double **hfset,int *hfsetlen,int *grping,dataptr dz);
- static int gen_text_output(int hfsetcnt,double **hfset,int *hfsetlen,int *grping,dataptr dz);
- static int gen_midi_output(int hfsetcnt,double **hfset,int *hfsetlen,int *grping,dataptr dz);
- static void print_grouping_structure(int n,int *grping,int *grping_cnt,int *in_grp,int hfsetcnt);
- static void printout_grouping_structure(int n,int *grping,int *grping_cnt,int *in_grp,int hfsetcnt,dataptr dz);
- static void set_pitch_to_print(int midi);
- static void set_midi_to_print(int midi);
- static void print_pitchset(void);
- static void printout_pitchset(dataptr dz);
- static int sort_by_chord(double **hfset,int *hfsetlen,double *intv,int *hfsetcnt,int *grping,dataptr dz);
- static int sort_by_pitchclass_equivalence
- (double **hfset,int *hfsetlen,double *pich,int hfsetcnt,int *grping,int *intcnt,
- double *intv,int *intvcnt,double *intv2,int *intvcnt2,dataptr dz);
- static int sort_by_reference_note_equivalence
- (double **hfset,int *hfsetlen,int hfsetcnt,int *grping,dataptr dz);
- static void sort_by_maxint(double **hfset,int n,int m,int setlen,dataptr dz);
- static void sort_by_density(double **hfset,int n,int m,int setlen,int lowest);
- static void sort_by_density_regardless_of_size
- (double **hfset,double *intv,int *intcnt,double *intv2,int *intcnt2,int n,int m,int setlen,int densest_first);
- static void sort_by_maxintsize_and_density(double **hfset,int n,int m,int setlen,int lowest);
- static void sort_by_octave_equivalence(double **hfset,int n,int m,int setlen);
- static void sort_by_interval_stacking(double **hfset,int n,int m,int setlen,int highest_first);
- static void eliminate_oct_duplicated_sets(double **hfset,int *hfsetcnt,int *hfsetlen,int *grping,int *grping_cnt,int type);
- static int setup_naming(char **thisfilename,dataptr dz);
- static int create_outfile_name(int ccnt,char *thisfilename,dataptr dz);
- static void gen_note(int maxjitter,double *tabstart,double *tabend,double **tabmin, double **tabmax,double **hfset,
- double tabscale,double sintabsize,int splicelen, double *sintab,int n, int j);
- int next_file(int *samps_written,char *thisfilename,int *ccnt,unsigned int *space_needed,
- int *samp_space_available, dataptr dz);
- static void gen_note2(double *tabstart,double *tabend,double midival,
- double tabscale,double sintabsize,int splicelen, double *sintab);
- //static void gen_note3(double *tabstart,double *tabend,double midival,int tabsize,int splicelen, short *intab);
- static void gen_note3(double *tabstart,double *tabend,double midival,int tabsize,int splicelen, float *intab);
- int gen_dp_output(dataptr dz);
- #define LEAVESPACE (10*1024)
- int sorting_type = 0;
- int do_hfperm(dataptr dz)
- {
- int exit_status;
- char temp[48];
- double **hfset = 0, **combo = 0, secs;
- int *combolen = 0, combocnt = 0;
- int hfsetcnt = 0, hrs = 0, mins = 0;
- int *hfsetlen = 0;
- int *grping = NULL;
- int grping_cnt;
- if((exit_status = generate_perms(&combo,&combolen,&combocnt,dz))<0)
- return(exit_status);
- substitute_midivals_in_perms(combo,combolen,combocnt,dz);
- switch(dz->process) {
- case(HF_PERM1) :
- if((exit_status = generate_hfsets(combocnt,combo,combolen,&hfset,&hfsetlen,&hfsetcnt,dz))<0)
- return(exit_status);
- break;
- case(HF_PERM2):
- hfset = combo;
- hfsetcnt = combocnt;
- hfsetlen = combolen;
- }
- if((grping = (int *)malloc(hfsetcnt * sizeof(int)))==NULL)
- print_outwarning_flush("Insufficient memory to store grouping information.\n");
- grping_cnt = sort_hfsets(hfset,hfsetlen,&hfsetcnt,grping,dz);
- grping_cnt /= 2;
- dz->tempsize = hfsetcnt * (dz->iparam[HP1_ELEMENT_SIZE] + dz->iparam[HP1_GAP_SIZE]);
- dz->tempsize += grping_cnt * dz->iparam[HP1_GGAP_SIZE];
- if(dz->true_outfile_stype == SAMP_FLOAT)
- dz->tempsize *= sizeof(float);
- else
- dz->tempsize *= sizeof(short);
- if(dz->mode == HFP_SNDOUT || dz->mode == HFP_SNDSOUT) {
- if(dz->mode == HFP_SNDOUT && ((unsigned int)dz->tempsize > (getdrivefreespace(dz->outfilename) - LEAVESPACE))) {
- sprintf(errstr,"dz->tempsize = %d dz->outfilesize = %d Insufficient space on the hard disk to store the output file.\n",
- dz->tempsize,dz->outfilesize);
- return(MEMORY_ERROR);
- } else {
- sprintf(errstr,"Generating %d chords\n",hfsetcnt);
- print_outmessage(errstr);
- if((secs = dz->tempsize/(double)dz->infile->srate) > 60.0) {
- mins = (int)floor(secs/60.0);
- secs -= (mins * 60.0);
- if(mins > 60) {
- hrs = mins/60;
- mins -= (hrs * 60);
- }
- }
- sprintf(errstr,"Duration of output file: ");
- if(hrs) {
- sprintf(temp,"%d hrs ",hrs);
- strcat(errstr,temp);
- }
- if(mins) {
- sprintf(temp,"%d mins ",mins);
- strcat(errstr,temp);
- }
- sprintf(temp,"%.2lf secs\n",secs);
- strcat(errstr,temp);
- print_outmessage_flush(errstr);
- }
- }
- switch(dz->mode) {
- case(HFP_SNDOUT):
- if((exit_status = gen_output(hfsetcnt,hfset,hfsetlen,grping,dz))<0)
- return(exit_status);
- break;
- case(HFP_SNDSOUT):
- if((exit_status = gen_outputs(hfsetcnt,hfset,hfsetlen,grping,dz))<0)
- return(exit_status);
- break;
- case(HFP_TEXTOUT):
- if((exit_status = gen_text_output(hfsetcnt,hfset,hfsetlen,grping,dz))<0)
- return(exit_status);
- break;
- case(HFP_MIDIOUT):
- if((exit_status = gen_midi_output(hfsetcnt,hfset,hfsetlen,grping,dz))<0)
- return(exit_status);
- break;
- }
- return(FINISHED);
- }
- /************************** GENERATE_PERMS **************************/
- int generate_perms(double ***combo,int **combolen,int *combocnt,dataptr dz)
- {
- int exit_status;
- int n, j, maxsize;
- int *element;
- if(dz->iparam[HP1_HFCNT] == dz->iparam[HP1_MINSET]) {
- if((*combo = (double **)malloc(sizeof(double *)))==NULL) {
- sprintf(errstr,"Out of memory for harmonic combinations.\n");
- return(MEMORY_ERROR);
- }
- if((*combolen = (int *)malloc(sizeof(int)))==NULL) {
- sprintf(errstr,"Out of memory for harmonic combination counts.\n");
- return(MEMORY_ERROR);
- }
- if(((*combo)[0] = (double *)malloc(dz->iparam[HP1_HFCNT] * sizeof(double)))==NULL) {
- sprintf(errstr,"Out of memory for harmonic combinations.\n");
- return(MEMORY_ERROR);
- }
- for(n=0;n<dz->iparam[HP1_HFCNT];n++)
- (*combo)[0][n] = n;
- (*combolen)[0] = dz->iparam[HP1_HFCNT];
- *combocnt = 1;
- return(FINISHED);
- } else {
- if((element = (int *)malloc(dz->iparam[HP1_HFCNT] * sizeof(int)))==NULL) {
- sprintf(errstr,"Out of memory for permutation elements.\n");
- return(MEMORY_ERROR);
- }
- if(dz->vflag[HP1_MINONLY])
- maxsize = dz->iparam[HP1_MINSET];
- else
- maxsize = dz->iparam[HP1_HFCNT];
- for(n=dz->iparam[HP1_MINSET];n<=maxsize;n++) {
- for(j=0;j<n;j++) /* initialise perm elements */
- element[j] = j-1;
- if((exit_status = set_element(0,n,dz->iparam[HP1_HFCNT],element,combo,combolen,combocnt))<0) {
- free(element);
- return(exit_status);
- }
- }
- }
- free(element);
- return(FINISHED);
- }
- /************************** SET_ELEMENT **************************
- *
- * Recursive function to set successive elements of a permutation.
- */
- int set_element(int element_no,int total_elements,int field_cnt,int *element,double ***combo,int **combolen,int *combocnt)
- {
- int exit_status, k;
- int limit = field_cnt - total_elements + element_no;
- for(;;) {
- element[element_no]++; /* incr the element number */
- if(element[element_no] > limit) { /* if it's now beyond max for this element */
- if(element_no > 0) { /* reset this, & all elements above it */
- k = element_no; /* to be in ascending sequence from element below */
- while(k < total_elements) { /* ready for incrementation of next lowest element */
- element[k] = element[k-1] + 1;
- k++;
- }
- }
- return(CONTINUE); /* then return to next lowest element */
- }
- if(element_no >= total_elements-1) { /* if all elements have been set, store the combination */
- if((exit_status = store_combo(combo,combocnt,combolen,element,total_elements))<0)
- return(exit_status);
- } else { /* but if not, go on to set the next element */
- if((exit_status = set_element(element_no+1,total_elements,field_cnt,element,combo,combolen,combocnt))<0)
- return(exit_status);
- }
- }
- return(CONTINUE); /* NOTREACHED */
- }
- /************************** STORE_COMBO **************************/
- int store_combo(double ***combo,int *combocnt,int **combolen,int *element,int total_elements)
- {
- int n, j;
- j = *combocnt;
- (*combocnt)++; /* incr count of combinations */
- if(*combocnt == 1) { /* create a new combo_store location */
- if((*combo = (double **)malloc(sizeof(double *)))==NULL) {
- sprintf(errstr,"Out of memory for harmonic combinations.\n");
- return(MEMORY_ERROR);
- } /* create a new combo_store_cnt location */
- if((*combolen = (int *)malloc(sizeof(int)))==NULL) {
- sprintf(errstr,"Out of memory for harmonic combinations.\n");
- return(MEMORY_ERROR);
- }
- } else {
- if((*combo = (double **)realloc((char *)(*combo),(*combocnt) * sizeof(double *)))==NULL) {
- sprintf(errstr,"Out of memory for harmonic combinations.\n");
- return(MEMORY_ERROR);
- }
- if((*combolen = (int *)realloc((char *)(*combolen),(*combocnt) * sizeof(int)))==NULL) {
- sprintf(errstr,"Out of memory for harmonic combinations.\n");
- return(MEMORY_ERROR);
- }
- } /* create the new combo_store */
- if(((*combo)[j] = (double *)malloc(total_elements * sizeof(double)))==NULL) {
- sprintf(errstr,"Out of memory for harmonic combinations.\n");
- return(MEMORY_ERROR);
- }
- for(n=0; n < total_elements; n++) /* store the new combo */
- (*combo)[j][n] = (double)element[n];
- (*combolen)[j] = total_elements; /* store the count of the new combo */
- return(FINISHED);
- }
- /************************** 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;
- }
- /**************************** SUBSTITUTE_MIDIVALS_IN_PERMS *******************************/
- void substitute_midivals_in_perms(double **combo,int *combolen,int combocnt,dataptr dz)
- {
- double *hf = dz->parray[0];
- int n, m, k;
- for(n=0;n<combocnt;n++) {
- for(m=0;m < combolen[n];m++) {
- k = (int)combo[n][m];
- combo[n][m] = hf[k];
- }
- }
- }
- /**************************** BUBLSORT_HF *******************************/
- void bublsort_hf(double *hf,dataptr dz)
- {
- int n, m;
- double temp;
- for(n=0;n<dz->iparam[HP1_HFCNT]-1;n++) {
- for(m = n+1; m<dz->iparam[HP1_HFCNT]; m++) {
- if(hf[m] < hf[n]) {
- temp = hf[n];
- hf[n] = hf[m];
- hf[m] = temp;
- }
- }
- }
- }
- /**************************** GENERATE_OCTS *******************************/
- int transpose_element(int element_no,double *thiscombo,int thiscombolen,double *origval,
- double ***hfset,int **hfsetlen,int *hfsetcnt,dataptr dz)
- {
- int exit_status;
- for(;;) {
- thiscombo[element_no] += 12.0;
- if(thiscombo[element_no] > (double)dz->iparam[HP1_TOPNOTE]) {
- thiscombo[element_no] = origval[element_no];
- return CONTINUE;
- }
- if(element_no >= thiscombolen-1) { /* if all elements have been set, store the hfset */
- if((exit_status = store_transposition(hfset,hfsetlen,hfsetcnt,thiscombo,thiscombolen))<0)
- return(exit_status);
- } else { /* but if not, go on to set the next element */
- if((exit_status =
- transpose_element(element_no+1,thiscombo,thiscombolen,origval,hfset,hfsetlen,hfsetcnt,dz))<0)
- return(exit_status);
- }
- }
- return(CONTINUE); /* NOTREACHED */
- }
- /**************************** STORE_TRANSPOSITION *******************************/
- int store_transposition(double ***hfset,int **hfsetlen,int *hfsetcnt,double *thiscombo,int thiscombolen)
- {
- int n, j;
- j = *hfsetcnt;
- (*hfsetcnt)++; /* incr count of hfset */
- if(*hfsetcnt == 1) { /* create a new hfset_store location */
- if((*hfset = (double **)malloc(sizeof(double *)))==NULL) {
- sprintf(errstr,"Out of memory for final sets.\n");
- return(MEMORY_ERROR);
- } /* create a new hfset_store_cnt location */
- if((*hfsetlen = (int *)malloc(sizeof(int)))==NULL) {
- sprintf(errstr,"Out of memory for final sets.\n");
- return(MEMORY_ERROR);
- }
- } else {
- if((*hfset = (double **)realloc((char *)(*hfset),(*hfsetcnt) * sizeof(double *)))==NULL) {
- sprintf(errstr,"Out of memory for final sets.\n");
- return(MEMORY_ERROR);
- }
- if((*hfsetlen = (int *)realloc((char *)(*hfsetlen),(*hfsetcnt) * sizeof(int)))==NULL) {
- sprintf(errstr,"Out of memory for final sets.\n");
- return(MEMORY_ERROR);
- }
- } /* create the new hfset store */
- if(((*hfset)[j] = (double *)malloc(thiscombolen * sizeof(double)))==NULL) {
- sprintf(errstr,"Out of memory for final sets.\n");
- return(MEMORY_ERROR);
- }
- for(n=0; n < thiscombolen; n++) /* store the new hfset */
- (*hfset)[j][n] = thiscombo[n];
- (*hfsetlen)[j] = thiscombolen; /* store the count of the new hfset */
- return(FINISHED);
- }
- /************************** GENERATE_HFSETS **************************/
- int generate_hfsets(int combocnt,double **combo,int *combolen,double ***hfset,int **hfsetlen,int *hfsetcnt,dataptr dz)
- {
- int exit_status;
- int n, j;
- double *origval;
- if((origval = (double *)malloc(dz->iparam[HP1_HFCNT] * sizeof(double)))==NULL) {
- sprintf(errstr,"Out of memory for storing original comobo vals.\n");
- return(MEMORY_ERROR);
- }
- for(n=0;n<combocnt;n++) {
- for(j=0;j<combolen[n];j++) {
- combo[n][j] -= 12.0;
- origval[j] = combo[n][j];
- }
- if((exit_status = transpose_element(0,combo[n],combolen[n],origval,hfset,hfsetlen,hfsetcnt,dz))<0)
- return(exit_status);
- }
- return(FINISHED);
- }
- /************************** SORT_HFSETS **************************/
- int sort_hfsets(double **hfset,int *hfsetlen,int *hfsetcnt,int *grping,dataptr dz)
- {
- int n, m, j;
- double temp;
- int itemp;
- double *intv, *intv2, *pich;
- int *intvcnt, *intvcnt2;
- // int grping_cnt = 0, in_grp = 0;
- int grping_cnt = 0;
- int *minint = NULL, *intcnt = NULL;
- int hfsetcount = *hfsetcnt;
- grping[0] = -1; /* flags output not to do grouping */
- for(j = 0;j<hfsetcount;j++) { /* Sort the individual sets themselves, so pitches are in ascending order */
- for(n=0;n<hfsetlen[j]-1;n++) {
- for(m = n+1; m<hfsetlen[j]; m++) {
- if(hfset[j][m] < hfset[j][n]) {
- temp = hfset[j][n];
- hfset[j][n] = hfset[j][m];
- hfset[j][m] = temp;
- }
- }
- }
- }
- print_outmessage_flush("Sorting chords by note-count.\n");
- for(n=0;n<hfsetcount-1;n++) { /* Sort the sets by size */
- for(m = n+1; m<hfsetcount; m++) {
- if(hfsetlen[m] < hfsetlen[n]) {
- itemp = hfsetlen[n];
- hfsetlen[n] = hfsetlen[m];
- hfsetlen[m] = itemp;
- }
- }
- }
- switch(dz->iparam[HP1_SORT1]) {
- case(ROOT):
- case(TOP):
- case(PCLASS):
- if ((intv = (double *)malloc(dz->iparam[HP1_HFCNT] * sizeof(double)))==NULL) {
- print_outwarning_flush("Insufficient memory to sort chords in terms of pitch equivalence.\n");
- return 0;
- }
- if ((intv2 = (double *)malloc(dz->iparam[HP1_HFCNT] * sizeof(double)))==NULL) {
- print_outwarning_flush("Insufficient memory to sort chords in terms of pitch equivalence.\n");
- return 0;
- }
- if ((intvcnt = (int *)malloc(dz->iparam[HP1_HFCNT] * sizeof(int)))==NULL) {
- print_outwarning_flush("Insufficient memory to sort chords in terms of pitch equivalence.\n");
- return 0;
- }
- if ((intvcnt2 = (int *)malloc(dz->iparam[HP1_HFCNT] * sizeof(int)))==NULL) {
- print_outwarning_flush("Insufficient memory to sort chords in terms of pitch equivalence.\n");
- return 0;
- }
- if ((pich = (double *)malloc(dz->iparam[HP1_HFCNT] * sizeof(double)))==NULL) {
- print_outwarning_flush("Insufficient memory to sort chords in terms of pitch equivalence.\n");
- return 0;
- }
- if(dz->vflag[HP1_DENS] == OTHER_SORT) {
- if ((minint = (int *)malloc(hfsetcount * sizeof(int)))==NULL)
- print_outwarning_flush("Insufficient memory to sort chord-groups.\n");
- else if ((intcnt = (int *)malloc(hfsetcount * sizeof(int)))==NULL)
- print_outwarning_flush("Insufficient memory to sort chord-groups.\n");
- }
- switch(dz->iparam[HP1_SORT1]) {
- case(PCLASS):
- print_outmessage_flush("Sorting chords by pitchclass-equivalence.\n");
- grping_cnt = sort_by_pitchclass_equivalence
- (hfset,hfsetlen,pich,hfsetcount,grping,intcnt,intv,intvcnt,intv2,intvcnt2,dz);
- break;
- default:
- print_outmessage_flush("Sorting chords by reference-note-equivalence.\n");
- grping_cnt = sort_by_reference_note_equivalence(hfset,hfsetlen,hfsetcount,grping,dz);
- break;
- }
- break;
- case(CHORDTYPE):
- case(CHORD_1):
- if ((intv = (double *)malloc(dz->iparam[HP1_HFCNT] * sizeof(double)))==NULL) {
- print_outwarning_flush("Insufficient memory to sort chords in terms of interval equivalence.\n");
- return 0;
- }
- print_outmessage_flush("Sorting chords by interval-equivalence.\n");
- grping_cnt = sort_by_chord(hfset,hfsetlen,intv,hfsetcnt,grping,dz);
- break;
- default:
- sprintf(errstr,"Unknown chord sort type.\n");
- return(PROGRAM_ERROR);
- }
- if(dz->vflag[HP1_ELIMOCTS] && (dz->iparam[HP1_SORT1] != CHORD_1))
- eliminate_oct_duplicated_sets(hfset,hfsetcnt,hfsetlen,grping,&grping_cnt,sorting_type);
- return grping_cnt;
- }
- /************************** GEN_OUTPUT **************************/
- int gen_output(int hfsetcnt,double **hfset,int *hfsetlen,int *grping,dataptr dz)
- {
- int exit_status;
- // short *obuf = dz->sampbuf[0];
- float *obuf = dz->sampbuf[0];
- double *tab = (double *)dz->sampbuf[2];
- double *tabend = tab + dz->iparam[HP1_ELEMENT_SIZE];
- double tabscale = (double)HFP_TABSIZE/dz->infile->srate;
- double *sintab = (double *)dz->sampbuf[1];
- double sintabsize = (double)HFP_TABSIZE;
- double element_level;
- int samps_written = 0, samp_space_available, samps_to_write, gap_size;
- int n, i, j, grping_cnt = 0;
- int maxjitter = (int)round(drand48() * HFP_MAXJITTER * MS_TO_SECS * (double)dz->infile->srate);
- unsigned int element_byte_len = dz->iparam[HP1_ELEMENT_SIZE] * sizeof(double);
- unsigned int element_full_len = element_byte_len + (maxjitter * sizeof(double));
- double *tabmax = 0, *tabmin = tab + dz->iparam[HP1_ELEMENT_SIZE] + maxjitter;
- int splicelen = (int)round(HP1_SPLICELEN * MS_TO_SECS * (double)dz->infile->srate);
- int in_group = 0, in_grp = 0;
- print_outmessage_flush("Synthesis beginning.\n");
- memset((char *)dz->sampbuf[0],0,(size_t)dz->buflen * sizeof(float));
- for(n=0;n<hfsetcnt;n++) {
- memset((char *)dz->sampbuf[2],0,element_full_len);
- if(grping!=NULL && grping[0] != -1)
- print_grouping_structure(n,grping,&grping_cnt,&in_grp,hfsetcnt);
- errstr[0] = ENDOFSTR;
- for(j=0;j<hfsetlen[n];j++) {
- set_pitch_to_print((int)hfset[n][j]);
- gen_note(maxjitter,tab,tabend,&tabmin,&tabmax,hfset,tabscale,sintabsize,splicelen,sintab,n,j);
- }
- print_pitchset();
- element_level = HFP_OUTLEVEL/hfsetlen[n];
- tab = tabmin;
- while(tab < tabmax)
- *tab++ *= element_level;
- /* DO OUTPUT */
- samp_space_available = dz->buflen - samps_written;
- gap_size = dz->iparam[HP1_GAP_SIZE];
- if(grping!=NULL && grping[0] != -1) {
- if(grping[grping_cnt]==n) {
- in_group = 1;
- gap_size += dz->iparam[HP1_GGAP_SIZE]; /* make gap at start */
- grping_cnt++;
- } else if(grping[grping_cnt]==-n) {
- in_group = 0;
- gap_size += dz->iparam[HP1_GGAP_SIZE]; /* make gap at end */
- grping_cnt++; /* if grp end coincides with gp start */
- if(grping[grping_cnt]==n) { /* skip a grping value */
- in_group = 1;
- grping_cnt++;
- }
- } else if (!in_group)
- gap_size += dz->iparam[HP1_GGAP_SIZE]; /* make gap between non-grouped entries */
- }
- if(n!=0) { /* no gap at start */
- while(gap_size >= samp_space_available) {
- if((exit_status = write_samps(dz->sampbuf[0],dz->buflen,dz))<0)
- return(exit_status);
- memset((char *)dz->sampbuf[0],0,(size_t)dz->buflen * sizeof(float));
- gap_size -= samp_space_available;
- samp_space_available = dz->buflen;
- samps_written = 0;
- }
- samps_written += gap_size;
- samp_space_available = dz->buflen - samps_written;
- }
- i = 0;
- tab = tabmin;
- samp_space_available = dz->buflen - samps_written;
- samps_to_write = tabmax - tabmin;
- while(i < samps_to_write) {
- if(samp_space_available > samps_to_write) {
- while(i < samps_to_write)
- // obuf[samps_written++] = (short)round(tab[i++] * MAXSAMP);
- obuf[samps_written++] = (float)tab[i++];
- } else {
- while(samps_written < dz->buflen)
- // obuf[samps_written++] = (short)round(tab[i++] * MAXSAMP);
- obuf[samps_written++] = (float)tab[i++];
- if((exit_status = write_samps(dz->sampbuf[0],dz->buflen,dz))<0)
- return(exit_status);
- memset((char *)dz->sampbuf[0],0,(size_t)dz->buflen * sizeof(float));
- samps_written = 0;
- samp_space_available = dz->buflen;
- }
- }
- }
- if(grping!=NULL && grping[0] != -1)
- print_grouping_structure(n,grping,&grping_cnt,&in_grp,hfsetcnt);
- samps_written += dz->iparam[HP1_GAP_SIZE];
- while(samps_written >= dz->buflen) {
- if((exit_status = write_samps(dz->sampbuf[0],dz->buflen,dz))<0)
- return(exit_status);
- samps_written -= dz->buflen;
- }
- if(samps_written > 0) {
- if((exit_status = write_samps(dz->sampbuf[0],samps_written,dz))<0)
- return(exit_status);
- }
- return(FINISHED);
- }
- /************************** GEN_OUTPUTS **************************/
- int gen_outputs(int hfsetcnt,double **hfset,int *hfsetlen,int *grping,dataptr dz)
- {
- int exit_status;
- float *obuf = dz->sampbuf[0];
- double *tab = (double *)dz->sampbuf[2];
- double *tabend = tab + dz->iparam[HP1_ELEMENT_SIZE];
- double tabscale = (double)HFP_TABSIZE/dz->infile->srate;
- double *sintab = (double *)dz->sampbuf[1];
- double sintabsize = (double)HFP_TABSIZE;
- double element_level;
- int samps_written = 0, samp_space_available, samps_to_write, gap_size;
- int n, i, j, grping_cnt = 0;
- int maxjitter = (int)round(drand48() * HFP_MAXJITTER * MS_TO_SECS * (double)dz->infile->srate);
- unsigned int element_byte_len = dz->iparam[HP1_ELEMENT_SIZE] * sizeof(double);
- unsigned int element_full_len = element_byte_len + (maxjitter * sizeof(double));
- double *tabmax = 0, *tabmin = tab + dz->iparam[HP1_ELEMENT_SIZE] + maxjitter;
- int splicelen = (int)round(HP1_SPLICELEN * MS_TO_SECS * (double)dz->infile->srate);
- int in_group = 0, in_grp = 0;
- char *thisfilename;
- int ccnt = 0;
- unsigned int space_needed = dz->tempsize;
- superzargo = 0;
- if((exit_status = setup_naming(&thisfilename,dz))<0)
- return(exit_status);
- if((exit_status = create_outfile_name(0,thisfilename,dz))<0)
- return(exit_status);
- dz->process_type = UNEQUAL_SNDFILE; /* allow sndfile to be created */
- if((exit_status = create_sized_outfile(thisfilename,dz))<0) {
- fprintf(stdout, "WARNING: Soundfile %s already exists.\n", thisfilename);
- fflush(stdout);
- dz->process_type = OTHER_PROCESS;
- dz->ofd = -1;
- return(PROGRAM_ERROR);
- }
- if((unsigned int)dz->outfilesize < space_needed) {
- sprintf(errstr,"Insufficient space on the hard disk to store the output files.\n");
- return(MEMORY_ERROR);
- }
- dz->total_samps_written = 0;
- print_outmessage_flush("Synthesis beginning.\n");
- memset((char *)dz->sampbuf[0],0,(size_t)dz->buflen * sizeof(float));
- for(n=0;n<hfsetcnt;n++) {
- memset((char *)dz->sampbuf[2],0,element_full_len);
- if(grping!=NULL && grping[0] != -1)
- print_grouping_structure(n,grping,&grping_cnt,&in_grp,hfsetcnt);
- errstr[0] = ENDOFSTR;
- for(j=0;j<hfsetlen[n];j++) {
- set_pitch_to_print((int)hfset[n][j]);
- gen_note(maxjitter,tab,tabend,&tabmin,&tabmax,hfset,tabscale,sintabsize,splicelen,sintab,n,j);
- }
- print_pitchset();
- element_level = HFP_OUTLEVEL/hfsetlen[n];
- tab = tabmin;
- while(tab < tabmax)
- *tab++ *= element_level;
- /* DO OUTPUT */
- samp_space_available = dz->buflen - samps_written;
- gap_size = dz->iparam[HP1_GAP_SIZE];
- if(grping!=NULL && grping[0] != -1) {
- if(grping[grping_cnt]==n) {
- if(in_group == 0 && n!=0) {
- if((exit_status = next_file(&samps_written,thisfilename,&ccnt,&space_needed,&samp_space_available,dz))<0)
- return(exit_status);
- }
- in_group = 1;
- grping_cnt++;
- } else if(grping[grping_cnt]==-n) { /* if at end of group */
- in_group = 0;
- if((exit_status = next_file(&samps_written,thisfilename,&ccnt,&space_needed,&samp_space_available,dz))<0)
- return(exit_status);
- grping_cnt++; /* if grp end coincides with gp start */
- if(grping[grping_cnt]==n) { /* skip a grping value */
- in_group = 1;
- grping_cnt++;
- }
- } else if(in_group == 0 && n!=0) { /* if not a grouped chord */
- if((exit_status = next_file(&samps_written,thisfilename,&ccnt,&space_needed,&samp_space_available,dz))<0)
- return(exit_status);
- }
- }
- if(n!=0) { /* no gap at start */
- while(gap_size >= samp_space_available) {
- if((exit_status = write_samps(dz->sampbuf[0],dz->buflen,dz))<0)
- return(exit_status);
- memset((char *)dz->sampbuf[0],0,(size_t)dz->buflen * sizeof(float));
- gap_size -= samp_space_available;
- samp_space_available = dz->buflen;
- samps_written = 0;
- }
- samps_written += gap_size;
- samp_space_available = dz->buflen - samps_written;
- }
- i = 0;
- tab = tabmin;
- samp_space_available = dz->buflen - samps_written;
- samps_to_write = tabmax - tabmin;
- while(i < samps_to_write) {
- if(samp_space_available > samps_to_write) {
- while(i < samps_to_write)
- obuf[samps_written++] = (float)tab[i++];
- } else {
- while(samps_written < dz->buflen)
- obuf[samps_written++] = (float)tab[i++];
- if((exit_status = write_samps(dz->sampbuf[0],dz->buflen,dz))<0)
- return(exit_status);
- memset((char *)dz->sampbuf[0],0,(size_t)dz->buflen * sizeof(float));
- samps_written = 0;
- samp_space_available = dz->buflen;
- }
- }
- }
- if(grping!=NULL && grping[0] != -1)
- print_grouping_structure(n,grping,&grping_cnt,&in_grp,hfsetcnt);
- samps_written += dz->iparam[HP1_GAP_SIZE];
- while(samps_written >= dz->buflen) {
- if((exit_status = write_samps(dz->sampbuf[0],dz->buflen,dz))<0)
- return(exit_status);
- samps_written -= dz->buflen;
- }
- if(samps_written > 0) {
- if((exit_status = write_samps(dz->sampbuf[0],samps_written,dz))<0)
- return(exit_status);
- }
- /* CLOSE FILE */
- dz->outfiletype = SNDFILE_OUT; /* allows header to be written */
- if((exit_status = headwrite(dz->ofd,dz))<0)
- return(exit_status);
- dz->process_type = OTHER_PROCESS;
- dz->outfiletype = NO_OUTPUTFILE;
- if((exit_status = reset_peak_finder(dz))<0)
- return(exit_status);
- if(sndcloseEx(dz->ofd) < 0) {
- fprintf(stdout,"WARNING: Can't close output soundfile %s\n",thisfilename);
- fflush(stdout);
- }
- dz->ofd = -1;
- return(FINISHED);
- }
- /************************** GEN_TEXT_OUTPUT **************************/
- int gen_text_output(int hfsetcnt,double **hfset,int *hfsetlen,int *grping,dataptr dz)
- {
- int n, j, grping_cnt = 0;
- int in_grp = 0;
- for(n=0;n<hfsetcnt;n++) {
- if(grping!=NULL && grping[0] != -1) {
- printout_grouping_structure(n,grping,&grping_cnt,&in_grp,hfsetcnt,dz);
- }
- errstr[0] = ENDOFSTR;
- for(j=0;j<hfsetlen[n];j++) {
- set_pitch_to_print((int)hfset[n][j]);
- }
- printout_pitchset(dz);
- if(grping!=NULL && grping[0] != -1) {
- if(grping[grping_cnt]==n) {
- //in_group = 1;
- grping_cnt++;
- } else if(grping[grping_cnt]==-n) { /* if at end of group */
- //in_group = 0;
- grping_cnt++; /* if grp end coincides with gp start */
- if(grping[grping_cnt]==n) { /* skip a grping value */
- //in_group = 1;
- grping_cnt++;
- }
- }
- }
- }
- if(grping!=NULL && grping[0] != -1) {
- printout_grouping_structure(n,grping,&grping_cnt,&in_grp,hfsetcnt,dz);
- }
- display_virtual_time(dz->tempsize,dz);
- return(FINISHED);
- }
- /************************** GEN_MIDI_OUTPUT **************************/
- int gen_midi_output(int hfsetcnt,double **hfset,int *hfsetlen,int *grping,dataptr dz)
- {
- int n, j, grping_cnt = 0;
- // int in_group = 0, in_grp = 0;
- //int in_group = 0;
- for(n=0;n<hfsetcnt;n++) {
- errstr[0] = ENDOFSTR;
- for(j=0;j<hfsetlen[n];j++)
- set_midi_to_print((int)hfset[n][j]);
- printout_pitchset(dz);
- if(grping!=NULL && grping[0] != -1) {
- if(grping[grping_cnt]==n) {
- //in_group = 1;
- grping_cnt++;
- } else if(grping[grping_cnt]==-n) { /* if at end of group, or not a grouped chord */
- //in_group = 0;
- grping_cnt++; /* if grp end coincides with gp start */
- if(grping[grping_cnt]==n) { /* skip a grping value */
- //in_group = 1;
- grping_cnt++;
- }
- }
- }
- }
- display_virtual_time(dz->tempsize,dz);
- return(FINISHED);
- }
- /************************** PRINT_GROUPING_STRUCTURE **************************/
- void print_grouping_structure(int n,int *grping,int *grping_cnt,int *in_grp,int hfsetcnt)
- {
- if(grping[*grping_cnt]==-n && (n!=0)) { /* if end of group marked */
- *in_grp = 0;
- print_outmessage_flush("))- - - - - - -\n");
- if(grping[(*grping_cnt)+1]==n) { /* if start of group ALSO marked */
- *in_grp = 1;
- print_outmessage_flush("-------------((\n");
- }
- } else if(grping[*grping_cnt]==n) { /* if start of group marked */
- *in_grp = 1;
- print_outmessage_flush("-------------((\n");
- } else if(!(*in_grp)) { /* not inside a group */
- print_outmessage_flush("-----\n");
- } else if(n >= hfsetcnt) { /* inside a group at end of whole pass */
- print_outmessage_flush("))- - - - - - -\n");
- }
- }
- /************************** PRINTOUT_GROUPING_STRUCTURE **************************/
- void printout_grouping_structure(int n,int *grping,int *grping_cnt,int *in_grp,int hfsetcnt,dataptr dz)
- {
- if(grping[*grping_cnt]==-n && (n!=0)) { /* if end of group marked */
- *in_grp = 0;
- print_outmessage_flush("))- - - - - - -\n");
- fprintf(dz->fp,"))- - - - - - -\n");
- if(grping[(*grping_cnt)+1]==n) { /* if start of group ALSO marked */
- *in_grp = 1;
- print_outmessage_flush("-------------((\n");
- fprintf(dz->fp,"-------------((\n");
- }
- } else if(grping[*grping_cnt]==n) { /* if start of group marked */
- *in_grp = 1;
- print_outmessage_flush("-------------((\n");
- fprintf(dz->fp,"-------------((\n");
- } else if(!(*in_grp)) { /* not inside a group */
- print_outmessage_flush("-----\n");
- fprintf(dz->fp,"-----\n");
- } else if(n >= hfsetcnt) { /* inside a group at end of whole pass */
- print_outmessage_flush("))- - - - - - -\n");
- fprintf(dz->fp,"))- - - - - - -\n");
- }
- }
- /************************** SET_PITCH_TO_PRINT **************************/
- void set_pitch_to_print(int midi)
- {
- int oct = (midi/12)-5;
- char temp[12];
- midi = midi%12;
- switch(midi) {
- case(0): sprintf(temp,"C%d ",oct); break;
- case(1): sprintf(temp,"C#%d ",oct); break;
- case(2): sprintf(temp,"D%d ",oct); break;
- case(3): sprintf(temp,"Eb%d ",oct); break;
- case(4): sprintf(temp,"E%d ",oct); break;
- case(5): sprintf(temp,"F%d ",oct); break;
- case(6): sprintf(temp,"F#%d ",oct); break;
- case(7): sprintf(temp,"G%d ",oct); break;
- case(8): sprintf(temp,"Ab%d ",oct); break;
- case(9): sprintf(temp,"A%d ",oct); break;
- case(10): sprintf(temp,"Bb%d ",oct); break;
- case(11): sprintf(temp,"B%d ",oct); break;
- }
- if(oct>=0)
- strcat(temp," ");
- strcat(errstr,temp);
- }
- /************************** SET_MIDI_TO_PRINT **************************/
- void set_midi_to_print(int midi)
- {
- char temp[12];
- sprintf(temp,"%d ",midi);
- strcat(errstr,temp);
- }
- /************************** PRINT_PITCHSET **************************/
- void print_pitchset(void)
- {
- char temp[12];
- sprintf(temp,"\n");
- strcat(errstr,temp);
- print_outmessage_flush(errstr);
- }
- /************************** PRINTOUT_PITCHSET **************************/
- void printout_pitchset(dataptr dz)
- {
- char temp[12];
- sprintf(temp,"\n");
- strcat(errstr,temp);
- print_outmessage_flush(errstr);
- fprintf(dz->fp,"%s",errstr);
- }
- /************************** SORT_BY_CHORD ***************************
- *
- * Sort size-ordered then pitch-ordered sets, by equivalence of chords they make up.
- */
- int sort_by_chord(double **hfset,int *hfsetlen,double *intv,int *hfsetcnt,int *grping,dataptr dz)
- {
- int a, b, m, n, j, lastmatch, was_a_match;
- double *tempoint;
- int grping_cnt = 0, matching_intervals = 0;
- for(n=0;n<(*hfsetcnt)-1;n++) {
- for(j = 0; j<hfsetlen[n]-1; j++)
- intv[j] = hfset[n][j+1] - hfset[n][j]; /* set up intervals of first set as a comparison set */
- lastmatch = n;
- was_a_match = 0;
- for(m = n+1; m<=*hfsetcnt; m++) {
- if(m==*hfsetcnt || hfsetlen[m] != hfsetlen[n]){ /* if got to end of group-of-sets of same size */
- if(was_a_match) { /* if a matching-group has just been put together */
- for(a=n;a<lastmatch;a++) {
- for(b = a+1; b<=lastmatch; b++) { /* sort matching chords into pitch-ascending order */
- if(hfset[b][0] < hfset[a][0]) {
- tempoint = hfset[a];
- hfset[a] = hfset[b];
- hfset[b] = tempoint;
- }
- }
- }
- if(grping!=NULL && n!=0) {
- grping[grping_cnt++] = n; /* ....mark group start */
- grping[grping_cnt++] = -(lastmatch+1); /* mark group end */
- }
- if(lastmatch != m-1) { /* if match-group didn't end at end of last samesize-group */
- n = lastmatch+1; /* baktrak n to position AFTER END of matching set */
- for(j = 0; j<hfsetlen[n]-1; j++) /* set this set's intervals as comparison intervals */
- intv[j] = hfset[n][j+1] - hfset[n][j];
- m = n; /* reset m to run over sets after n */
- lastmatch = n;
- was_a_match = 0; /* search for further matching sets */
- continue;
- /* ELSE last match ended at end of group-of-sets */
- } else if(m < (*hfsetcnt)-1) { /* SO, if we're not at last set */
- for(j = 0; j<hfsetlen[m]-1; j++) /* establish interval comparison set for new setsize */
- intv[j] = hfset[m][j+1] - hfset[m][j];
- lastmatch = m; /* reset the base pointer of matching sets */
- was_a_match = 0;
- n = m; /* skip n-index to base of next group samesize sets */
- }
- } else { /* matching set not been made in this pass */
- m = *hfsetcnt; /* force n to advance */
- }
- } else {
- matching_intervals = 1; /* compare samesize (sorted) sets for matching intervals */
- for(j = 0; j<hfsetlen[m]-1; j++) {
- if (!flteq(intv[j],hfset[m][j+1] - hfset[m][j])) {
- matching_intervals = 0;
- break;
- }
- }
- if(matching_intervals) { /* if all intervals match */
- was_a_match = 1; /* note tha a match has been found in this pass */
- lastmatch++; /* incr pointer to last match position */
- if(m != lastmatch) { /* if the matching set is not AT this position */
- tempoint = hfset[lastmatch]; /* move it to that position */
- hfset[lastmatch] = hfset[m];
- hfset[m] = tempoint;
- }
- }
- }
- }
- }
- if(dz->iparam[HP1_SORT1] == CHORD_1) {
- for(b = 0; b < grping_cnt; b+=2) {
- m = grping[b] + 1;
- n = -(grping[b+1]);
- j = n - m;
- while(n < *hfsetcnt)
- hfset[m++] = hfset[n++];
- *hfsetcnt -= j;
- }
- grping_cnt = 0;
- grping[0] = -1;
- }
- return grping_cnt;
- }
- /************************** SORT_BY_PITCHCLASS_EQUIVALENCE ***************************
- *
- * Sort size-ordered THEN pitch-ordered sets, by pitch-class equivalence of root note in each size-group.
- */
- int sort_by_pitchclass_equivalence
- (double **hfset,int *hfsetlen,double *pich,int hfsetcnt,int *grping,int *intcnt,
- double *intv,int *intvcnt,double *intv2,int *intvcnt2,dataptr dz)
- {
- int j, k, m, n;
- int in_grp = 0, grping_cnt = 0, matching_pitches, setlen;
- n = 0;
- setlen = hfsetlen[n];
- for(j = 0; j<setlen; j++)
- pich[j] = fmod(hfset[n][j],12.0); /* set up pitches of first set, as a comparison set */
- for(m=1;m<hfsetcnt;m++) {
- if(hfsetlen[m] != setlen) {
- if(in_grp) {
- grping[grping_cnt++] = -m; /* mark end of group */
- in_grp = 0;
- }
- if(intcnt != NULL) {
- if(dz->vflag[HP1_DENS] == DENSE_SORT)
- sort_by_density_regardless_of_size(hfset,intv,intvcnt,intv2,intvcnt2,n,m,setlen,1);
- else
- sort_by_maxintsize_and_density(hfset,n,m,setlen,0);
- }
- n = m;
- setlen = hfsetlen[n];
- for(j = 0; j<setlen; j++)
- pich[j] = fmod(hfset[n][j],12.0); /* set up pitches of new comparison set */
- continue;
- }
- matching_pitches = 1; /* no pitch-class duplication in sets */
- for(j=0;j<hfsetlen[m];j++) {
- matching_pitches = 0;
- for(k=0;k<hfsetlen[m];k++) {
- if(flteq(fmod(hfset[m][j],12.0),pich[k])) {
- matching_pitches = 1;
- break;
- }
- }
- if(!matching_pitches)
- break;
- }
- if(matching_pitches) {
- if(!in_grp) {
- grping[grping_cnt++] = (m-1); /* mark start of group */
- in_grp = 1;
- }
- } else {
- if(in_grp) {
- grping[grping_cnt++] = -m; /* mark end of group */
- in_grp = 0;
- }
- if(intcnt != NULL) {
- if(dz->vflag[HP1_DENS] == DENSE_SORT)
- sort_by_density_regardless_of_size(hfset,intv,intvcnt,intv2,intvcnt2,n,m,setlen,1);
- else
- sort_by_maxintsize_and_density(hfset,n,m,setlen,0);
- }
- n = m;
- setlen = hfsetlen[n];
- for(j = 0; j<setlen; j++)
- pich[j] = fmod(hfset[n][j],12.0); /* set up pitches of new comparison set */
- continue;
- }
- }
- if(intcnt != NULL) {
- if(dz->vflag[HP1_DENS] == DENSE_SORT)
- sort_by_density_regardless_of_size(hfset,intv,intvcnt,intv2,intvcnt2,n,m,setlen,1);
- else
- sort_by_maxintsize_and_density(hfset,n,m,setlen,0);
- }
- return(grping_cnt);
- }
- /************************** SORT_BY_REFERENCE_NOTE_EQUIVALENCE ***************************
- *
- * Sort pitch-ordered by pitch-class equivalence of root note.
- */
- int sort_by_reference_note_equivalence(double **hfset,int *hfsetlen,int hfsetcnt,int *grping,dataptr dz)
- {
- int j, k, m, n;
- int in_grp = 0, grping_cnt = 0, setlen, end, note = 0;
- double *tempoint, thispitch, thatpitch;
- n = 0;
- m = n+1;
- while(m < hfsetcnt) {
- setlen = hfsetlen[n];
- end = setlen - 1;
- switch(dz->iparam[HP1_SORT1]) {
- case(ROOT): note = 0; break;
- case(TOP): note = end; break;
- }
- while(hfsetlen[m] == setlen) { /* find sets of same size */
- if(++m >= hfsetcnt)
- break;
- }
- for(j=n;j<m-1;j++) { /* sort all these samesize sets into root pitchclass order */
- if(dz->process == HF_PERM1)
- thispitch = fmod(hfset[j][note],12.0);
- else
- thispitch = hfset[j][note];
- for(k=j+1;k<m;k++) {
- if(dz->process == HF_PERM1)
- thatpitch = fmod(hfset[k][note],12.0);
- else
- thatpitch = hfset[k][note];
- if(thatpitch < thispitch) {
- tempoint = hfset[k];
- hfset[k] = hfset[j];
- hfset[j] = tempoint;
- }
- }
- }
- k = n; /* sort all these into same-root sets */
- j = k+1;
- if(j >= hfsetcnt)
- break;
- in_grp = 0;
- while(j < m) {
- if(dz->process == HF_PERM1) {
- thispitch = fmod(hfset[k][note],12.0);
- thatpitch = fmod(hfset[j][note],12.0);
- } else {
- thispitch = hfset[k][note];
- thatpitch = hfset[j][note];
- }
- while(flteq(thatpitch,thispitch)) {
- if(!in_grp) {
- grping[grping_cnt++] = k; /* mark start of group */
- in_grp = 1;
- }
- if(++j >= m)
- break;
- if(dz->process == HF_PERM1) {
- thispitch = fmod(hfset[k][note],12.0);
- thatpitch = fmod(hfset[j][note],12.0);
- } else {
- thispitch = hfset[k][note];
- thatpitch = hfset[j][note];
- }
- }
- if(in_grp) { /* sort all these into density:tessitura order */
- grping[grping_cnt++] = -j; /* mark end of group */
- sort_by_maxint(hfset,k,j,setlen,dz);
- in_grp = 0; /* sort same-root sets into interval size and stack order */
- }
- k = j;
- j = k+1;
- }
- n = m;
- m = n+1;
- }
- return(grping_cnt);
- }
- /********************************* SORT_BY_MAXINT *********************************
- *
- * Sort pitch-ordered sets of FIXED SIZE by size of largest interval, then by interval density
- */
- void sort_by_maxint(double **hfset,int n,int m,int setlen,dataptr dz)
- {
- int j, k;
- double j_maxint, k_maxint, *tempoint;
- int end = setlen - 1;
- int in_grp;
- for(j=n;j<m-1;j++) { /* sort all by size of largest interval */
- j_maxint = hfset[j][end] - hfset[j][0];
- for(k=j+1;k<m;k++) {
- k_maxint = hfset[k][end] - hfset[k][0];
- switch(dz->vflag[HP1_SPAN]) {
- case(MAXSPAN_FIRST):
- if(k_maxint < j_maxint) {
- tempoint = hfset[j];
- hfset[j] = hfset[k];
- hfset[k] = tempoint;
- j_maxint = k_maxint;
- }
- break;
- case(MAXSPAN_LAST):
- if(k_maxint > j_maxint) {
- tempoint = hfset[j];
- hfset[j] = hfset[k];
- hfset[k] = tempoint;
- j_maxint = k_maxint;
- }
- break;
- }
- }
- }
- k = n;
- j = k+1;
- in_grp = 0;
- while(j < m) { /* sort largest-interval sets by internal interval arrangement */
- in_grp = 0;
- k_maxint = hfset[k][end] - hfset[k][0];
- j_maxint = hfset[j][end] - hfset[j][0];
- while(flteq(j_maxint,k_maxint)) {
- in_grp = 1;
- if(++j >= m)
- break;
- j_maxint = hfset[j][end] - hfset[j][0];
- }
- if(in_grp) {
- switch(dz->vflag[HP1_DENS]) {
- case(DENSE_SORT): sort_by_density(hfset,k,j,setlen,0); break;
- case(OTHER_SORT): sort_by_interval_stacking(hfset,k,j,setlen,0); break;
- }
- sort_by_octave_equivalence(hfset,n,m,setlen);
- }
- k = j;
- j = k+1;
- }
- }
- /********************************* SORT_BY_DENSITY *********************************
- *
- * Sort pitch-ordered sets of FIXED SIZE , WITH FIXED MAX INTERVAL by density...
- * measure the deviation from the mean inteval size between adjacent notes.
- * Minimum deviation = minimum density.
- */
- void sort_by_density(double **hfset,int n,int m,int setlen,int lowest)
- {
- int j, k, x;
- double j_deviation, k_deviation, y, average_intsize;
- double *tempoint;
- average_intsize = (hfset[n][setlen-1] - hfset[n][0])/(setlen-1);
- for(j=n;j<m-1;j++) {
- j_deviation = 0;
- for(x = 1; x < setlen; x++) {
- y = hfset[j][x] - hfset[j][x-1];
- y = fabs(y - average_intsize);
- j_deviation += y; /* no advantage in taking rms */
- }
- for(k=j+1;k<m;k++) {
- k_deviation = 0;
- for(x = 1; x < setlen; x++) {
- y = hfset[k][x] - hfset[k][x-1];
- y = fabs(y - average_intsize);
- k_deviation += y; /* no advantage in taking rms */
- }
- if(lowest) {
- if(k_deviation < j_deviation) {
- tempoint = hfset[k];
- hfset[k] = hfset[j];
- hfset[j] = tempoint;
- j_deviation = k_deviation;
- }
- } else {
- if(k_deviation > j_deviation) {
- tempoint = hfset[k];
- hfset[k] = hfset[j];
- hfset[j] = tempoint;
- j_deviation = k_deviation;
- }
- }
- }
- }
- }
- /********************************* SORT_BY_MAXINTSIZE_AND_DENSITY *********************************
- *
- * Sort pitch-ordered sets of FIXED SIZE , NOT of FIXED MAX INTERVAL by density...
- * measure the deviation from the mean inteval size between adjacent notes.
- * Minimum deviation = minimum density.
- */
- void sort_by_maxintsize_and_density(double **hfset,int n,int m,int setlen,int lowest)
- {
- int j, k, end = setlen - 1, in_grp;
- double j_intsize, k_intsize;
- double *tempoint;
- for(j=n;j<m-1;j++) { /* sort by max-intsize */
- j_intsize = hfset[j][end] - hfset[j][0];
- for(k=j+1;k<m;k++) {
- k_intsize = hfset[k][end] - hfset[k][0];
- if(k_intsize < j_intsize) {
- tempoint = hfset[k];
- hfset[k] = hfset[j];
- hfset[j] = tempoint;
- j_intsize = k_intsize;
- }
- }
- }
- j = n;
- k = j+1;
- while(k < m) {
- j_intsize = hfset[j][end] - hfset[j][0];
- in_grp = 0;
- while(flteq(hfset[k][end] - hfset[k][0],j_intsize)) {
- in_grp = 1;
- if(++k >= m)
- break;
- }
- if(in_grp)
- sort_by_density(hfset,j,k,setlen,lowest);
- j = k;
- k = j+1;
- }
- }
- /********************************* SORT_BY_OCTAVE_EQUIVALENCE *********************************
- *
- * Sort pitch-ordered sets of FIXED SIZE by equivalence at octave transposition, putting lower tessitura item first.
- */
- void sort_by_octave_equivalence
- (double **hfset,int n,int m,int setlen)
- {
- int i, j, j_base, j_adj, k, oct_equivalence;
- double *tempoint, int_diff;
- for(j=n;j<m-1;j++) {
- j_base = j;
- j_adj = j+1; /* if sets are separate by multiple of an octave */
- for(k=j+1;k<m;k++) {
- if(flteq(fmod((int_diff = hfset[k][0] - hfset[j][0]),12.0),0.0)) {
- oct_equivalence = 1;
- for(n=1;n<setlen;n++) {
- if(!flteq(hfset[k][n] - hfset[j][n],int_diff)) {
- oct_equivalence = 0;
- break;
- }
- }
- if(oct_equivalence) { /* if oct-equivalent */
- if(k != j_adj) { /* if NOT adjacent */
- tempoint = hfset[j_adj];
- hfset[j_adj] = hfset[k]; /* move oct-equiv set to be adjacent to j */
- hfset[k] = tempoint;
- }
- i = j;
- while(hfset[j_adj][0] < hfset[i][0]) {
- if(--i < j_base)
- break;
- }
- i++;
- if(i<=j) {
- tempoint = hfset[i];
- hfset[i] = hfset[j_adj]; /* move lower register item to correct place in group */
- hfset[j_adj] = tempoint;
- }
- j++; /* advance to new oct-equiv position */
- j_adj++;
- }
- }
- }
- }
- }
- /********************************* SORT_BY_INTERVAL_STACKING *********************************
- *
- * Sort pitch-ordered sets of FIXED SIZE , WITH FIXED MAX INTERVAL by sequnce of pitches within...
- * NORMALLY - start with chord having the lowest pitches (on average)
- * ... if 'highest-first' flag set, start with chord with highest pitches (on average)
- */
- void sort_by_interval_stacking(double **hfset,int n,int m,int setlen,int highest_first)
- {
- int j, k, x;
- double j_height, k_height;
- double *tempoint;
- for(j=n;j<m-1;j++) {
- j_height = 0;
- for(x = 1; x < setlen; x++)
- j_height += hfset[j][x] - hfset[j][0];
- for(k=j+1;k<m;k++) {
- k_height = 0;
- for(x = 1; x < setlen; x++)
- k_height += hfset[k][x] - hfset[k][0];
- if(highest_first) {
- if(k_height > j_height) {
- tempoint = hfset[k];
- hfset[k] = hfset[j];
- hfset[j] = tempoint;
- j_height = k_height;
- }
- } else {
- if(k_height < j_height) {
- tempoint = hfset[k];
- hfset[k] = hfset[j];
- hfset[j] = tempoint;
- j_height = k_height;
- }
- }
- }
- }
- }
- /********************************* ELIMINATE_OCT_DUPLICATED_SETS *********************************
- *
- * Sort ordered-by-size, then pitch-ordered sets, eliniating stes dupliated at 8vas.
- */
- void eliminate_oct_duplicated_sets(double **hfset,int *hfsetcnt,int *hfsetlen,int *grping,int *grping_cnt,int type)
- {
- int a, b, n, m, j, k, oct_equivalence, setlen;
- double *tempoint, int_diff;
- n=0;
- m = n+1;
- setlen = hfsetlen[n];
- while(n < *hfsetcnt) {
- while(hfsetlen[m] == setlen) { /* find equal-size sets */
- if(++m >= *hfsetcnt)
- break;
- }
- if(m == n+1) {
- n++;
- if((m = n+1) >= *hfsetcnt)
- break;
- setlen = hfsetlen[n];
- continue;
- }
- for(j=n;j<m-1;j++) {
- for(k = j+1;k<m;k++) {
- if(flteq(fmod((int_diff = hfset[k][0] - hfset[j][0]),12.0),0.0)) {
- oct_equivalence = 1;
- for(a=1;a<setlen;a++) {
- if(!flteq(hfset[k][a] - hfset[j][a],int_diff)) {
- oct_equivalence = 0;
- break;
- }
- }
- if(oct_equivalence) { /* if oct-equivalent */
- if(type == TOPNOTE) {
- if(hfset[k][0] > hfset[j][0]) {
- tempoint = hfset[j];
- hfset[j] = hfset[k]; /* keep the higher-register item */
- hfset[k] = tempoint;
- }
- } else {
- if(hfset[k][0] < hfset[j][0]) {
- tempoint = hfset[j];
- hfset[j] = hfset[k]; /* keep the lower-register item */
- hfset[k] = tempoint;
- }
- }
- for(a=k,b=k+1;b<*hfsetcnt;a++,b++) /* delete unwanted set */
- hfset[a] = hfset[b];
- if(grping != NULL) { /* reposition grouping marks */
- for(a=0;a<*grping_cnt;a++) {
- /* if start or end of short group */
- if(((grping[a] == k) && (a+1 < *grping_cnt) && (grping[a+1] >= -(k+2)))
- || ((grping[a] == k-1) && (a+1 < *grping_cnt) && (grping[a+1] >= -(k+1)))) {
- if(a+2 < *grping_cnt) { /* eliminate both */
- for(b = a+2; b < *grping_cnt;b++)
- grping[b-2] = grping[b];
- }
- *grping_cnt -= 2;
- a -= 1; /* step back to resume parse */
- }
- else if(grping[a] > k) /* decrement all markers beyond */
- grping[a]--;
- else if(grping[a] < -k)
- grping[a]++;
- }
- }
- (*hfsetcnt)--; /* decrement all counters */
- m--;
- k--;
- }
- }
- }
- }
- n = m;
- if((m = n+1) >= *hfsetcnt)
- break;
- setlen = hfsetlen[n];
- }
- }
- /********************************* SORT_BY_DENSITY_REGARDLESS_OF_SIZE *********************************
- *
- * Sort pitch-ordered sets of FIXED LENGTH . by density, regardless of MAX INTERVAL...
- * .... sort on basis of maximum number of minsize intervals.
- */
- void sort_by_density_regardless_of_size
- (double **hfset,double *interv,int *intervcnt,double *interv2,int *intervcnt2,int n,int m,int setlen,int densest_first)
- {
- int a, j, k, x, q, do_swap, equivalent;
- double tempdb, *tempoint;
- int intsetlen1 = setlen - 1;
- int intsetlen2 = setlen - 1;
- int tempoi, end = setlen - 1;
- double *intv = interv, *intv2 = interv2;
- int *intvcnt = intervcnt, *intvcnt2 = intervcnt2, *tempii;
- for(j=n;j<m-1;j++) {
- intsetlen1 = setlen - 1;
- for(x=1;x<setlen;x++) {
- intv[x-1] = hfset[j][x] - hfset[j][x-1]; /* find each interval and count it */
- intvcnt[x-1] = 1;
- }
- for(x=0;x<intsetlen1-1;x++) {
- for(q=x+1;q<intsetlen1;q++) {
- if(flteq(intv[q],intv[x])) { /* compare intervals */
- intvcnt[x]++; /* if same, incr count of first */
- a = q;
- while(a< intsetlen1-1) { /* and eliminate other from set */
- intv[a] = intv[a+1];
- a++;
- }
- intsetlen1--;
- q--;
- }
- }
- }
- for(x=0;x<intsetlen1-1;x++) { /* sort intervals by size */
- for(q=x+1;q<intsetlen1;q++) {
- if(intv[q] < intv[x]) {
- tempdb = intv[q];
- intv[q] = intv[x];
- intv[x] = tempdb;
- tempoi = intvcnt[q];
- intvcnt[q] = intvcnt[x];
- intvcnt[x] = tempoi;
- }
- }
- }
- for(k=j+1;k<m;k++) {
- intsetlen2 = setlen - 1;
- for(x=1;x<setlen;x++) {
- intv2[x-1] = hfset[k][x] - hfset[k][x-1];
- intvcnt2[x-1] = 1;
- }
- for(x=0;x<intsetlen2-1;x++) {
- for(q=x+1;q<intsetlen2;q++) {
- if(flteq(intv2[q],intv2[x])) {
- intvcnt2[x]++;
- a = q;
- while(a < intsetlen2-1) {
- intv2[a] = intv2[a+1];
- a++;
- }
- intsetlen2--;
- q--;
- }
- }
- }
- for(x=0;x<intsetlen2-1;x++) {
- for(q=x+1;q<intsetlen2;q++) {
- if(intv2[q] < intv2[x]) {
- tempdb = intv2[q];
- intv2[q] = intv2[x];
- intv2[x] = tempdb;
- tempoi = intvcnt2[q];
- intvcnt2[q] = intvcnt2[x];
- intvcnt2[x] = tempoi;
- }
- }
- }
- do_swap = 0;
- equivalent = 1;
- if(densest_first) {
- for(a=0;a<min(intsetlen1,intsetlen2);a++) {
- if(intv2[a] > intv[a]) {
- equivalent = 0;
- break;
- } else if(intv2[a] < intv[a]) {
- equivalent = 0;
- do_swap = 1;
- break;
- } else {
- if(intvcnt2[a] > intvcnt[a]) {
- equivalent = 0;
- do_swap = 1;
- break;
- } else if(intvcnt2[a] < intvcnt[a]) {
- equivalent = 0;
- break;
- }
- }
- }
- } else {
- for(a=0;a<min(intsetlen1,intsetlen2);a++) {
- if(intv2[a] < intv[a]) {
- equivalent = 0;
- break;
- } else if(intv2[a] > intv[a]) {
- equivalent = 0;
- do_swap = 1;
- break;
- } else {
- if(intvcnt2[a] < intvcnt[a]) {
- equivalent = 0;
- do_swap = 1;
- break;
- } else if(intvcnt2[a] > intvcnt[a]) {
- equivalent = 0;
- break;
- }
- }
- }
- }
- if((!do_swap) && equivalent) { /* swap if total range is greater */
- if(hfset[j][end] - hfset[j][0] > hfset[k][end] - hfset[k][0])
- do_swap = 1;
- else if(hfset[j][0] > hfset[k][0]) /* swap if root is lower */
- do_swap = 1;
- }
- if(do_swap) {
- tempoint = hfset[k];
- hfset[k] = hfset[j];
- hfset[j] = tempoint;
- tempoint = intv;
- intv = intv2;
- intv2 = tempoint;
- tempii = intvcnt ;
- intvcnt = intvcnt2;
- intvcnt2 = tempii;
- }
- }
- }
- }
- /******************************* SETUP_NAMING ******************************/
- int setup_naming(char **thisfilename,dataptr dz)
- {
- int innamelen = strlen(dz->wordstor[0]);
- int numlen = 5;
- // FEB 2010 TW
- if((*thisfilename = (char *)malloc((innamelen + numlen + 10) * sizeof(char)))==NULL) {
- sprintf(errstr,"INSUFFICIENT MEMORY for outfilename.\n");
- return(MEMORY_ERROR);
- }
- return(FINISHED);
- }
- /********************************** CREATE_OUTFILE_NAME ********************************/
- int create_outfile_name(int ccnt,char *thisfilename,dataptr dz)
- {
- strcpy(thisfilename,dz->wordstor[0]);
- // FEB 2010 TW
- if(!sloom)
- insert_separator_on_sndfile_name(thisfilename,1);
- insert_new_number_at_filename_end(thisfilename,ccnt,1);
- return(FINISHED);
- }
- /********************************** GEN_NOTE ********************************/
- void gen_note(int maxjitter,double *tabstart,double *tabend,double **tabmin, double **tabmax,double **hfset,
- double tabscale,double sintabsize,int splicelen, double *sintab,int n, int j)
- {
- int jitter, initial_phase, i;
- double *this_tabend, *startsplice_end, *endsplice_start, *tab;
- double sintabpos, sintabincr;
- int intpos, nxtpos;
- double frac, vallo, valhi, valdif;
- jitter = (int)round(drand48() * maxjitter);
- tab = tabstart + jitter;
- this_tabend = tabend + jitter;
- *tabmin = min(tab,*tabmin);
- *tabmax = max(this_tabend,*tabmax);
- tab++; /* 1st val = 0 */
- /* START POSITION IN TABLE TO READ TO GENERATE SOUND */
- initial_phase = (int)round(drand48() * HFP_TABSIZE);
- sintabincr = (miditohz(hfset[n][j]) * tabscale);
- sintabpos = sintabincr + initial_phase;
- sintabpos = fmod(sintabpos,sintabsize);
- startsplice_end = tab + splicelen;
- endsplice_start = this_tabend - splicelen;
- /* START OF EACH CONSTITUENT MUST BE SPLICED */
- i = 0;
- while(tab < startsplice_end) {
- intpos = (int)floor(sintabpos);
- nxtpos = intpos+1;
- frac = sintabpos - (double)intpos;
- vallo = sintab[intpos];
- valhi = sintab[nxtpos];
- valdif= valhi - vallo;
- *tab += (vallo + (valdif * frac)) * (i/(double)splicelen);
- i++;
- sintabpos += sintabincr;
- sintabpos = fmod(sintabpos,sintabsize);
- tab++;
- }
- while(tab < endsplice_start) {
- intpos = (int)floor(sintabpos);
- nxtpos = intpos+1;
- frac = sintabpos - (double)intpos;
- vallo = sintab[intpos];
- valhi = sintab[nxtpos];
- valdif= valhi - vallo;
- *tab += vallo + (valdif * frac);
- sintabpos += sintabincr;
- sintabpos = fmod(sintabpos,sintabsize);
- tab++;
- }
- /* END OF EACH CONSTITUENT MUST BE SPLICED */
- i = splicelen - 1;
- while(tab < this_tabend) {
- intpos = (int)floor(sintabpos);
- nxtpos = intpos+1;
- frac = sintabpos - (double)intpos;
- vallo = sintab[intpos];
- valhi = sintab[nxtpos];
- valdif= valhi - vallo;
- *tab += (vallo + (valdif * frac)) * (i/(double)splicelen);
- i--;
- sintabpos += sintabincr;
- sintabpos = fmod(sintabpos,sintabsize);
- tab++;
- }
- }
- /********************************** NEXT_FILE ********************************/
- int next_file(int *samps_written,char *thisfilename,int *ccnt,unsigned int *space_needed,
- int *samp_space_available,dataptr dz)
- {
- int exit_status;
- /* FLUSH BUFS */
- *samps_written += dz->iparam[HP1_GAP_SIZE];
- while(*samps_written >= dz->buflen) {
- if((exit_status = write_samps(dz->sampbuf[0],dz->buflen,dz))<0)
- return(exit_status);
- *samps_written -= dz->buflen;
- }
- if(*samps_written > 0) {
- if((exit_status = write_samps(dz->sampbuf[0],*samps_written,dz))<0)
- return(exit_status);
- }
- /* CLOSE FILE */
- dz->outfiletype = SNDFILE_OUT; /* allows header to be written */
- if((exit_status = headwrite(dz->ofd,dz))<0)
- return(exit_status);
- dz->process_type = OTHER_PROCESS; /* restore true status */
- dz->outfiletype = NO_OUTPUTFILE; /* restore true status */
- superzargo += dz->total_samps_written; /* accumulator of total samples written */
- if((exit_status = reset_peak_finder(dz))<0)
- return(exit_status);
- if(sndcloseEx(dz->ofd) < 0) {
- fprintf(stdout,"WARNING: Can't close output soundfile %s\n",thisfilename);
- fflush(stdout);
- }
- dz->ofd = -1;
- (*ccnt)++;
- /* OPEN NEW FILE */
- if((exit_status = create_outfile_name(*ccnt,thisfilename,dz))<0)
- return(exit_status);
- dz->process_type = UNEQUAL_SNDFILE; /* allow sndfile to be created */
- if((exit_status = create_sized_outfile(thisfilename,dz))<0) {
- fprintf(stdout, "WARNING: Soundfile %s already exists.\n",thisfilename);
- fflush(stdout);
- dz->process_type = OTHER_PROCESS;
- dz->ofd = -1;
- return(PROGRAM_ERROR);
- }
- *space_needed -= dz->total_samps_written;
- if((unsigned int)dz->outfilesize < *space_needed) {
- sprintf(errstr,"Insufficient space on the hard disk to store the next output file.\n");
- return(MEMORY_ERROR);
- }
- /* RESET BUFFERS */
- dz->total_samps_written = 0;
- memset((char *)dz->sampbuf[0],0,(size_t)dz->buflen * sizeof(float));
- *samp_space_available = dz->buflen;
- *samps_written = 0;
- //NEW TW
- return(FINISHED);
- }
- /********************************** GEN_DP_OUTPUT ********************************/
- int gen_dp_output(dataptr dz)
- {
- int exit_status;
- float *obuf = dz->sampbuf[0];
- double *tabend, *tab = (double *)dz->sampbuf[3];
- double *accumtab = (double *)dz->sampbuf[2];
- double *perm = dz->parray[1];
- double tabscale = (double)HFP_TABSIZE/dz->infile->srate;
- double *sintab = (double *)dz->sampbuf[1];
- float *intab = dz->sampbuf[1];
- double sintabsize; //, pad;
- int intabsize;
- int samps_written = 0, samp_space_available, samps_to_write;
- int note_being_permed, noteno, index_in_new_perm, index_in_last_perm, i, j, no_of_perms, permcounter, transpos_cnt;
- int maxjitter = (int)round(drand48() * HFP_MAXJITTER * MS_TO_SECS * (double)dz->infile->srate);
- unsigned int element_byte_len = dz->iparam[DP_DUR] * sizeof(double);
- unsigned int element_full_len = element_byte_len + (maxjitter * sizeof(double));
- double *tabmin = accumtab, *tabmax = accumtab + dz->iparam[DP_DUR] + maxjitter;
- int splicelen = (int)round(HP1_SPLICELEN * MS_TO_SECS * (double)dz->infile->srate);
- double ampmult = 1.0/(double)(dz->iparam[DP_CYCCNT] + 1);
- double *permset, thistranspos;
- int accumtabstart, accumtabend, a, b;
- int jitter, endindex_of_last_perm, endindex_of_last_perm_but_one, endindex_in_new_perm = 0, len, thislen;
- /* JUNE 2004 */
- sprintf(errstr,"ERROR: This program is currently malfunctioning.\n");
- return(PROGRAM_ERROR);
- /* JUNE 2004 */
- switch(dz->process) {
- case(DEL_PERM):
- sintabsize = (double)HFP_TABSIZE;
- ampmult *= MAXSAMP;
- break;
- case(DEL_PERM2):
- intabsize = dz->iparam[DP_DUR];
- break;
- }
- dz->tempsize = dz->iparam[DP_DUR] * (dz->iparam[DP_NOTECNT] + dz->iparam[DP_CYCCNT]);
- if((permset =
- (double *)malloc((unsigned int)round(pow(dz->iparam[DP_PERMCNT],dz->iparam[DP_CYCCNT])) * sizeof(double))) == NULL) {
- sprintf(errstr,"No memory for permutations of notes\n");
- return(MEMORY_ERROR);
- }
- for(noteno = 0; noteno < dz->iparam[DP_NOTECNT]/* + dz->iparam[DP_CYCCNT]*/; noteno++) {
- sprintf(errstr,"Expanding note %d\n",noteno+1);
- print_outmessage_flush(errstr);
- memset(accumtab,0,element_full_len);
- for(note_being_permed = noteno, no_of_perms = 0;
- note_being_permed >= max(0,noteno - dz->iparam[DP_CYCCNT]);
- note_being_permed--, no_of_perms++) {
- if(note_being_permed >= dz->iparam[DP_NOTECNT])
- continue;
- jitter = (int)(drand48() * maxjitter);
- accumtabstart = jitter;
- permset[0] = dz->parray[1][note_being_permed];
- endindex_of_last_perm = 0;
- endindex_of_last_perm_but_one = 0;
- for(permcounter = 0; permcounter < no_of_perms; permcounter++) {
- index_in_last_perm = endindex_of_last_perm;
- endindex_in_new_perm = ((index_in_last_perm+1) * dz->iparam[DP_PERMCNT]) - 1;
- index_in_new_perm = endindex_in_new_perm;
- while(index_in_last_perm >= 0) {
- for(transpos_cnt = dz->iparam[DP_PERMCNT]-1; transpos_cnt >= 0; transpos_cnt--)
- permset[index_in_new_perm--] = permset[index_in_last_perm] + perm[transpos_cnt];
- index_in_last_perm--;
- }
- endindex_of_last_perm_but_one = endindex_of_last_perm;
- endindex_of_last_perm = endindex_in_new_perm;
- }
- tab = (double *)dz->sampbuf[3];
- if(no_of_perms > 0) {
- if((len = (int)round((double)dz->iparam[DP_DUR]/(double)(endindex_of_last_perm_but_one+1))) <= splicelen * 2) {
- sprintf(errstr,"Notes have become too short for splices to be made.\n");
- return(GOAL_FAILED);
- }
- for(i = 0, j = 0; i <= endindex_of_last_perm; i++, j++) {
- j %= dz->iparam[DP_PERMCNT];
- switch(dz->process) {
- case(DEL_PERM):
- thislen = (int)round(len * dz->parray[2][j]);
- if(thislen <= splicelen * 2) {
- sprintf(errstr,"Notes have become too short for splices to be made.\n");
- return(GOAL_FAILED);
- }
- tabend = tab + thislen;
- memset((char *)tab,0,element_byte_len);
- gen_note2(tab,tabend,permset[i],tabscale,sintabsize,splicelen,sintab); break;
- case(DEL_PERM2):
- thistranspos = pow(2.0,(permset[i]/12.0));
- thislen = (int)round(len/thistranspos);
- thislen = min(thislen,len);
- if(thislen <= splicelen * 2) {
- sprintf(errstr,"Notes have become too short for splices to be made.\n");
- return(GOAL_FAILED);
- }
- tabend = tab + thislen;
- memset((char *)tab,0,element_byte_len);
- gen_note3(tab,tabend,thistranspos,intabsize,splicelen,intab); break;
- }
- accumtabstart = accumtabstart + thislen;
- accumtabend = accumtabstart + thislen;
- //pad = pow(ROLLOFF,no_of_perms);
- accumtabstart += thislen;
- }
- } else {
- len = dz->iparam[DP_DUR];
- tabend = tab + len;
- memset(tab,0,element_byte_len);
- switch(dz->process) {
- case(DEL_PERM): gen_note2(tab,tabend,permset[0],tabscale,sintabsize,splicelen,sintab); break;
- case(DEL_PERM2): gen_note3(tab,tabend,permset[0],intabsize,splicelen,intab); break;
- }
- accumtabend = accumtabstart + len;
- for(a=accumtabstart, b = 0; a < accumtabend;a++,b++)
- accumtab[a] += tab[b];
- accumtabstart += len;
- }
- }
- /* DO OUTPUT */
- samp_space_available = dz->buflen - samps_written;
- i = 0;
- samps_to_write = tabmax - tabmin;
- while(i < samps_to_write) {
- if(samp_space_available > samps_to_write) {
- while(i < samps_to_write)
- obuf[samps_written++] = (float)(accumtab[i++] * ampmult);
- } else {
- while(samps_written < dz->buflen)
- obuf[samps_written++] = (float)(accumtab[i++] * ampmult);
- if((exit_status = write_samps(dz->sampbuf[0],dz->buflen,dz))<0)
- return(exit_status);
- memset((char *)dz->sampbuf[0],0,(size_t)dz->buflen * sizeof(float));
- samps_written = 0;
- samp_space_available = dz->buflen;
- }
- }
- }
- while(samps_written >= dz->buflen) {
- if((exit_status = write_samps(dz->sampbuf[0],dz->buflen,dz))<0)
- return(exit_status);
- samps_written -= dz->buflen;
- }
- if(samps_written > 0) {
- if((exit_status = write_samps(dz->sampbuf[0],samps_written,dz))<0)
- return(exit_status);
- }
- return(FINISHED);
- }
- /********************************** GEN_NOTE2 ********************************/
- void gen_note2(double *tabstart,double *tabend,double midival,
- double tabscale,double sintabsize,int splicelen, double *sintab)
- {
- int initial_phase, i;
- double *startsplice_end, *endsplice_start, *tab;
- double sintabpos, sintabincr;
- int intpos, nxtpos;
- double frac, vallo, valhi, valdif;
- tab = tabstart;
- *tab++ = 0; /* 1st val = 0 */
- /* START POSITION IN TABLE TO READ TO GENERATE SOUND */
- initial_phase = (int)round(drand48() * HFP_TABSIZE);
- sintabincr = (miditohz(midival) * tabscale);
- sintabpos = sintabincr + initial_phase;
- sintabpos = fmod(sintabpos,sintabsize);
- startsplice_end = tab + splicelen;
- endsplice_start = tabend - splicelen;
- /* START OF EACH CONSTITUENT MUST BE SPLICED */
- i = 0;
- while(tab < startsplice_end) {
- intpos = (int)floor(sintabpos);
- nxtpos = intpos+1;
- frac = sintabpos - (double)intpos;
- vallo = sintab[intpos];
- valhi = sintab[nxtpos];
- valdif= valhi - vallo;
- *tab += (vallo + (valdif * frac)) * (i/(double)splicelen);
- i++;
- sintabpos += sintabincr;
- sintabpos = fmod(sintabpos,sintabsize);
- tab++;
- }
- while(tab < endsplice_start) {
- intpos = (int)floor(sintabpos);
- nxtpos = intpos+1;
- frac = sintabpos - (double)intpos;
- vallo = sintab[intpos];
- valhi = sintab[nxtpos];
- valdif= valhi - vallo;
- *tab += vallo + (valdif * frac);
- sintabpos += sintabincr;
- sintabpos = fmod(sintabpos,sintabsize);
- tab++;
- }
- /* END OF EACH CONSTITUENT MUST BE SPLICED */
- i = splicelen - 1;
- while(tab < tabend) {
- intpos = (int)floor(sintabpos);
- nxtpos = intpos+1;
- frac = sintabpos - (double)intpos;
- vallo = sintab[intpos];
- valhi = sintab[nxtpos];
- valdif= valhi - vallo;
- *tab += (vallo + (valdif * frac)) * (i/(double)splicelen);
- i--;
- sintabpos += sintabincr;
- sintabpos = fmod(sintabpos,sintabsize);
- tab++;
- }
- }
- /********************************** GEN_NOTE3 ********************************/
- //void gen_note3(double *tabstart,double *tabend,double midival,int intabsize,int splicelen, short *intab)
- void gen_note3(double *tabstart,double *tabend,double midival,int intabsize,int splicelen, float *intab)
- {
- int i;
- double *startsplice_end, *endsplice_start, *tab;
- double tabpos, tabincr, effective_len;
- int intpos, nxtpos;
- double frac, vallo, valhi, valdif;
- tab = tabstart;
- *tab++ = 0; /* 1st val = 0 */
- tabincr = (miditohz(midival)/miditohz(60.0));
- effective_len = (double)(tabend - tabstart);
- if(effective_len * tabincr > (double)intabsize) {
- effective_len /= tabincr;
- tabend = tabstart + (int)effective_len;
- }
- tabpos = tabincr;
- startsplice_end = tab + splicelen;
- endsplice_start = tabend - splicelen;
- /* START OF EACH CONSTITUENT MUST BE SPLICED */
- i = 0;
- while(tab < startsplice_end) {
- intpos = (int)floor(tabpos);
- nxtpos = intpos+1;
- frac = tabpos - (double)intpos;
- vallo = intab[intpos];
- valhi = intab[nxtpos];
- valdif= valhi - vallo;
- *tab += (vallo + (valdif * frac)) * (i/(double)splicelen);
- i++;
- tabpos += tabincr;
- tab++;
- }
- while(tab < endsplice_start) {
- intpos = (int)floor(tabpos);
- nxtpos = intpos+1;
- frac = tabpos - (double)intpos;
- vallo = intab[intpos];
- valhi = intab[nxtpos];
- valdif= valhi - vallo;
- *tab += vallo + (valdif * frac);
- tabpos += tabincr;
- tab++;
- }
- /* END OF EACH CONSTITUENT MUST BE SPLICED */
- i = splicelen - 1;
- while(tab < tabend) {
- intpos = (int)floor(tabpos);
- nxtpos = intpos+1;
- frac = tabpos - (double)intpos;
- vallo = intab[intpos];
- valhi = intab[nxtpos];
- valdif= valhi - vallo;
- *tab += (vallo + (valdif * frac)) * (i/(double)splicelen);
- i--;
- tabpos += tabincr;
- tab++;
- }
- }
|