texture2.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517
  1. /*
  2. * Copyright (c) 1983-2013 Trevor Wishart and Composers Desktop Project Ltd
  3. * http://www.trevorwishart.co.uk
  4. * http://www.composersdesktop.com
  5. *
  6. This file is part of the CDP System.
  7. The CDP System is free software; you can redistribute it
  8. and/or modify it under the terms of the GNU Lesser General Public
  9. License as published by the Free Software Foundation; either
  10. version 2.1 of the License, or (at your option) any later version.
  11. The CDP System is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. GNU Lesser General Public License for more details.
  15. You should have received a copy of the GNU Lesser General Public
  16. License along with the CDP System; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  18. 02111-1307 USA
  19. *
  20. */
  21. /* floatsam version: no changes */
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <structures.h>
  25. #include <tkglobals.h>
  26. #include <globcon.h>
  27. #include <processno.h>
  28. #include <modeno.h>
  29. #include <arrays.h>
  30. #include <texture.h>
  31. #include <cdpmain.h>
  32. #include <sfsys.h>
  33. #include <osbind.h>
  34. /***************************** GENERATING TEXTURES WITH NO HFIELD(S) ******************************/
  35. static int setup_motif_params
  36. (noteptr phrasenote,double tsettime,double *thisamp,double ampstep,double *phraseamp,
  37. int phrno,double rangemult,noteptr thisnote,noteptr tsetnote,
  38. double multiplier,double timeadjust,dataptr dz);
  39. static void gen_orn_pitch(noteptr thisnote,noteptr tsetnote,noteptr phrasenote,
  40. float phrlpitch,float phrfirstpitch,dataptr dz);
  41. static void gen_mtf_pitch(noteptr thisnote,noteptr tsetnote,noteptr phrasenote,float phrfirstpitch);
  42. static int dec_centre(double tsetpitch,float *val,int gpsize,double gprlow,double gprange,dataptr dz);
  43. static int pscat(double range,double bottom,int pindex,double *val,dataptr dz);
  44. static int initialise_phrases
  45. (int **phrnotecnt,double **phraseamp,double **phrange,noteptr **phrlastnote,dataptr dz);
  46. static int do_ev_pch
  47. (double *thispitch,double thistime,double *pptop,double *ppbot,dataptr dz);
  48. static int get_gpparams
  49. (double thistime,double thispitch,unsigned char dectypecnt,double *gprange,double *gprlow,int *gpsize,
  50. double *gpdense,double pptop,double ppbot,unsigned char dectypestor,int mingrpsize,dataptr dz);
  51. static int orientrange
  52. (double thispitch,double pptop, double ppbot,double *gprange, double *gprlow,
  53. unsigned char dectypestor,unsigned char dectypecnt,dataptr dz);
  54. static void squeezrange(double thispitch,double *gprange,double *gprlow, double pptop, double ppbot);
  55. /**************************** DO_TEXTURE *****************************/
  56. int do_texture(dataptr dz)
  57. {
  58. int exit_status;
  59. noteptr tsetnote = dz->tex->timeset->firstnote;
  60. unsigned int texflag = dz->tex->txflag;
  61. unsigned char dectypestor = dz->tex->dectypstor;
  62. unsigned char dectypecnt = dz->tex->dectypcnt;
  63. unsigned char amptypestor = dz->tex->amptypstor;
  64. unsigned char amptypecnt = dz->tex->amptypcnt;
  65. int ampdirected = dz->tex->ampdirectd;
  66. motifptr tset = dz->tex->timeset;
  67. motifptr *phrase = dz->tex->phrase;
  68. int phrcount = dz->tex->phrasecnt;
  69. int *phrnotecnt=NULL;
  70. double *phraseamp=NULL, *phrange=NULL;
  71. noteptr thisnote=NULL, nextnote=NULL, phrasenote=NULL, nextevent=NULL, *phrlastnote=NULL, *shadow=NULL;
  72. float phrlpitch=0.0, phrfirstpitch=0.0;
  73. unsigned char thisinstr, amptype=0;
  74. double tsettime=0.0, thistime=0.0, thispitch=0.0, ampstep=0.0, thepitch=0.0, thisamp=0.0, thisdur=0.0;
  75. double rangemult=0.0, gpdense=0.0, gprange=0.0, gprlow=0.0, multiplier=0.0;
  76. double timeadjust = 0.0; /* default */
  77. int phrno=0, n=0, shadowsize=0, gpsize=0, mingrpsize = 0;
  78. double pptop=0.0, ppbot=0.0;
  79. int shadindex = 0;
  80. dz->iparam[SPINIT] = 0;
  81. if(texflag & IS_CLUMPED) {
  82. if((dz->tex->phrasecnt > 0)
  83. && (exit_status = initialise_phrases(&phrnotecnt,&phraseamp,&phrange,&phrlastnote,dz))<0)
  84. return(exit_status);
  85. if(texflag & IS_GROUPS)
  86. mingrpsize = 1;
  87. if((exit_status= make_shadow(tset,&shadowsize,&shadow))<0)
  88. return(exit_status);
  89. if(texflag & IS_DECOR) {
  90. setup_decor(&pptop,&ppbot,&shadindex,&tsetnote,dz);
  91. } else if(texflag & IS_MOTIFS) {
  92. if((exit_status = set_motifs(phrcount,phrase,phrnotecnt,phraseamp,phrange,phrlastnote))<0)
  93. return(exit_status);
  94. } else if(texflag & IS_ORNATE) {
  95. if((exit_status = set_motifs(phrcount,phrase,phrnotecnt,phraseamp,phrange,phrlastnote))<0)
  96. return(exit_status);
  97. if(dz->vflag[WHICH_CHORDNOTE]==DECOR_HIGHEST)
  98. tsetnote = gethipitch(tsetnote,&shadindex);
  99. }
  100. }
  101. while(tsetnote!=(noteptr)0) {
  102. tsettime = (double)tsetnote->ntime;
  103. thistime = tsettime;
  104. if((exit_status = read_values_from_all_existing_brktables(thistime,dz))<0)
  105. return(exit_status);
  106. if(texflag & IS_DECOR)
  107. thispitch = tsetnote->pitch;
  108. if(texflag & IS_ORN_OR_MTF) {
  109. if((exit_status =
  110. setup_motif_or_ornament(thistime,&multiplier,&phrno,&phrasenote,phrase,dz))<0)
  111. return(exit_status);
  112. }
  113. if(!(texflag & IS_ORN_OR_DEC)) {
  114. if((exit_status = do_ev_pch(&thispitch,thistime,&pptop,&ppbot,dz))<0)
  115. return(exit_status);
  116. tsetnote->pitch = (float)thispitch;
  117. }
  118. if((exit_status = do_amp_instr_dur(&thisamp,&thisinstr,&thisdur,tsetnote,thistime,dz))<0)
  119. return(exit_status);
  120. if(texflag & IS_CLUMPED) {
  121. if(texflag & IS_MOTIFS) {
  122. if((exit_status = getmtfdur(tsetnote,phrasenote,&thisdur,multiplier,dz))<0)
  123. return(exit_status);
  124. tsetnote->dur = (float)thisdur;
  125. }
  126. if(texflag & IS_ORN_OR_MTF) {
  127. gpsize = phrnotecnt[phrno];
  128. phrfirstpitch = phrasenote->pitch;
  129. } else {
  130. if((exit_status = get_gpparams(thistime,thispitch,dectypecnt,
  131. &gprange,&gprlow,&gpsize,&gpdense,pptop,ppbot,dectypestor,mingrpsize,dz))<0)
  132. return(exit_status);
  133. }
  134. if(texflag & IS_DECOR) {
  135. if((exit_status = position_and_size_decoration(&thistime,tsettime,gpdense,&gpsize,dz))<0)
  136. return(exit_status);
  137. } else
  138. gpsize--;
  139. if(texflag & IS_ORNATE) {
  140. phrlpitch = (phrlastnote[phrno])->pitch;
  141. if((exit_status = setup_ornament
  142. (&timeadjust,&thistime,&gpsize,phrlastnote,multiplier,&phrasenote,phrno,dz))<0)
  143. return(exit_status);
  144. }
  145. if(!(texflag & IS_DECOR))
  146. nextnote = tsetnote->next;
  147. if(gpsize>0) { /* 3b */
  148. if(texflag & IS_ORN_OR_MTF) {
  149. if((exit_status = orn_or_mtf_amp_setup
  150. (ampdirected,phrange,phrno,thisamp,gpsize,&rangemult,&ampstep,&amptype,amptypestor,amptypecnt,dz))<0)
  151. return(exit_status);
  152. }
  153. if(texflag & IS_MOTIFS) {
  154. if((exit_status = set_motif_amp
  155. (tsetnote,&thisamp,gpsize,ampstep,phrasenote,rangemult,phraseamp,phrno,amptype))<0)
  156. return(exit_status);
  157. } else if(texflag & IS_ORNATE) {
  158. if((exit_status = set_ornament_amp
  159. (phraseamp,phrlastnote,&thisamp,phrasenote,phrno,tsetnote,ampstep,rangemult,gpsize,dz))<0)
  160. return(exit_status);
  161. } else if(texflag & IS_GROUPS) {
  162. if((exit_status = set_group_amp
  163. (tsetnote,&thisamp,&amptype,&ampstep,gpsize,amptypecnt,amptypestor,dz))<0)
  164. return(exit_status);
  165. } else if(texflag & IS_DECOR) {
  166. if((exit_status = set_decor_amp
  167. (ampdirected,&thisamp,&ampstep,gpsize,&amptype,amptypecnt,amptypestor,dz))<0)
  168. return(exit_status);
  169. }
  170. if(dz->iparam[TEX_GPSPACE]!=IS_STILL) {
  171. if((exit_status = init_group_spatialisation(tsetnote,shadindex,shadow,shadowsize,dz))<0)
  172. return(exit_status);
  173. }
  174. thisnote = tsetnote;
  175. if(texflag & IS_DECOR)
  176. nextnote = tsetnote->next;
  177. else if(texflag & IS_ORNATE) {
  178. if(!dz->vflag[IS_PRE])
  179. phrasenote = phrasenote->next;
  180. }
  181. if(texflag & IS_ORN_OR_DEC)
  182. nextevent = getnextevent_to_decorate(tsetnote,&shadindex,dz);
  183. for(n=0;n<gpsize;n++) {
  184. if((exit_status = make_new_note(&thisnote))<0)
  185. return(exit_status);
  186. if(texflag & IS_DEC_OR_GRP) {
  187. if((exit_status = set_group_params
  188. (tsetnote,thisnote,gpdense,ampstep,&thisamp,&thistime,thisdur,dz))<0)
  189. return(exit_status);
  190. if((exit_status = do_grp_ins(tsetnote->instr,&(thisnote->instr),dz))<0)
  191. return(exit_status);
  192. thisnote->motioncentre = tsetnote->motioncentre;
  193. if(texflag & IS_DECOR) {
  194. if((exit_status = dec_centre
  195. (thispitch,&(thisnote->pitch),gpsize,gprlow,gprange,dz))<0)
  196. return(exit_status);
  197. } else {
  198. if((exit_status = pscat(gprange,gprlow,PM_GPPICH,&thepitch,dz))<0)
  199. return(exit_status);
  200. thisnote->pitch = (float)thepitch;
  201. }
  202. thisnote->ntime = (float)thistime;
  203. } else {
  204. if((exit_status = check_next_phrasenote_exists(&phrasenote,texflag,dz))<0)
  205. return(exit_status);
  206. if((exit_status = setup_motif_params(phrasenote,thistime,&thisamp,ampstep,phraseamp,phrno,
  207. rangemult,thisnote,tsetnote,multiplier,timeadjust,dz))<0)
  208. return(exit_status);
  209. if(texflag & IS_MOTIFS) {
  210. gen_mtf_pitch(thisnote,tsetnote,phrasenote,phrfirstpitch);
  211. } else {
  212. gen_orn_pitch(thisnote,tsetnote,phrasenote,phrlpitch,phrfirstpitch,dz);
  213. phrasenote = phrasenote->next;
  214. }
  215. }
  216. if((exit_status = setspace(tsetnote,thisnote,gpsize,dz))<0)
  217. return(exit_status);
  218. }
  219. thisnote->next = nextnote;
  220. if(nextnote!=(noteptr)0)
  221. nextnote->last = thisnote;
  222. if(texflag & IS_ORN_OR_DEC)
  223. tsetnote = nextevent;
  224. } else if(texflag & IS_ORN_OR_DEC)
  225. tsetnote = getnextevent_to_decorate(tsetnote,&shadindex,dz);
  226. } else
  227. tsetnote = tsetnote->next;
  228. if(texflag & IS_MTF_OR_GRP) {
  229. tsetnote = nextnote;
  230. shadindex++;
  231. }
  232. }
  233. if((texflag & IS_DECOR) && dz->vflag[DISCARD_ORIGLINE]) {
  234. if((exit_status = erase_shadow(shadowsize,shadow,tset))<0)
  235. return(exit_status);
  236. }
  237. if(texflag & IS_CLUMPED)
  238. return arrange_notes_in_timeorder(tset);
  239. return(FINISHED);
  240. }
  241. /**************************** SETUP_MOTIF_PARAMS ****************************/
  242. int setup_motif_params
  243. (noteptr phrasenote,double tsettime,double *thisamp,double ampstep,double *phraseamp, int phrno,
  244. double rangemult,noteptr thisnote,noteptr tsetnote,double multiplier,double timeadjust,dataptr dz)
  245. {
  246. double notetime, ampdif;
  247. notetime = getnotetime(phrasenote,tsettime,multiplier,timeadjust,dz);
  248. *thisamp += ampstep;
  249. ampdif =(phraseamp[phrno] - phrasenote->amp)*rangemult;/* e */
  250. return do_mtf_params(thisnote,*thisamp,phrasenote,tsetnote,ampdif,notetime,multiplier,dz);
  251. }
  252. /**************************** GEN_ORN_PITCH ****************************/
  253. void gen_orn_pitch
  254. (noteptr thisnote,noteptr tsetnote,noteptr phrasenote,float phrlpitch,float phrfirstpitch,dataptr dz)
  255. {
  256. if(dz->vflag[IS_PRE])
  257. thisnote->pitch = (float)(tsetnote->pitch + phrasenote->pitch - phrlpitch);
  258. else
  259. thisnote->pitch = (float)(tsetnote->pitch + phrasenote->pitch - phrfirstpitch);
  260. }
  261. /**************************** GEN_MTF_PITCH ****************************/
  262. void gen_mtf_pitch(noteptr thisnote,noteptr tsetnote,noteptr phrasenote,float phrfirstpitch)
  263. {
  264. thisnote->pitch = (float)(tsetnote->pitch + phrasenote->pitch - phrfirstpitch);
  265. thisnote->pitch = (float)octadjust((double)thisnote->pitch);
  266. }
  267. /************************* DEC_CENTRE ******************************
  268. *
  269. * Centre a decoration on the decorated pitch.
  270. *
  271. * (1) For groupsize 1 or 2, k=1
  272. * For groupsize 3 or 4, k=2
  273. * For groupsize 5 or 6, k=3 etc
  274. * (2) Scatter pitches as normally.
  275. * (3) If range is NOT one-sided, proceed..otherwise return in normal way.
  276. * (4) Find ratio of upper half of range to lower.
  277. * (5) Find distance from decorated note.
  278. * (6) Save the current value of allowed repetitions.
  279. * THese are number of times a note occurs above the decorated pitch,
  280. * before it can do so again (same for below).
  281. * (7) If the allowed repetitions are bigger than k, replace it by k.
  282. * This means that if we allow 3 repetitions but there are only
  283. * 1,2,3 or 4 notes, we force, 1 repetition for 2 notes, 2 repetitions
  284. * for 3 or 4 notes etc. but allow 3 repetitions for 5,6 etc notes.
  285. * (8) Select above or below decorated pitch.
  286. * (9) If meant to be above note, but is below it, put note in other
  287. * half of range, with appropriate adjustment for relative sizes
  288. * of half-ranges.
  289. * (10) If meant to be below note, but is above it, put note in other
  290. * half of range, with appropriate adjustment for relative sizes
  291. * of half-ranges.
  292. * (11) Restore the repetcnt value!!
  293. */
  294. int dec_centre(double tsetpitch,float *val,int gpsize,double gprlow,double gprange,dataptr dz)
  295. {
  296. int exit_status;
  297. double a, q, w, gprhi = gprlow + gprange, ulratio;
  298. int s, save, k = (gpsize+1)/2; /* 1 */
  299. if((exit_status = pscat(gprange,gprlow,PM_GPPICH,&a,dz))<0) /* 2 */
  300. return(exit_status);
  301. if((w=tsetpitch-gprlow)>FLTERR && !flteq(tsetpitch,gprhi)) {/* 3 */
  302. ulratio = (gprhi-tsetpitch)/w; /* 4 */
  303. q = a-tsetpitch; /* 5 */
  304. save = dz->iparray[TXREPETCNT][PM_DECABV]; /* 6 */
  305. if(dz->iparray[TXREPETCNT][PM_DECABV]>k) /* 7 */
  306. dz->iparray[TXREPETCNT][PM_DECABV] = k;
  307. if((exit_status = doperm((int)2,PM_DECABV,&s,dz))<0) /* 8 */
  308. return(exit_status);
  309. if(s && q<0.0) /* 9 */
  310. a = tsetpitch - (q*ulratio);
  311. if(!s && q>0.0) /* 10 */
  312. a = tsetpitch - (q/ulratio);
  313. dz->iparray[TXREPETCNT][PM_DECABV] = save; /* 11 */
  314. if(a<MIDIBOT || a>MIDITOP) {
  315. sprintf(errstr,"TEXTURE: Problem in dec_centre()\n");
  316. return(PROGRAM_ERROR);
  317. }
  318. }
  319. *val = (float)a;
  320. return(FINISHED);
  321. }
  322. /***************************** PSCAT ************************************
  323. *
  324. * A weighted version of pscatx().
  325. *
  326. * Select a random value within 'range', by permuting one of BANDCNT UNequal
  327. * ranges, and selecting a random value within the chosen range. The upper
  328. * and lower band are half as wide as the inner 3 bands, ensuring that
  329. * values within these outer bands are squeezed into a narrow-range-of-values
  330. * near the boundaries of the total range.
  331. */
  332. int pscat(double range,double bottom,int pindex,double *val,dataptr dz)
  333. {
  334. int exit_status;
  335. double bandbottom, bandwidth, x;
  336. int k;
  337. if((exit_status = doperm((int)BANDCNT,pindex,&k,dz))<0)
  338. return(exit_status);
  339. bandwidth = range/(double)LAYERCNT;
  340. switch(k) {
  341. case(0):
  342. bandbottom = 0.0;
  343. break;
  344. case(BANDCNT-1):
  345. bandbottom = (LAYERCNT-1) * bandwidth;
  346. break;
  347. default:
  348. bandbottom = bandwidth + ((double)((k-1) * 2) * bandwidth);
  349. bandwidth *= 2.0;
  350. break;
  351. }
  352. x = (drand48() * bandwidth);
  353. x += bandbottom;
  354. *val = x + bottom;
  355. return(FINISHED);
  356. }
  357. /**************************** INITIALISE_PHRASES *******************************/
  358. int initialise_phrases(int **phrnotecnt,double **phraseamp,double **phrange,noteptr **phrlastnote,dataptr dz)
  359. {
  360. if((*phrnotecnt = (int *)malloc(dz->tex->phrasecnt * sizeof(int)))==NULL) {
  361. sprintf(errstr,"INSUFFICIENT MEMORY for phrase notecnt array.\n");
  362. return(MEMORY_ERROR);
  363. }
  364. if((*phraseamp = (double *)malloc(dz->tex->phrasecnt * sizeof(double)))==NULL) {
  365. sprintf(errstr,"INSUFFICIENT MEMORY for phrase amplitude array.\n");
  366. return(MEMORY_ERROR);
  367. }
  368. if((*phrange = (double *)malloc(dz->tex->phrasecnt * sizeof(double)))==NULL) {
  369. sprintf(errstr,"INSUFFICIENT MEMORY for phrase range array.\n");
  370. return(MEMORY_ERROR);
  371. }
  372. if((*phrlastnote = (noteptr *)malloc(dz->tex->phrasecnt * sizeof(noteptr)))==NULL) {
  373. sprintf(errstr,"INSUFFICIENT MEMORY for phrase lastnote array.\n");
  374. return(MEMORY_ERROR);
  375. }
  376. return(FINISHED);
  377. }
  378. /********************** DO_EV_PCH *******************************
  379. *
  380. * Set pitch of event (not group etc.).
  381. */
  382. int do_ev_pch
  383. (double *thispitch,double thistime,double *pptop,double *ppbot,dataptr dz)
  384. {
  385. int exit_status;
  386. if((exit_status = getvalue(TEXTURE_MAXPICH,TEXTURE_MINPICH,thistime,PM_PITCH,thispitch,dz))<0)
  387. return(exit_status);
  388. if(*thispitch > MIDITOP || *thispitch < MIDIBOT) {
  389. sprintf(errstr,"TEXTURE: pitch [%.1f] out of midirange at time %.2f\n",*thispitch,thistime);
  390. return(DATA_ERROR);
  391. }
  392. *pptop = dz->param[TEXTURE_MAXPICH];
  393. *ppbot = dz->param[TEXTURE_MINPICH];
  394. return(FINISHED);
  395. }
  396. /************************** GET_GPPARMAS **************************
  397. *
  398. * Get the parameters for a group of notes.
  399. *
  400. * (1) Get gprange in normal way.
  401. * (2) Don't adjust range.
  402. * (3) For decorations, the range may be oriented, above, below
  403. * or centred on the initial note. So range is adjusted here.
  404. */
  405. int get_gpparams(double thistime,double thispitch,unsigned char dectypecnt,
  406. double *gprange,double *gprlow,int *gpsize,double *gpdense,double pptop,double ppbot,
  407. unsigned char dectypestor,int mingrpsize,dataptr dz)
  408. {
  409. int exit_status;
  410. if((exit_status = getvalue(TEX_GPRANGHI,TEX_GPRANGLO,thistime,PM_GPRANG,gprange,dz))<0)
  411. return(exit_status); /* 1 */
  412. if(!dectypecnt)
  413. squeezrange(thispitch,gprange,gprlow,pptop,ppbot);
  414. else {
  415. if((exit_status = orientrange
  416. (thispitch,pptop,ppbot,gprange,gprlow,dectypestor,dectypecnt,dz))<0)/* 3 */
  417. return(exit_status);
  418. }
  419. if((exit_status = igetvalue(TEX_GPSIZEHI,TEX_GPSIZELO,thistime,PM_GPSIZE,gpsize,dz))<0)
  420. return(PROGRAM_ERROR);
  421. if(*gpsize < mingrpsize) {
  422. sprintf(errstr,"Impossible GROUP SIZE value [%d]\n",*gpsize);
  423. return(PROGRAM_ERROR);
  424. }
  425. return get_density_val(thistime,gpdense,dz);
  426. }
  427. /*************************** ORIENTRANGE ******************************
  428. *
  429. */
  430. int orientrange
  431. (double thispitch,double pptop, double ppbot,double *gprange, double *gprlow,
  432. unsigned char dectypestor,unsigned char dectypecnt,dataptr dz)
  433. {
  434. int exit_status;
  435. unsigned char dectype;
  436. double top;
  437. int k;
  438. if((exit_status = doperm((int)dectypecnt,PM_ORIENT,&k,dz))<0)
  439. return(exit_status);
  440. if((exit_status = gettritype(k,dectypestor,&dectype))<0)
  441. return(exit_status);
  442. switch(dectype) {
  443. case(0): /* centred range */
  444. squeezrange(thispitch,gprange,gprlow,pptop,ppbot);
  445. dz->vflag[DECCENTRE] = TRUE;
  446. break;
  447. case(1): /* range above note */
  448. top = min((thispitch + *gprange),pptop);
  449. *gprlow = max((top - *gprange),ppbot);
  450. *gprange = top - *gprlow;
  451. dz->vflag[DECCENTRE] = FALSE;
  452. break;
  453. case(2): /* range below note */
  454. top = thispitch;
  455. *gprlow = max((top - *gprange),ppbot);
  456. *gprange = top - *gprlow;
  457. dz->vflag[DECCENTRE] = FALSE;
  458. break;
  459. default:
  460. sprintf(errstr,"TEXTURE: Problem in orientrange()\n");
  461. return(PROGRAM_ERROR);
  462. }
  463. return(FINISHED);
  464. }
  465. /*************************** SQUEEZRANGE ******************************
  466. *
  467. * Adjust range to lie within texture limits.
  468. *
  469. * (2) Top of range is at current pitch plus half range. If this is
  470. * above current top-of-texture range (pptop) move top down.
  471. * (3) Bottom of range is gprange below top. If this is below
  472. * bottom-of-texture range (ppbot), move gprangelo up.
  473. * (4) Recalculate the true gprange within true limits.
  474. */
  475. void squeezrange(double thispitch,double *gprange,double *gprlow, double pptop, double ppbot)
  476. {
  477. double top;
  478. top = min((thispitch + (*gprange/2.0)),pptop); /* 2 */
  479. *gprlow = max((top-*gprange),ppbot); /* 3 */
  480. *gprange = top - *gprlow; /* 4 */
  481. }