texprepromch.c 60 KB

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