texprepro.c 63 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661
  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 */
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <memory.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 <ctype.h>
  33. #include <sfsys.h>
  34. #include <osbind.h>
  35. #include <cdpmain.h>
  36. //#if defined unix || defined __GNUC__
  37. #define round(x) lround((x))
  38. //#endif
  39. #define omit_count is_rectified
  40. #define omit_item is_mapping
  41. #define one_in rampbrksize
  42. #define negscat fzeroset
  43. #define SQUASH (2.0) /* non-linearity factor */
  44. #define MAXPOSCNT (512) /* max no. of spatial positions between lspkrs */
  45. static int initialise_texture_structure(dataptr dz);
  46. static int set_up_and_fill_insample_buffers(insamptr **insound,dataptr dz);
  47. static int setup_texflag(texptr tex,dataptr dz);
  48. static int adjust_some_input_params(dataptr dz);
  49. static int preset_some_internal_texture_params(dataptr dz);
  50. static int install_unused_texture_flags(int *total_flags,int unused_flags,dataptr dz);
  51. static int install_the_internal_flags(int total_flags,int internal_flags,dataptr dz);
  52. static int get_the_notedata(texptr tex,dataptr dz);
  53. static int extend_timeset(dataptr dz);
  54. static int generate_timeset(dataptr dz);
  55. static int do_prespace(motifptr tset,dataptr dz);
  56. static int get_sample_pitches(FILE *fp,dataptr dz);
  57. static int get_motifs(FILE *fp,int *motifcnt,dataptr dz);
  58. static int motifchek(motifptr thismotif);
  59. static void convert_cmdline_instrnos_to_internal_representation(dataptr dz);
  60. static int check_max_transpos_compatible_with_splicelen(dataptr dz);
  61. static int set_amptype_params(dataptr dz);
  62. static int set_decor_pitchposition_params(dataptr dz);
  63. static void copy_note(noteptr thisnote,noteptr orignote);
  64. static int add_motif_to_end_of_motiflist(motifptr *new,dataptr dz);
  65. static int scatter_and_quantise_tset_times(double *lasttime,noteptr *thisnote,dataptr dz);
  66. static int pre_space(noteptr thisnote,dataptr dz);
  67. static int getpos(double thistime,double *position,dataptr dz);
  68. static int spread_and_set_cpos(double *position,double given_position,double spread,dataptr dz);
  69. static int chekrang(double *val);
  70. static int read_a_note_from_notedata_file
  71. (noteptr thisnote,int noteno,int motifno,double *lasttime,dataptr dz);
  72. static int generate_tset_times(double *thistime,noteptr *thisnote,dataptr dz);
  73. static int un_link_note(noteptr thisnote);
  74. static int new_motif(motifptr *thismotif);
  75. static int unlink_last_motif(motifptr thismotif);
  76. static void subtract_one_from_brkvals(int paramno,dataptr dz);
  77. static int bigscatter(noteptr *thisnote,double thistime,double timestep,double scatter,double *lasttime,dataptr dz);
  78. static int get_data_item(char *q,char **p,double *val);
  79. static int init_note(noteptr *thisnote);
  80. static void put_znote(noteptr thisnote);
  81. static int assign_timeset_hfset_motifsets(dataptr dz);
  82. static int massage_params(dataptr dz);
  83. static int init_motifs(dataptr dz);
  84. /************************* TEXTURE_PREPROCESS ****************************
  85. *
  86. * (1) Establish the bitflag which characterises the texture process.
  87. * (2) For consistency across all texture processes, all unused flags are mallocd.
  88. * This ensures that the numbering of the INTERNAL flags is consistent across all applics.
  89. * (3) Convert some input parameters to form used internally, and check some against insnd lengths.
  90. */
  91. int texture_preprocess(dataptr dz)
  92. {
  93. int exit_status;
  94. int total_flags, unused_flags, n;
  95. unsigned int texflag;
  96. initialise_random_sequence(0,TEXTURE_SEED,dz);
  97. if((exit_status = initialise_texture_structure(dz))<0)
  98. return(exit_status);
  99. if((exit_status = set_up_and_fill_insample_buffers(&(dz->tex->insnd),dz))<0)
  100. return(exit_status);
  101. if((exit_status = initperm(&(dz->tex->perm),dz))<0)
  102. return(exit_status);
  103. if((exit_status = setup_texflag(dz->tex,dz))<0) /* 1 */
  104. return(exit_status);
  105. texflag = dz->tex->txflag;
  106. if((exit_status = adjust_some_input_params(dz))<0)
  107. return(exit_status);
  108. if((exit_status = preset_some_internal_texture_params(dz))<0)
  109. return(exit_status);
  110. /* 2 */
  111. unused_flags = TOTAL_POSSIBLE_USER_FLAGS - dz->application->vflag_cnt;
  112. if((exit_status = install_unused_texture_flags(&total_flags,unused_flags,dz))<0)
  113. return(exit_status);
  114. if((exit_status = install_the_internal_flags(total_flags,INTERNAL_FLAGS_CNT,dz))<0)
  115. return(exit_status);
  116. if((exit_status = get_the_notedata(dz->tex,dz))<0)
  117. return(exit_status);
  118. if((exit_status = assign_timeset_hfset_motifsets(dz))<0)
  119. return(exit_status);
  120. if((exit_status = massage_params(dz))<0) /* 3 */
  121. return(exit_status);
  122. if(texflag & ORN_DEC_OR_TIMED) {
  123. if((exit_status = extend_timeset(dz))<0) /* 7 */
  124. return(exit_status);
  125. } else {
  126. if((exit_status = generate_timeset(dz))<0) /* 8 */
  127. return(exit_status);
  128. }
  129. if((exit_status = do_prespace(dz->tex->timeset,dz))<0)
  130. return(exit_status);
  131. if(dz->process == SIMPLE_TEX && dz->vflag[CYCLIC_TEXFLAG]) {
  132. if(dz->infilecnt < 2)
  133. dz->vflag[CYCLIC_TEXFLAG] = 0;
  134. else if (dz->vflag[PERM_TEXFLAG]) {
  135. if((dz->peakno = (int *)malloc(dz->infilecnt * sizeof(int))) == NULL) {
  136. sprintf(errstr,"Insufficient memory for cyclic permutations of input files.\n");
  137. return(MEMORY_ERROR);
  138. }
  139. if((dz->lastpeakno = (int *)malloc(dz->infilecnt * sizeof(int))) == NULL) {
  140. sprintf(errstr,"Insufficient memory for cyclic permutations of input files.\n");
  141. return(MEMORY_ERROR);
  142. }
  143. for(n=0;n<dz->infilecnt;n++) {
  144. dz->peakno[n] = n;
  145. dz->lastpeakno[n] = n;
  146. }
  147. }
  148. }
  149. /* create stereo outfile here! */
  150. /* RWD 4:2002 now we can open outfile with corect params! */
  151. //TW UPDATE to use stereo input means that dz->infile->channels must be retained for now
  152. //TW Open outfile later (texture5.c)
  153. return(FINISHED);
  154. }
  155. /*********************** INITIALISE_TEXTURE_STRUCTURE ******************************/
  156. int initialise_texture_structure(dataptr dz)
  157. {
  158. int n;
  159. if((dz->tex = (texptr)malloc(sizeof(struct textural)))==NULL) {
  160. sprintf(errstr,"INSUFFICIENT MEMORY for texture structure.\n");
  161. return(MEMORY_ERROR);
  162. }
  163. dz->tex->txflag = 0;
  164. dz->tex->motifhead = (motifptr)0;
  165. dz->tex->insnd = (insamptr *)0;
  166. dz->tex->timeset = (motifptr)0;
  167. dz->tex->hfldmotif = (motifptr)0;
  168. dz->tex->phrase = (motifptr *)0;
  169. dz->tex->perm = (int **)0;
  170. dz->tex->dectypstor = 0;
  171. dz->tex->dectypcnt = 0;
  172. dz->tex->amptypstor = 0;
  173. dz->tex->amptypcnt = 0;
  174. dz->tex->phrasecnt = 0;
  175. dz->tex->ampdirectd = FALSE;
  176. if((dz->tex->insnd = (insamptr *)malloc(dz->infilecnt * sizeof(insamptr)))==NULL) {
  177. sprintf(errstr,"INSUFFICIENT MEMORY for texture insound structure.\n");
  178. return(MEMORY_ERROR);
  179. }
  180. for(n=0;n<dz->infilecnt;n++) {
  181. dz->tex->insnd[n] = (insamptr)0;
  182. if((dz->tex->insnd[n]= (insamptr)malloc(sizeof(struct insample)))==NULL) {
  183. sprintf(errstr,"INSUFFICIENT MEMORY for texture insound[%d] structure.\n",n+1);
  184. return(MEMORY_ERROR);
  185. }
  186. }
  187. return(FINISHED);
  188. }
  189. /************************** SET_UP_AND_FILL_INSAMPLE_BUFFERS ****************************
  190. *
  191. * 1) Set buffer pointer to zero, until it has been malloced.
  192. * This make freeing of tex structure possible.
  193. */
  194. int set_up_and_fill_insample_buffers(insamptr **insound,dataptr dz)
  195. {
  196. int n;
  197. int samps_read;
  198. int thisbufsize;
  199. int wrap_around_samps = 1;
  200. for(n=0;n<dz->infilecnt;n++) {
  201. ((*insound)[n])->buffer = /*(float *)0*/NULL; /* 1 */
  202. thisbufsize = dz->insams[n];
  203. thisbufsize += wrap_around_samps;
  204. if((((*insound)[n])->buffer = (float *)malloc(thisbufsize * sizeof(float)))==NULL) {
  205. sprintf(errstr,"INSUFFICIENT MEMORY for texture insound buffer pointer %d.\n",n+1);
  206. return(MEMORY_ERROR);
  207. }
  208. memset((char *)((*insound)[n])->buffer,0,thisbufsize * sizeof(float));
  209. if((samps_read = fgetfbufEx(((*insound)[n])->buffer,thisbufsize,dz->ifd[n],0)) < 0) {
  210. sprintf(errstr,"Can't read sndfile %d to buffer: set_up_and_fill_insample_buffers()\n",n+1);
  211. return(SYSTEM_ERROR);
  212. }
  213. if(samps_read != dz->insams[n]) {
  214. sprintf(errstr,"Error reading sndfile %d to buf: set_up_and_fill_insample_buffers()\n",n+1);
  215. return(PROGRAM_ERROR);
  216. }
  217. }
  218. return(FINISHED);
  219. }
  220. /***************************** SETUP_TEXFLAG ****************************/
  221. int setup_texflag(texptr tex,dataptr dz)
  222. {
  223. tex->txflag = 0;
  224. switch(dz->process) {
  225. case(SIMPLE_TEX): break;
  226. case(GROUPS): tex->txflag |= IS_GROUPS; break;
  227. case(DECORATED): tex->txflag |= IS_DECOR; break;
  228. case(PREDECOR): tex->txflag |= IS_DECOR; tex->txflag |= ISPRE_DECORORN; break;
  229. case(POSTDECOR): tex->txflag |= IS_DECOR; tex->txflag |= ISPOST_DECORORN; break;
  230. case(ORNATE): tex->txflag |= IS_ORNATE; break;
  231. case(PREORNATE): tex->txflag |= IS_ORNATE; tex->txflag |= ISPRE_DECORORN; break;
  232. case(POSTORNATE): tex->txflag |= IS_ORNATE; tex->txflag |= ISPOST_DECORORN; break;
  233. case(MOTIFS): tex->txflag |= IS_MOTIFS; break;
  234. case(MOTIFSIN): tex->txflag |= IS_MOTIFS; tex->txflag |= MOTIF_IN_HF; break;
  235. case(TIMED): tex->txflag |= ISTIMED; break;
  236. case(TGROUPS): tex->txflag |= IS_GROUPS; tex->txflag |= ISTIMED; break;
  237. case(TMOTIFS): tex->txflag |= IS_MOTIFS; tex->txflag |= ISTIMED; break;
  238. case(TMOTIFSIN): tex->txflag |= IS_MOTIFS; tex->txflag |= MOTIF_IN_HF; tex->txflag |= ISTIMED; break;
  239. default:
  240. sprintf(errstr,"Unknown process in setup_texflag()\n");
  241. return(PROGRAM_ERROR);
  242. }
  243. switch(dz->mode) {
  244. case(TEX_NEUTRAL): break;
  245. case(TEX_HFIELD): tex->txflag |= ISHARM; break;
  246. case(TEX_HFIELDS): tex->txflag |= ISHARM; tex->txflag |= ISMANY_HFLDS; break;
  247. case(TEX_HSET): tex->txflag |= ISHARM; tex->txflag |= IS_HS; break;
  248. case(TEX_HSETS): tex->txflag |= ISHARM; tex->txflag |= IS_HS; tex->txflag |= ISMANY_HFLDS; break;
  249. default:
  250. sprintf(errstr,"Unknown mode in setup_texflag()\n");
  251. return(PROGRAM_ERROR);
  252. }
  253. return(FINISHED);
  254. }
  255. /************************** ADJUST_SOME_INPUT_PARAMS ****************************
  256. *
  257. * (1) dz->vflag[WHICH_CHORDNOTE] internally carries all 3 vals (first,highest,every).
  258. *
  259. * (2) Gprange, in cases with Hfields, is an integer count of HF-field notes to use.
  260. */
  261. int adjust_some_input_params(dataptr dz)
  262. {
  263. int texflag = dz->tex->txflag;
  264. if((texflag & IS_ORN_OR_DEC) && dz->vflag[FORCE_EVERY]==TRUE)
  265. dz->vflag[WHICH_CHORDNOTE] = DECOR_EVERY; /* 1 */
  266. if((texflag & IS_DEC_OR_GRP) && (texflag & ISHARM)) { /* 2 */
  267. dz->is_int[TEX_GPRANGLO] = TRUE;
  268. dz->is_int[TEX_GPRANGHI] = TRUE;
  269. dz->iparam[TEX_GPRANGLO] = round(dz->param[TEX_GPRANGLO]);
  270. dz->iparam[TEX_GPRANGHI] = round(dz->param[TEX_GPRANGHI]);
  271. }
  272. return(FINISHED);
  273. }
  274. /***************************** PRESET_SOME_INTERNAL_TEXTURE_PARAMS ****************************/
  275. int preset_some_internal_texture_params(dataptr dz)
  276. {
  277. int cnt = 0;
  278. dz->iparam[SPINIT] = 0; cnt++; /* ALL CLUMPS */
  279. dz->iparam[SPCNT] = 0; cnt++;
  280. dz->iparam[DIRECTION] = 0; cnt++;
  281. dz->param[CPOS] = 0.5; cnt++; /* for safety only */ /* SPATIALISATION */
  282. dz->param[TPOSITION] = 0.5; cnt++; /* for safety only */
  283. dz->param[THISSPRANGE]= 1.0; cnt++; /* full range */
  284. /*dz->iparam[TEX_MAXOUT]= 0.0; cnt++; *//* min value */
  285. dz->param[TEX_MAXOUT] = 0.0; cnt++; /*RWD*/
  286. if(cnt != dz->application->internal_param_cnt) {
  287. sprintf(errstr,"preset_some_internal_texture_params() has false count\n");
  288. return(PROGRAM_ERROR);
  289. }
  290. dz->itemcnt = 0;
  291. return(FINISHED);
  292. }
  293. /***************************** INSTALL_UNUSED_TEXTURE_FLAGS ****************************/
  294. int install_unused_texture_flags(int *total_flags,int unused_flags,dataptr dz)
  295. {
  296. int n;
  297. *total_flags = dz->application->vflag_cnt + unused_flags;
  298. if(unused_flags > 0) {
  299. if((dz->vflag =
  300. (char *)realloc(dz->vflag,(*total_flags) * sizeof(char)))==NULL) {
  301. sprintf(errstr,"INSUFFICIENT MEMORY for internal flags.\n");
  302. return(MEMORY_ERROR);
  303. }
  304. for(n=0;n<unused_flags;n++) {
  305. switch(n) {
  306. case(4): dz->vflag[2] = FALSE; break;
  307. case(3): dz->vflag[3] = FALSE; break;
  308. case(2): dz->vflag[4] = FALSE; break;
  309. case(1): dz->vflag[5] = FALSE; break;
  310. case(0): dz->vflag[6] = FALSE; break;
  311. }
  312. }
  313. }
  314. return(FINISHED);
  315. }
  316. /***************************** INSTALL_THE_INTERNAL_FLAGS ****************************/
  317. int install_the_internal_flags(int total_flags,int internal_flags,dataptr dz)
  318. {
  319. /* THESE FLAGS ARE NOT AVAILABLE TO USER : but they are used in the code */
  320. total_flags += internal_flags;
  321. if((dz->vflag =
  322. (char *)realloc(dz->vflag,total_flags * sizeof(char)))==NULL) {
  323. sprintf(errstr,"INSUFFICIENT MEMORY to reallocate internal flags.\n");
  324. return(MEMORY_ERROR);
  325. }
  326. dz->iparam[DECCENTRE] = FALSE;
  327. return(FINISHED);
  328. }
  329. /***************************** GET_THE_NOTEDATA ****************************/
  330. int get_the_notedata(texptr tex,dataptr dz)
  331. {
  332. int exit_status;
  333. unsigned int texflag = tex->txflag;
  334. int motifcnt, expected_motifcnt = 0;
  335. if(dz->fp==NULL) {
  336. sprintf(errstr,"notedata fileptr not initialised: get_the_notedata()\n");
  337. return(PROGRAM_ERROR);
  338. }
  339. if((exit_status = get_sample_pitches(dz->fp,dz))<0) {
  340. sprintf(errstr,"Insufficient pitch values in notedata file.\n");
  341. return(DATA_ERROR);
  342. }
  343. if((exit_status = get_motifs(dz->fp,&motifcnt,dz))<0)
  344. return(exit_status);
  345. if(texflag & ORN_DEC_OR_TIMED) expected_motifcnt++; /* Line to work on */
  346. if(texflag & ISHARM) expected_motifcnt++; /* HF data */
  347. if(texflag & IS_ORN_OR_MTF) expected_motifcnt++; /* Ornmnts or mtfs */
  348. if(texflag & IS_ORN_OR_MTF) {
  349. if(motifcnt < expected_motifcnt) {
  350. sprintf(errstr,"Insufficient motifs in notedata file.\n");
  351. return(DATA_ERROR);
  352. }
  353. } else {
  354. if(motifcnt!=expected_motifcnt) {
  355. sprintf(errstr,"Incorrect number [%d] of motifs in notedata file (expected %d).\n",
  356. motifcnt,expected_motifcnt);
  357. return(DATA_ERROR);
  358. }
  359. }
  360. return(FINISHED);
  361. }
  362. /**************************** EXTEND_TIMESET *******************************/
  363. int extend_timeset(dataptr dz)
  364. {
  365. int exit_status;
  366. int origcnt = 0, n;
  367. noteptr startnote = dz->tex->motifhead->firstnote;
  368. noteptr orignote, thisnote = startnote;
  369. double *timediff;
  370. if(startnote==(noteptr)0) {
  371. sprintf(errstr,"Problem in note timings: extend_timeset()\n");
  372. return(PROGRAM_ERROR);
  373. }
  374. while(thisnote!=(noteptr)0) {
  375. if(thisnote->ntime > dz->param[TEXTURE_DUR]) {
  376. delete_notes_here_and_beyond(thisnote);
  377. return(FINISHED);
  378. }
  379. thisnote = thisnote->next;
  380. origcnt++;
  381. }
  382. if((timediff = (double *)malloc(origcnt * sizeof(double)))==NULL) {
  383. sprintf(errstr,"INSUFFICIENT MEMORY for timegaps array.\n");
  384. return(MEMORY_ERROR);
  385. }
  386. n = 1;
  387. thisnote = startnote;
  388. while(thisnote->next !=(noteptr)0) {
  389. thisnote = thisnote->next;
  390. timediff[n++] = thisnote->ntime - thisnote->last->ntime;
  391. }
  392. if(dz->brksize[TEXTURE_SKIP]) {
  393. if((exit_status = read_value_from_brktable(thisnote->ntime,TEXTURE_SKIP,dz))<0) {
  394. free(timediff);
  395. return(exit_status);
  396. }
  397. }
  398. timediff[0] = dz->param[TEXTURE_SKIP];
  399. n = 0;
  400. orignote = startnote;
  401. for(;;) {
  402. if(thisnote->ntime > dz->param[TEXTURE_DUR] && timediff[n] > 0.0)
  403. break;
  404. if((exit_status = make_new_note(&thisnote))<0) {
  405. free(timediff);
  406. return(exit_status);
  407. }
  408. copy_note(thisnote,orignote);
  409. thisnote->ntime = (float)(thisnote->last->ntime + timediff[n]);
  410. if(++n>=origcnt) {
  411. if(dz->brksize[TEXTURE_SKIP]) {
  412. if((exit_status = read_value_from_brktable(thisnote->ntime,TEXTURE_SKIP,dz))<0) {
  413. free(timediff);
  414. return(exit_status);
  415. }
  416. timediff[0] = dz->param[TEXTURE_SKIP];
  417. }
  418. n = 0;
  419. orignote = startnote;
  420. } else
  421. orignote = orignote->next;
  422. }
  423. dz->brksize[TEXTURE_SKIP] = 0; /* prevent future reads */
  424. free(timediff);
  425. return(FINISHED);
  426. }
  427. /*********************************************************************
  428. *
  429. * (1) Generating the tset (set of timed values on or around which the
  430. * texture is to be generated).
  431. */
  432. /************************** GENERATE_TIMESET ******************************
  433. *
  434. * (A) Zero all other parameters besides time.
  435. */
  436. int generate_timeset(dataptr dz)
  437. {
  438. int exit_status;
  439. double lasttime, thistime = 0.0;
  440. noteptr thisnote;
  441. motifptr tset;
  442. if((exit_status = add_motif_to_end_of_motiflist(&(dz->tex->timeset),dz))<0)
  443. return(exit_status);
  444. tset = dz->tex->timeset;
  445. if((thisnote = tset->firstnote)==(noteptr)0) {
  446. sprintf(errstr,"Failure to find 1st note in motif: generate_timeset()\n");
  447. return(PROGRAM_ERROR);
  448. }
  449. put_znote(thisnote); /* A */
  450. thisnote->ntime = (float)thistime;
  451. if(dz->brksize[TEXTURE_PACK]) {
  452. if((exit_status = read_value_from_brktable(thistime,TEXTURE_PACK,dz))<0)
  453. return(exit_status);
  454. }
  455. thistime += dz->param[TEXTURE_PACK];
  456. while(thistime<dz->param[TEXTURE_DUR]) {
  457. if((exit_status = generate_tset_times(&thistime,&thisnote,dz))<0)
  458. return(exit_status);
  459. put_znote(thisnote); /* A */
  460. }
  461. thisnote = tset->firstnote;
  462. lasttime = thisnote->ntime;
  463. thisnote = thisnote->next;
  464. dz->omit_count = 0;
  465. dz->omit_item = 0;
  466. dz->negscat = -1; // Initialisation
  467. while(thisnote!=(noteptr)0) {
  468. if((exit_status = scatter_and_quantise_tset_times(&lasttime,&thisnote,dz))<0)
  469. return(exit_status);
  470. }
  471. dz->brksize[TEXTURE_PACK] = 0; /* set these brktables to appear empty, so no read attempts later */
  472. dz->brksize[TEXTURE_SCAT] = 0;
  473. dz->brksize[TEXTURE_TGRID] = 0;
  474. if(dz->process == SIMPLE_TEX)
  475. dz->brksize[TEX_PHGRID] = 0;
  476. return(FINISHED);
  477. }
  478. /***************************** DO_PRESPACE ******************************
  479. *
  480. * Spatialise the time set, prior to output phase&/or ornamentation.
  481. */
  482. int do_prespace(motifptr tset,dataptr dz)
  483. {
  484. int exit_status;
  485. noteptr thisnote = tset->firstnote;
  486. while(thisnote!=(noteptr)0) {
  487. if((exit_status = pre_space(thisnote,dz))<0)
  488. return(exit_status);
  489. thisnote = thisnote->next;
  490. }
  491. return(FINISHED);
  492. }
  493. /**************************** GET_SAMPLE_PITCHES *****************************/
  494. int get_sample_pitches(FILE *fp,dataptr dz)
  495. {
  496. int exit_status;
  497. /* TW AUGUST 2006: 200--> 2000 */
  498. char temp[200000], *q;
  499. int pitchcnt = 0;
  500. double *p;
  501. int got_all_pitches = FALSE;
  502. /* TW AUGUST 2006: 200--> 2000 */
  503. while(!got_all_pitches && (fgets(temp,200000,fp)!=NULL)) {
  504. q = temp;
  505. if(*q == ';') // Allow comments in file
  506. continue;
  507. p = &(((dz->tex->insnd)[pitchcnt])->pitch);
  508. while((exit_status = get_float_from_within_string(&q,p))==TRUE) {
  509. if(++pitchcnt >= dz->infilecnt) {
  510. got_all_pitches = TRUE;
  511. break;
  512. }
  513. p = &(((dz->tex->insnd)[pitchcnt])->pitch);
  514. }
  515. if(exit_status==FALSE)
  516. return(DATA_ERROR);
  517. }
  518. if(!got_all_pitches)
  519. return(DATA_ERROR);
  520. return(FINISHED);
  521. }
  522. /**************************** GET_MOTIFS *****************************
  523. *
  524. * Read data from an ascii file to notelist.
  525. */
  526. int get_motifs(FILE *fp,int *motifcnt,dataptr dz)
  527. {
  528. int exit_status;
  529. motifptr thismotif;
  530. noteptr thisnote;
  531. char *p, temp[200];
  532. double lasttime = 0.0;
  533. int datalen, noteno, motifno = 0;
  534. if((exit_status = init_motifs(dz))<0) /* 8 */
  535. return(exit_status);
  536. thismotif = dz->tex->motifhead;
  537. while(fgets(temp,200,fp)!=NULL) {
  538. p = temp;
  539. while(isspace(*p))
  540. p++;
  541. if(*p==ENDOFSTR)
  542. continue;
  543. if(*p!=TEXTURE_SEPARATOR) {
  544. //TW UPDATE
  545. sprintf(errstr,"'%c' missing before datacount in notedata file: motif %d (or more notes listed than indicated by %cN)\n"
  546. "check datalen is correct\n",TEXTURE_SEPARATOR,motifno+1,TEXTURE_SEPARATOR);
  547. return(DATA_ERROR);
  548. }
  549. p++;
  550. if(!isdigit(*p) || sscanf(p,"%d",&datalen)!=1) {
  551. sprintf(errstr,"No datalength given: motif %d\n",motifno+1);
  552. return(DATA_ERROR);
  553. }
  554. if(datalen <= 0) {
  555. sprintf(errstr,"Invalid data length %d in notedata: motif %d\n",datalen,motifno+1);
  556. return(DATA_ERROR);
  557. }
  558. motifno++;
  559. thisnote = thismotif->firstnote;
  560. for(noteno=1;noteno<=datalen;noteno++) {
  561. if((exit_status = read_a_note_from_notedata_file(thisnote,noteno,motifno,&lasttime,dz))<0)
  562. return(exit_status);
  563. if(exit_status==CONTINUE) {
  564. noteno--;
  565. continue;
  566. }
  567. if((exit_status = make_new_note(&thisnote))<0)
  568. return(exit_status);
  569. }
  570. if((exit_status = un_link_note(thisnote))<0)
  571. return(exit_status);
  572. if((exit_status = new_motif(&thismotif))<0)
  573. return(exit_status);
  574. }
  575. *motifcnt = motifno;
  576. if(motifno > 0)
  577. return unlink_last_motif(thismotif);
  578. return(FINISHED);
  579. }
  580. /************************** MOTIFCHEK ********************************
  581. *
  582. * Check we've not run out of motifs.
  583. */
  584. int motifchek(motifptr thismotif)
  585. {
  586. if(thismotif == (motifptr)0) {
  587. sprintf(errstr,"motifchek(): Insufficient motifs: even though correctly counted.\n");
  588. return(PROGRAM_ERROR);
  589. }
  590. return(FINISHED);
  591. }
  592. /***************************** CONVERT_CMDLINE_INSTRNOS_TO_INTERNAL_REPRESENTATION ****************************/
  593. void convert_cmdline_instrnos_to_internal_representation(dataptr dz)
  594. {
  595. if(dz->brksize[TEXTURE_INSLO])
  596. subtract_one_from_brkvals(TEXTURE_INSLO,dz);
  597. else
  598. dz->iparam[TEXTURE_INSLO]--;
  599. if(dz->brksize[TEXTURE_INSHI])
  600. subtract_one_from_brkvals(TEXTURE_INSHI,dz);
  601. else
  602. dz->iparam[TEXTURE_INSHI]--;
  603. }
  604. /***************************** CHECK_MAX_TRANSPOS_COMPATIBLE_WITH_SPLICELEN ****************************/
  605. int check_max_transpos_compatible_with_splicelen(dataptr dz)
  606. {
  607. int n, exit_status;
  608. double max_maxpitch, max_minpitch, max_transpospitch, maxupshift, upratio, minlen;
  609. double min_sndlength = (TEXTURE_SPLICELEN + TEXTURE_SAFETY) * MS_TO_SECS * (double)dz->infile->srate;
  610. dz->frametime = TEXTURE_SPLICELEN;
  611. if(dz->brksize[TEXTURE_MAXPICH]) {
  612. if((exit_status = get_maxvalue_in_brktable(&max_maxpitch,TEXTURE_MAXPICH,dz))<0)
  613. return(exit_status);
  614. } else
  615. max_maxpitch = dz->param[TEXTURE_MAXPICH];
  616. if(dz->brksize[TEXTURE_MINPICH]) {
  617. if((exit_status = get_maxvalue_in_brktable(&max_minpitch,TEXTURE_MINPICH,dz))<0)
  618. return(exit_status);
  619. } else
  620. max_minpitch = dz->param[TEXTURE_MINPICH];
  621. max_transpospitch = max(max_minpitch,max_maxpitch);
  622. dz->zeroset = 0; /* use as flag re splicelen change */
  623. for(n=0;n<dz->infilecnt;n++) {
  624. maxupshift = max_transpospitch - ((dz->tex->insnd)[n])->pitch;
  625. upratio = pow(2.0,(maxupshift/SEMITONES_PER_OCTAVE));
  626. minlen = (double)dz->insams[n]/upratio;
  627. if(minlen < min_sndlength) {
  628. dz->frametime = 2.0;
  629. min_sndlength = (dz->frametime + TEXTURE_SAFETY) * MS_TO_SECS * (double)dz->infile->srate;
  630. #ifdef MINDUR_OVERRIDE
  631. min_sndlength = 0.0;
  632. #endif
  633. if(minlen < min_sndlength) {
  634. dz->frametime = 1.0;
  635. min_sndlength = (dz->frametime + TEXTURE_SAFETY) * MS_TO_SECS * (double)dz->infile->srate;
  636. if(minlen < min_sndlength) {
  637. sprintf(errstr,"sndfile %d [%.3lf secs] too short for max upward transposition [ratio %.2lf].\n",
  638. n+1,(double)dz->insams[n]/(double)dz->infile->srate,upratio);
  639. return(DATA_ERROR);
  640. }
  641. }
  642. }
  643. }
  644. return(FINISHED);
  645. }
  646. /************************* SET_AMPTYPE_PARAMS *******************************/
  647. int set_amptype_params(dataptr dz)
  648. { int mask = 1, n;
  649. dz->tex->amptypcnt = 0;
  650. dz->tex->amptypstor = 0;
  651. switch(dz->iparam[TEX_AMPCONT]) {
  652. case(IS_MIXED): dz->tex->amptypstor |= 1; dz->tex->amptypstor |= 2; break;
  653. case(IS_CRESC): dz->tex->amptypstor |= 2; break;
  654. case(IS_FLAT): dz->tex->amptypstor |= 1; break;
  655. case(IS_DECRESC): dz->tex->amptypstor |= 4; break;
  656. case(IS_FLAT_AND_CRESC): dz->tex->amptypstor |= 1; dz->tex->amptypstor |= 2; break;
  657. case(IS_CRESC_AND_DECRESC): dz->tex->amptypstor |= 2; dz->tex->amptypstor |= 4; break;
  658. case(IS_FLAT_AND_DECRESC): dz->tex->amptypstor |= 1; dz->tex->amptypstor |= 4; break;
  659. case(IS_DIRECTIONAL): dz->tex->ampdirectd = TRUE; dz->tex->amptypcnt = 1; break;
  660. case(IS_DIREC_OR_FLAT): dz->tex->ampdirectd = TRUE; dz->tex->amptypcnt = 2; break;
  661. default:
  662. sprintf(errstr,"Unknown case in set_amptype_params()\n");
  663. return(PROGRAM_ERROR);
  664. }
  665. if(dz->tex->amptypstor > 0) {
  666. for(n=0;n<3;n++) {
  667. if(mask & dz->tex->amptypstor)
  668. dz->tex->amptypcnt++;
  669. mask <<= 1;
  670. }
  671. }
  672. return(FINISHED);
  673. }
  674. /************************* SET_DECOR_PITCHPOSITION_PARAMS ******************************/
  675. int set_decor_pitchposition_params(dataptr dz)
  676. {
  677. int n, mask = 1;
  678. dz->tex->dectypstor = 0;
  679. dz->tex->dectypcnt = 0;
  680. switch(dz->iparam[TEX_DECPCENTRE]) {
  681. case(DEC_CENTRED): dz->tex->dectypstor |= 1; break;
  682. case(DEC_ABOVE): dz->tex->dectypstor |= 2; break;
  683. case(DEC_BELOW): dz->tex->dectypstor |= 4; break;
  684. case(DEC_C_A): dz->tex->dectypstor |= 1; dz->tex->dectypstor |= 2; break;
  685. case(DEC_C_B): dz->tex->dectypstor |= 1; dz->tex->dectypstor |= 4; break;
  686. case(DEC_A_B): dz->tex->dectypstor |= 2; dz->tex->dectypstor |= 4; break;
  687. case(DEC_C_A_B): dz->tex->dectypstor |= 1; dz->tex->dectypstor |= 2; dz->tex->dectypstor |= 4; break;
  688. default:
  689. sprintf(errstr,"Unknown case in set_decor_pitchposition_params()\n");
  690. return(PROGRAM_ERROR);
  691. }
  692. if(dz->tex->dectypstor > 0) {
  693. for(n=0;n<3;n++) {
  694. if(mask & dz->tex->dectypstor)
  695. dz->tex->dectypcnt++;
  696. mask <<= 1;
  697. }
  698. }
  699. return(FINISHED);
  700. }
  701. /********************** DELETE_NOTES_HERE_AND_BEYOND *******************************
  702. void delete_notes_here_and_beyond(noteptr startnote)
  703. {
  704. noteptr here = startnote;
  705. if(here==(noteptr)0)
  706. return;
  707. while(here->next!=(noteptr)0)
  708. here=here->next;
  709. while(here!=startnote) {
  710. here=here->last;
  711. free(here->next);
  712. }
  713. if(startnote->last!=(noteptr)0)
  714. startnote->last->next = (noteptr)0;
  715. free(startnote);
  716. }
  717. ****/
  718. /********************** MAKE_NEW_NOTE ****************************
  719. *
  720. * Create new link in note list.
  721. */
  722. int make_new_note(noteptr *thisnote)
  723. {
  724. if(((*thisnote)->next = (noteptr)malloc(sizeof(struct nnote)))==NULL) {
  725. sprintf(errstr,"INSUFFICIENT MEMORY for a further note store.\n");
  726. return(MEMORY_ERROR);
  727. }
  728. (*thisnote)->next->last = *thisnote;
  729. *thisnote = (*thisnote)->next;
  730. (*thisnote)->next = (noteptr)0;
  731. return(FINISHED);
  732. }
  733. /**************************** COPY_NOTE *******************************/
  734. void copy_note(noteptr thisnote,noteptr orignote)
  735. {
  736. thisnote->ntime = orignote->ntime;
  737. thisnote->amp = orignote->amp;
  738. thisnote->pitch = orignote->pitch;
  739. thisnote->dur = orignote->dur;
  740. thisnote->instr = orignote->instr;
  741. thisnote->spacepos = orignote->spacepos;
  742. thisnote->motioncentre = orignote->motioncentre;
  743. }
  744. /************************** ADD_MOTIF_TO_END_OF_MOTIFLIST ******************************
  745. *
  746. * Create new motif at end of list.
  747. */
  748. int add_motif_to_end_of_motiflist(motifptr *new,dataptr dz)
  749. {
  750. int exit_status;
  751. motifptr here = dz->tex->motifhead;
  752. while(here->next!=(motifptr)0)
  753. here = here->next;
  754. if((exit_status = new_motif(&here))<0)
  755. return(exit_status);
  756. *new = here;
  757. return(FINISHED);
  758. }
  759. /************************* SCATTER_AND_QUANTISE_TSET_TIMES ******************************/
  760. //
  761. //int scatter_and_quantise_tset_times(double *lasttime,noteptr *thisnote,dataptr dz)
  762. //{
  763. // int exit_status;
  764. // double thistime = (*thisnote)->ntime; /* 1 */
  765. // double timestep = thistime - *lasttime; /* 2 */
  766. // *lasttime = thistime; /* 2a */
  767. // if(dz->brksize[TEXTURE_SCAT]) {
  768. // if((exit_status = read_value_from_brktable(thistime,TEXTURE_SCAT,dz))<0)
  769. // return(exit_status);
  770. // }
  771. // if(dz->param[TEXTURE_SCAT]>1.0) { /* 3a */
  772. // if((exit_status = bigscatter(thisnote,thistime,timestep,dz->param[TEXTURE_SCAT],lasttime,dz))<0)
  773. // return(exit_status);
  774. // } else {
  775. // if(!flteq(dz->param[TEXTURE_SCAT],0.0)) /* 4 */
  776. // thistime -= (float)(drand48() * dz->param[TEXTURE_SCAT] * timestep);
  777. //
  778. // if(dz->param[TEXTURE_TGRID]>0.0)
  779. // thistime = quantise(thistime,dz->param[TEXTURE_TGRID]); /* 6 */
  780. // (*thisnote)->ntime = (float)thistime;
  781. // }
  782. // *thisnote = (*thisnote)->next;
  783. // return(FINISHED); /* 8a */
  784. //}
  785. //
  786. /************************* SCATTER_AND_QUANTISE_TSET_TIMES ******************************/
  787. int scatter_and_quantise_tset_times(double *lasttime,noteptr *thisnote,dataptr dz)
  788. {
  789. int exit_status;
  790. double thistime = (*thisnote)->ntime; /* 1 */
  791. double timestep = thistime - *lasttime; /* 2 */
  792. noteptr lastnote, priornote;
  793. *lasttime = thistime; /* 2a */
  794. if(dz->brksize[TEXTURE_SCAT]) {
  795. if((exit_status = read_value_from_brktable(thistime,TEXTURE_SCAT,dz))<0)
  796. return(exit_status);
  797. }
  798. if(dz->param[TEXTURE_SCAT]>1.0) { /* 3a */
  799. if((exit_status = bigscatter(thisnote,thistime,timestep,dz->param[TEXTURE_SCAT],lasttime,dz))<0)
  800. return(exit_status);
  801. } else {
  802. if(!flteq(dz->param[TEXTURE_SCAT],0.0)) /* 4 */
  803. thistime -= (float)(drand48() * dz->param[TEXTURE_SCAT] * timestep);
  804. if(dz->param[TEXTURE_TGRID]>0.0)
  805. thistime = quantise(thistime,dz->param[TEXTURE_TGRID]); /* 6 */
  806. (*thisnote)->ntime = (float)thistime;
  807. }
  808. if(dz->brksize[TEX_PHGRID]) {
  809. if((exit_status = read_value_from_brktable(thistime,TEX_PHGRID,dz))<0)
  810. return(exit_status);
  811. dz->one_in = (int)ceil(dz->param[TEX_PHGRID]);
  812. } else
  813. dz->one_in = dz->iparam[TEX_PHGRID];
  814. dz->one_in %= 64; // Omit 1 in 63, goes to omit none (at value 64)
  815. if(dz->one_in == 0) { // No omissions: go to next note
  816. dz->omit_count = 0;
  817. *thisnote = (*thisnote)->next;
  818. } else {
  819. dz->one_in = max(dz->one_in,2); // dz->one_in cannot be less than 2
  820. if(dz->omit_count == dz->omit_item) { // If this is item to omit
  821. lastnote = *thisnote;
  822. *thisnote = (*thisnote)->next; // Go to next note
  823. priornote = lastnote->last; // Unlink last note
  824. priornote->next = *thisnote;
  825. if(*thisnote != NULL)
  826. (*thisnote)->last = priornote;
  827. free(lastnote);
  828. } else // Else don't omit this note
  829. *thisnote = (*thisnote)->next; // Just go to next note
  830. dz->omit_count++; // Advance counter in omit-size group.
  831. if(dz->omit_count >= dz->one_in) { // Once the group has been used up
  832. dz->omit_count = 0; // Reset noteset-group counter, and determine (by random selection)
  833. if(dz->param[TEXTURE_SEED] < 32)
  834. dz->omit_item = (int)floor(drand48() * dz->one_in); // event to drop in next dz->one_in events.
  835. }
  836. return FINISHED;
  837. }
  838. return(FINISHED); /* 8a */
  839. }
  840. /************************* SCATTER_AND_QUANTISE_TSET_TIMES ******************************/
  841. //
  842. //int scatter_and_quantise_tset_times(double *lasttime,noteptr *thisnote,dataptr dz)
  843. //{
  844. // int exit_status;
  845. // double thistime = (*thisnote)->ntime; /* 1 */
  846. // double timestep = thistime - *lasttime; /* 2 */
  847. // noteptr lastnote, priornote;
  848. // double thisscat;
  849. // *lasttime = thistime; /* 2a */
  850. // if(dz->brksize[TEXTURE_SCAT]) {
  851. // dz->negscat = 0;
  852. // if((exit_status = read_value_from_brktable(thistime,TEXTURE_SCAT,dz))<0)
  853. // return(exit_status);
  854. // if(dz->param[TEXTURE_SCAT] < 0.0)
  855. // dz->negscat = 1;
  856. // } else if(dz->negscat < 0) { // Initialise negative-scattering, where not a trime-variable pscatter param
  857. // dz->negscat = 0;
  858. // if(dz->param[TEXTURE_SCAT] < 0.0)
  859. // dz->negscat = 1;
  860. // }
  861. // if (dz->negscat) { // -3.1 becomes scatter = 0.1 ,events-to-drop = 1-in-3
  862. // thisscat = -dz->param[TEXTURE_SCAT];
  863. // dz->one_in = (int)floor(thisscat); // Proportion of events to be dropped = 1 in dz->one_in
  864. // thisscat -= dz->one_in; // Scatter to be used
  865. // dz->one_in = max(dz->one_in,2); // dz->one_in cannot be less than 2
  866. //
  867. // if(dz->omit_count == dz->omit_item) { // If this is item to omit
  868. // lastnote = *thisnote;
  869. // *thisnote = (*thisnote)->next; // Go to next note
  870. // priornote = lastnote->last; // Unlink last note
  871. // priornote->next = *thisnote;
  872. // (*thisnote)->last = priornote;
  873. // free(lastnote);
  874. // } else { // Otherwise, scatter event time
  875. // if(!flteq(thisscat,0.0))
  876. // thistime -= (float)(drand48() * thisscat * timestep);
  877. // if(dz->param[TEXTURE_TGRID]>0.0) // (and quantise if ness)
  878. // thistime = quantise(thistime,dz->param[TEXTURE_TGRID]);
  879. // (*thisnote)->ntime = (float)thistime;
  880. // *thisnote = (*thisnote)->next; // and go to next note
  881. // }
  882. // dz->omit_count++; // Advance counter in omit-size group.
  883. // if(dz->omit_count >= dz->one_in) { // Once the group has been used up
  884. // dz->omit_count = 0; // Reset noteset-group counter, and determine (by random selection)
  885. // if(dz->param[TEXTURE_SEED] < 32)
  886. // dz->omit_item = (int)floor(drand48() * dz->one_in); // event to drop in next dz->one_in events.
  887. // }
  888. // return FINISHED;
  889. // } else if(dz->param[TEXTURE_SCAT]>1.0) { /* 3a */
  890. ////TW UPDATE (original code error)
  891. // if((exit_status = bigscatter(thisnote,thistime,timestep,dz->param[TEXTURE_SCAT],lasttime,dz))<0)
  892. // return(exit_status);
  893. // } else {
  894. // if(!flteq(dz->param[TEXTURE_SCAT],0.0)) /* 4 */
  895. // thistime -= (float)(drand48() * dz->param[TEXTURE_SCAT] * timestep);
  896. //
  897. // if(dz->param[TEXTURE_TGRID]>0.0)
  898. // thistime = quantise(thistime,dz->param[TEXTURE_TGRID]); /* 6 */
  899. // (*thisnote)->ntime = (float)thistime;
  900. // }
  901. // *thisnote = (*thisnote)->next;
  902. // return(FINISHED); /* 8a */
  903. //}
  904. /************************** PRE_SPACE ********************************
  905. *
  906. * Store spatial data in the tsetnote spacepos and motioncentre.
  907. */
  908. int pre_space(noteptr thisnote,dataptr dz)
  909. {
  910. int exit_status;
  911. double position;
  912. if((exit_status = getpos((double)thisnote->ntime,&position,dz))<0)
  913. return(exit_status);
  914. thisnote->spacepos = (float)position;
  915. thisnote->motioncentre = (float)dz->param[CPOS];
  916. return(FINISHED);
  917. }
  918. /************************** GETPOS ****************************
  919. *
  920. * Calculate spatial position of event from it's time.
  921. */
  922. int getpos(double thistime,double *position,dataptr dz)
  923. {
  924. int exit_status;
  925. if(dz->brksize[TEXTURE_POS] && (exit_status = read_value_from_brktable(thistime,TEXTURE_POS,dz))<0)
  926. return(exit_status);
  927. if(dz->brksize[TEXTURE_SPRD] && (exit_status = read_value_from_brktable(thistime,TEXTURE_SPRD,dz))<0)
  928. return(exit_status);
  929. if(dz->param[TEXTURE_SPRD] > 0.0) {
  930. if((exit_status = spread_and_set_cpos(position,dz->param[TEXTURE_POS],dz->param[TEXTURE_SPRD],dz))<0)
  931. return(exit_status);
  932. } else {
  933. /* NOV 1997--> */
  934. dz->param[CPOS] = dz->param[TEXTURE_POS];
  935. /* <--NOV 1997 */
  936. *position = dz->param[TEXTURE_POS];
  937. }
  938. return(FINISHED);
  939. }
  940. /***************************** SPREAD_AND_SET_CPOS *****************************/
  941. int spread_and_set_cpos(double *position,double given_position,double spread,dataptr dz)
  942. {
  943. int exit_status;
  944. int posno, spswitch;
  945. int poscnt,hposcnt;
  946. double hspread,spacing, closeness, squash;
  947. /* total stereospace has MAXPOSCNT positions: calc no. & spacing of positions available at given spread */
  948. poscnt = round(spread * (double)MAXPOSCNT);
  949. hposcnt = poscnt/2;
  950. hspread = spread/(double)2.0;
  951. if(hposcnt != 0)
  952. spacing = hspread/(double)hposcnt;
  953. else {
  954. /* bandwidth effectively zero: return given position */
  955. dz->param[CPOS] = given_position;
  956. *position = given_position;
  957. return(FINISHED);
  958. }
  959. /* randomly select leftwards/rightwards of the given position */
  960. if((exit_status = doperm(2,PM_SPACE,&spswitch,dz))<0)
  961. return(exit_status);
  962. if(!spswitch)
  963. spswitch = -1;
  964. /* randomly chose a pos (to left or right) around centre pos */
  965. posno = round(drand48() * hposcnt);
  966. posno *= spswitch;
  967. /* calculate warping coefficient to avoid position-spread leaking over edges of stereo-space */
  968. if(spread>(double)1.0/SQUASH)
  969. squash = (double)1.0/spread;
  970. else
  971. squash = SQUASH;
  972. /* If (position+spread) leaks to right of stereo-space : squeeze position */
  973. if(given_position>=0.5 && (given_position + spread) > 1.0) {
  974. closeness = (given_position - 0.5)/(double)0.5;
  975. dz->param[CPOS] = given_position - (hspread*pow(closeness,squash));
  976. /* If (position+spread) leaks to left of stereo-space : squeeze position */
  977. } else if(given_position<0.5 && given_position < spread) {
  978. closeness = (0.5 - given_position)/(double)0.5;
  979. dz->param[CPOS] = given_position + (hspread*pow(closeness,squash));
  980. } else
  981. dz->param[CPOS] = given_position;
  982. /* generate true position, around central position */
  983. *position = dz->param[CPOS] + ((double)posno * spacing);
  984. return chekrang(position);
  985. }
  986. /*************************** CHEKRANG **************************
  987. *
  988. * Check variable lies within range 0.0 to 1.0.
  989. */
  990. int chekrang(double *val)
  991. {
  992. if(flteq(*val,1.0))
  993. *val = 1.0;
  994. if(flteq(*val,0.0))
  995. *val = 0.0;
  996. if(*val<0.0 || *val>1.0) {
  997. sprintf(errstr,"value [%f] outside range 0-1: chekrang()\n",*val);
  998. return(PROGRAM_ERROR);
  999. }
  1000. return(FINISHED);
  1001. }
  1002. /************************** READ_A_NOTE_FROM_NOTEDATA_FILE ********************************/
  1003. int read_a_note_from_notedata_file(noteptr thisnote,int noteno,int motifno,double *lasttime,dataptr dz)
  1004. {
  1005. int exit_status;
  1006. unsigned int texflag = dz->tex->txflag;
  1007. char temp[200], *p, *q;
  1008. double val;
  1009. int /*instr_no,*/ start;
  1010. if(dz->fp==NULL) {
  1011. sprintf(errstr,"Note datafile descriptor not initialised: read_a_note_from_notedata_file()\n");
  1012. return(PROGRAM_ERROR);
  1013. }
  1014. if(fgets(temp,200,dz->fp)==NULL){
  1015. sprintf(errstr,"Note data line for note %d, motif %d missing in notedatafile\n",noteno,motifno);
  1016. return(DATA_ERROR);
  1017. }
  1018. p =temp;
  1019. while(isspace(*p))
  1020. p++;
  1021. q = p;
  1022. if(*q==ENDOFSTR)
  1023. return(CONTINUE);
  1024. if((exit_status = get_data_item(q,&p,&val))<0) {
  1025. sprintf(errstr,"No time data for note %d, motif %d in notedatafile\n",noteno,motifno);
  1026. return(DATA_ERROR);
  1027. }
  1028. if(exit_status==FINISHED) {
  1029. sprintf(errstr,"No data after time for note %d, motif %d in notedatafile\n",noteno,motifno);
  1030. return(DATA_ERROR);
  1031. }
  1032. thisnote->ntime = (float)val;
  1033. if((noteno > 1) && (*lasttime > thisnote->ntime)) {
  1034. sprintf(errstr,"Notes in reverse time order: notedata file : motif %d: notes %d & %d\n",
  1035. motifno,noteno,noteno-1);
  1036. return(DATA_ERROR);
  1037. }
  1038. *lasttime = thisnote->ntime;
  1039. p++;
  1040. q = p;
  1041. if((exit_status = get_data_item(q,&p,&val))<0) {
  1042. sprintf(errstr,"No instr_no for note %d, motif %d in notedatafile\n",noteno,motifno);
  1043. return(DATA_ERROR);
  1044. }
  1045. if(exit_status==FINISHED) {
  1046. sprintf(errstr,"No data after instr_no for note %d, motif %d in notedatafile\n",noteno,motifno);
  1047. return(DATA_ERROR);
  1048. }
  1049. // instr_no = round(val);
  1050. p++;
  1051. q = p;
  1052. if((exit_status = get_data_item(q,&p,&val))<0) {
  1053. sprintf(errstr,"No pitch data for note %d, motif %d in notedatafile\n",noteno,motifno);
  1054. return(DATA_ERROR);
  1055. }
  1056. if(exit_status==FINISHED) {
  1057. sprintf(errstr,"No data after pitch for note %d, motif %d in notedatafile\n",noteno,motifno);
  1058. return(DATA_ERROR);
  1059. }
  1060. thisnote->pitch = (float)val;
  1061. /* NEEDS TESTING FOR MIDIRANGE: EXCEPT IN TIMING SET CASE */
  1062. if(!(texflag & ISTIMED) || motifno!=1) {
  1063. if(val < MIDIMIN || val > MIDIMAX) {
  1064. sprintf(errstr,"pitch value [%lf] out of range (%d to %d): motif %d: note %d\n",
  1065. val,MIDIMIN,MIDIMAX,motifno,noteno);
  1066. return(DATA_ERROR);
  1067. }
  1068. }
  1069. p++;
  1070. q = p;
  1071. if((exit_status = get_data_item(q,&p,&val))<0) {
  1072. sprintf(errstr,"No amplitude data for note %d, motif %d in notedatafile\n",noteno,motifno);
  1073. return(DATA_ERROR);
  1074. }
  1075. if(exit_status==FINISHED) {
  1076. sprintf(errstr,"No data after amp for note %d, motif %d in notedatafile\n",noteno,motifno);
  1077. return(DATA_ERROR);
  1078. }
  1079. thisnote->amp = (float)val;
  1080. /* 1999 THIS NEEDS TESTING FOR MIDIRANGE EXCEPT IN TIMING SET CASE */
  1081. if(!(texflag & ISTIMED) || motifno!=1) {
  1082. if(val < MIDIMIN || val > MIDIMAX) {
  1083. sprintf(errstr,"amplitude value [%lf] out of range (%d to %d): motif %d: note %d\n",
  1084. val,MIDIMIN,MIDIMAX,motifno,noteno);
  1085. return(DATA_ERROR);
  1086. }
  1087. }
  1088. p++;
  1089. q = p;
  1090. if((exit_status = get_data_item(q,&p,&val))<0) {
  1091. sprintf(errstr,"No duration data for note %d, motif %d in notedatafile\n",noteno,motifno);
  1092. return(DATA_ERROR);
  1093. }
  1094. thisnote->dur = (float)val;
  1095. if(texflag & IS_ORN_OR_MTF) {
  1096. if(texflag & IS_ORNATE) {
  1097. start = 2;
  1098. } else {
  1099. start = 1;
  1100. if(texflag & ISTIMED)
  1101. start++;
  1102. }
  1103. if(texflag & ISHARM)
  1104. start++;
  1105. if(motifno >= start) {
  1106. if(val <= FLTERR) {
  1107. sprintf(errstr,"Duration value [%lf] is too small: motif %d: note %d\n",val,motifno,noteno);
  1108. return(DATA_ERROR);
  1109. }
  1110. }
  1111. } else {
  1112. thisnote->dur = 1.0f; /* default ; redundant */
  1113. }
  1114. return(FINISHED);
  1115. }
  1116. /***************************** GENERATE_TSET_TIMES **********************************
  1117. *
  1118. * Store time initially as SECONDS.
  1119. *
  1120. * (1) Create location for a new note.
  1121. * (2) Go to that new note.
  1122. * (3) Store the current time at this note.
  1123. * (4) Find note-density at this time, and generate time of next event.
  1124. * (5) Return nextnote.
  1125. */
  1126. int generate_tset_times(double *thistime,noteptr *thisnote,dataptr dz)
  1127. {
  1128. int exit_status;
  1129. if((exit_status = make_new_note(thisnote))<0)
  1130. return(exit_status); /* 1 */
  1131. (*thisnote)->ntime = (float)(*thistime); /* 3 */
  1132. if(dz->brksize[TEXTURE_PACK]) {
  1133. if((exit_status = read_value_from_brktable(*thistime,TEXTURE_PACK,dz))<0)
  1134. return(exit_status);
  1135. }
  1136. *thistime += dz->param[TEXTURE_PACK]; /* 4 */
  1137. return(FINISHED); /* 5 */
  1138. }
  1139. /********************** UN_LINK_NOTE ******************************
  1140. *
  1141. * Deletes empty address space at end of notelist.
  1142. */
  1143. int un_link_note(noteptr thisnote)
  1144. {
  1145. if(thisnote->last==(noteptr)0) {
  1146. sprintf(errstr,"Problem in un_link_note()\n");
  1147. return(PROGRAM_ERROR);
  1148. }
  1149. thisnote = thisnote->last;
  1150. free(thisnote->next);
  1151. thisnote->next = (noteptr)0;
  1152. return(FINISHED);
  1153. }
  1154. /************************ NEW_MOTIF *****************************
  1155. *
  1156. * Set up next motif in a list of musical-motifs.
  1157. * Set up location of first note of this motif.
  1158. */
  1159. int new_motif(motifptr *thismotif)
  1160. {
  1161. int exit_status;
  1162. motifptr newmotif;
  1163. noteptr thisnote;
  1164. if((newmotif = (motifptr)malloc(sizeof (struct motif)))==NULL) {
  1165. sprintf(errstr,"INSUFFICIENT MEMORY to store next motif.\n");
  1166. return(MEMORY_ERROR);
  1167. }
  1168. (*thismotif)->next = newmotif;
  1169. newmotif->last = *thismotif;
  1170. newmotif->next = (motifptr)0;
  1171. if((exit_status = init_note(&thisnote))<0)
  1172. return(exit_status);
  1173. thisnote->next = (noteptr)0;
  1174. thisnote->last = (noteptr)0;
  1175. newmotif->firstnote = thisnote;
  1176. *thismotif = newmotif;
  1177. return(FINISHED);
  1178. }
  1179. /********************** UNLINK_LAST_MOTIF ******************************
  1180. *
  1181. * Deletes empty address space at end of motiflist.
  1182. */
  1183. int unlink_last_motif(motifptr thismotif)
  1184. {
  1185. if(thismotif->last==(motifptr)0) {
  1186. sprintf(errstr,"Problem in unlink_last_motif()\n");
  1187. return(PROGRAM_ERROR);
  1188. }
  1189. thismotif = thismotif->last;
  1190. free(thismotif->next);
  1191. thismotif->next = (motifptr)0;
  1192. return(FINISHED);
  1193. }
  1194. /**************************** SUBTRACT_ONE_FROM_BRKVALS ****************************/
  1195. void subtract_one_from_brkvals(int paramno,dataptr dz)
  1196. {
  1197. double *p = dz->brk[paramno] + 1;
  1198. double *pend = dz->brk[paramno] + (dz->brksize[paramno] * 2);
  1199. while(p < pend) {
  1200. *p -= 1.0;
  1201. p += 2;
  1202. }
  1203. }
  1204. /************************ BIGSCATTER *************************************
  1205. *
  1206. * (1) The number of time-points to be randomly scattered as a group is
  1207. * scatcnt.
  1208. * (1a) Base time is the time from which these new scattered times are offset.
  1209. * (2) Save the current position in note list as 'here'.
  1210. * (3) Go forward in note list until there are scatcnt notes inclusive
  1211. * between here and there, or until list runs out.
  1212. * (3a) If the list runs out, modify scatcnt accordingly.
  1213. * (4) Note the (original) time of the last of these events. This will
  1214. * be returned as the new 'lasttime' for the next cycle of the
  1215. * program.
  1216. * (5) Make the time-step include the total duration of all these
  1217. * events.
  1218. * (5a) Generate a set of times AT RANDOM within this large timestep,
  1219. sort them and store them.
  1220. * (6) Replace existing times by scattered times, relative to basetime.
  1221. * (6a) Convert to MIDitime.
  1222. * (6b) Quantise if necessary.
  1223. * (7) Replace the last time.
  1224. * (9) Return the last note we worked on.
  1225. */
  1226. int bigscatter(noteptr *thisnote,double thistime,double timestep,double scatter,double *lasttime,dataptr dz)
  1227. {
  1228. int n, scatcnt = round(scatter); /* 1 */
  1229. double *sct, *scti;
  1230. double basetime = thistime - timestep; /* 1a */
  1231. noteptr here = *thisnote; /* 2 */
  1232. noteptr there = *thisnote; /* 2 */
  1233. if((scti = (double *)malloc(scatcnt * sizeof(double)))==NULL) {
  1234. sprintf(errstr,"INSUFFICIENT MEMORY for scattering structure.\n");
  1235. return(MEMORY_ERROR);
  1236. }
  1237. sct = scti;
  1238. for(n=0;n < scatcnt-1; n++) { /* 3 */
  1239. if(there->next==(noteptr)0) {
  1240. scatcnt = n+1; /* 3a */
  1241. break;
  1242. }
  1243. there = there->next;
  1244. }
  1245. *lasttime = there->ntime; /* 4 */
  1246. timestep += *lasttime - thistime; /* 5 */
  1247. for(n= 0;n<scatcnt;n++) /* 5a */
  1248. *sct++ = drand48() * timestep;
  1249. upsort(scti,scatcnt);
  1250. sct = scti;
  1251. while(here!=there) { /* 6 */
  1252. thistime = basetime + (*sct++);
  1253. if(dz->param[TEXTURE_TGRID]>0.0)
  1254. thistime = quantise(thistime,dz->param[TEXTURE_TGRID]); /* 6b */
  1255. here->ntime = (float)thistime;
  1256. here = here->next;
  1257. }
  1258. thistime = basetime + *sct; /* 7 */
  1259. if(dz->param[TEXTURE_TGRID]>0.0)
  1260. thistime = quantise(thistime,dz->param[TEXTURE_TGRID]);
  1261. there->ntime = (float)thistime;
  1262. free(scti);
  1263. *thisnote = there;
  1264. return(FINISHED); /* 9 */
  1265. }
  1266. /************************** QUANTISE *************************************
  1267. *
  1268. * Quantise time point onto a grid.
  1269. */
  1270. double quantise(double thistime,double timegrid)
  1271. {
  1272. int gridpoint;
  1273. timegrid *= MS_TO_SECS;
  1274. gridpoint = round(thistime/timegrid);
  1275. return((double)gridpoint * timegrid);
  1276. }
  1277. /************************* GET_DATA_ITEM ****************************/
  1278. int get_data_item(char *q,char **p,double *val)
  1279. {
  1280. int exit_status = CONTINUE;
  1281. if(*q==ENDOFSTR)
  1282. return(DATA_ERROR);
  1283. while(isspace(**p)) {
  1284. (*p)++;
  1285. if(**p == ENDOFSTR)
  1286. return(DATA_ERROR);
  1287. }
  1288. if(**p==TEXTURE_SEPARATOR)
  1289. return(DATA_ERROR);
  1290. while(!isspace(**p) && **p!=ENDOFSTR) {
  1291. (*p)++;
  1292. }
  1293. if(**p==ENDOFSTR)
  1294. exit_status = FINISHED;
  1295. **p = ENDOFSTR;
  1296. if(sscanf(q,"%lf",val)!=1)
  1297. return(DATA_ERROR);
  1298. return(exit_status);
  1299. }
  1300. /************************* INIT_NOTE ****************************
  1301. *
  1302. * Initialise notelist.
  1303. */
  1304. int init_note(noteptr *thisnote)
  1305. {
  1306. if((*thisnote = (noteptr)malloc(sizeof(struct nnote)))==NULL) {
  1307. sprintf(errstr,"INSUFFICIENT MEMORY for another note.\n");
  1308. return(MEMORY_ERROR);
  1309. }
  1310. (*thisnote)->next = (noteptr)0;
  1311. (*thisnote)->last = (noteptr)0;
  1312. return(FINISHED);
  1313. }
  1314. /********************** UPSORT *******************************
  1315. *
  1316. * Sort set of doubles into ascending order.
  1317. */
  1318. void upsort(double *scti,int scatcnt)
  1319. {
  1320. double sct;
  1321. int n, m;
  1322. for(n=0;n<(scatcnt-1);n++) {
  1323. for(m=n+1;m<scatcnt;m++) {
  1324. if(*(scti+m)<*(scti+n)) {
  1325. sct = *(scti+m);
  1326. *(scti+m) = *(scti+n);
  1327. *(scti+n) = sct;
  1328. }
  1329. }
  1330. }
  1331. }
  1332. /*********************** PUT_ZNOTE ********************************
  1333. *
  1334. * Put zero values in all parameters except time.
  1335. */
  1336. void put_znote(noteptr thisnote)
  1337. {
  1338. thisnote->amp = 0.0f;
  1339. thisnote->pitch = 0.0f;
  1340. thisnote->dur = 0.0f;
  1341. thisnote->instr = 0;
  1342. thisnote->spacepos = 0.0f;
  1343. thisnote->motioncentre = 0.0f;
  1344. }
  1345. /************************* ASSIGN_TIMESET_HFSET_MOTIFSETS ******************************
  1346. *
  1347. * Assign appropriate pointers to input motifs.
  1348. *
  1349. * (1) If it's a timed texture, indicate first motif in list as that
  1350. * which defines the set of times (tset).
  1351. * Similarly, if texture is ornamented or decorated, point to first
  1352. * motif as that to BE ornamented or decorated (tset).
  1353. * (2) If the texture restricted to HF(s) or HS(s), indicate next motif
  1354. * as the HF-set (hfldmotif). It may be read in different ways (as HF, as
  1355. * HS, or as time-varying of either type) at a later time.
  1356. * (3) If texture consists of motifs, or is to use specific ornaments...
  1357. * (4) count the number of motifs remaining.
  1358. * (5) Set up the array of phrases to point to the appropriate motifs.
  1359. */
  1360. int assign_timeset_hfset_motifsets(dataptr dz)
  1361. {
  1362. int exit_status;
  1363. unsigned int texflag = dz->tex->txflag;
  1364. motifptr here, thismotif = dz->tex->motifhead;
  1365. int n;
  1366. dz->tex->phrasecnt = 0;
  1367. if(texflag & ORN_DEC_OR_TIMED) {
  1368. if((exit_status = motifchek(thismotif))<0)
  1369. return(exit_status);
  1370. dz->tex->timeset = thismotif; /* 1 */
  1371. thismotif = thismotif->next;
  1372. }
  1373. if(texflag & ISHARM) { /* 2 */
  1374. if((exit_status = motifchek(thismotif))<0)
  1375. return(exit_status);
  1376. dz->tex->hfldmotif = thismotif;
  1377. thismotif = thismotif->next;
  1378. }
  1379. if((texflag & IS_ORNATE) || (texflag & IS_MOTIFS)) { /* 3 */
  1380. if((exit_status = motifchek(thismotif))<0)
  1381. return(exit_status);
  1382. here = thismotif;
  1383. while(thismotif!=(motifptr)0) { /* 4 */
  1384. dz->tex->phrasecnt++;
  1385. thismotif = thismotif->next;
  1386. } /* 5 */
  1387. if((dz->tex->phrase = (motifptr *)malloc(dz->tex->phrasecnt * sizeof(motifptr)))==NULL) {
  1388. sprintf(errstr,"INSUFFICIENT MEMORY for phrase array.\n");
  1389. return(MEMORY_ERROR);
  1390. }
  1391. thismotif = here;
  1392. n = -1;
  1393. while(thismotif!=(motifptr)0) {
  1394. dz->tex->phrase[++n] = thismotif;
  1395. thismotif = thismotif->next;
  1396. }
  1397. }
  1398. return(FINISHED);
  1399. }
  1400. /***************************** MASSAGE_PARAMS ****************************/
  1401. int massage_params(dataptr dz)
  1402. {
  1403. int exit_status;
  1404. unsigned int texflag = dz->tex->txflag;
  1405. convert_cmdline_instrnos_to_internal_representation(dz);
  1406. if((exit_status = check_max_transpos_compatible_with_splicelen(dz))<0)
  1407. return(exit_status);
  1408. if(texflag & IS_CLUMPED) {
  1409. if((exit_status = set_amptype_params(dz))<0)
  1410. return(exit_status);
  1411. }
  1412. if(texflag & IS_DECOR) {
  1413. if((exit_status = set_decor_pitchposition_params(dz))<0)
  1414. return(exit_status);
  1415. }
  1416. return(FINISHED);
  1417. }
  1418. /************************* INIT_MOTIFS *****************************
  1419. *
  1420. * Set up head item of a list of musical-motifs.
  1421. * Set up location of first note of first motif.
  1422. */
  1423. int init_motifs(dataptr dz)
  1424. {
  1425. int exit_status;
  1426. noteptr thisnote;
  1427. if((dz->tex->motifhead = (motifptr)malloc(sizeof (struct motif)))==NULL) {
  1428. sprintf(errstr,"INSUFFICIENT MEMORY to store any motifs.\n");
  1429. return(MEMORY_ERROR);
  1430. }
  1431. dz->tex->motifhead->next = (motifptr)0;
  1432. dz->tex->motifhead->last = (motifptr)0;
  1433. if((exit_status = init_note(&thisnote))<0)
  1434. return(exit_status);
  1435. dz->tex->motifhead->firstnote = thisnote;
  1436. thisnote->next = (noteptr)0;
  1437. thisnote->last = (noteptr)0;
  1438. return(FINISHED);
  1439. }
  1440. /******************************** INITPERM *********************************
  1441. *
  1442. * Establish storage space for permutation parameters.
  1443. *
  1444. * (1) create pointers to the items within the permuted sets. Initialise to zero.
  1445. * (2) Create storage for current length of each perm. Initialise to zero.
  1446. * (3) Create storage for previous length of each perm. Initialise to -1 (impossible).
  1447. * If new perm different length to old, space for permuted elements will need to be re-malloced.
  1448. * (4) Create pointers to storage areas for each permuted set. Initialise to point nowhere.
  1449. * These will be malloced when the size of each set-to-permute is known.
  1450. * (5) Create storage for previous outputed val in each perm. Initialise to -1 (impossible).
  1451. * This is useful at permutation boundaries, when a particular element may be repeated more
  1452. * than permitted no. of times if there's no check. These constants allow no. of repets to be counted.
  1453. * (6) Create counter of current no. of consecutive repets of an element in each of the (output) perms.
  1454. * Initialise to 0, though this is arbitrary, as repetcnt should always be set on any call of do_perm.
  1455. * (7) Create storage for max no. of allowed consecutive repets of an element in each perm-set.
  1456. * Initialise to 1, which is the default if no info is given to the contrary.
  1457. */
  1458. int initperm(int ***permm,dataptr dz)
  1459. {
  1460. int n;
  1461. if((dz->iparray[TXPERMINDEX] = (int *)malloc(PERMCNT * sizeof(int)))==NULL) { /* 1 */
  1462. sprintf(errstr,"INSUFFICIENT MEMORY for permutation indeces.\n");
  1463. return(MEMORY_ERROR);
  1464. }
  1465. for(n=0;n<PERMCNT;n++)
  1466. dz->iparray[TXPERMINDEX][n] = 0;
  1467. if((dz->iparray[TXPERMLEN] = (int *)malloc(PERMCNT * sizeof(int)))==NULL) { /* 2 */
  1468. sprintf(errstr,"INSUFFICIENT MEMORY for permutation lengths.\n");
  1469. return(MEMORY_ERROR);
  1470. }
  1471. for(n=0;n<PERMCNT;n++)
  1472. dz->iparray[TXPERMLEN][n] = 0;
  1473. if((dz->iparray[TXLASTPERMLEN] = (int *)malloc(PERMCNT * sizeof(int)))==NULL) { /* 3 */
  1474. sprintf(errstr,"INSUFFICIENT MEMORY for last permutation lengths.\n");
  1475. return(MEMORY_ERROR);
  1476. }
  1477. for(n=0;n<PERMCNT;n++)
  1478. dz->iparray[TXLASTPERMLEN][n] = -1;
  1479. if((*permm = (int **)malloc(PERMCNT * sizeof(int *)))==NULL) { /* 4 */
  1480. sprintf(errstr,"INSUFFICIENT MEMORY for permutations.\n");
  1481. return(MEMORY_ERROR);
  1482. }
  1483. for(n=0;n<PERMCNT;n++)
  1484. (*permm)[n] = (int *)0;
  1485. if((dz->iparray[TXLASTPERMVAL] = (int *)malloc(PERMCNT * sizeof(int)))==NULL) { /* 5 */
  1486. sprintf(errstr,"INSUFFICIENT MEMORY for last permutation values.\n");
  1487. return(MEMORY_ERROR);
  1488. }
  1489. for(n=0;n<PERMCNT;n++)
  1490. dz->iparray[TXLASTPERMVAL][n] = -1;
  1491. if((dz->iparray[TXREPETCNT] = (int *)malloc(PERMCNT * sizeof(int)))==NULL) { /* 6 */
  1492. sprintf(errstr,"INSUFFICIENT MEMORY for permutation repetition counts.\n");
  1493. return(MEMORY_ERROR);
  1494. }
  1495. for(n=0;n<PERMCNT;n++)
  1496. dz->iparray[TXREPETCNT][n] = 1;
  1497. if((dz->iparray[TXRPT] = (int *)malloc(PERMCNT * sizeof(int)))==NULL) { /* 7 */
  1498. sprintf(errstr,"INSUFFICIENT MEMORY for permutation repetitions.\n");
  1499. return(MEMORY_ERROR);
  1500. }
  1501. /* THESE ARE THE DEFAULT NUMBER OF REPETITIONS-OF-AN-ENTITY ALLOWED IN A PERM */
  1502. dz->iparray[TXRPT][PM_SPACE] = SPACE_REPETS;
  1503. dz->iparray[TXRPT][PM_PITCH] = PITCH_REPETS;
  1504. dz->iparray[TXRPT][PM_AMP] = AMP_REPETS;
  1505. dz->iparray[TXRPT][PM_DUR] = DUR_REPETS;
  1506. dz->iparray[TXRPT][PM_INSNO] = INSNO_REPETS;
  1507. dz->iparray[TXRPT][PM_GPRANG] = GPRANG_REPETS;
  1508. dz->iparray[TXRPT][PM_GPSIZE] = GPSIZE_REPETS;
  1509. dz->iparray[TXRPT][PM_GPDENS] = GPDENS_REPETS;
  1510. dz->iparray[TXRPT][PM_GPCNTR] = GPCNTR_REPETS;
  1511. dz->iparray[TXRPT][PM_GPPICH] = GPPICH_REPETS;
  1512. dz->iparray[TXRPT][PM_ORNPOS] = ORNPOS_REPETS;
  1513. dz->iparray[TXRPT][PM_GPSPAC] = GPSPAC_REPETS;
  1514. dz->iparray[TXRPT][PM_ORIENT] = ORIENT_REPETS;
  1515. dz->iparray[TXRPT][PM_DECABV] = DECABV_REPETS;
  1516. dz->iparray[TXRPT][PM_MULT] = MULT_REPETS;
  1517. dz->iparray[TXRPT][PM_WHICH] = WHICH_REPETS;
  1518. dz->iparray[TXRPT][PM_GPPICH2]= GPPICH2_REPETS;
  1519. return(FINISHED);
  1520. }