texture3.c 93 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361
  1. /*
  2. * Copyright (c) 1983-2023 Trevor Wishart and Composers Desktop Project Ltd
  3. * http://www.trevorwishart.co.uk
  4. * http://www.composersdesktop.com
  5. *
  6. This file is part of the CDP System.
  7. The CDP System is free software; you can redistribute it
  8. and/or modify it under the terms of the GNU Lesser General Public
  9. License as published by the Free Software Foundation; either
  10. version 2.1 of the License, or (at your option) any later version.
  11. The CDP System is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. GNU Lesser General Public License for more details.
  15. You should have received a copy of the GNU Lesser General Public
  16. License along with the CDP System; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  18. 02111-1307 USA
  19. *
  20. */
  21. /* floatsam version: no changes */
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <float.h>
  25. #include <structures.h>
  26. #include <tkglobals.h>
  27. #include <globcon.h>
  28. #include <processno.h>
  29. #include <modeno.h>
  30. #include <arrays.h>
  31. #include <texture.h>
  32. #include <cdpmain.h>
  33. #include <sfsys.h>
  34. #include <osbind.h>
  35. //#if defined unix || defined __GNUC__
  36. #define round(x) lround((x))
  37. //#endif
  38. #define CHARBITSIZE (8) /* number of bits in a char */
  39. struct ffit { /* Structure for FIT of motif to HS */
  40. float transpose;
  41. float fit;
  42. struct ffit *next;
  43. struct ffit *last;
  44. };
  45. typedef struct ffit *fitptr;
  46. /* RWD Feb 2014: now in sfsys,h, differently! */
  47. #ifdef MAXINT
  48. # undef MAXINT
  49. #endif
  50. #define MAXINT (2147483647)
  51. /***************************** GENERATING TEXTURES WITH HFIELD(S) ******************************/
  52. static int set_hfmotifs(double *hs,motifptr *phrase,int *phrnotecnt,double *phraseamp,
  53. double *phrange, noteptr *phrlastnote,int *endhsindex,int **hfphrase,
  54. int hsnotecnt,fitptr fithead,double **notestor,dataptr dz);
  55. static int gethfphrase
  56. (double *hs,double **notestor,int z,double lopitch,double hipitch,int **hfphrase,
  57. int hsnotecnt,int *phrnotecnt,motifptr *phrase,fitptr fithead);
  58. static int shrink_to_hs
  59. (int z,int hsnotecnt,double hipitch,double lopitch,double hstop,double hsbot,
  60. double *hs, int *hfphrase,motifptr *phrase,int *phrnotecnt);
  61. static int findhfphrase
  62. (int z,double *hs,double hstop,int hsnotecnt,double lopitch,
  63. double origlo,motifptr *phrase,int **hfphrase,int *phrnotecnt,fitptr fithead,double **notestor);
  64. static int getmtfindeces
  65. (double transpose,int z,int hsnotecnt,double *hs,motifptr *phrase,int *phrnotecnt,int **hfphrase);
  66. static int get_fit(double *notestor,fitptr thisfit,double lopitch,double origlo,int z,
  67. int hsnotecnt,int *phrnotecnt,double *hs,fitptr *newfit);
  68. static int put_fit(fitptr thisfit,double transval,double fitval,fitptr *newfit);
  69. static int best_fit(fitptr fithead,double *transpose);
  70. static void free_fitlist(fitptr fithead);
  71. static double hfadjust(double thispitch,double *hs,int x1,int x2,int texflag,int hsnotecnt);
  72. static int convert_pitch_to_nearest_hset_pitch(double thispitch,double *hs,int hsnotecnt);
  73. static int hfadj2(int hsi,int hfnotecnt,int hsnotecnt);
  74. static int setup_hfield(noteptr thisnote,double **hs,int *hsnotecnt,double **hf,int *hfnotecnt,int texflag);
  75. static int get_next_hfield
  76. (double **hf,double **hs,double inputtime,int *hf_cnt,int *hs_cnt,int *hfnotecnt,
  77. noteptr *thishfnote,double *thishftime,double *nexthftime,int hfdatacnt,int *hsnotecnt,
  78. noteptr *thishsnote,double *thishstime,double *nexthstime,double *hft,int texflag);
  79. static int setup_motif_note
  80. (double thisamp,int thisinstr,double thisdur,noteptr tsetnote,noteptr phrasenote,
  81. double *thispitch,double thistime,int *hsindex,int hsnotecnt,double *hs,
  82. double *pptop,double *ppbot,int *shadindex,char *shadbits,double multiplier,dataptr dz);
  83. static int setup_group_note
  84. (double thisamp,int thisinstr,double thisdur,noteptr tsetnote,
  85. double *thispitch,double thistime,int *hsindex,int hsnotecnt,double *hs,
  86. double *pptop,double *ppbot,int *shadindex,char *shadbits,dataptr dz);
  87. static int setup_ornamentation
  88. (int *starthsi,int *endhsi,noteptr *nextevent,noteptr tsetnote,noteptr *phrasenote,
  89. int *shadindex, int *endhsindex,int *hfphrase,int phrno,dataptr dz);
  90. static int generate_motifin_note_pitch
  91. (int n,int hsindex,int starthsindex,int hsnotecnt,double thispitch,
  92. int *hfphrase,noteptr *thisnote,double *hs,int texflag);
  93. static int generate_motif_note_pitch
  94. (noteptr tsetnote,noteptr phrasenote,double phrfirstnote,noteptr thisnote);
  95. static int generate_ornament_note_pitch
  96. (int n,double *hs, int hsi, int endhsi,int starthsi,noteptr *thisnote,noteptr *phrasenote,
  97. int *hfphrase,int hfnotecnt,int hsnotecnt,dataptr dz);
  98. static int do_ev_hfpch
  99. (double thistime,int *hsindex,double *val,
  100. int hsnotecnt,double *hs,double *pptop,double *ppbot,dataptr dz);
  101. static int getp_as_index
  102. (double thistime,int *val,int hsnotecnt,double *hs,double *pptop,double *ppbot,dataptr dz);
  103. static int init_shadbits(int shadowsize,int *shshsize,char **shadbits);
  104. static int geths(noteptr thisnote,double **hs,int *hsnotecnt);
  105. static int gethf(noteptr thisnote,double **hf,int *hfnotecnt);
  106. static int gen_hs(double **hf,double **hs, int *hsnotecnt, int hfnotecnt);
  107. // static int chekrepeat(noteptr thisnote,double lastpitch);
  108. static void set_shadbit(int k,char *shadbits);
  109. static int geths_lobnd(double thispitch,double *hs,int hsnotecnt);
  110. static int gethfnote(double thispitch,double *hf,int *hfnotecnt);
  111. static int setmtfparams
  112. (noteptr thisnote,double thisamp,noteptr phrasenote,noteptr tsetnote,double ampdif,
  113. double notetime,int gpsize,double multiplier,dataptr dz);
  114. static int initialise_hfphrases
  115. (int ***hfphrase,int **endhsindex,int **phrnotecnt,double **phraseamp,double **phrange,
  116. noteptr **phrlastnote,dataptr dz);
  117. static int readhftimes(noteptr firstnote, int *hfdatacnt,double **hft);
  118. static int init_fits(fitptr *thisfit);
  119. static int get_hfgpparams(double thistime,double thispitch,double *hs,int hsnotecnt,
  120. int *gpsize,int *hfrange,int *hfgpranglo,int *hfgpranghi,
  121. double *gprange,double *gpdense,int mingrpsize,
  122. double *gprlow, int dectypecnt,unsigned char dectypestor,dataptr dz);
  123. static int generate_group_note(noteptr thisnote,noteptr testnote,double thistime,
  124. int hfrange,int hfgpranglo,double *hs,int *hsindex,int gpsize,dataptr dz);
  125. static int generate_decor_note(noteptr thisnote,noteptr tsetnote,
  126. double thispitch,double thistime,int hfrange,int hfgpranghi,int hfgpranglo,
  127. double *hs,int *hsindex,int hsnotecnt,double gprlow,double gprange,int gpsize,dataptr dz);
  128. static void del_ghosts(int shshsize,char *shadbits,noteptr *shadow,int shadowsize,motifptr tset);
  129. static int geths_hibnd(double thispitch,int hsnotecnt,double *hs);
  130. static int geths_above(double thispitch,double *hs,int hsnotecnt);
  131. static int fit_unlink(fitptr thisfit);
  132. static int new_fit(fitptr thisfit,fitptr *newfit);
  133. static int getnexths(double **hs,double inputtime,int *hs_cnt,int *hsnotecnt,noteptr *thishsnote,
  134. double *thishstime,double *nexthstime,int hfdatacnt,double *hft);
  135. static int getnexthf(double **hf,double **hs, int *hsnotecnt,double inputtime,int *hf_cnt,
  136. int *hfnotecnt,noteptr *thishfnote,double *thishftime,double *nexthftime,int hfdatacnt,double *hft);
  137. static int hfscat(int prange,int pbottom,int permindex,int *val,dataptr dz);
  138. static int gethsnote(double thispitch,double *thishs,int *hsnotecnt);
  139. static void hfsqueezrange
  140. (double thispitch,int *hfrange,int *hfgpranghi,int *hfgpranglo,int hsnotecnt,double *hs);
  141. static int hforientrange(double thispitch,int *hfrange,int *hfgpranghi,int *hfgpranglo,
  142. int hsnotecnt,double *hs,int dectypecnt,unsigned char dectypestor,dataptr dz);
  143. static int dec_hfcentre(double tsetpitch,double *hs,int hsnotecnt,
  144. int hfrange,int hfgpranghi,int hfgpranglo,double gprlow,double gprange,int gpsize,
  145. double *val,dataptr dz);
  146. static int hfscatx(int prange,int pbottom,int permindex,int *val,dataptr dz);
  147. static int get_first_hs(noteptr thisnote,double **hs,int *hsnotecnt);
  148. static int get_first_hf(noteptr thisnote,double **hf,int *hfnotecnt);
  149. static int setup_first_hfield
  150. (noteptr thisnote,double **hs,int *hsnotecnt,double **hf,int *hfnotecnt,int texflag);
  151. static int octeq(double a,double b);
  152. /**************************** DO_SIMPLE_HFTEXTURE ****************************/
  153. int do_simple_hftexture(dataptr dz)
  154. {
  155. int exit_status;
  156. unsigned int texflag = dz->tex->txflag;
  157. motifptr tset = dz->tex->timeset;
  158. motifptr hfmotif = dz->tex->hfldmotif;
  159. int hsindex;
  160. noteptr tsetnote = tset->firstnote;
  161. noteptr nextnote;
  162. double thistime, thispitch = -1.0 /* , lastpitch = -1.0 */ ; //RWD use init val to pacify gcc.
  163. noteptr thishfnote = hfmotif->firstnote;
  164. noteptr thishsnote = hfmotif->firstnote;
  165. double thishftime,nexthftime,thishstime,nexthstime,thisamp,thisdur;
  166. unsigned char thisinstr;
  167. int hf_cnt = 1, hfnotecnt = 0;
  168. int hs_cnt = 1, hsnotecnt = 0 /*, repeated = 0 */;
  169. int hfdatacnt = 0;
  170. double *hft, pptop, ppbot;
  171. double *hs = (double *)0, *hf = (double *)0;
  172. dz->iparam[SPINIT] = 0;
  173. if((exit_status = readhftimes(hfmotif->firstnote,&hfdatacnt,&hft))<0)
  174. return(exit_status);
  175. thishftime = nexthftime = thishstime = nexthstime = hft[0];
  176. if(texflag & ISMANY_HFLDS) {
  177. if((exit_status = setup_first_hfield(hfmotif->firstnote,&hs,&hsnotecnt,&hf,&hfnotecnt,texflag))<0)
  178. return(exit_status);
  179. } else {
  180. if((exit_status = setup_hfield(hfmotif->firstnote,&hs,&hsnotecnt,&hf,&hfnotecnt,texflag))<0)
  181. return(exit_status);
  182. }
  183. while(tsetnote!=(noteptr)0) { /* 3 */
  184. // repeated = chekrepeat(tsetnote,lastpitch);
  185. // lastpitch = tsetnote->pitch;
  186. thistime = (double)tsetnote->ntime; /* 5 */
  187. if((exit_status = read_values_from_all_existing_brktables(thistime,dz))<0)
  188. return(exit_status);
  189. if(texflag & ISMANY_HFLDS) {
  190. if((exit_status = get_next_hfield(&hf,&hs,thistime,&hf_cnt,&hs_cnt,
  191. &hfnotecnt,&thishfnote,&thishftime,&nexthftime,hfdatacnt,
  192. &hsnotecnt,&thishsnote,&thishstime,&nexthstime,hft,texflag))<0)
  193. return(exit_status);
  194. }
  195. if((exit_status = do_amp_instr_dur(&thisamp,&thisinstr,&thisdur,tsetnote,thistime,dz))<0)
  196. return(exit_status);
  197. if((exit_status = do_ev_hfpch(thistime,&hsindex,&thispitch,hsnotecnt,hs,&pptop,&ppbot,dz))<0)
  198. return(exit_status);
  199. tsetnote->pitch = (float)thispitch;
  200. if(exit_status == CONTINUE) {
  201. nextnote = tsetnote->next;
  202. del_note(tsetnote,tset);
  203. tsetnote = nextnote;
  204. } else
  205. tsetnote = tsetnote->next;
  206. }
  207. if(tset->firstnote==(noteptr)0) {
  208. sprintf(errstr,"The harmonic set specified does not tally with the range.\n");
  209. return(DATA_ERROR);
  210. }
  211. return(FINISHED);
  212. }
  213. /**************************** DO_CLUMPED_HFTEXTURE ****************************/
  214. int do_clumped_hftexture(dataptr dz)
  215. {
  216. int exit_status;
  217. unsigned int texflag = dz->tex->txflag;
  218. unsigned char dectypestor = dz->tex->dectypstor;
  219. unsigned char dectypecnt = dz->tex->dectypcnt;
  220. unsigned char amptypestor = dz->tex->amptypstor;
  221. unsigned char amptypecnt = dz->tex->amptypcnt;
  222. int ampdirected = dz->tex->ampdirectd;
  223. motifptr tset = dz->tex->timeset;
  224. motifptr hfmotif = dz->tex->hfldmotif;
  225. motifptr *phrase = dz->tex->phrase;
  226. int **hfphrase = NULL;
  227. int *endhsindex=NULL, *phrnotecnt=NULL;
  228. double *phraseamp=NULL, *phrange=NULL;
  229. unsigned char amptype = 0;
  230. fitptr fithead = NULL;
  231. noteptr tsetnote = tset->firstnote;
  232. noteptr thisnote=NULL, nextnote=NULL, phrasenote=NULL, nextevent=NULL, *shadow=NULL;
  233. double thispitch = 0.0, /* lastpitch = -1.0,*/ ampstep = 0.0, ampdif = 0.0, notetime = 0.0, thisamp = 0.0, thisdur = 0.0;
  234. unsigned char thisinstr;
  235. double phrfirstnote = 0.0, thistime = 0.0, rangemult = 0.0, gprlow = 0.0;
  236. double timeadjust = 0.0; /* default */
  237. noteptr thishfnote = hfmotif->firstnote;
  238. noteptr thishsnote = hfmotif->firstnote;
  239. noteptr *phrlastnote = NULL;
  240. double thishftime = 0.0,nexthftime = 0.0,thishstime = 0.0,nexthstime = 0.0,tsettime = 0.0;
  241. int hf_cnt = 1, hfnotecnt = 0, mingrpsize = 0, shadindex = 0, shadowsize=0;
  242. double gprange = 0.0,gpdense = 0.0,multiplier = 0.0;
  243. double *notestor=NULL;
  244. int hfgpranglo=0,hfgpranghi=0;
  245. int hs_cnt = 1, hsnotecnt = 0 /*, repeated = 0 */;
  246. int hfdatacnt = 0, hfrange = 0, gpsize,shshsize = 0;
  247. int phrno = 0, n=0, hsindex=0, starthsindex=0, hfchanged=0;
  248. int hsi=0, starthsi = 0, endhsi=0;
  249. char *shadbits = NULL;
  250. double *hft=NULL, pptop=0.0, ppbot=0.0;
  251. double *hs = (double *)0, *hf = (double *)0;
  252. if((dz->tex->phrasecnt > 0) && (exit_status = initialise_hfphrases
  253. (&hfphrase,&endhsindex,&phrnotecnt,&phraseamp,&phrange,&phrlastnote,dz))<0)
  254. return(exit_status);
  255. dz->iparam[SPINIT] = 0;
  256. if(texflag & IS_GROUPS)
  257. mingrpsize = 1;
  258. if((exit_status = readhftimes(hfmotif->firstnote,&hfdatacnt,&hft))<0)
  259. return(exit_status);
  260. thishftime = nexthftime = thishstime = nexthstime = hft[0];
  261. if((exit_status = make_shadow(tset,&shadowsize,&shadow))<0)
  262. return(exit_status);
  263. if((texflag & MOTIF_IN_HF) || (texflag & IS_ORNATE)) {
  264. if((exit_status = init_fits(&fithead))<0)
  265. return(exit_status);
  266. }
  267. if(texflag & IS_DECOR)
  268. setup_decor(&pptop,&ppbot,&shadindex,&tsetnote,dz);
  269. else {
  270. if((exit_status = init_shadbits(shadowsize,&shshsize,&shadbits))<0)
  271. return(exit_status);
  272. }
  273. if(texflag & ISMANY_HFLDS) {
  274. if((exit_status = setup_first_hfield(hfmotif->firstnote,&hs,&hsnotecnt,&hf,&hfnotecnt,texflag))<0)
  275. return(exit_status);
  276. } else {
  277. if((exit_status = setup_hfield(hfmotif->firstnote,&hs,&hsnotecnt,&hf,&hfnotecnt,texflag))<0)
  278. return(exit_status);
  279. }
  280. if((texflag & MOTIF_IN_HF) || ((texflag & IS_ORNATE) && !(texflag & ISMANY_HFLDS))) {
  281. if((exit_status = set_hfmotifs
  282. (hs,phrase,phrnotecnt,phraseamp,phrange,phrlastnote,endhsindex,hfphrase,hsnotecnt,fithead,&notestor,dz))<0)
  283. return(exit_status);
  284. } else if(texflag & IS_MOTIFS) {
  285. if((exit_status = set_motifs
  286. (dz->tex->phrasecnt,phrase,phrnotecnt,phraseamp,phrange,phrlastnote))<0)
  287. return(exit_status);
  288. }
  289. while(tsetnote!=(noteptr)0) {
  290. if(!(texflag & IS_ORNATE)) {
  291. // repeated = chekrepeat(tsetnote,lastpitch);
  292. // lastpitch = tsetnote->pitch;
  293. }
  294. tsettime = thistime = (double)tsetnote->ntime;
  295. if((exit_status = read_values_from_all_existing_brktables(thistime,dz))<0)
  296. return(exit_status);
  297. if(texflag & ISMANY_HFLDS) {
  298. if((exit_status = get_next_hfield(&hf,&hs,thistime,&hf_cnt,&hs_cnt,
  299. &hfnotecnt,&thishfnote,&thishftime,&nexthftime,hfdatacnt,
  300. &hsnotecnt,&thishsnote,&thishstime,&nexthstime,hft,texflag))<0)
  301. return(exit_status);
  302. hfchanged = exit_status;
  303. if(((texflag & MOTIF_IN_HF) || (texflag & IS_ORNATE)) && hfchanged) {
  304. if((exit_status = set_hfmotifs
  305. (hs,phrase,phrnotecnt,phraseamp,phrange,phrlastnote,endhsindex,hfphrase,hsnotecnt,fithead,&notestor,dz))<0)
  306. return(exit_status);
  307. }
  308. }
  309. if(texflag & IS_ORN_OR_MTF) {
  310. if((exit_status = setup_motif_or_ornament(thistime,&multiplier,&phrno,&phrasenote,phrase,dz))<0)
  311. return(exit_status);
  312. }
  313. if((exit_status = do_amp_instr_dur(&thisamp,&thisinstr,&thisdur,tsetnote,thistime,dz))<0)
  314. return(exit_status);
  315. if(texflag & IS_DECOR)
  316. thispitch = tsetnote->pitch;
  317. if(texflag & IS_MTF_OR_GRP) {
  318. if(texflag & IS_GROUPS)
  319. exit_status = setup_group_note
  320. (thisamp,thisinstr,thisdur,tsetnote,&thispitch,
  321. thistime,&hsindex,hsnotecnt,hs,&pptop,&ppbot,&shadindex,shadbits,dz);
  322. else
  323. exit_status = setup_motif_note
  324. (thisamp,thisinstr,thisdur,tsetnote,phrasenote,&thispitch,
  325. thistime,&hsindex,hsnotecnt,hs,&pptop,&ppbot,&shadindex,shadbits,multiplier,dz);
  326. if(exit_status==CONTINUE)
  327. continue;
  328. }
  329. if(texflag & IS_ORN_OR_MTF)
  330. gpsize = phrnotecnt[phrno];
  331. else {
  332. if((exit_status = get_hfgpparams
  333. (thistime,thispitch,hs,hsnotecnt,&gpsize,&hfrange,&hfgpranglo,&hfgpranghi,
  334. &gprange,&gpdense,mingrpsize,&gprlow,dectypecnt,dectypestor,dz))<0)
  335. return(exit_status);
  336. }
  337. if(texflag & IS_DECOR) {
  338. if((exit_status = position_and_size_decoration(&thistime,tsettime,gpdense,&gpsize,dz))<0)
  339. return(exit_status);
  340. } else
  341. gpsize--;
  342. if(texflag & IS_MOTIFS)
  343. phrfirstnote = phrasenote->pitch;
  344. else if(texflag & IS_ORNATE) {
  345. if((hsi = convert_pitch_to_nearest_hset_pitch((double)tsetnote->pitch,hs,hsnotecnt))<0)
  346. gpsize = 0; /* note out of bounds, ornament omitted */
  347. if((exit_status = setup_ornament
  348. (&timeadjust,&thistime,&gpsize,phrlastnote,multiplier,&phrasenote,phrno,dz))<0)
  349. return(exit_status);
  350. }
  351. if(!(texflag & IS_DECOR))
  352. nextnote = tsetnote->next;
  353. if(gpsize>0) {
  354. if(texflag & IS_ORN_OR_MTF) {
  355. if((exit_status = orn_or_mtf_amp_setup
  356. (ampdirected,phrange,phrno,thisamp,gpsize,&rangemult,&ampstep,&amptype,amptypestor,amptypecnt,dz))<0)
  357. return(exit_status);
  358. }
  359. if(texflag & IS_MOTIFS) {
  360. if((exit_status = set_motif_amp
  361. (tsetnote,&thisamp,gpsize,ampstep,phrasenote,rangemult,phraseamp,phrno,amptype))<0)
  362. return(exit_status);
  363. } else if(texflag & IS_ORNATE) {
  364. if((exit_status = set_ornament_amp
  365. (phraseamp,phrlastnote,&thisamp,phrasenote,phrno,tsetnote,ampstep,rangemult,gpsize,dz))<0)
  366. return(exit_status);
  367. } else if (texflag & IS_GROUPS) {
  368. if((exit_status = set_group_amp
  369. (tsetnote,&thisamp,&amptype,&ampstep,gpsize,amptypecnt,amptypestor,dz))<0)
  370. return(exit_status);
  371. } else if (texflag & IS_DECOR) {
  372. if((exit_status = set_decor_amp
  373. (ampdirected,&thisamp,&ampstep,gpsize,&amptype,amptypecnt,amptypestor,dz))<0)
  374. return(exit_status);
  375. }
  376. if(dz->iparam[TEX_GPSPACE]!=IS_STILL) {
  377. if((exit_status = init_group_spatialisation(tsetnote,shadindex,shadow,shadowsize,dz))<0)
  378. return(exit_status);
  379. }
  380. thisnote = tsetnote;
  381. if(texflag & MOTIF_IN_HF)
  382. starthsindex = *(hfphrase[phrno]);
  383. else if(texflag & IS_ORNATE) {
  384. if((exit_status = setup_ornamentation
  385. (&starthsi,&endhsi,&nextevent,tsetnote,&phrasenote,&shadindex,endhsindex,hfphrase[phrno],phrno,dz))<0)
  386. return(exit_status);
  387. } else if(texflag & IS_DECOR) {
  388. nextnote = tsetnote->next;
  389. nextevent = getnextevent_to_decorate(tsetnote,&shadindex,dz);
  390. }
  391. for(n=0;n<gpsize;n++) {
  392. if((exit_status = make_new_note(&thisnote))<0)
  393. return(exit_status);
  394. if(texflag & IS_ORN_OR_MTF) {
  395. if((exit_status = check_next_phrasenote_exists(&phrasenote,texflag,dz))<0)
  396. return(exit_status);
  397. notetime = getnotetime(phrasenote,thistime,multiplier,timeadjust,dz);
  398. thisamp += ampstep;
  399. ampdif = (phraseamp[phrno]-phrasenote->amp)*rangemult;
  400. if((exit_status = setmtfparams
  401. (thisnote,thisamp,phrasenote,tsetnote,ampdif,notetime,gpsize,multiplier,dz))<0)
  402. return(exit_status);
  403. } else {
  404. if((exit_status = set_group_params
  405. (tsetnote,thisnote,gpdense,ampstep,&thisamp,&thistime,thisdur,dz))<0)
  406. return(exit_status);
  407. }
  408. if(texflag & MOTIF_IN_HF) {
  409. if((exit_status = generate_motifin_note_pitch
  410. (n,hsindex,starthsindex,hsnotecnt,thispitch,hfphrase[phrno],&thisnote,hs,texflag))<0)
  411. return(exit_status);
  412. } else if(texflag & IS_MOTIFS) {
  413. if((exit_status = generate_motif_note_pitch(tsetnote,phrasenote,phrfirstnote,thisnote))<0)
  414. return(exit_status);
  415. } else if (texflag & IS_ORNATE) {
  416. if((exit_status = generate_ornament_note_pitch
  417. (n,hs,hsi,endhsi,starthsi,&thisnote,&phrasenote,hfphrase[phrno],hfnotecnt,hsnotecnt,dz))<0)
  418. return(exit_status);
  419. } else if(texflag & IS_GROUPS) {
  420. if((exit_status = generate_group_note
  421. (thisnote,tsetnote,thistime,hfrange,hfgpranglo,hs,&hsindex,gpsize,dz))<0)
  422. return(exit_status);
  423. } else if(texflag & IS_DECOR) {
  424. if((exit_status = generate_decor_note
  425. (thisnote,tsetnote,thispitch,thistime,hfrange,hfgpranghi,hfgpranglo,
  426. hs,&hsindex,hsnotecnt,gprlow,gprange,gpsize,dz))<0)
  427. return(exit_status);
  428. }
  429. if(exit_status==CONTINUE)
  430. continue;
  431. }
  432. thisnote->next = nextnote;
  433. if(nextnote!=(noteptr)0)
  434. nextnote->last = thisnote;
  435. if(texflag & IS_ORN_OR_DEC)
  436. tsetnote = nextevent;
  437. } else if(texflag & IS_ORN_OR_DEC)
  438. tsetnote = getnextevent_to_decorate(tsetnote,&shadindex,dz);
  439. if(texflag & IS_MTF_OR_GRP) {
  440. tsetnote = nextnote;
  441. shadindex++;
  442. }
  443. }
  444. if(texflag & IS_MTF_OR_GRP)
  445. del_ghosts(shshsize,shadbits,shadow,shadowsize,tset); /* 5 */
  446. if(texflag & IS_DECOR) {
  447. if(dz->vflag[DISCARD_ORIGLINE] && (exit_status = erase_shadow(shadowsize,shadow,tset))<0)
  448. return(exit_status);
  449. } else
  450. free(shadbits);
  451. if((texflag & MOTIF_IN_HF) || (texflag & IS_ORNATE))
  452. free(fithead);
  453. return arrange_notes_in_timeorder(tset);
  454. }
  455. /**************************** SET_HFMOTIFS *******************************
  456. *
  457. * initialise all parameters of input motifs to be used for MOTIFS or
  458. * ORNAMENTS, including their HS indexing!!!
  459. *
  460. * (1)For each input motif (called a 'phrase').
  461. * phrnotecnt[n] = 0;
  462. * (2) Initialise count of number of notes to 0, maximum amplitude
  463. * of phrase to 0.0, and lowest pitch-index to hsnotecnt.
  464. * (3) Go through each note of the motif.
  465. * (4) Add up the number of notes in it.
  466. * (5) Find it's lowest pitch.
  467. * (6) Find it's loudest note (and set as phraseamp).
  468. * (7) Establish dynamic range of phrase.
  469. * (9) Ensure motif starts at zero time.
  470. * (10) Generate the corresponding HS indices, in their lowest configuration.
  471. * (11) Store hfindex of last note of phrase.
  472. */
  473. int set_hfmotifs
  474. (double *hs,motifptr *phrase,int *phrnotecnt,double *phraseamp,double *phrange,noteptr *phrlastnote,
  475. int *endhsindex,int **hfphrase,int hsnotecnt,fitptr fithead,double **notestor,dataptr dz)
  476. {
  477. int exit_status;
  478. int n;
  479. double mintime, minamp, minpitch, maxpitch;
  480. noteptr thisnote, lastnote = (noteptr)0;
  481. for(n=0;n<dz->tex->phrasecnt;n++) { /* 1 */
  482. if((exit_status = arrange_notes_in_timeorder(phrase[n]))<0)
  483. return(exit_status);
  484. phrnotecnt[n] = 0;
  485. phraseamp[n] = 0.0; /* 2 */
  486. minamp = DBL_MAX;
  487. minpitch = DBL_MAX;
  488. maxpitch = -2.0f;
  489. mintime = DBL_MAX;
  490. thisnote = phrase[n]->firstnote; /* 3 */
  491. while(thisnote!=(noteptr)0) {
  492. phrnotecnt[n]++; /* 4 */
  493. if((double)thisnote->pitch<minpitch)
  494. minpitch = thisnote->pitch; /* 5 */
  495. if((double)thisnote->pitch>maxpitch)
  496. maxpitch = thisnote->pitch; /* 5 */
  497. if(thisnote->ntime<mintime)
  498. mintime = thisnote->ntime; /* 5 */
  499. if((double)thisnote->amp>phraseamp[n])
  500. phraseamp[n] = (double)thisnote->amp;/* 6 */
  501. if(thisnote->amp<minamp)
  502. minamp = thisnote->amp; /* 6 */
  503. thisnote = thisnote->next;
  504. }
  505. if(minamp == DBL_MAX
  506. || minpitch == DBL_MAX
  507. || maxpitch == -2.0f
  508. || mintime == DBL_MAX) {
  509. sprintf(errstr,"Error parsing notelist: set_hfmotifs()\n");
  510. return(PROGRAM_ERROR);
  511. }
  512. thisnote = phrase[n]->firstnote;
  513. phrange[n] = phraseamp[n] - (double)minamp; /* 7 */
  514. while(thisnote!=(noteptr)0) {
  515. thisnote->ntime = (float)(thisnote->ntime - mintime); /* 9 */
  516. lastnote = thisnote;
  517. thisnote = thisnote->next;
  518. }
  519. if((phrlastnote[n] = lastnote)==(noteptr)0) {
  520. sprintf(errstr,"Encountered an empty motif: set_hfmotifs()\n");
  521. return(PROGRAM_ERROR);
  522. }
  523. if((exit_status = gethfphrase(hs,notestor,n,minpitch,maxpitch,hfphrase,hsnotecnt,phrnotecnt,phrase,fithead))<0) /* 10 */
  524. return(exit_status);
  525. endhsindex[n] = *(hfphrase[n]+phrnotecnt[n]-1); /* 11 */
  526. }
  527. return(FINISHED);
  528. }
  529. /*********************** GETHFPHRASE *********************************
  530. *
  531. * Get the hfphrase best corresponding to the input motif.
  532. *
  533. * (0) Create storage space to store HS-indices of phrase.
  534. * (1) HIpitch of phrase higher than top of HS
  535. * AND LOpitch of phrase lower than bottom of HS.
  536. * ..Shrink the motif to size of HS, and establish hfphrase.
  537. * (2) HIpitch of phrase higher than top of HS
  538. * BUT LOpitch within HS range.
  539. * .. transpose phraselimits down onto bottom pitch of HS.
  540. * (a) If HIpitch of phrase STILL higher than top of HS
  541. * ..Shrink the motif to size of HS, and establish hfphrase.
  542. * (3) LOpitch of phrase lower than bottom of HS
  543. * BUT HIpitch within HS range.
  544. * .. transpose phraselimits up onto bottom pitch of HS.
  545. * (a) If HIpitch of phrase is NOW higher than top of HS
  546. * ..Shrink the motif to size of HS, and establish hfphrase.
  547. * (4) Phrase lies with the limits of HS.
  548. * .. transpose phraselimits down onto bottom pitch of HS.
  549. * (5) Find appropriate hfphrase.
  550. */
  551. int gethfphrase
  552. (double *hs,double **notestor,int z,double lopitch,double hipitch,
  553. int **hfphrase,int hsnotecnt,int *phrnotecnt,motifptr *phrase,fitptr fithead)
  554. {
  555. double origlo = lopitch, hstop = hs[hsnotecnt-1], hsbot = hs[0];
  556. double stepdown, stepup;
  557. if((hfphrase[z] = (int *)malloc(phrnotecnt[z] * sizeof(int)))==NULL) { /* 0 */
  558. sprintf(errstr,"INSUFFICIENT MEMORY for harmonic field phrase array.\n");
  559. return(MEMORY_ERROR);
  560. }
  561. if(hipitch>=hstop) {
  562. if(lopitch<=hsbot) /* 1 */
  563. return shrink_to_hs(z,hsnotecnt,hipitch,lopitch,hstop,hsbot,hs,hfphrase[z],phrase,phrnotecnt);
  564. else {
  565. stepdown = lopitch - hsbot; /* 2 */
  566. hipitch -= stepdown;
  567. lopitch -= stepdown;
  568. if(hipitch>hstop) /* a */
  569. return shrink_to_hs(z,hsnotecnt,hipitch,lopitch,hstop,hsbot,hs,hfphrase[z],phrase,phrnotecnt);
  570. }
  571. } else {
  572. if(lopitch<=hsbot) { /* 3 */
  573. stepup = hsbot - lopitch;
  574. hipitch += stepup;
  575. lopitch += stepup;
  576. if(hipitch>hstop) /*a */
  577. return shrink_to_hs(z,hsnotecnt,hipitch,lopitch,hstop,hsbot,hs,hfphrase[z],phrase,phrnotecnt);
  578. } else { /* 4 */
  579. stepdown = lopitch - hsbot;
  580. hipitch -= stepdown;
  581. lopitch -= stepdown;
  582. }
  583. }
  584. return findhfphrase(z,hs,hstop,hsnotecnt,lopitch,origlo,phrase,hfphrase,phrnotecnt,fithead,notestor);
  585. } /* 5 */
  586. /************************* SHRINK_TO_HS **************************
  587. *
  588. * Shrink motif so it fits with HS, then find best HS fit.
  589. *
  590. * (1) Establish pitch-shrinking ratio.
  591. * (2) For every note...
  592. * (3) Shrink intervals and thus move pitch to appropriate position inside
  593. * range of HS.
  594. * (4) Find index of the next lowest HS notes.
  595. * (4a) If note falls outside field, set distance to note to maximum poss.
  596. * (4b) Else find pitch distances of this note from original pitch.
  597. * (5) Find index of the next highest HS notes.
  598. * (5a) If note falls outside field, set distance to note to maximum poss.
  599. * (5b) Else find pitch distances of this note from original pitch.
  600. * (6) Select HSindex of nearest pitch and store in hfphrase.
  601. * (7) Save the lowest such index.
  602. * (8) Transpose all indices down to lowest possible values.
  603. */
  604. int shrink_to_hs(int z,int hsnotecnt,double hipitch,double lopitch,double hstop,
  605. double hsbot,double *hs, int *hfphrase, motifptr *phrase,int *phrnotecnt)
  606. {
  607. noteptr thisnote = phrase[z]->firstnote;
  608. double shrink ,thispitch, x, y;
  609. int minindex = MAXINT, xx, yy, q, n = 0;
  610. shrink = (hstop - hsbot)/(hipitch-lopitch); /* 1 */
  611. for(;;) { /* 2 */
  612. thispitch = thisnote->pitch;
  613. thispitch = ((thispitch - lopitch) * shrink) + hsbot; /* 3 */
  614. if((xx = geths_lobnd(thispitch,hs,hsnotecnt))<0) /* 4 */
  615. x = DBL_MAX; /* 4a */
  616. else
  617. x = fabs(hs[xx] - thispitch); /* 4b */
  618. if((yy = geths_hibnd(thispitch,hsnotecnt,hs))>=hsnotecnt) /* 5 */
  619. y = DBL_MAX; /* 5a */
  620. else
  621. y = fabs(hs[yy] - thispitch); /* 5b */
  622. if(x<y)
  623. q = xx; /* 6 */
  624. else
  625. q = yy;
  626. *(hfphrase+n) = q;
  627. if(q<minindex)
  628. minindex = q; /* 7 */
  629. if((thisnote = thisnote->next)==(noteptr)0)
  630. break;
  631. if(++n >= phrnotecnt[z]) {
  632. sprintf(errstr,"accounting problem in shrink_to_hs()\n");
  633. return(PROGRAM_ERROR);
  634. }
  635. }
  636. for(n=0;n<phrnotecnt[z];n++) /* 8 */
  637. *(hfphrase+n) -= minindex;
  638. return(FINISHED);
  639. }
  640. /*********************** FINDHFPHRASE *********************************
  641. *
  642. * Extract the best fit onto the HS, and transpose it down to bottom
  643. * of indices.
  644. *
  645. * (1) Set the FIT-pointer to head of fits-list.
  646. * (2) Set up a store for the note values to be tested.
  647. * (3) Get interval of transposition to take motif to bottom of HS range.
  648. * (4) Store original note values of phrase transposed down to bottom of HS range.
  649. * (5) Find the fit-value for motif in its start position.
  650. * (6) Outer loop will transpose the phrase through a range...
  651. * (7) Set amount to transpose phrase (shift) to max.
  652. Then for every note of the phrase.....
  653. * (8) Find the HSindex of the nearest note above the current note.
  654. * (If there isn't one break out completely).
  655. * (9) If the difference in pitch between this and the current note
  656. * is smaller than the minimum shift, reset minimum shift.
  657. * (10)Then, for every note of the phrase...
  658. * (11)transpose it up by this minimum transposition.
  659. * If this takes any note of the phrase outside the range of HS
  660. * break out completely.
  661. * (12)Back in outer loop, find the fitting-value for this transposition
  662. * of the motif, which is a measure of how far its notes are from
  663. * the closest HS values.
  664. * (13) Outside the outer loop, unlink the last unwanted member iof fitlist.
  665. * (14) Find the best fitvalue, and return the amount by which orig motif
  666. * should be transposed to get onto this best fit.
  667. * (15) Free the fit-list (retains fithead).
  668. * (16) Get the appropriate HS indices.
  669. */
  670. int findhfphrase
  671. (int z,double *hs,double hstop,int hsnotecnt,double lopitch,double origlo,
  672. motifptr *phrase,int **hfphrase,int *phrnotecnt,fitptr fithead,double **notestor)
  673. {
  674. int exit_status;
  675. int hsindex, OK = 1, n, got_transpose = 0;
  676. noteptr thisnote = phrase[z]->firstnote;
  677. fitptr thisfit = fithead; /* 1 */
  678. double shift, thisshift, transpose = 0.0, stepdown, *noteval;
  679. if(*notestor!=NULL)
  680. free(*notestor); /* 2 */
  681. if((noteval = *notestor = (double *)malloc(phrnotecnt[z] * sizeof(double)))==NULL) {
  682. sprintf(errstr,"INSUFFICIENT MEMORY for note value array.\n");
  683. return(MEMORY_ERROR);
  684. }
  685. stepdown = origlo - lopitch; /* 3 */
  686. while(thisnote!=(noteptr)0) {
  687. *noteval = (double)thisnote->pitch - stepdown; /* 4 */
  688. noteval++;
  689. thisnote = thisnote->next;
  690. }
  691. if((exit_status = get_fit(*notestor,thisfit,lopitch,origlo,z,hsnotecnt,phrnotecnt,hs,&thisfit))<0)
  692. return(exit_status); /* 5 */
  693. if(exit_status == CONTINUE) {
  694. transpose = thisfit->last->transpose;
  695. got_transpose = 1;
  696. OK = 0;
  697. }
  698. while(OK) { /* 6 */
  699. shift = DBL_MAX; /* 7 */
  700. noteval = *notestor;
  701. for(n=0;n<phrnotecnt[z];n++) {
  702. if((hsindex = geths_above(*noteval,hs,hsnotecnt))>=hsnotecnt) { /* 8 */
  703. OK = 0;
  704. break;
  705. }
  706. if((thisshift = hs[hsindex] - *noteval)<shift)
  707. shift = thisshift; /* 9 */
  708. noteval++;
  709. }
  710. if(shift==DBL_MAX) {
  711. sprintf(errstr,"Error parsing phrase: findhfphrase()\n");
  712. return(PROGRAM_ERROR);
  713. }
  714. if(!OK)
  715. break;
  716. noteval = *notestor;
  717. for(n=0;n<phrnotecnt[z];n++) { /* 10 */
  718. if((*noteval++ += (float)shift)>hstop) {
  719. OK = 0; /* 11 */
  720. break;
  721. }
  722. }
  723. lopitch += shift;
  724. if((exit_status = get_fit(*notestor,thisfit,lopitch,origlo,z,hsnotecnt,phrnotecnt,hs,&thisfit))<0)
  725. return(exit_status); /* 12 */
  726. if(exit_status == CONTINUE) {
  727. transpose = thisfit->last->transpose;
  728. got_transpose = 1;
  729. break;
  730. }
  731. }
  732. if((exit_status = fit_unlink(thisfit))<0) /* 13 */
  733. return(exit_status);
  734. if (!got_transpose) {
  735. if((exit_status = best_fit(fithead,&transpose))<0) /* 14 */
  736. return(exit_status);
  737. }
  738. free_fitlist(fithead); /* 15 */
  739. return getmtfindeces(transpose,z,hsnotecnt,hs,phrase,phrnotecnt,hfphrase);
  740. } /* 16 */
  741. /*************************** GETMTFINDECES *****************************
  742. *
  743. * Get the HS indices of the phrase, transposed to lowest position in HS.
  744. *
  745. * (0) Point to start of storage space for the HS-indices of the phrase.
  746. * (1) Mark end of this storage space (for accounting purposes).
  747. * (2) For every note of the phrase...
  748. * (3) Get the pitch..
  749. * (4) Transpose the pitch by the input transposition.
  750. * (5) Find the nearest HS set members above and below the note.
  751. * (6) Decide which is nearest.
  752. * (7) Assign index of nearest value to the HS-index store.
  753. * (8) Keep a note of the smallest index.
  754. * (9) Increment the index-store pointer.
  755. * (10) Decrement all the indeces to tranpose them all to lowest values
  756. * in the hfphrase store.
  757. */
  758. int getmtfindeces(double transpose,int z,int hsnotecnt,double *hs,motifptr *phrase,int *phrnotecnt,int **hfphrase)
  759. {
  760. noteptr thisnote = phrase[z]->firstnote;
  761. int *thisindex, xx, yy, minindex = MAXINT, *indexend;
  762. double x, y, thispitch;
  763. thisindex = hfphrase[z]; /* 0 */
  764. indexend = hfphrase[z] + phrnotecnt[z]; /* 1 */
  765. for(;;) { /* 2 */
  766. thispitch = thisnote->pitch; /* 3 */
  767. thispitch += transpose; /* 4 */
  768. xx = geths_lobnd(thispitch,hs,hsnotecnt); /* 5 */
  769. yy = geths_hibnd(thispitch,hsnotecnt,hs);
  770. x = fabs(hs[xx] - thispitch); /* 6 */
  771. y = fabs(hs[yy] - thispitch);
  772. if(x<y)
  773. *thisindex = xx; /* 7 */
  774. else
  775. *thisindex = yy;
  776. if(*thisindex<minindex)
  777. minindex = *thisindex; /* 8 */
  778. if((thisnote = thisnote->next)==(noteptr)0)
  779. break;
  780. if(++thisindex>=indexend) { /* 9 */
  781. sprintf(errstr,"TEXTURE: Problem in getmtfindices()\n");
  782. return(PROGRAM_ERROR);
  783. }
  784. }
  785. for(thisindex = hfphrase[z];thisindex<indexend;thisindex++)
  786. *thisindex -= minindex; /* 10 */
  787. return(FINISHED);
  788. }
  789. /****************************** GET_FIT ************************************
  790. *
  791. * Create list of fit_values for motif over HS.
  792. *
  793. * (1) For every note of the phrase.
  794. * (3) Find the index of the next lowest HS note. If there is not one
  795. * something is wrong!
  796. * (4) Find the index of the next highest HS note. If there is not one
  797. * something is wrong!
  798. * (5) Find the pitch distance between these notes on the original pitch.
  799. * (6) Add the minimum of these two, to a running sum of such differences.
  800. * (7) Store the fit-value and the associated ttansposition, creating a
  801. * new storage space in the fit list, in the process.
  802. */
  803. int get_fit(double *notestor,fitptr thisfit,double lopitch,double origlo,int z,
  804. int hsnotecnt,int *phrnotecnt,double *hs,fitptr *newfit)
  805. {
  806. int exit_status;
  807. double x, y, sum = 0.0, *noteval = notestor;
  808. int xx, yy, n;
  809. for(n=0;n<phrnotecnt[z];n++) { /* 1 */
  810. if((xx = geths_lobnd(*noteval,hs,hsnotecnt))<0) { /* 3 */
  811. sprintf(errstr,"Problem 1 in get_fit()\n");
  812. return(PROGRAM_ERROR);
  813. }
  814. if((yy=geths_hibnd(*noteval,hsnotecnt,hs))>=hsnotecnt) {/* 4 */
  815. sprintf(errstr,"Problem 2 in get_fit()\n");
  816. return(PROGRAM_ERROR);
  817. }
  818. x = fabs(hs[xx] - *noteval); /* 5 */
  819. y = fabs(hs[yy] - *noteval);
  820. sum += min(x,y); /* 6 */
  821. noteval++;
  822. }
  823. if((exit_status = put_fit(thisfit,lopitch - origlo,sum,newfit))<0)
  824. return(exit_status);
  825. if(flteq(sum,0.0))
  826. return(CONTINUE);
  827. return(FINISHED); /* 7 */
  828. }
  829. /************************* PUT_FIT *****************************
  830. *
  831. * Put fit value in motif-fits list.
  832. */
  833. int put_fit(fitptr thisfit,double transval,double fitval,fitptr *newfit)
  834. {
  835. int exit_status;
  836. thisfit->transpose = (float)transval;
  837. thisfit->fit = (float)fitval;
  838. if((exit_status = new_fit(thisfit,newfit))<0)
  839. return(exit_status);
  840. return(FINISHED);
  841. }
  842. /************************* BEST_FIT *****************************
  843. *
  844. * Find the appropriate transposition to move the current motif
  845. * to a pitch where it has the best fit with the HS.
  846. *
  847. * (1) From all available transpositions, find best (lowest) fit value.
  848. * (2) From all available transpositions, find all those which have
  849. * this bestfit value, and select the one which involves the
  850. * least transposition.
  851. * (3) Once the transpositions begin to increase, we are moving away from
  852. * the smallest transposition, so quit.
  853. * (4) Return the best transposition.
  854. */
  855. int best_fit(fitptr fithead,double *transpose)
  856. {
  857. fitptr thisfit = fithead;
  858. double bestfit = DBL_MAX, besttranspose = DBL_MAX;
  859. double abstranspose = DBL_MAX, thistranspose;
  860. while(thisfit!=(fitptr)0) { /* 1 */
  861. if(thisfit->fit<(float)bestfit)
  862. bestfit = (double)thisfit->fit;
  863. thisfit = thisfit->next;
  864. }
  865. thisfit = fithead;
  866. while(thisfit!=(fitptr)0) { /* 2 */
  867. thistranspose = fabs((double)thisfit->transpose);
  868. if(flteq((double)thisfit->fit,bestfit)) {
  869. if(thistranspose<abstranspose) {
  870. besttranspose = (double)thisfit->transpose;
  871. abstranspose = fabs(besttranspose);
  872. }
  873. }
  874. if(thistranspose>abstranspose+FLTERR)
  875. break; /* 3 */
  876. thisfit = thisfit->next;
  877. }
  878. if(besttranspose==DBL_MAX) {
  879. sprintf(errstr,"Problem in best_fit()\n");
  880. return(PROGRAM_ERROR);
  881. }
  882. *transpose = besttranspose;
  883. return(FINISHED); /* 4 */
  884. }
  885. /************************* INIT_FITS() *****************************
  886. *
  887. * Set up head item of a list of motif-fits.
  888. */
  889. int init_fits(fitptr *thisfit)
  890. {
  891. if((*thisfit = (fitptr)malloc(sizeof (struct ffit)))==NULL) {
  892. sprintf(errstr,"INSUFFICIENT MEMORY for fitting array.\n");
  893. return(MEMORY_ERROR);
  894. }
  895. (*thisfit)->next = (fitptr)0;
  896. (*thisfit)->last = (fitptr)0;
  897. return(FINISHED);
  898. }
  899. /************************* NEW_FIT() *****************************
  900. *
  901. * Set up next fit in a list of motif-fits.
  902. */
  903. int new_fit(fitptr thisfit,fitptr *newfit)
  904. {
  905. if((*newfit = (fitptr)malloc(sizeof (struct ffit)))==NULL) {
  906. sprintf(errstr,"new_fit()\n");
  907. return(PROGRAM_ERROR);
  908. }
  909. thisfit->next = *newfit;
  910. (*newfit)->last = thisfit;
  911. (*newfit)->next = (fitptr)0;
  912. return(FINISHED);
  913. }
  914. /********************** FIT_UNLINK() ******************************
  915. *
  916. * Deletes empty address space at end of fitlist.
  917. */
  918. int fit_unlink(fitptr thisfit)
  919. {
  920. if(thisfit->last==(fitptr)0) {
  921. sprintf(errstr,"Problem in fit_unlink()\n");
  922. return(PROGRAM_ERROR);
  923. }
  924. thisfit = thisfit->last;
  925. free(thisfit->next);
  926. thisfit->next = (fitptr)0;
  927. return(FINISHED);
  928. }
  929. /********************** FREE_FITLIST() ******************************
  930. *
  931. * Deletes fitlist, retaining head.
  932. */
  933. void free_fitlist(fitptr fithead)
  934. {
  935. fitptr thisfit;
  936. if((thisfit = fithead->next)==(fitptr)0)
  937. return;
  938. while(thisfit->next!=(fitptr)0) {
  939. thisfit = thisfit->next;
  940. free(thisfit->last);
  941. }
  942. free(thisfit);
  943. }
  944. /**************************** HFADJUST *********************************
  945. *
  946. * Pitch outside HS range. Adjust it.
  947. *
  948. * (1) If this is a HS, there's nothing we can do about it. Return -1.0
  949. * which will cause note to be deleted in calling environment.
  950. * (2) If it's an HF however....
  951. * Set newpitch at appropriate interval from original pitch.
  952. * (3) If it's now above the HS
  953. * (4) transpose it down by octaves until it is in the HS.
  954. * (5) If still not in HS, mark for deletion.
  955. * (6) If it's BELOW the HS.
  956. * (7) transpose it up by octaves until it is in the HS.
  957. * (8) If still not in HS, mark for deletion.
  958. * (9) Return new pitch.
  959. */
  960. double hfadjust(double thispitch,double *hs,int x1,int x2,int texflag,int hsnotecnt)
  961. {
  962. double newpitch;
  963. if(texflag & IS_HS)
  964. return(-1.0); /* 1 */
  965. else {
  966. newpitch = thispitch+hs[x1]-hs[x2]; /* 2 */
  967. if(newpitch > hs[hsnotecnt-1]) { /* 3 */
  968. while(newpitch>hs[hsnotecnt-1])
  969. newpitch -= SEMITONES_PER_OCTAVE; /* 4 */
  970. if(newpitch<hs[0]) /* 5 */
  971. return(-1.0);
  972. } else {
  973. if(newpitch<hs[0]) { /* 6 */
  974. while(newpitch <hs[0])
  975. newpitch += SEMITONES_PER_OCTAVE;/* 7 */
  976. if(newpitch>hs[hsnotecnt-1])
  977. return(-1.0); /* 8 */
  978. }
  979. }
  980. }
  981. return(newpitch); /* 9 */
  982. }
  983. /**************************** CONVERT_PITCH_TO_NEAREST_HSET_PITCH *********************************
  984. *
  985. * Convert pitch value to nearest HS value.
  986. *
  987. * ignores the problem of note repetitions in the tset.
  988. * Note repetitions were only important where the tset notes were being
  989. * forced onto an HS. Here the HS values are being extracted so the notes
  990. * can be ornamented. The pitch values of the tset are NOT themselves altered.
  991. */
  992. int convert_pitch_to_nearest_hset_pitch(double thispitch,double *hs,int hsnotecnt)
  993. {
  994. int n, m;
  995. if(thispitch<hs[0]) {
  996. if(hs[0] - thispitch > hs[1] - hs[0])
  997. return(-1);
  998. else
  999. return(0);
  1000. }
  1001. n = 1;
  1002. m = n-1;
  1003. while(n<hsnotecnt) {
  1004. if(flteq(hs[n],thispitch))
  1005. return(n);
  1006. if(hs[n]>thispitch) {
  1007. if(hs[n] - thispitch > thispitch - hs[m])
  1008. return(m);
  1009. else
  1010. return(n);
  1011. }
  1012. n++;
  1013. m++;
  1014. }
  1015. if(hsnotecnt>1 && (thispitch - hs[hsnotecnt-1] > hs[hsnotecnt-1] - hs[hsnotecnt-2]))
  1016. return(-1);
  1017. return(hsnotecnt-1);
  1018. }
  1019. /**************************** HFADJ2 *********************************
  1020. *
  1021. * HFindex outside HS range. Adjust it.
  1022. * Applies only to HF (i.e. an HS containing octave transpositions)
  1023. * not to HS.
  1024. */
  1025. int hfadj2(int hsi,int hfnotecnt,int hsnotecnt)
  1026. {
  1027. if(hsi<0) {
  1028. while(hsi<0)
  1029. hsi += hfnotecnt;
  1030. } else {
  1031. while(hsi>=hsnotecnt)
  1032. hsi -= hfnotecnt;
  1033. }
  1034. if(hsi<0 || hsi>=hsnotecnt)
  1035. return(-1);
  1036. return(hsi);
  1037. }
  1038. /**************************** SETUP_HFIELD *********************************/
  1039. int setup_hfield(noteptr thisnote,double **hs,int *hsnotecnt,double **hf,int *hfnotecnt,int texflag)
  1040. {
  1041. int exit_status;
  1042. if(texflag & IS_HS) {
  1043. if((exit_status = geths(thisnote,hs,hsnotecnt))<0)
  1044. return(exit_status);
  1045. } else {
  1046. if((exit_status = gethf(thisnote,hf,hfnotecnt))<0) /* 2 */
  1047. return(exit_status);
  1048. if((exit_status = gen_hs(hf,hs,hsnotecnt,*hfnotecnt))<0)
  1049. return(exit_status);
  1050. }
  1051. return(FINISHED);
  1052. }
  1053. /**************************** SETUP_FIRST_HFIELD *********************************/
  1054. int setup_first_hfield(noteptr thisnote,double **hs,int *hsnotecnt,double **hf,int *hfnotecnt,int texflag)
  1055. {
  1056. int exit_status;
  1057. if(texflag & IS_HS) {
  1058. if((exit_status = get_first_hs(thisnote,hs,hsnotecnt))<0)
  1059. return(exit_status);
  1060. } else {
  1061. if((exit_status = get_first_hf(thisnote,hf,hfnotecnt))<0) /* 2 */
  1062. return(exit_status);
  1063. if((exit_status = gen_hs(hf,hs,hsnotecnt,*hfnotecnt))<0)
  1064. return(exit_status);
  1065. }
  1066. return(FINISHED);
  1067. }
  1068. /**************************** GET_NEXT_HFIELD *********************************/
  1069. int get_next_hfield(double **hf,double **hs,double inputtime,
  1070. int *hf_cnt,int *hs_cnt,int *hfnotecnt,noteptr *thishfnote,double *thishftime,double *nexthftime,int hfdatacnt,
  1071. int *hsnotecnt,noteptr *thishsnote,double *thishstime,double *nexthstime,double *hft,int texflag)
  1072. {
  1073. if(texflag & IS_HS)
  1074. return getnexths(hs,inputtime,hs_cnt,hsnotecnt,thishsnote,thishstime,nexthstime,hfdatacnt,hft);
  1075. else
  1076. return getnexthf(hf,hs,hsnotecnt,inputtime,hf_cnt,hfnotecnt,thishfnote,thishftime,nexthftime,hfdatacnt,hft);
  1077. }
  1078. /**************************** SETUP_MOTIF_NOTE *********************************
  1079. *
  1080. * (1) If the program is given a pitchrange OUTSIDE the bounds of the
  1081. * specified HF or HS, do_ev_hfpch() returns a -ve value. In this
  1082. * case, the associated tset note is marked for DELETION by setting
  1083. * the bitflag associated with the shadow (address) of the tset note.
  1084. * It will be deleted at the very end, by del_ghosts().
  1085. */
  1086. int setup_motif_note
  1087. (double thisamp,int thisinstr,double thisdur,noteptr tsetnote,noteptr phrasenote,
  1088. double *thispitch,double thistime,int *hsindex,int hsnotecnt,double *hs,
  1089. double *pptop,double *ppbot,int *shadindex,char *shadbits,double multiplier,dataptr dz)
  1090. {
  1091. int exit_status;
  1092. tsetnote->amp = (float)thisamp;
  1093. tsetnote->instr = (unsigned char)thisinstr;
  1094. if(dz->vflag[DONT_KEEP_MTFDUR])
  1095. tsetnote->dur = (float)thisdur;
  1096. else
  1097. tsetnote->dur = (float)(phrasenote->dur * multiplier);
  1098. if(flteq((double)tsetnote->dur,0.0)) {
  1099. sprintf(errstr,"setup_motif_note(): Zero duration\n");
  1100. return(PROGRAM_ERROR);
  1101. }
  1102. if((exit_status = do_ev_hfpch(thistime,hsindex,thispitch,hsnotecnt,hs,pptop,ppbot,dz))<0)
  1103. return(exit_status);
  1104. if(exit_status==CONTINUE) {
  1105. set_shadbit(*shadindex,shadbits); /* 1 */
  1106. tsetnote = tsetnote->next;
  1107. (*shadindex)++;
  1108. return(CONTINUE);
  1109. }
  1110. tsetnote->pitch = (float)(*thispitch);
  1111. return(FINISHED);
  1112. }
  1113. /**************************** SETUP_GROUP_NOTE *********************************/
  1114. int setup_group_note
  1115. (double thisamp,int thisinstr,double thisdur,noteptr tsetnote,
  1116. double *thispitch,double thistime,int *hsindex,int hsnotecnt,double *hs,
  1117. double *pptop,double *ppbot,int *shadindex,char *shadbits,dataptr dz)
  1118. {
  1119. int exit_status;
  1120. tsetnote->amp = (float)thisamp;
  1121. tsetnote->instr = (unsigned char)thisinstr;
  1122. tsetnote->dur = (float)thisdur;
  1123. if((exit_status = do_ev_hfpch(thistime,hsindex,thispitch,hsnotecnt,hs,pptop,ppbot,dz))<0) /* 1 */
  1124. return(exit_status);
  1125. if(exit_status==CONTINUE) {
  1126. set_shadbit(*shadindex,shadbits);
  1127. tsetnote = tsetnote->next;
  1128. (*shadindex)++;
  1129. return(CONTINUE);
  1130. }
  1131. tsetnote->pitch = (float)(*thispitch);
  1132. return(FINISHED);
  1133. }
  1134. /**************************** SETUP_ORNAMENTATION *********************************/
  1135. int setup_ornamentation
  1136. (int *starthsi,int *endhsi,noteptr *nextevent,noteptr tsetnote,
  1137. noteptr *phrasenote,int *shadindex,int *endhsindex,int *hfphrase,int phrno,dataptr dz)
  1138. {
  1139. *starthsi = *hfphrase;
  1140. *endhsi = endhsindex[phrno];
  1141. *nextevent = getnextevent_to_decorate(tsetnote,shadindex,dz);
  1142. if(!dz->vflag[IS_PRE])
  1143. *phrasenote = (*phrasenote)->next;
  1144. return(FINISHED);
  1145. }
  1146. /**************************** GENERATE_MOTIF_NOTE_PITCH *********************************/
  1147. int generate_motifin_note_pitch(int n,int hsindex,int starthsindex,int hsnotecnt,double thispitch,
  1148. int *hfphrase,noteptr *thisnote,double *hs,int texflag)
  1149. {
  1150. int notehsindex, thishsindex;
  1151. double newpitch;
  1152. notehsindex = *(hfphrase+n+1);
  1153. thishsindex = hsindex + notehsindex - starthsindex;
  1154. if(thishsindex<0 || thishsindex>=hsnotecnt) {
  1155. if((newpitch = hfadjust(thispitch,hs,notehsindex,starthsindex,texflag,hsnotecnt))<0.0) {
  1156. *thisnote = (*thisnote)->last;
  1157. free((*thisnote)->next);
  1158. return(CONTINUE);
  1159. } else
  1160. (*thisnote)->pitch = (float)newpitch;
  1161. } else
  1162. (*thisnote)->pitch=(float)hs[thishsindex];
  1163. return(FINISHED);
  1164. }
  1165. /**************************** GENERATE_MOTIF_NOTE_PITCH *********************************/
  1166. int generate_motif_note_pitch(noteptr tsetnote,noteptr phrasenote,double phrfirstnote,noteptr thisnote)
  1167. {
  1168. thisnote->pitch=(float)(tsetnote->pitch + phrasenote->pitch - phrfirstnote);
  1169. thisnote->pitch=(float)octadjust((double)thisnote->pitch);
  1170. return(FINISHED);
  1171. }
  1172. /**************************** GENERATE_ORNAMENT_NOTE_PITCH *********************************
  1173. *
  1174. * hsi = harmonic-set index.
  1175. */
  1176. int generate_ornament_note_pitch
  1177. (int n,double *hs,int hsi, int endhsi,int starthsi,noteptr *thisnote,
  1178. noteptr *phrasenote,int *hfphrase,int hfnotecnt,int hsnotecnt,dataptr dz)
  1179. {
  1180. unsigned int texflag = dz->tex->txflag;
  1181. int thishsi, refhsi, notehsi;
  1182. if(dz->vflag[IS_PRE]) {
  1183. refhsi = endhsi;
  1184. notehsi = *(hfphrase+n);
  1185. } else {
  1186. refhsi = starthsi;
  1187. notehsi = *(hfphrase+n+1);
  1188. }
  1189. thishsi = hsi + notehsi - refhsi;
  1190. *phrasenote = (*phrasenote)->next;
  1191. if(thishsi<0 || thishsi>=hsnotecnt) {
  1192. if((texflag & IS_HS) || (thishsi=hfadj2(thishsi,hfnotecnt,hsnotecnt))<0) {
  1193. *thisnote = (*thisnote)->last;
  1194. free((*thisnote)->next);
  1195. return(CONTINUE);
  1196. }
  1197. }
  1198. (*thisnote)->pitch=(float)hs[thishsi];
  1199. return(FINISHED);
  1200. }
  1201. /********************** DO_EV_HFPCH *******************************
  1202. *
  1203. * Generate pitch of event (note group etc.) within HS.
  1204. *
  1205. * (2) If getp_as_index() returns -1 , this means
  1206. * that the pitch range specified is outside the HS, so a value of
  1207. * -1.0 is returned to calling environment and tset note is DELETED!!
  1208. */
  1209. int do_ev_hfpch(double thistime,int *hsindex,double *val,int hsnotecnt,double *hs,double *pptop,double *ppbot,dataptr dz)
  1210. {
  1211. int exit_status;
  1212. if((exit_status = getp_as_index(thistime,hsindex,hsnotecnt,hs,pptop,ppbot,dz))<0)
  1213. return(exit_status);
  1214. if(*hsindex==-1) /* a */
  1215. return(CONTINUE); /* 2 */
  1216. *val = hs[*hsindex];
  1217. return(FINISHED);
  1218. }
  1219. /****************************** GETP_AS_INDEX *********************************
  1220. *
  1221. * Get integer value of a hf-pitch index, using pitch either from table,
  1222. * or fixed value.
  1223. *
  1224. * (1) Read values of pitch-range limits from tables (or fixed vals).
  1225. * (2) If either of pitch values is negative, if it's from a table,
  1226. * reject it....
  1227. * (3) But otherwise it can be regarded as a flag. Return -1 causing
  1228. * the INPUT pitch to be converted to a HS pitch and returned.
  1229. * (4) Check that range is not inverted.
  1230. * (5) Get the note in HS which is > upper pitch boundary. If all HS notes
  1231. * are above this (function returns 0) return -1.
  1232. * If all HS notes are BELOW this pitch, function returns hsnotecnt,
  1233. * wehich forces upper limit of HSindex generated by doperm() to be
  1234. * hsnotecnt-1, the highest pitch in the HS.
  1235. * (6) Get the note in HS which is >= lower pitch boundary. If there
  1236. * is no such note (function returns hsnotecnt) return -1.
  1237. * (7) Return a weighted scattered value of hf-index, within the
  1238. * defined range.
  1239. */
  1240. int getp_as_index(double thistime,int *val,int hsnotecnt,double *hs,double *pptop,double *ppbot,dataptr dz)
  1241. {
  1242. int exit_status;
  1243. int a, b;
  1244. double range;
  1245. if(dz->brk[TEXTURE_MAXPICH]) { /* 1 */
  1246. if((exit_status = read_value_from_brktable(thistime,TEXTURE_MAXPICH,dz))<0)
  1247. return(exit_status);
  1248. }
  1249. if(dz->brk[TEXTURE_MINPICH]) {
  1250. if((exit_status = read_value_from_brktable(thistime,TEXTURE_MINPICH,dz))<0)
  1251. return(exit_status);
  1252. }
  1253. *pptop = dz->param[TEXTURE_MAXPICH];
  1254. *ppbot = dz->param[TEXTURE_MINPICH];
  1255. if((range = dz->param[TEXTURE_MAXPICH] - dz->param[TEXTURE_MINPICH])<0.0) /* 4 */
  1256. swap (&dz->param[TEXTURE_MAXPICH],&dz->param[TEXTURE_MINPICH]);
  1257. if((a = geths_above(dz->param[TEXTURE_MAXPICH],hs,hsnotecnt))==0) { /* 5 */
  1258. *val = -1;
  1259. return(FINISHED);
  1260. }
  1261. if((b = geths_hibnd(dz->param[TEXTURE_MINPICH],hsnotecnt,hs))>=hsnotecnt) { /* 6 */
  1262. *val = -1;
  1263. return(FINISHED);
  1264. }
  1265. if((exit_status = hfscat(a-b,b,PM_PITCH,&a,dz))<0) /* 7 */
  1266. return(exit_status);
  1267. if( a < 0 || a >= hsnotecnt) { /* 7 */
  1268. sprintf(errstr,"TEXTURE: getp_as_index(): TW's logic of index generation wrong\n");
  1269. return(DATA_ERROR);
  1270. }
  1271. *val = a;
  1272. return(FINISHED);
  1273. }
  1274. /**************************** INIT_SHADBITS ****************************
  1275. *
  1276. * Set up, and initialise to zero, a bitflag with one bit for each shadow
  1277. * (tset address).
  1278. */
  1279. int init_shadbits(int shadowsize,int *shshsize,char **shadbits)
  1280. {
  1281. int n = shadowsize;
  1282. *shshsize = 1;
  1283. while((n -= CHARBITSIZE)>0)
  1284. (*shshsize)++;
  1285. if((*shadbits = (char *)malloc((size_t)(*shshsize)))==NULL) {
  1286. sprintf(errstr,"INSUFFICIENT MEMORY for shadwoing array.\n");
  1287. return(MEMORY_ERROR);
  1288. }
  1289. for(n=0; n<(*shshsize); n++)
  1290. (*shadbits)[n] = 0;
  1291. return(FINISHED);
  1292. }
  1293. /****************************** GETHS ***********************************
  1294. *
  1295. * Extract HS from input data.
  1296. */
  1297. int geths(noteptr thisnote,double **hs,int *hsnotecnt)
  1298. {
  1299. int exit_status;
  1300. int size = BIGARRAY;
  1301. if((*hs = (double *)malloc(BIGARRAY * sizeof(double)))==NULL) {
  1302. sprintf(errstr,"INSUFFICIENT MEMORY for harmonic set array.\n");
  1303. return(MEMORY_ERROR);
  1304. }
  1305. while(thisnote!=(noteptr)0) {
  1306. if((exit_status = gethsnote(thisnote->pitch,*hs,hsnotecnt))<0)
  1307. return(exit_status);
  1308. if(*hsnotecnt >= BIGARRAY) {
  1309. size += BIGARRAY;
  1310. if((*hs=(double *)realloc((char *)(*hs),size * sizeof(double)))==NULL){
  1311. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate harmonic set array.\n");
  1312. return(MEMORY_ERROR);
  1313. }
  1314. }
  1315. thisnote = thisnote->next;
  1316. }
  1317. if((*hs=(double *)realloc((char *)(*hs),*hsnotecnt*sizeof(double)))==NULL){
  1318. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate harmonic set array.\n");
  1319. return(MEMORY_ERROR);
  1320. }
  1321. upsort(*hs,*hsnotecnt);
  1322. return(FINISHED);
  1323. }
  1324. /****************************** GETHF ***********************************
  1325. *
  1326. * Extract HF from input data.
  1327. */
  1328. int gethf(noteptr thisnote,double **hf,int *hfnotecnt)
  1329. {
  1330. int exit_status;
  1331. int size = BIGARRAY;
  1332. if((*hf = (double *)malloc(size * sizeof(double)))==NULL) {
  1333. sprintf(errstr,"INSUFFICIENT MEMORY for harmonic field array.\n");
  1334. return(MEMORY_ERROR);
  1335. }
  1336. while(thisnote!=(noteptr)0) {
  1337. if((exit_status = gethfnote(thisnote->pitch,*hf,hfnotecnt))<0)
  1338. return(exit_status);
  1339. if(*hfnotecnt >= size) {
  1340. size += BIGARRAY;
  1341. if((*hf = (double *)realloc((char *)(*hf),size * sizeof(double)))==NULL){
  1342. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate harmonic field array.\n");
  1343. return(MEMORY_ERROR);
  1344. }
  1345. }
  1346. thisnote = thisnote->next;
  1347. }
  1348. if((*hf=(double *)realloc((char *)(*hf),*hfnotecnt * sizeof(double)))==NULL){
  1349. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate harmonic field array.\n");
  1350. return(MEMORY_ERROR);
  1351. }
  1352. upsort(*hf,*hfnotecnt);
  1353. return(FINISHED);
  1354. }
  1355. /****************************** GEN_HS ***********************************
  1356. *
  1357. * Generate HS from a HF.
  1358. *
  1359. * NB This function assumes thas HF is ordered in ascending pitch order.
  1360. *
  1361. * (1) Eliminate octave dupliates in hf.
  1362. * (2) Initialise the HS count to zero.
  1363. * (3) Start in the lowest octave.
  1364. * (4) Go round loop generating HS, until we're out of (MIDI) range.
  1365. * (5) Each time round loop, point to start of HF.
  1366. * (6) And for all HF members, put them in HS + a (loop) number of 8ves,
  1367. * counting the HS as we go.
  1368. * (7) Once the pitch of any note exceeds MIDI upper limit (MIDITOP), break
  1369. * from inner and (OK=0) outer loops.
  1370. * (8) Each time round outer loop, increment octave.
  1371. * (9) Reallocate the HS to the store 'hs'
  1372. */
  1373. int gen_hs(double **hf,double **hs, int *hsnotecnt, int hfnotecnt)
  1374. {
  1375. int n, m, k, thisoct, OK = 1;
  1376. int size = BIGARRAY;
  1377. double nextpitch;
  1378. double *thishf;
  1379. if((*hs)!=(double *)0)
  1380. free(*hs);
  1381. if((*hs = (double *)malloc(size * sizeof(double)))==NULL) {
  1382. sprintf(errstr,"INSUFFICIENT MEMORY for harmonic set array.\n");
  1383. return(MEMORY_ERROR);
  1384. }
  1385. for(n=0;n<hfnotecnt-1;n++) { /* 1 */
  1386. for(m=n+1;m<hfnotecnt;m++) {
  1387. if(octeq((*hf)[n],(*hf)[m])) {
  1388. k = m + 1;
  1389. while(k < hfnotecnt) {
  1390. (*hf)[k-1] = (*hf)[k];
  1391. k++;
  1392. }
  1393. hfnotecnt--;
  1394. m--;
  1395. }
  1396. }
  1397. }
  1398. *hsnotecnt = 0; /* 2 */
  1399. thisoct = 0; /* 3 */
  1400. while(OK) { /* 4 */
  1401. thishf = *hf; /* 5 */
  1402. for(n=0;n<hfnotecnt;n++) { /* 6 */
  1403. if((nextpitch = (*thishf++)+((double)thisoct*SEMITONES_PER_OCTAVE))<=MIDITOP) {
  1404. (*hs)[(*hsnotecnt)++] = nextpitch;
  1405. if(*hsnotecnt>=size) {
  1406. size += BIGARRAY;
  1407. if((*hs =(double *)realloc((char *)(*hs),size * sizeof(double)))==NULL) {
  1408. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate harmonic set array.\n");
  1409. return(MEMORY_ERROR);
  1410. }
  1411. }
  1412. } else {
  1413. OK = 0; /* 7 */
  1414. break;
  1415. }
  1416. }
  1417. thisoct++; /* 8 */
  1418. }
  1419. if((*hs=(double *)realloc((char *)(*hs),*hsnotecnt * sizeof(double)))==NULL){
  1420. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate harmonic set array.\n");
  1421. return(MEMORY_ERROR);
  1422. }
  1423. return(FINISHED);
  1424. }
  1425. /**************************** CHEKREPEAT *********************************
  1426. *
  1427. * Flag if there is a repeated note in the source data.
  1428. */
  1429. #if 0
  1430. // removed vars set but unused, so this func no longer needed
  1431. int chekrepeat(noteptr thisnote,double lastpitch)
  1432. {
  1433. if(flteq((double)thisnote->pitch,lastpitch))
  1434. return(TRUE);
  1435. return(FALSE);
  1436. }
  1437. #endif
  1438. /****************************** GETNEXTHF ***********************************
  1439. *
  1440. * Get the harmonic field pertaining to this time, + 'hfnotecnt'.
  1441. *
  1442. * NB 2: THIS FUNCTION ASSUMES IN WILL BE ACCESSED IN TIME-INCREASING ORDER.
  1443. *
  1444. * (1) Current time preset to zero.
  1445. * (2) Nexttime to time of next hf in hf_data_motif.
  1446. * (3) Static pointer points into current place in hf_data_motif.
  1447. * (3a) If noteptr points to zero w'ere
  1448. EITHER we're at end of notelist: therefore no more HF data,
  1449. hence retain existing data.
  1450. OR we have not initialised the noteptr, which should happen
  1451. on first call to this function, BUT in this case the
  1452. hfnotecnt will be zero as we have not yet created an HF.
  1453. In this case, error, exit.
  1454. * (4) If time of function access still less than time of entry of next
  1455. * harmonic field, do nothing (i.e. stay with current hf returning
  1456. * current hfnotecnt).
  1457. * (5) If time of function access is after time of next harmonic field
  1458. * advance down hfs, until TOFA is before next hf (NB last time in
  1459. * the hft[] is AFTER end of texture duration).
  1460. * (6) Establish temporary storage space to read a new hf, and set the
  1461. * hf pointer 'thishf' to point to it.
  1462. * (7) Walk through the input notes until we get to notes corresponding
  1463. * to time of the hf we want.
  1464. * (8) Store the harmonic field in the temporary array.
  1465. * (9) Free any existing hf.
  1466. * (10) Reallocate the new hf to the array hf[], and set the hf pointer
  1467. * 'thishf' to point at it.
  1468. * (11) Generate the associated HS !!!
  1469. */
  1470. int getnexthf
  1471. (double **hf,double **hs, int *hsnotecnt,double inputtime,int *hf_cnt,int *hfnotecnt,
  1472. noteptr *thishfnote,double *thishftime,double *nexthftime,int hfdatacnt,double *hft)
  1473. {
  1474. int exit_status;
  1475. int size = BIGARRAY;
  1476. if(*thishfnote==(noteptr)0) { /* 3a */
  1477. if(*hfnotecnt==0) {
  1478. sprintf(errstr,"INSUFFICIENT MEMORY for hfield notecount array.\n");
  1479. return(PROGRAM_ERROR);
  1480. }
  1481. return(TRUE);
  1482. }
  1483. if(inputtime<*nexthftime) /* 4 */
  1484. return(FALSE);
  1485. while(*nexthftime<=inputtime) { /* 5 */
  1486. if(*hf_cnt>=hfdatacnt) {
  1487. sprintf(errstr,"INSUFFICIENT MEMORY for hfield count array.\n");
  1488. return(PROGRAM_ERROR);
  1489. }
  1490. *thishftime = *nexthftime;
  1491. *nexthftime = hft[*hf_cnt];
  1492. (*hf_cnt)++;
  1493. }
  1494. if(*hf!=(double *)0) /* 9 */
  1495. free(*hf);
  1496. if((*hf = (double *)malloc(size * sizeof(double)))==NULL) {
  1497. sprintf(errstr,"INSUFFICIENT MEMORY for hfield array.\n");
  1498. return(MEMORY_ERROR);
  1499. }
  1500. while(!flteq((double)(*thishfnote)->ntime,*thishftime)) { /* 7 */
  1501. if((*thishfnote = (*thishfnote)->next)==(noteptr)0) {
  1502. sprintf(errstr,"TEXTURE: Search problem in getnexthf()\n");
  1503. return(PROGRAM_ERROR);
  1504. }
  1505. }
  1506. *hfnotecnt = 0;
  1507. while(flteq((double)(*thishfnote)->ntime,*thishftime)) { /* 8 */
  1508. if((exit_status = gethfnote((*thishfnote)->pitch,*hf,hfnotecnt))<0)
  1509. return(exit_status);
  1510. if(*hfnotecnt >= size) {
  1511. size += BIGARRAY;
  1512. if((*hf = (double *)realloc((char *)(*hf),size * sizeof(double)))==NULL) {
  1513. sprintf(errstr,"TEXTURE: realloc failed in getnexthf()\n");
  1514. return(PROGRAM_ERROR);
  1515. }
  1516. }
  1517. if((*thishfnote = (*thishfnote)->next)==(noteptr)0)
  1518. break;
  1519. }
  1520. if((*hf=(double *)realloc((char *)(*hf),*hfnotecnt * sizeof(double)))==NULL){
  1521. sprintf(errstr,"TEXTURE: getnexthf(): realloc() failed\n"); /* 10 */
  1522. return(PROGRAM_ERROR);
  1523. }
  1524. upsort(*hf,*hfnotecnt);
  1525. if((exit_status = gen_hs(hf,hs,hsnotecnt,*hfnotecnt))<0) /* 11 */
  1526. return(exit_status);
  1527. return(TRUE);
  1528. }
  1529. /****************************** GETNEXTHS ***********************************
  1530. *
  1531. * Get the harmonic set pertaining to this time.
  1532. *
  1533. * NB 2: THIS FUNCTION ASSUMES IT WILL BE ACCESSED IN TIME-INCREASING ORDER.
  1534. *
  1535. * (3) Static pointer points into current place in hf_data_motif.
  1536. * (3a) If noteptr points to zero w'ere
  1537. EITHER we're at end of notelist: therefore no more HF data,
  1538. hence retain existing data.
  1539. OR we have not initialised the noteptr, which should happen
  1540. on first call to this function, BUT in this case the
  1541. hsnotecnt will be zero as we have not yet created an HS.
  1542. In this case, error, exit.
  1543. * (4) If time of function access still less than time of entry of next
  1544. * harmonic set, do nothing (i.e. stay with current hs returning
  1545. * current harmonic set cnt hsnotecnt).
  1546. * (5) If time of function access is after time of next harmonic set
  1547. * advance down HSs, until TOFA is before next hs (NB last time in
  1548. * the hft[] is AFTER end of texture duration).
  1549. * (6) Establish temporary storage space to read a new hs, and set the
  1550. * hs pointer 'thishs' to point to it.
  1551. * (7) Walk through the input notes until we get to notes corresponding
  1552. * to time of the hs we want.
  1553. * (8) Store the harmonic set in the temporary array.
  1554. * (9) Free any existing hs.
  1555. * (10) Reallocate the new hs to the array hs[], and set the hs pointer
  1556. * 'thishs' to point at it.
  1557. */
  1558. int getnexths
  1559. (double **hs,double inputtime,int *hs_cnt,int *hsnotecnt,noteptr *thishsnote,
  1560. double *thishstime,double *nexthstime,int hfdatacnt,double *hft)
  1561. {
  1562. int exit_status;
  1563. int size = BIGARRAY;
  1564. if(*thishsnote==(noteptr)0) { /* 3a */
  1565. if(*hsnotecnt==0) {
  1566. sprintf(errstr,"getnexths() not initialised\n");
  1567. return(PROGRAM_ERROR);
  1568. }
  1569. return(TRUE);
  1570. }
  1571. if(inputtime<*nexthstime) /* 4 */
  1572. return(FALSE);
  1573. while(*nexthstime<=inputtime) { /* 5 */
  1574. if(*hs_cnt>=hfdatacnt) {
  1575. sprintf(errstr,"Timing problem in getnexths()\n");
  1576. return(PROGRAM_ERROR);
  1577. }
  1578. *thishstime = *nexthstime;
  1579. *nexthstime = hft[*hs_cnt];
  1580. (*hs_cnt)++;
  1581. }
  1582. if(*hs!=(double *)0) /* 9 */
  1583. free(*hs);
  1584. if((*hs = (double *)malloc(size * sizeof(double)))==NULL) {
  1585. sprintf(errstr,"INSUFFICIENT MEMORY for harmonic set array.\n");
  1586. return(MEMORY_ERROR);
  1587. }
  1588. while(!flteq((double)(*thishsnote)->ntime,*thishstime)) { /* 7 */
  1589. if((*thishsnote = (*thishsnote)->next)==(noteptr)0) {
  1590. sprintf(errstr,"TEXTURE: Search problem in getnexths()\n");
  1591. return(PROGRAM_ERROR);
  1592. }
  1593. }
  1594. *hsnotecnt = 0;
  1595. while(flteq((double)(*thishsnote)->ntime,*thishstime)) { /* 8 */
  1596. if((exit_status = gethsnote((*thishsnote)->pitch,*hs,hsnotecnt))<0)
  1597. return(exit_status);
  1598. if(*hsnotecnt >= size) {
  1599. size += BIGARRAY;
  1600. if((*hs =(double *)realloc((char *)(*hs),size * sizeof(double)))==NULL) {
  1601. sprintf(errstr,"TEXTURE: realloc failed in getnexths()\n");
  1602. return(PROGRAM_ERROR);
  1603. }
  1604. }
  1605. if((*thishsnote = (*thishsnote)->next)==(noteptr)0)
  1606. break;
  1607. }
  1608. if((*hs=(double *)realloc((char *)(*hs),*hsnotecnt * sizeof(double)))==NULL){
  1609. sprintf(errstr,"TEXTURE: getnexths(): realloc() failed\n");/* 10 */
  1610. return(PROGRAM_ERROR);
  1611. }
  1612. upsort(*hs,*hsnotecnt);
  1613. return(TRUE);
  1614. }
  1615. /***************************** GETHSNOTE ************************************
  1616. *
  1617. * Read a note and store in harmonic SET, IF not already there.
  1618. */
  1619. int gethsnote(double thispitch,double *thishs,int *hsnotecnt)
  1620. {
  1621. int n, OK = 0;
  1622. for(n=0;n<*hsnotecnt;n++) {
  1623. if(flteq(thispitch,thishs[n])) {
  1624. OK = 1;
  1625. break;
  1626. }
  1627. }
  1628. if(!OK)
  1629. thishs[*hsnotecnt] = (double)thispitch;
  1630. (*hsnotecnt)++;
  1631. return(FINISHED);
  1632. }
  1633. /***************************** READHFTIMES ************************************
  1634. *
  1635. * Read times at which successive harmonic fields(sets) enter, and store as list.
  1636. */
  1637. int readhftimes(noteptr firstnote, int *hfdatacnt,double **hft)
  1638. {
  1639. double lasttime, firsttime;
  1640. int arraysize = BIGARRAY;
  1641. noteptr thisnote = firstnote;
  1642. *hfdatacnt = 0;
  1643. if((*hft = (double *)malloc(arraysize * sizeof(double)))==NULL) {
  1644. sprintf(errstr,"INSUFFICIENT MEMORY for harmonic field times array.\n");
  1645. return(MEMORY_ERROR);
  1646. }
  1647. lasttime = thisnote->ntime;
  1648. (*hft)[0] = lasttime;
  1649. while(thisnote!=(noteptr)0) {
  1650. if(!flteq((double)thisnote->ntime,lasttime)) {
  1651. if(++(*hfdatacnt)>=arraysize-1) {
  1652. arraysize += BIGARRAY;
  1653. if((*hft = (double *)realloc((char *)(*hft),arraysize * sizeof(double)))==NULL) {
  1654. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate harmonic field times array.\n");
  1655. return(PROGRAM_ERROR);
  1656. }
  1657. }
  1658. (*hft)[*hfdatacnt] = thisnote->ntime;
  1659. lasttime = thisnote->ntime;
  1660. }
  1661. thisnote = thisnote->next;
  1662. }
  1663. (*hft)[++(*hfdatacnt)] = DBL_MAX; /* 1 */
  1664. (*hfdatacnt)++;
  1665. if((*hft = (double *)realloc((char *)(*hft),(*hfdatacnt) * sizeof(double)))==NULL){
  1666. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate harmonic field times array.\n");
  1667. return(PROGRAM_ERROR);
  1668. }
  1669. if(!flteq(**hft,0.0)) {
  1670. fprintf(stdout,"WARNING: Harmonic Field Data: No field at ZERO time.\n"
  1671. "ADJUSTING FIRST FIELD TO ZERO TIME\n");
  1672. fflush(stdout);
  1673. thisnote = firstnote;
  1674. firsttime = thisnote->ntime;
  1675. while(flteq(firsttime,**hft)) {
  1676. thisnote->ntime = 0.0f;
  1677. if((thisnote = thisnote->next)==(noteptr)0)
  1678. break;
  1679. }
  1680. **hft = 0.0;
  1681. }
  1682. return(FINISHED);
  1683. }
  1684. /***************************** DEL_GHOSTS ******************************
  1685. *
  1686. * Delete all tset notes MARKED for deletion in shadbits bitflag.
  1687. *
  1688. * (1) For each byte in the bitflag...
  1689. * (2) Set the bitmask to the first bit.
  1690. * (3) For every bit in this byte....
  1691. * (4) If this bit is set, delete the associated shadow (tset) note.
  1692. * (5) Advance the bitflag internal to the byte leftwards.
  1693. * (6) Advance the count of shadows, and if it reaches the total number
  1694. * of shadows, exit, because remaining bits in this byte (if any)
  1695. * have no meaning.
  1696. */
  1697. void del_ghosts(int shshsize,char *shadbits,noteptr *shadow,int shadowsize,motifptr tset)
  1698. {
  1699. int n,m,mask,k = 0;
  1700. for(n=0;n<shshsize;n++) { /* 1 */
  1701. mask = 1; /* 2 */
  1702. for(m=0;m<CHARBITSIZE;m++) { /* 3 */
  1703. if(shadbits[n] & mask) /* 4 */
  1704. del_note(shadow[k],tset);
  1705. mask <<= 1; /* 5 */
  1706. if(++k >= shadowsize) /* 6 */
  1707. return;
  1708. }
  1709. }
  1710. }
  1711. /************************** GET_HFGPPARAMS **************************
  1712. *
  1713. * Get the parameters for a group of notes.
  1714. *
  1715. * (0) If pitch to decorate lies outside the HF range, return with gpsize
  1716. * set to zero.
  1717. * (1) If group range is expressed in HS-note units..
  1718. * (a) Read the gprange as an integer number of (HS) notes.
  1719. * (b) If HS-range exceeds HS limits, squeeze it.
  1720. * (c) If HS-range is to be oriented about note, orient it appropriately.
  1721. * (2) Otherwise...
  1722. * (a) Read group range in normal way.
  1723. * (b) If range exceeds HS limits, squeeze it.
  1724. * (c) If range is to be oriented about note, orient it appropriately.
  1725. * (d) If the range lies outside range of the HS,
  1726. * set the groupsize to ZERO and return.
  1727. * (e) Otherwise set the HS-range.
  1728. * (3) Read group size.
  1729. * (4) Read group density.
  1730. * (5) number of midicliks in a gpdense time-interval.
  1731. * (6) number of quantisation units, rounded.
  1732. * (7) readjust gpdense to be number of units * length of units,
  1733. * and reconvert to seconds.
  1734. */
  1735. int get_hfgpparams(double thistime,double thispitch,double *hs,int hsnotecnt,
  1736. int *gpsize,int *hfrange,int *hfgpranglo,int *hfgpranghi,double *gprange,double *gpdense,int mingrpsize,
  1737. double *gprlow, int dectypecnt,unsigned char dectypestor,dataptr dz)
  1738. {
  1739. int exit_status;
  1740. if(thispitch<hs[0] || thispitch>hs[hsnotecnt-1]) {
  1741. *gpsize = 0; /* 0 */
  1742. return(FINISHED);
  1743. }
  1744. if((exit_status = igetvalue(TEX_GPRANGHI,TEX_GPRANGLO,thistime,PM_GPRANG,hfrange,dz))<0)
  1745. return(exit_status);
  1746. if(!dectypecnt) {
  1747. hfsqueezrange(thispitch,hfrange,hfgpranghi,hfgpranglo,hsnotecnt,hs); /* b */
  1748. dz->vflag[DECCENTRE] = FALSE;
  1749. } else {
  1750. if((exit_status = hforientrange
  1751. (thispitch,hfrange,hfgpranghi,hfgpranglo,hsnotecnt,hs,dectypecnt,dectypestor,dz))<0) /* c */
  1752. return(exit_status);
  1753. }
  1754. /* OCT 17 : hfgpranghi,lo are max & min INDECES within the harmonic field */
  1755. *hfrange = *hfgpranghi - *hfgpranglo; /* e */
  1756. /* OCT 17 : FROM hfgpranghi,lo the actual PITCH values can be deduced */
  1757. *gprlow = hs[*hfgpranglo];
  1758. *gprange = hs[*hfgpranghi] - hs[*hfgpranglo];
  1759. if((exit_status = igetvalue(TEX_GPSIZEHI,TEX_GPSIZELO,thistime,PM_GPSIZE,gpsize,dz))<0)
  1760. return(exit_status);
  1761. if(*gpsize < mingrpsize) {
  1762. sprintf(errstr,"TEXTURE: Impossible GROUP SIZE value [%d]: get_hfgpparams()\n",*gpsize);
  1763. return(PROGRAM_ERROR);
  1764. }
  1765. if((exit_status = getvalue(TEX_GPPACKHI,TEX_GPPACKLO,thistime,PM_GPDENS,gpdense,dz))<0)
  1766. return(exit_status);
  1767. /* NEW MAR 2000 */
  1768. *gpdense *= MS_TO_SECS;
  1769. if(dz->param[TEX_PHGRID]>0.0)
  1770. *gpdense = quantise(*gpdense,dz->param[TEX_PHGRID]);
  1771. return(FINISHED);
  1772. }
  1773. /*************************** HFSQUEEZRANGE ******************************
  1774. *
  1775. * Adjust range to lie within HF limits.
  1776. *
  1777. * (2) Top of range is at current pitch's HF index (approx). If this is
  1778. * above current top-of-HF range (hsnotecnt) move top down.
  1779. * (3) Bottom of range is igprange below top. If this is below
  1780. * bottom-of-HF (0), move igprlow up.
  1781. * (4) Recalculate the true igprange within true limits.
  1782. */
  1783. void hfsqueezrange(double thispitch,int *hfrange,int *hfgpranghi,int *hfgpranglo,int hsnotecnt,double *hs)
  1784. {
  1785. int halfrange = *hfrange/2;
  1786. if(halfrange * 2 != *hfrange)
  1787. halfrange++;
  1788. *hfgpranghi = min((geths_hibnd(thispitch,hsnotecnt,hs)+halfrange),hsnotecnt); /* 2 */
  1789. *hfgpranglo = max((*hfgpranghi - *hfrange),0); /* 3 */
  1790. *hfrange = *hfgpranghi - *hfgpranglo; /* 4 */
  1791. }
  1792. /****************************** GETHS_HIBND **********************************
  1793. *
  1794. * hibnd >= pitch
  1795. *
  1796. * Find the index of the harmonic-set note that is immediately above or
  1797. * equal to the input pitch.
  1798. *
  1799. * NB CALL WITH geths_hibnd((double)thisnote->pitch);
  1800. *
  1801. * If the pitch is beyond the HS, n returns the value 'hsnotecnt'.
  1802. */
  1803. int geths_hibnd(double thispitch,int hsnotecnt,double *hs)
  1804. {
  1805. int n;
  1806. for(n=0;n<hsnotecnt;n++) {
  1807. if(hs[n]>thispitch || flteq(hs[n],thispitch))
  1808. break;
  1809. }
  1810. return(n); /* 1 */
  1811. }
  1812. /*************************** HFORIENTRANGE ******************************
  1813. *
  1814. * As orientrange() but applied to HF/HS case.
  1815. */
  1816. int hforientrange
  1817. (double thispitch,int *hfrange,
  1818. int *hfgpranghi,int *hfgpranglo,int hsnotecnt,double *hs,int dectypecnt,unsigned char dectypestor,dataptr dz)
  1819. {
  1820. int exit_status;
  1821. unsigned char dectype;
  1822. int k;
  1823. if((exit_status=doperm((int)dectypecnt,PM_ORIENT,&k,dz))<0)
  1824. return(exit_status);
  1825. if((exit_status=gettritype(k,dectypestor,&dectype))<0)
  1826. return(exit_status);
  1827. switch(dectype) {
  1828. case(0): /* centred range */
  1829. hfsqueezrange(thispitch,hfrange,hfgpranghi,hfgpranglo,hsnotecnt,hs);
  1830. dz->vflag[DECCENTRE] = TRUE;
  1831. break;
  1832. case(1): /* range above note */
  1833. *hfgpranghi = min((geths_hibnd(thispitch,hsnotecnt,hs) + *hfrange),hsnotecnt);
  1834. *hfgpranglo = max((*hfgpranghi - *hfrange),0);
  1835. *hfrange = *hfgpranghi - *hfgpranglo;
  1836. dz->vflag[DECCENTRE] = FALSE;
  1837. break;
  1838. case(2): /* range below note */
  1839. *hfgpranghi = geths_hibnd(thispitch,hsnotecnt,hs);
  1840. *hfgpranglo = max((*hfgpranghi - *hfrange),0);
  1841. *hfrange = *hfgpranghi - *hfgpranglo;
  1842. dz->vflag[DECCENTRE] = FALSE;
  1843. break;
  1844. default:
  1845. sprintf(errstr,"TEXTURE: Problem in hforientrange()\n");
  1846. return(PROGRAM_ERROR);
  1847. }
  1848. return(FINISHED);
  1849. }
  1850. /****************************** GETHS_ABOVE **********************************
  1851. *
  1852. * above > pitch
  1853. *
  1854. * Find the index of the harmonic-set note that is immediately above
  1855. * the input pitch.
  1856. *
  1857. * NB CALL WITH geths_above((double)thisnote->pitch);
  1858. *
  1859. * If the pitch is beyond the HS, n gets the value 'hsnotecnt', which becomes
  1860. * the upper limit of the search range for doperm() ensuring that highest
  1861. * possible HSindex val is hsnotecnt-1, the highest pitch in the HS.
  1862. */
  1863. int geths_above(double thispitch,double *hs,int hsnotecnt)
  1864. {
  1865. int n;
  1866. for(n=0;n<hsnotecnt;n++) {
  1867. if(hs[n]>thispitch)
  1868. break;
  1869. }
  1870. return(n); /* 1 */
  1871. }
  1872. /****************************** GENERATE_GROUP_NOTE **********************************/
  1873. int generate_group_note
  1874. (noteptr thisnote,noteptr tsetnote,double thistime,int hfrange,int hfgpranglo,
  1875. double *hs,int *hsindex,int gpsize,dataptr dz)
  1876. {
  1877. int exit_status;
  1878. unsigned char thisinstr;
  1879. if((exit_status = do_grp_ins(tsetnote->instr,&thisinstr,dz))<0)
  1880. return(exit_status);
  1881. thisnote->instr = thisinstr;
  1882. thisnote->motioncentre = tsetnote->motioncentre;
  1883. if((exit_status = hfscat(hfrange,hfgpranglo,PM_GPPICH,hsindex,dz))<0)
  1884. return(exit_status);
  1885. thisnote->pitch = (float)hs[*hsindex]; /* 7 */
  1886. thisnote->ntime = (float)thistime;
  1887. return setspace(tsetnote,thisnote,gpsize,dz);
  1888. }
  1889. /******************************* HFSCAT ***********************************
  1890. *
  1891. * A weighted version of hfscatx().
  1892. */
  1893. int hfscat(int prange,int pbottom,int permindex,int *val,dataptr dz)
  1894. {
  1895. int exit_status;
  1896. double bandbottom, bandtop, bandwidth;
  1897. int ibandbottom, ibandtop, ibandwidth, k;
  1898. if(prange<=LAYERCNT) {
  1899. if((exit_status = doperm((int)prange,permindex,&k,dz))<0)
  1900. return(exit_status);
  1901. *val = k + pbottom;
  1902. return(FINISHED);
  1903. }
  1904. if((exit_status = doperm((int)BANDCNT,permindex,&k,dz))<0)
  1905. return(exit_status);
  1906. bandwidth = (double)prange/(double)LAYERCNT;
  1907. switch(k) {
  1908. case(0):
  1909. bandbottom = 0;
  1910. break;
  1911. case(BANDCNT-1):
  1912. bandbottom = (double)(LAYERCNT-1) * bandwidth;
  1913. break;
  1914. default:
  1915. bandbottom = bandwidth + ((double)((k-1) * 2) * bandwidth);
  1916. bandwidth *= 2.0;
  1917. break;
  1918. }
  1919. bandtop = bandbottom + bandwidth;
  1920. ibandtop = round(bandtop);
  1921. ibandbottom = round(bandbottom);
  1922. ibandwidth = ibandtop - ibandbottom;
  1923. k = (int)(drand48() * (double)ibandwidth);
  1924. k += ibandbottom;
  1925. k += pbottom;
  1926. *val = k;
  1927. return(FINISHED);
  1928. }
  1929. /****************************** GENERATE_DECOR_NOTE **********************************/
  1930. int generate_decor_note(noteptr thisnote,noteptr tsetnote,
  1931. double thispitch,double thistime,int hfrange,int hfgpranghi,int hfgpranglo,double *hs,int *hsindex,
  1932. int hsnotecnt,double gprlow,double gprange,int gpsize,dataptr dz)
  1933. {
  1934. int exit_status;
  1935. double val;
  1936. if((exit_status = do_grp_ins(tsetnote->instr,&thisnote->instr,dz))<0)
  1937. return(exit_status);
  1938. thisnote->motioncentre = tsetnote->motioncentre;
  1939. if(dz->vflag[DECCENTRE]) {
  1940. if((exit_status = dec_hfcentre
  1941. (thispitch,hs,hsnotecnt,hfrange,hfgpranghi,hfgpranglo,gprlow,gprange,gpsize,&val,dz))<0)
  1942. return(exit_status);
  1943. thisnote->pitch = (float)val;
  1944. } else {
  1945. if((exit_status = hfscat(hfrange,hfgpranglo,PM_GPPICH,hsindex,dz))<0)
  1946. return(exit_status);
  1947. thisnote->pitch = (float)hs[*hsindex];
  1948. }
  1949. thisnote->ntime = (float)(thistime);
  1950. return setspace(tsetnote,thisnote,gpsize,dz);
  1951. }
  1952. /************************* DEC_HFCENTRE *******************************/
  1953. int dec_hfcentre(double tsetpitch,double *hs,int hsnotecnt,int hfrange,int hfgpranghi,int hfgpranglo,
  1954. double gprlow,double gprange,int gpsize,double *val,dataptr dz)
  1955. {
  1956. int exit_status;
  1957. double a, gprhi = gprlow + gprange;
  1958. int s, save, k, hfcentre, n_above, n_below, hsindex;
  1959. if(tsetpitch-gprlow<=FLTERR || flteq(tsetpitch,gprhi)) {
  1960. if((exit_status = hfscatx(hfrange,hfgpranglo,PM_GPPICH,&hsindex,dz))<0)
  1961. return(exit_status);
  1962. *val = hs[hsindex];
  1963. return(FINISHED); /* 1 */
  1964. }
  1965. n_below = hfrange/2; /* 2 */
  1966. if(((n_above=n_below)+n_below)!=hfrange)
  1967. n_above++;
  1968. if(((hfcentre =geths_hibnd(tsetpitch,hsnotecnt,hs)) + n_above) > hsnotecnt)
  1969. n_above = hsnotecnt - hfcentre; /* 3 */
  1970. if(hfcentre - n_below < 0)
  1971. n_below = hfcentre; /* 4 */
  1972. if(n_above<=0 || n_below<=0) {
  1973. if((exit_status = hfscatx(hfrange,hfgpranglo,PM_GPPICH,&hsindex,dz))<0)
  1974. return(exit_status);
  1975. else {
  1976. *val = hs[hsindex];
  1977. return(FINISHED); /* 5 */
  1978. }
  1979. }
  1980. save = dz->iparray[TXREPETCNT][PM_DECABV]; /* 6 */
  1981. k = (gpsize+1)/2;
  1982. if(dz->iparray[TXREPETCNT][PM_DECABV]>k)
  1983. dz->iparray[TXREPETCNT][PM_DECABV] = k;
  1984. if((exit_status = doperm((int)2,PM_DECABV,&s,dz))<0)
  1985. return(exit_status);
  1986. if(s) {
  1987. if((exit_status = hfscatx(n_above,hfgpranghi - n_above,PM_GPPICH,&hsindex,dz))<0)
  1988. return(exit_status);
  1989. } else {
  1990. if((exit_status = hfscatx(n_below,hfgpranglo,PM_GPPICH2,&hsindex,dz))<0)
  1991. return(exit_status);
  1992. }
  1993. dz->iparray[TXREPETCNT][PM_DECABV] = save;
  1994. a = hs[hsindex];
  1995. if(a<MIDIBOT || a>MIDITOP) {
  1996. sprintf(errstr,"TEXTURE: Problem in dec_hfcentre()\n");
  1997. return(PROGRAM_ERROR);
  1998. }
  1999. *val = a;
  2000. return(FINISHED);
  2001. }
  2002. /******************************* HFSCATX ***********************************
  2003. *
  2004. * As pscat, but working with ranges of integers, especially the indeces
  2005. * of an HS.
  2006. */
  2007. int hfscatx(int prange,int pbottom,int permindex,int *val,dataptr dz)
  2008. {
  2009. int exit_status;
  2010. double bandbottom, bandtop, bandwidth;
  2011. int ibandbottom, ibandtop, ibandwidth, k;
  2012. if(prange<=BANDCNT) {
  2013. if((exit_status = doperm((int)prange,permindex,val,dz))<0)
  2014. return(exit_status);
  2015. *val += pbottom;
  2016. return(FINISHED);
  2017. }
  2018. if((exit_status = doperm((int)BANDCNT,permindex,val,dz))<0)
  2019. return(exit_status);
  2020. k = *val;
  2021. bandwidth = (double)prange/(double)BANDCNT;
  2022. bandbottom = (double)k * bandwidth;
  2023. bandtop = (double)(k+1) * bandwidth;
  2024. ibandbottom = round(bandbottom);
  2025. ibandtop = round(bandtop);
  2026. ibandwidth = ibandtop - ibandbottom;
  2027. k = (int)(drand48() * (double)ibandwidth);
  2028. k += ibandbottom;
  2029. *val = k + pbottom;
  2030. return(FINISHED);
  2031. }
  2032. /******************************** SET_SHADBIT ****************************
  2033. *
  2034. * Set a bit in the shadow's bitfag.
  2035. */
  2036. void set_shadbit(int k,char *shadbits)
  2037. {
  2038. int bitunit = k/CHARBITSIZE;
  2039. int bitshift = k % 8;
  2040. int mask = 1;
  2041. mask <<= bitshift;
  2042. shadbits[bitunit] |= mask;
  2043. }
  2044. /****************************** GETHS_LOBND **********************************
  2045. *
  2046. * lobnd =< pitch
  2047. *
  2048. * Find the index of the harmonic-set note that is immediately below, or
  2049. * equal to the input pitch.
  2050. *
  2051. * NB CALL WITH geths_lobnd((double)thisnote->pitch);
  2052. *
  2053. * NB: If the entered pitch is lower than the entire HS, function returns -1.
  2054. */
  2055. int geths_lobnd(double thispitch,double *hs,int hsnotecnt)
  2056. {
  2057. int n;
  2058. for(n=0;n<hsnotecnt;n++) {
  2059. if(hs[n]>thispitch)
  2060. break;
  2061. }
  2062. return(--n); /* 1 */
  2063. }
  2064. /***************************** GETHFNOTE ************************************
  2065. *
  2066. * Read a note and store in harmonic field IF not already there.
  2067. */
  2068. int gethfnote(double thispitch,double *hf,int *hfnotecnt)
  2069. {
  2070. int n, OK = 0;
  2071. float notetransp = (float)fmod(thispitch,SEMITONES_PER_OCTAVE);
  2072. if(flteq((double)notetransp,0.0))
  2073. notetransp = (float)(notetransp + SEMITONES_PER_OCTAVE);
  2074. for(n=0;n<*hfnotecnt;n++) {
  2075. if(flteq((double)notetransp,hf[n])) {
  2076. OK = 1;
  2077. break;
  2078. }
  2079. }
  2080. if(!OK)
  2081. hf[*hfnotecnt] = (double)notetransp;
  2082. (*hfnotecnt)++;
  2083. return(FINISHED);
  2084. }
  2085. /**************************** SETMTFPARAMS *******************************
  2086. *
  2087. * Establish easy parameters of motif or ornament.
  2088. */
  2089. int setmtfparams
  2090. (noteptr thisnote,double thisamp,noteptr phrasenote,noteptr tsetnote,double ampdif,double notetime,
  2091. int gpsize,double multiplier,dataptr dz)
  2092. {
  2093. int exit_status;
  2094. if((exit_status = do_mtf_params(thisnote,thisamp,phrasenote,tsetnote,ampdif,notetime,multiplier,dz))<0)
  2095. return(exit_status);
  2096. return setspace(tsetnote,thisnote,gpsize,dz);
  2097. }
  2098. /**************************** INITIALISE_HFPHRASES *******************************/
  2099. int initialise_hfphrases
  2100. (int ***hfphrase,int **endhsindex,int **phrnotecnt,double **phraseamp,double **phrange,
  2101. noteptr **phrlastnote,dataptr dz)
  2102. {
  2103. if((*hfphrase = (int **)malloc(dz->tex->phrasecnt * sizeof(int *)))==NULL) {
  2104. sprintf(errstr,"INSUFFICIENT MEMORY for harmonic field phrases.\n");
  2105. return(MEMORY_ERROR);
  2106. }
  2107. if((*endhsindex = (int *)malloc(dz->tex->phrasecnt * sizeof(int)))==NULL) {
  2108. sprintf(errstr,"INSUFFICIENT MEMORY for harmonic set indices.\n");
  2109. return(MEMORY_ERROR);
  2110. }
  2111. if((*phrnotecnt = (int *)malloc(dz->tex->phrasecnt * sizeof(int)))==NULL) {
  2112. sprintf(errstr,"INSUFFICIENT MEMORY for harmonic field phrase notecnt.\n");
  2113. return(MEMORY_ERROR);
  2114. }
  2115. if((*phraseamp = (double *)malloc(dz->tex->phrasecnt * sizeof(double)))==NULL) {
  2116. sprintf(errstr,"INSUFFICIENT MEMORY for phrase amplitude array.\n");
  2117. return(MEMORY_ERROR);
  2118. }
  2119. if((*phrange = (double *)malloc(dz->tex->phrasecnt * sizeof(double)))==NULL) {
  2120. sprintf(errstr,"INSUFFICIENT MEMORY for phrase range array.\n");
  2121. return(MEMORY_ERROR);
  2122. }
  2123. if((*phrlastnote = (noteptr *)malloc(dz->tex->phrasecnt * sizeof(noteptr)))==NULL) {
  2124. sprintf(errstr,"INSUFFICIENT MEMORY for phrase lastnote array.\n");
  2125. return(MEMORY_ERROR);
  2126. }
  2127. return(FINISHED);
  2128. }
  2129. /****************************** GET_FIRST_HS ***********************************
  2130. *
  2131. * Extract HS from input data.
  2132. */
  2133. int get_first_hs(noteptr thisnote,double **hs,int *hsnotecnt)
  2134. {
  2135. int exit_status;
  2136. int size = BIGARRAY;
  2137. noteptr startnote = thisnote;
  2138. double thistime = 0.0;
  2139. if((*hs = (double *)malloc(BIGARRAY * sizeof(double)))==NULL) {
  2140. sprintf(errstr,"INSUFFICIENT MEMORY for harmonic set array.\n");
  2141. return(MEMORY_ERROR);
  2142. }
  2143. while(thisnote!=(noteptr)0) {
  2144. if((exit_status = gethsnote(thisnote->pitch,*hs,hsnotecnt))<0)
  2145. return(exit_status);
  2146. if(thisnote==startnote)
  2147. thistime = thisnote->ntime;
  2148. else {
  2149. if(!flteq((double)thisnote->ntime,thistime)) {
  2150. (*hsnotecnt)--;
  2151. break;
  2152. }
  2153. }
  2154. if(*hsnotecnt >= BIGARRAY) {
  2155. size += BIGARRAY;
  2156. if((*hs=(double *)realloc((char *)(*hs),size * sizeof(double)))==NULL){
  2157. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate harmonic set array.\n");
  2158. return(MEMORY_ERROR);
  2159. }
  2160. }
  2161. thisnote = thisnote->next;
  2162. }
  2163. if((*hs=(double *)realloc((char *)(*hs),*hsnotecnt*sizeof(double)))==NULL){
  2164. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate harmonic set array.\n");
  2165. return(MEMORY_ERROR);
  2166. }
  2167. upsort(*hs,*hsnotecnt);
  2168. return(FINISHED);
  2169. }
  2170. /****************************** GET_FIRST_HF ***********************************
  2171. *
  2172. * Extract first HF from input data.
  2173. */
  2174. int get_first_hf(noteptr thisnote,double **hf,int *hfnotecnt)
  2175. {
  2176. int exit_status;
  2177. int size = BIGARRAY;
  2178. noteptr startnote = thisnote;
  2179. double thistime = 0.0;
  2180. if((*hf = (double *)malloc(size * sizeof(double)))==NULL) {
  2181. sprintf(errstr,"INSUFFICIENT MEMORY for harmonic field array.\n");
  2182. return(MEMORY_ERROR);
  2183. }
  2184. while(thisnote!=(noteptr)0) {
  2185. if((exit_status = gethfnote(thisnote->pitch,*hf,hfnotecnt))<0)
  2186. return(exit_status);
  2187. if(thisnote==startnote)
  2188. thistime = thisnote->ntime;
  2189. else {
  2190. if(!flteq((double)thisnote->ntime,thistime)) {
  2191. (*hfnotecnt)--;
  2192. break;
  2193. }
  2194. }
  2195. if(*hfnotecnt >= size) {
  2196. size += BIGARRAY;
  2197. if((*hf = (double *)realloc((char *)(*hf),size * sizeof(double)))==NULL){
  2198. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate harmonic field array.\n");
  2199. return(MEMORY_ERROR);
  2200. }
  2201. }
  2202. thisnote = thisnote->next;
  2203. }
  2204. if((*hf=(double *)realloc((char *)(*hf),*hfnotecnt * sizeof(double)))==NULL){
  2205. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate harmonic field array.\n");
  2206. return(MEMORY_ERROR);
  2207. }
  2208. upsort(*hf,*hfnotecnt);
  2209. return(FINISHED);
  2210. }
  2211. /******************************** OCTEQ *************************************/
  2212. int octeq(double a,double b)
  2213. {
  2214. a = fmod(a,12.0);
  2215. b = fmod(b,12.0);
  2216. if(flteq(a,b)) {
  2217. return(1);
  2218. }
  2219. return(0);
  2220. }