1 /* Copyright (c) 1995, 1996, 1997, 1998, 2002, 2003, 2004, 2006
2 * by Arkkra Enterprises */
3 /* All rights reserved */
7 * Description: This file contains functions for creating CHORD linked lists
8 * and erasing invisible voices.
16 static void swingmidi P((void));
17 static struct GRPSYL *voicevis P((struct GRPSYL *gs_p));
18 static void combine_voices P((void));
19 static void chkhand1 P((struct GRPSYL *gs1_p, struct MAINLL *staffmll_p));
20 static int chk2groups P((struct GRPSYL *hi_p, struct GRPSYL *lo_p,
21 struct MAINLL *mll_p, int qual));
22 static void chkhand2 P((struct GRPSYL *gs1_p, struct MAINLL *staffmll_p));
23 static int chk2neighbors P((struct GRPSYL *first_p, struct GRPSYL *second_p,
24 struct GRPSYL *gs1_p, struct MAINLL *mll_p));
25 static void dohand P((struct GRPSYL *gs1_p, struct MAINLL *staffmll_p));
26 static void comb2groups P((struct GRPSYL *dest_p, struct GRPSYL *src_p,
27 struct MAINLL *mll_p));
28 static void addsrc2dest P((struct GRPSYL *dest_p, struct GRPSYL *src_p));
29 static int setgrpptrs P((struct GRPSYL *gs1_p, struct GRPSYL *v_p[]));
30 static int hastieslur P((struct GRPSYL *gs_p));
35 * Abstract: Set up the linked lists of chords.
39 * Description: This function scans through the main linked list looking
40 * for STAFF structures. It joins the GRPSYL structures in
41 * the lists that they head, into perpendicular linked lists,
42 * allocating a CHORD to head each of these. It also links
43 * the CHORDs for each measure together into a linked list.
45 * While doing the above, it also calls voicevis() to check if a
46 * voice should be invisible, and if so changes it to a measure
47 * space. It also applies the swingunit and voicecombine
56 struct MAINLL *mainll_p; /* point at item in main linked list */
57 struct MAINLL *mainch_p; /* for headcell of a chord list */
59 RATIONAL *vtime; /* cum. time of each voice and verse */
60 struct GRPSYL **grpsyl_p; /* pointers along GRPSYL lists */
61 struct STAFF *staff_p; /* point at a staff structure */
63 RATIONAL mintime; /* the minimum vtime */
64 register int num; /* no. of visible voices/verses */
65 register int v; /* index into grpsyl_p[] */
66 struct CHORD *ch_p; /* pointer to current chord */
67 struct CHORD *och_p; /* pointer to old chord */
68 struct GRPSYL *gs_p; /* pointer to current group/syllable */
69 int n; /* loop variable */
70 int firstgs; /* flag for first group/syllable */
71 int quit; /* flag for being done */
74 debug(16, "makechords");
76 * If we are generating MIDI, we may need to change lengths (fulltimes)
77 * of groups. This has to be done now, before we link groups together
80 if (Doing_MIDI == YES) {
84 gs_p = 0; /* keep lint happy; will be set before used */
86 /* malloc enough of these for all voices and verses */
87 MALLOC(rational, vtime, MAXSTAFFS * (MAXVOICES + Maxverses));
88 MALLOC(GRPSYL *, grpsyl_p, MAXSTAFFS * (MAXVOICES + Maxverses));
90 mainll_p = Mainllhc_p; /* point at first thing in main LL */
92 initstructs(); /* clean out old SSV info */
95 * Loop once for each measure in the input.
98 num = 0; /* number of linked lists in measure */
101 * Look for the first structure in this measure that points off
102 * to a linked list of groups/syllables. If we hit the end of
103 * the main linked list, we're all done, so break out.
105 while (mainll_p != 0 && mainll_p->str != S_STAFF) {
106 if (mainll_p->str == S_SSV)
107 asgnssv(mainll_p->u.ssv_p);
108 mainll_p = mainll_p->next;
118 * We've found another measure with STAFF in it. Allocate
119 * a chord headcell for this measure, and put it in the
122 mainch_p = newMAINLLstruct(S_CHHEAD, 0);
123 insertMAINLL(mainch_p, mainll_p->prev);
126 * Look for the last STAFF structure in the measure. While
127 * doing this, point at first element of all the group/syllable
128 * linked lists, and keep count of them. Ignore invisible
129 * staffs. Skip over any grace groups.
131 while (mainll_p != 0 && mainll_p->str == S_STAFF) {
132 staff_p = mainll_p->u.staff_p;
134 if (staff_p->visible == YES) {
136 /* do all the voices on this staff */
137 for (n = 0; n < MAXVOICES &&
138 staff_p->groups_p[n] != 0; n++) {
140 * Zap voice if invisible. Set both
141 * of these to point at the first
142 * GRPSYL, which will be a new one if
145 grpsyl_p[num] = staff_p->groups_p[n] =
146 voicevis(staff_p->groups_p[n]);
148 /* skip leading grace groups */
149 while (grpsyl_p[num] != 0 &&
150 grpsyl_p[num]->grpvalue == GV_ZERO)
151 grpsyl_p[num] = grpsyl_p[num]->next;
152 if (grpsyl_p[num] == 0)
153 pfatal("nothing but grace groups found");
157 /* do all the verses on this staff */
158 for (n = 0; n < staff_p->nsyllists; n++)
159 grpsyl_p[num++] = staff_p->syls_p[n];
161 mainll_p = mainll_p->next;
165 * Set up the first chord from the first note in each
166 * voice/verse. Its linked list of GRPSYLs will include
167 * the first GRPSYL in every linked list off of a visible
170 MALLOC(CHORD, ch_p, 1);
171 mainch_p->u.chhead_p->ch_p = ch_p; /* point at first chord */
172 ch_p->ch_p = 0; /* only member on list so far */
173 ch_p->starttime = Zero; /* start time = any voice */
175 /* point headcell at first and set its first group's time */
176 ch_p->gs_p = grpsyl_p[0];
177 vtime[0] = grpsyl_p[0]->fulltime;
179 /* for each remaining one, point prev one at it & set time */
180 for (v = 1; v < num; v++) {
181 grpsyl_p[v-1]->gs_p = grpsyl_p[v];
182 vtime[v] = grpsyl_p[v]->fulltime;
184 grpsyl_p[num-1]->gs_p = 0; /* terminate linked list */
186 /* point at second GRPSYL in each voice/verse, if any */
187 for (v = 0; v < num; v++)
188 grpsyl_p[v] = grpsyl_p[v]->next;
191 * Loop until groups/syllables in the voices/verses are used
192 * up. Form a chord for each time at which any voice/verse
193 * has a GRPSYL structure, though ignore grace groups.
197 * If every GRPSYL currently pointed at by a grpsyl_p[]
198 * is the last in its list (the measure), there are no
199 * more chords in this measure, and quit will remain
202 quit = YES; /* first assume "quit" */
203 for (v = 0; v < num; v++) {
204 /* find next item (if any) not a grace group */
205 while (grpsyl_p[v] != 0 &&
206 grpsyl_p[v]->grpsyl == GS_GROUP &&
207 grpsyl_p[v]->grpvalue == GV_ZERO) {
209 grpsyl_p[v] = grpsyl_p[v]->next;
212 /* check if voice/verse has another item */
213 if (grpsyl_p[v] != 0) {
214 quit = NO; /* yes, so don't quit yet */
218 /* if time to quit, skip rest of loop, and get out */
223 * At least one voice/verse has another note in it.
224 * Find the earliest time at which something changes.
227 for (v = 1; v < num; v++)
228 if (LT(vtime[v], mintime))
231 /* allocate memory for another chord */
232 och_p = ch_p; /* remember where previous chord is */
233 MALLOC(CHORD, ch_p, 1);
234 och_p->ch_p = ch_p; /* point previous chord at it*/
235 ch_p->ch_p = 0; /* terminate in case last */
237 ch_p->starttime = mintime; /* starting time for chord*/
240 * Form a new linked list. The head cell is the new
241 * chord, and the list connects it to all the groups/
242 * syllables that start at this time.
245 for (v = 0; v < num; v++) {
246 if (EQ(vtime[v], mintime)) {
248 * This voice/verse has a grpsyl at
249 * this time. Make the previous one
250 * point at it, set its pointer to 0
251 * in case it turns out to be the last,
252 * and add its length to vtime[v].
254 if (firstgs == YES) {
255 /* point headcell at first */
256 ch_p->gs_p = grpsyl_p[v];
259 /* point previous one at ours*/
260 gs_p->gs_p = grpsyl_p[v];
263 /* set gs_p to point at our new one */
266 vtime[v] = radd(vtime[v],
269 /* get next GRPSYL in voice/verse */
270 grpsyl_p[v] = gs_p->next;
274 gs_p->gs_p = 0; /* terminate linked list */
278 * Set the duration of each chord in this measure. It's the
279 * next chord's start time minus this chord's start time.
280 * But for the last chord, it's the time signature minus
281 * this chord's start time. Also set pseudodur, which is a
282 * function of the duration. The amount of width the chord
283 * "deserves" to be allocated is proportional to pseudodur.
285 for (ch_p = mainch_p->u.chhead_p->ch_p; ch_p->ch_p != 0;
287 ch_p->duration = rsub(ch_p->ch_p->starttime,
289 ch_p->pseudodur = pow(RAT2FLOAT(ch_p->duration),
292 ch_p->duration = rsub(Score.time, ch_p->starttime);
293 ch_p->pseudodur = pow(RAT2FLOAT(ch_p->duration), Score.packexp);
296 /* if voicecombine parm was ever set, combine voices if possible */
297 if (Vcombused == YES) {
305 * Abstract: Alter groups' time to implement the "swingunit" parameter.
309 * Description: This function loops through every GRPSYL in every voice,
310 * adjusting their fulltime so that they will start and end at
311 * different times, if necessary, to follow the "swingunit" parm.
312 * Each measure is divided into durations of "swingunit", starting
313 * at the beginning. (Usually the timesig divided by swingunit
314 * will be an integer, but if not, the last piece will be shorter.)
315 * The time where one group ends and the next group starts will be
316 * altered in either of these two circumstances:
317 * 1. The current boundary time is halfway into a swingunit, and
318 * each group is at least half a swingunit long.
319 * 2. The current boundary time is 3/4 of the way into a swingunit,
320 * and the first group is at least 3/4 of a swingunit long, and
321 * and the second group is at least 1/4 of a swingunit long.
322 * In both of these cases, the fulltimes are altered so that the
323 * meeting point is 2/3 of the way into the swingunit.
329 struct MAINLL *mainll_p; /* point along main linked list */
330 struct GRPSYL *gs_p; /* point along a GRPSYL list */
331 struct GRPSYL *prev_p; /* the GRPSYL before gs_p */
332 int vidx; /* voice index, 0 to MAXVOICES-1 */
333 RATIONAL quot; /* quotient */
334 RATIONAL swingunit; /* from SSV */
335 RATIONAL starttime; /* offset into measure of gs_p */
336 RATIONAL halfswing; /* swingunit/2 */
337 RATIONAL sixthswing; /* swingunit/6 */
338 RATIONAL twelfthswing; /* swingunit/12 */
339 RATIONAL threefourthsswing; /* 3/4 * swingunit */
340 RATIONAL onefourthswing; /* 1/4 * swingunit */
341 static RATIONAL six = {6,1};
342 static RATIONAL twelve = {12,1};
347 for (mainll_p = Mainllhc_p; mainll_p != 0; mainll_p = mainll_p->next) {
349 switch (mainll_p->str) {
351 /* need to keep swingunit up to date */
352 asgnssv(mainll_p->u.ssv_p);
355 break; /* break out and handle this staff */
360 /* loop through every voice on this staff */
361 for (vidx = 0; vidx < MAXVOICES; vidx++) {
363 swingunit = vvpath(mainll_p->u.staff_p->staffno,
364 vidx + 1, SWINGUNIT)->swingunit;
366 /* skip this voice if swingunit was not set */
367 if (EQ(swingunit, Zero)) {
371 /* various rationals we will need in the loop below */
372 halfswing = rdiv(swingunit, Two);
373 threefourthsswing = rmul(swingunit, Three_fourths);
374 onefourthswing = rmul(swingunit, One_fourth);
375 sixthswing = rdiv(swingunit, six);
376 twelfthswing = rdiv(swingunit, twelve);
378 /* accumulate starttime */
381 /* for lint; we'll never really check it when it's 0 */
384 /* find first nongrace group in voice (0 if none) */
385 gs_p = mainll_p->u.staff_p->groups_p[vidx];
386 gs_p = gs_p != 0 && gs_p->grpvalue == GV_ZERO ?
387 nextnongrace(gs_p) : gs_p;
389 /* loop through every nongrace group in this voice */
390 for ( ; gs_p != 0; gs_p = nextnongrace(gs_p)) {
392 quot = rdiv(starttime, swingunit);
394 /* set starttime for the following group here
395 * because we may alter fulltime below */
396 starttime = radd(starttime, gs_p->fulltime);
398 /* handle case 1 (see prolog above) */
400 GE(gs_p->fulltime, halfswing) &&
401 GE(prev_p->fulltime, halfswing)) {
403 prev_p->fulltime = radd(
404 prev_p->fulltime, sixthswing);
405 gs_p->fulltime = rsub(
406 gs_p->fulltime, sixthswing);
409 /* handle case 2 (see prolog above) */
410 if (quot.d == 4 && quot.n % 4 == 3 &&
411 GE(gs_p->fulltime, onefourthswing) &&
412 GE(prev_p->fulltime, threefourthsswing)) {
414 prev_p->fulltime = rsub(
415 prev_p->fulltime, twelfthswing);
416 gs_p->fulltime = radd(
417 gs_p->fulltime, twelfthswing);
429 * Abstract: If this voice is to be invisible, make it a measure space.
431 * Returns: pointer to first GRPSYL; this equals the input pointer if the
432 * voice is visible, else it points at the new measure space GRPSYL
434 * Description: This function finds out if the given voice is supposed to be
435 * invisible this measure. If so, it throws away the current
436 * GRPSYL list, replacing it with a single GRPSYL that is a
437 * measure space. See the big comment in svpath() in ssv.c.
441 static struct GRPSYL *
444 struct GRPSYL *gs_p; /* first GRPSYL in this voice's linked list */
447 struct GRPSYL *ngs_p; /* pointer to the new GRPSYL */
451 * At this point we know that the command line -s option allows this
452 * staff to be printed, and in fact this staff will be printed, because
453 * at least one of its voice(s) is supposed to be. (We know this
454 * because where we were called from, staff_p->visible == YES, and that
455 * was set by calling svpath().) If the staff weren't being printed,
456 * we wouldn't need to bother wiping out its invisible voice(s).
460 * This voice must be changed to a measure space if the -s option says
461 * it should be invisible, or if the SSVs say so. The vvpath function
462 * checks both things.
464 if (vvpath(gs_p->staffno, gs_p->vno, VISIBLE)->visible == NO) {
467 * Allocate a new GRPSYL and make it a measure space, with the
468 * same inputlineno etc. as the first in the current list.
470 ngs_p = newGRPSYL(GS_GROUP);
472 ngs_p->inputlineno = gs_p->inputlineno;
473 ngs_p->inputfile = gs_p->inputfile;
474 ngs_p->staffno = gs_p->staffno;
475 ngs_p->vno = gs_p->vno;
476 ngs_p->grpsyl = GS_GROUP;
477 ngs_p->is_meas = YES;
478 ngs_p->basictime = -1;
480 /* in one compiler the following had to be done separately */
481 /* like this, because it couldn't do the structure assignment */
482 ngs_p->fulltime.n = Score.time.n;
483 ngs_p->fulltime.d = Score.time.d;
485 ngs_p->grpcont = GC_SPACE;
490 /* throw away the old GRPSYL list */
493 return (ngs_p); /* ret pointer to the measure space */
496 return (gs_p); /* ret pointer to the original, unchanged GRPSYL */
500 * Name: combine_voices()
502 * Abstract: Combine GRPSYLs in voices according to the voicecombine parm.
506 * Description: This function, if requested by the voicecombine parameter,
507 * combines the appropriate groups in each chord on each staff
508 * where it can. (The set of groups in one chord on one staff is
509 * called a "hand" in the following code and in some other places
510 * in Mup, because I get tired of spelling out the whole phrase.)
511 * Because of beaming and ties/slurs, some groups may need to
512 * remain uncombined because their neighbors can't be combined.
513 * So the work is done in three passes. The first pass looks at
514 * each hand individually to see what can be done there. The
515 * second pass applies the neighbor rules. The third pass does
516 * the actual combining.
519 * NOTE: GRPSYL.pvno is used as a scratch area in these functions. The macro
520 * below defines COMB to be pvno for this use. We rely on the fact that CALLOC
521 * initialized it to 0. We count the low order bit as bit 0. Two sets of bits
522 * are used, as follows.
524 * Bit "x+y" being set to 1 means that the GRPSYLs of voices x and y can be
525 * combined (looking only at the groups in this chord, not groups they may be
526 * tie/beamed to, etc.). This scheme works only because the only voice numbers
527 * are 1, 2, and 3, so that uses bits 3, 4, and 5. The first pass sets them,
528 * and the second pass reads them.
530 * Bits 6 through 13 are used in pairs for voice numbers of groups that really
531 * should be combined, with all rules applied. The SHIFT macros below give the
532 * rightmost bit of each of the voice numbers, for the two possible sources and
533 * destinations that can happen, given that only 3 voices can exist. Pass 2
534 * sets these bits, and pass 3 reads them.
540 #define DEST2SHIFT 12
545 struct MAINLL *mll_p; /* point along main linked list */
546 struct MAINLL *staffmll_p; /* point a group's staff's MLL struct */
547 struct CHORD *ch_p; /* point along a chord list */
548 struct GRPSYL *gs1_p; /* point along the GRPSYL list of a chord */
549 int staff; /* staff number we are working on */
550 int pass; /* the three passes we must make */
553 /* run the three passes */
554 for (pass = 1; pass <= 3; pass++) {
556 initstructs(); /* clean out old SSV info */
558 for (mll_p = Mainllhc_p; mll_p != 0; mll_p = mll_p->next) {
560 switch (mll_p->str) {
562 /* keep SSVs up to date (but midmeasure SSVs
563 * don't matter for what we're doing here) */
564 asgnssv(mll_p->u.ssv_p);
567 break; /* break out to handle the chords */
569 continue; /* ignore everything else */
573 * Loop through each chord in this list.
575 for (ch_p = mll_p->u.chhead_p->ch_p; ch_p != 0;
578 * Loop through the linked list of GRPSYLs
579 * hanging off this chord. Skip the syllables;
580 * just deal with the groups.
583 staff = 0; /* before first staff */
585 /* find first group on next staff */
587 gs1_p->staffno == staff) {
590 if (gs1_p == 0) { /* no next staff */
594 /* remember this new staff number */
595 staff = gs1_p->staffno;
597 /* tab ignores vcombine */
598 if (is_tab_staff(staff)) {
602 /* 1-line ignores vcombine */
603 if (svpath(staff, STAFFLINES)->
608 /* if no groups, only syls, ignore */
609 if (gs1_p->grpsyl == GS_SYLLABLE) {
613 /* skip staff if only one voice */
614 if (svpath(staff, VSCHEME)->vscheme
619 /* get the staff's MLL struct */
620 staffmll_p = chmgrp2staffm(
626 * Set individual combineability
627 * in the "COMB" field.
629 chkhand1(gs1_p, staffmll_p);
633 * Apply the neighbor rules.
635 chkhand2(gs1_p, staffmll_p);
639 * Do the actual combining.
641 dohand(gs1_p, staffmll_p);
653 * Abstract: Find which voices are combineable, ignoring neighbor rules.
657 * Description: This function finds out which groups in this hand can be
658 * combined, of the ones requested by the voicecombine parameter,
659 * but ignoring neighbor rules. It stores the results in
660 * the COMB field of all the groups.
664 chkhand1(gs1_p, mll_p)
666 struct GRPSYL *gs1_p; /* first group in this hand */
667 struct MAINLL *mll_p; /* MLL struct for this group */
671 * Index the following by voice number to find the expected "height" of
672 * the voices, relative to each other. A higher number means we expect
673 * that that voice should normally be higher.
675 static int pitch[MAXVOICES + 1] = { 0, 3, 1, 2 };
677 struct SSV *ssv_p; /* the SSV with voice combine info */
678 struct GRPSYL *gs_p; /* point along GRPSYLs of the chord */
679 /* index the following by vno; it points at the GRPSYL for this vno */
680 struct GRPSYL *v_p[MAXVOICES + 1];
681 int slot1, slot2; /* indices into SSV's vcombine array */
682 int firstvno, secondvno; /* two voices from ssv_p->vcombine[] */
683 int combineable; /* YES or NO */
684 int comb; /* accumulate combineable bits */
687 /* point at each group; if only one, no combining can be done */
688 if (setgrpptrs(gs1_p, v_p) == 1) {
692 /* get the list of groups we want to combine */
693 ssv_p = svpath(gs1_p->staffno, VCOMBINE);
695 /* for each pair of voices to be combined, see if they can be */
697 for (slot1 = 0; slot1 < MAXVOICES; slot1++) {
698 firstvno = ssv_p->vcombine[slot1];
700 break; /* end of list, done with outer loop */
702 /* voice must have a group in this chord */
703 if (v_p[firstvno] == 0) {
704 continue; /* skip this iteration */
706 for (slot2 = slot1 + 1; slot2 < MAXVOICES; slot2++) {
707 secondvno = ssv_p->vcombine[slot2];
708 if (secondvno == 0) {
709 break; /* end of list, done with inner loop */
711 /* voice must have a group in this chord */
712 if (v_p[secondvno] == 0) {
713 continue; /* skip this iteration */
715 /* must pass higher voice first */
716 if (pitch[firstvno] > pitch[secondvno]) {
717 combineable = chk2groups(v_p[firstvno],
718 v_p[secondvno], mll_p,
719 ssv_p->vcombinequal);
721 combineable = chk2groups(v_p[secondvno],
722 v_p[firstvno], mll_p,
723 ssv_p->vcombinequal);
726 /* if this pair was combineable, remember that */
727 if (combineable == YES) {
728 comb |= 1 << (firstvno + secondvno);
733 /* save comb in all the groups, for easy access */
734 for (gs_p = gs1_p; gs_p != 0 && gs_p->staffno == gs1_p->staffno &&
735 gs_p->grpsyl == GS_GROUP; gs_p = gs_p->gs_p) {
743 * Abstract: Find whether two groups are combineable.
747 * Description: This function finds out if the given groups can be combined,
748 * ignoring beam and tie/slur issues. If either has preceding
749 * grace groups, they are also checked (via recursive calls) and
750 * they must also be able to be combined, to get a YES answer.
754 chk2groups(hi_p, lo_p, mll_p, qual)
756 struct GRPSYL *hi_p; /* group that should have higher pitch */
757 struct GRPSYL *lo_p; /* group that should have lower pitch */
758 struct MAINLL *mll_p; /* MLL struct for this group */
759 int qual; /* voice combine qualifier */
762 struct GRPSYL *phi_p; /* group before hi_p */
763 struct GRPSYL *plo_p; /* group before lo_p */
764 struct MAINLL *tempmll_p; /* temp copy of mll_p */
765 int widx; /* index into "with" lists */
766 int hidx, lidx; /* index into note lists */
767 int mintop; /* steps above c0 of top group's lowest note */
768 int maxbot; /* steps above c0 of bot group's highest note */
769 int n; /* loop variable */
770 struct NOTE *hnote_p; /* point at a note in the high group */
771 struct NOTE *lnote_p; /* point at a note in the low group */
772 struct SLURTO *hslur_p; /* point at a slur in the high group */
773 struct SLURTO *lslur_p; /* point at a slur in the high group */
777 * Since the groups are in the same chord, we know they start at the
778 * same time. Require that they end at the same time.
780 if (NE(hi_p->fulltime, lo_p->fulltime)) {
784 /* covered by the fulltime check, except for bizarre tuplet cases */
785 if (hi_p->basictime != lo_p->basictime) {
788 if (hi_p->dots != lo_p->dots) {
792 /* don't allow "mr" and "1r" (for example) to combine */
793 if (hi_p->is_meas != lo_p->is_meas) {
797 /* tuploc must agree */
798 if (hi_p->tuploc != lo_p->tuploc) {
802 /* tupcont must agree */
803 if (hi_p->tupcont != lo_p->tupcont) {
807 /* if printtup is set in both groups, they must agree */
808 if (hi_p->printtup != PT_DEFAULT && lo_p->printtup != PT_DEFAULT &&
809 hi_p->printtup != lo_p->printtup) {
813 /* if tupside is set in both groups, they must agree */
814 if (hi_p->tupside != PL_UNKNOWN && lo_p->tupside != PL_UNKNOWN &&
815 hi_p->tupside != lo_p->tupside) {
819 /* don't allow cross staff beamed groups */
820 if (hi_p->beamto != CS_SAME || lo_p->beamto != CS_SAME) {
824 /* don't allow cross staff stemmed groups */
825 if (hi_p->stemto != CS_SAME || lo_p->stemto != CS_SAME) {
829 /* if either is a space, there can be no other conflict */
830 if (hi_p->grpcont == GC_SPACE || lo_p->grpcont == GC_SPACE) {
834 /***** both groups are GC_NOTES and/or GC_REST *****/
836 /* group size must agree */
837 if (hi_p->grpsize != lo_p->grpsize) {
841 /* if both are rests, there can be no other conflict */
842 if (hi_p->grpcont == GC_REST && lo_p->grpcont == GC_REST) {
846 /* if only one is a rest, there is a conflict */
847 if (hi_p->grpcont == GC_REST || lo_p->grpcont == GC_REST) {
851 /***** both groups are GC_NOTES *****/
853 /* head shape must agree */
854 if (hi_p->headshape != lo_p->headshape) {
858 /* beaming must be the same on both, except on grace beamloc doesn't
859 * matter, since if we combine them we'll beam them all anyway */
860 if (hi_p->beamloc != lo_p->beamloc && hi_p->grpvalue == GV_NORMAL) {
863 if (hi_p->breakbeam != lo_p->breakbeam) {
866 if (hi_p->beamslope != NOBEAMANGLE && lo_p->beamslope != NOBEAMANGLE &&
867 hi_p->beamslope != lo_p->beamslope) {
871 /* if both stemdirs are set, they must agree */
872 if (hi_p->stemlen != STEMLEN_UNKNOWN &&
873 lo_p->stemlen != STEMLEN_UNKNOWN &&
874 hi_p->stemlen != lo_p->stemlen) {
878 /* if both stemdirs are forced, they must agree */
879 if (hi_p->stemdir != UNKNOWN && lo_p->stemdir != UNKNOWN &&
880 hi_p->stemdir != lo_p->stemdir) {
884 /* group ties out of this group must agree */
885 if (hi_p->tie != lo_p->tie) {
889 /* group ties into this group must agree */
891 phi_p = prevgrpsyl(hi_p, &tempmll_p);
893 plo_p = prevgrpsyl(lo_p, &tempmll_p);
894 if (phi_p != 0 && plo_p != 0 && phi_p->tie != plo_p->tie) {
898 /* tremelo slashes or alternation slashes must agree */
899 if (hi_p->slash_alt != lo_p->slash_alt) {
903 /* neither group can have a horizontal offset */
904 if (hi_p->ho_usage != HO_NONE || lo_p->ho_usage != HO_NONE) {
908 /* "with" lists must both be nonexistent, or else identical */
909 if (hi_p->nwith != lo_p->nwith) {
912 for (widx = 0; widx < hi_p->nwith; widx++) {
913 if (strcmp(hi_p->withlist[widx], lo_p->withlist[widx]) != 0) {
919 * Rolls aren't really implemented for voice 3. Voice 3 is just along
920 * for the ride, if it's in the middle of a roll. So we'll let it
921 * combine as long as both groups are in a roll, or not. But for
922 * voices 1 and 2, only allow specific combinations that make sense.
924 if (hi_p->vno == 1 && lo_p->vno == 2) {
925 switch ((hi_p->roll << 8) | lo_p->roll) {
926 case (NOITEM << 8) | NOITEM:
928 case (STARTITEM << 8) | INITEM:
929 case (STARTITEM << 8) | ENDITEM:
930 case (INITEM << 8) | INITEM:
931 case (INITEM << 8) | ENDITEM:
932 if (hi_p->rolldir != lo_p->rolldir) {
940 if ((hi_p->roll == NOITEM) != (lo_p->roll == NOITEM)) {
946 * If each group is preceded by a grace group, those grace groups must
947 * also be combineable. Notice that if there are multiple preceding
948 * grace groups, more recursive calls will occur. If one is preceded
949 * and the other isn't, there is no problem and nothing to check.
951 if (hi_p->prev != 0 && hi_p->prev->grpvalue == GV_ZERO &&
952 lo_p->prev != 0 && lo_p->prev->grpvalue == GV_ZERO) {
953 if (chk2groups(hi_p->prev, lo_p->prev, mll_p, qual) == NO) {
958 /* if either is a mrpt, the other must be, and there is no conflict */
959 if (hi_p->is_meas == YES) {
963 /***** both groups have a notelist *****/
966 * Do some checks involving overlapping of the groups. We'd like to
967 * use stepsup, but it won't be set to its correct value until
968 * setnotes.c. Fortunately, we don't need to know the absolute
969 * vertical position, only the relative. So just use steps above c0.
971 mintop = hi_p->notelist[hi_p->nnotes - 1].octave * 7 +
972 Letshift[hi_p->notelist[hi_p->nnotes - 1].letter - 'a'];
973 maxbot = lo_p->notelist[0].octave * 7 +
974 Letshift[lo_p->notelist[0].letter - 'a'];
976 * If the lowest note of the high group is higher than the highest of
977 * the low group, we are okay regardless of the vcombine qualifier,
978 * and there are no shared notes to check.
980 if (mintop > maxbot) {
984 /* if they are equal, and parm doesn't allow it, fail */
985 if (mintop == maxbot && qual == VC_NOOVERLAP) {
989 /* if there is true overlap, and parm doesn't allow it, fail */
990 if (mintop < maxbot && qual != VC_OVERLAP) {
995 * Any shared notes must be compatible, so check every note in the top
996 * group against every note in the bottom group. If any are equal,
997 * they must be compatible.
999 for (hidx = 0; hidx < hi_p->nnotes; hidx++) {
1001 hnote_p = &hi_p->notelist[hidx];
1003 for (lidx = 0; lidx < lo_p->nnotes; lidx++) {
1005 lnote_p = &lo_p->notelist[lidx];
1007 /* if the notes aren't equal, don't check them */
1008 if (hnote_p->octave != lnote_p->octave ||
1009 hnote_p->letter != lnote_p->letter) {
1010 /* the notes differ; no problem */
1014 /* notes match; check all the items that must agree */
1016 /* any slurs they have must be the same */
1017 if (hnote_p->nslurto != lnote_p->nslurto) {
1020 for (n = 0; n < hnote_p->nslurto; n++) {
1021 hslur_p = &hnote_p->slurtolist[n];
1022 lslur_p = &lnote_p->slurtolist[n];
1023 if (hslur_p->letter != lslur_p->letter) {
1026 if (hslur_p->octave != lslur_p->octave) {
1029 if (hslur_p->slurstyle != lslur_p->slurstyle) {
1032 if (hslur_p->slurdir != lslur_p->slurdir) {
1037 /* must have same accidental, or none */
1038 if (hnote_p->accidental != lnote_p->accidental) {
1042 /* head shape override, or none, must agree */
1043 if (hnote_p->headshape != lnote_p->headshape) {
1047 /* note size must agree */
1048 if (hnote_p->notesize != lnote_p->notesize) {
1052 /* tie related attributes must be the same */
1053 if (hnote_p->tie != lnote_p->tie) {
1056 if (hnote_p->tiestyle != lnote_p->tiestyle) {
1059 if (hnote_p->tiedir != lnote_p->tiedir) {
1062 if (hnote_p->is_bend != lnote_p->is_bend) {
1065 if (hnote_p->smallbend != lnote_p->smallbend) {
1071 return (YES); /* passed all tests, the groups are combineable */
1077 * Abstract: Make final decision on what can be combined in this hand.
1081 * Description: This function applies the additional rules about beaming and
1082 * ties/slurs to the results of chkhand1(), to decide what groups
1083 * in this hand truly should be combined. It stores the results
1084 * in the COMB field of all the groups.
1088 chkhand2(gs1_p, mll_p)
1090 struct GRPSYL *gs1_p; /* first group in this hand */
1091 struct MAINLL *mll_p; /* MLL struct for this group */
1094 struct SSV *ssv_p; /* the SSV with voice combine info */
1095 /* index the following by vno; it points at the GRPSYL for this vno */
1096 struct GRPSYL *v_p[MAXVOICES + 1];
1097 int slot1, slot2; /* indices into SSV's vcombine array */
1098 int firstvno, secondvno; /* two voices from ssv_p->vcombine[] */
1099 int keep_going; /* try some more? */
1102 /* if we already know no combining can be done, get out */
1103 if (gs1_p->COMB == 0) {
1107 /* point at all the groups in this hand */
1108 (void)setgrpptrs(gs1_p, v_p);
1110 /* get the list of groups we want to combine */
1111 ssv_p = svpath(gs1_p->staffno, VCOMBINE);
1113 /* for each pair of voices to be combined, apply the neighbor rules */
1114 for (slot1 = 0; slot1 < MAXVOICES; slot1++) {
1115 firstvno = ssv_p->vcombine[slot1];
1116 if (firstvno == 0) {
1117 break; /* end of list, done with outer loop */
1119 /* voice must have a group in this chord */
1120 if (v_p[firstvno] == 0) {
1121 continue; /* skip this iteration */
1123 for (slot2 = slot1 + 1; slot2 < MAXVOICES; slot2++) {
1124 secondvno = ssv_p->vcombine[slot2];
1125 if (secondvno == 0) {
1126 break; /* end of list, done with inner loop */
1128 /* voice must have a group in this chord */
1129 if (v_p[secondvno] == 0) {
1130 continue; /* skip this iteration */
1133 * The group with the lower voice number should be the
1134 * one that absorbs the other. Pass it first.
1136 if (firstvno < secondvno) {
1137 keep_going = chk2neighbors(v_p[firstvno],
1138 v_p[secondvno], gs1_p, mll_p);
1140 keep_going = chk2neighbors(v_p[secondvno],
1141 v_p[firstvno], gs1_p, mll_p);
1144 /* get out now if we are told to */
1145 if (keep_going == NO) {
1153 * Name: chk2neighbors()
1155 * Abstract: Apply beaming and tie/slur rules to two groups in a hand.
1157 * Returns: YES or NO: should any further combining be attempted?
1159 * Description: This function checks whether the two groups should be combined,
1160 * by looking at neighboring groups if beaming or ties/slurs
1161 * are involved. It stores the answer in the COMB field of all
1164 * If we shouldn't combine the groups, we return YES so that we
1165 * can come back and try a different pair, if appropriate. If we
1166 * can combine the groups, we may return YES or NO; see comments
1171 chk2neighbors(dest_p, src_p, gs1_p, mll_p)
1173 struct GRPSYL *dest_p; /* group that should absorb the other */
1174 struct GRPSYL *src_p; /* group that should be absorbed */
1175 struct GRPSYL *gs1_p; /* first group in staff/chord */
1176 struct MAINLL *mll_p; /* MLL struct for these groups' staff */
1179 struct GRPSYL *d2_p, *s2_p; /* point at neighboring groups */
1180 struct GRPSYL *gs_p; /* point at groups in this chord */
1181 struct MAINLL *mll2_p, *mll3_p; /* more pointers into MLL */
1182 short mask; /* to be applied to "COMB" */
1183 short comb; /* hold combineability bits */
1184 int keep_going; /* return code */
1188 * Set up the bit that we must check in each chord to see if these two
1189 * voices are combineable.
1191 mask = 1 << (dest_p->vno + src_p->vno);
1194 * Start at this chord, and keep looking to the right as long as the
1195 * groups are beamed or tied/slurred.
1198 for (d2_p = dest_p, s2_p = src_p; d2_p != 0 && s2_p != 0;
1199 d2_p = nextglobnongrace(d2_p, &mll2_p),
1200 s2_p = nextglobnongrace(s2_p, &mll2_p)) {
1202 * If the groups in that chord are not combineable, we must not
1203 * combine our original groups either. The same flags are set
1204 * in d2_p and s2_p, so we could have checked either.
1206 if ((d2_p->COMB & mask) == 0) {
1211 * If the groups are not beamed or tied/slurred to the right,
1212 * we don't have to look any farther. For beams, we only have
1213 * to check one group, since the other must agree or we
1214 * wouldn't be here. For ties/slurs, we only have to check the
1215 * the src, since those are the ones that wouldn't work if
1216 * these groups were combined and the next ones weren't.
1218 if ((s2_p->beamloc == NOITEM || s2_p->beamloc == ENDITEM) &&
1219 hastieslur(s2_p) == NO) {
1225 * Start at this chord, and keep looking to the left as long as the
1226 * groups are beamed or tied/slurred.
1229 for (d2_p = dest_p, s2_p = src_p; d2_p != 0 && s2_p != 0;
1230 d2_p = prevglobnongrace(d2_p, &mll2_p),
1231 s2_p = prevglobnongrace(s2_p, &mll2_p)) {
1233 if ((d2_p->COMB & mask) == 0) {
1237 mll3_p = mll2_p; /* don't alter mll2_p */
1238 if ((s2_p->beamloc == NOITEM || s2_p->beamloc == STARTITEM) &&
1239 hastieslur(prevglobnongrace(s2_p, &mll3_p)) == NO) {
1244 /* for convenience, copy the COMB bits into a local variable */
1245 comb = dest_p->COMB;
1248 * We passed all the tests, so remember that we should combine the
1249 * original groups. Also decide whether any more should be tried.
1251 if (((comb >> SRC1SHIFT) & 0x3) == 0) {
1252 /* first groups to be combined in this hand */
1253 comb |= src_p->vno << SRC1SHIFT;
1254 comb |= dest_p->vno << DEST1SHIFT;
1256 * If chkhand1() said all the groups in this hand were
1257 * combineable, we can come back later and try to combine the
1258 * other group. Otherwise, don't. We know the non-combineable
1259 * group will fail to combine, so don't waste the time.
1261 if ((comb & 0x38) == ((1 << (1 + 2)) | (1 << (1 + 3)) |
1268 /* second groups to be combined in this hand */
1269 comb |= src_p->vno << SRC2SHIFT;
1270 comb |= dest_p->vno << DEST2SHIFT;
1271 keep_going = NO; /* only 2 combinings can be done */
1275 * Since we will combine these two groups, the new dest group has
1276 * inherited any incompatibility that src might have had with the
1277 * other group (if any). So find the new value of the comb bits.
1278 * Set this new comb value into all the groups in this hand. We do
1279 * this for the benefit of later chords on this staff, if they are
1280 * beamed or tied/slurred to us.
1282 switch (dest_p->vno + src_p->vno) {
1283 case 1 + 2: /* combined 2 into 1 */
1284 /* if 2 and 3 can't combine, now 1 and 3 can't */
1285 if ((comb & (1 << (2 + 3))) == 0) {
1286 comb &= ~(1 << (1 + 3));
1289 case 1 + 3: /* combined 3 into 1 */
1290 /* if 3 and 2 can't combine, now 1 and 2 can't */
1291 if ((comb & (1 << (3 + 2))) == 0) {
1292 comb &= ~(1 << (1 + 2));
1295 case 2 + 3: /* combined 3 into 2 */
1296 /* if 3 and 1 can't combine, now 2 and 1 can't */
1297 if ((comb & (1 << (3 + 1))) == 0) {
1298 comb &= ~(1 << (2 + 1));
1302 for (gs_p = gs1_p; gs_p != 0 && gs_p->staffno == gs1_p->staffno &&
1303 gs_p->grpsyl == GS_GROUP; gs_p = gs_p->gs_p) {
1307 return (keep_going);
1313 * Abstract: Combine the appropriate GRPSYLs in one chord on one staff.
1317 * Description: This function combines GRPSYLs in one chord on one staff. It
1318 * uses the previously determined list of what is combineable in
1323 dohand(gs1_p, mll_p)
1325 struct GRPSYL *gs1_p; /* first group on this staff in this chord */
1326 struct MAINLL *mll_p; /* MLL struct for this group */
1329 /* index the following by vno; it points at the GRPSYL for this vno */
1330 struct GRPSYL *v_p[MAXVOICES + 1];
1331 int srcv, destv; /* src and dest voice numbers */
1334 /* if we already know no combining can be done, get out */
1335 if (gs1_p->COMB == 0) {
1339 /* point at all the groups in this hand */
1340 (void)setgrpptrs(gs1_p, v_p);
1342 /* get first src group's voice number */
1343 srcv = (gs1_p->COMB >> SRC1SHIFT) & 0x3;
1346 /* find the dest's voice and combine */
1347 destv = (gs1_p->COMB >> DEST1SHIFT) & 0x3;
1348 comb2groups(v_p[destv], v_p[srcv], mll_p);
1350 /* get second src group's voice number */
1351 srcv = (gs1_p->COMB >> SRC2SHIFT) & 0x3;
1354 /* find the dest's voice and combine */
1355 destv = (gs1_p->COMB >> DEST2SHIFT) & 0x3;
1356 comb2groups(v_p[destv], v_p[srcv], mll_p);
1362 * Name: comb2groups()
1364 * Abstract: Combine one group into another.
1368 * Description: This function combines the src group into the dest group,
1369 * including handling any preceding grace groups.
1373 comb2groups(dest_p, src_p, mll_p)
1375 struct GRPSYL *dest_p; /* group that should absorb the other */
1376 struct GRPSYL *src_p; /* group that should be absorbed */
1377 struct MAINLL *mll_p; /* MLL struct for these groups' staff */
1380 struct GRPSYL *dgrace_p; /* dest grace group */
1381 struct GRPSYL *sgrace_p; /* src grace group */
1382 struct GRPSYL *dmem_p; /* remember a group from dest voice */
1383 struct GRPSYL *smem_p; /* remember a group from src voice */
1384 struct GRPSYL *temp_p; /* temp pointer */
1385 struct GRPSYL *fgs_p; /* first grace in src voice */
1389 * Add the src into the dest, and make the src group into a space if it
1390 * isn't already a space.
1392 addsrc2dest(dest_p, src_p);
1393 if (src_p->grpcont != GC_SPACE) {
1394 src_p->grpcont = GC_SPACE;
1395 src_p->grpvalue = GV_NORMAL;
1396 src_p->grpsize = GS_NORMAL;
1397 src_p->headshape = HS_UNKNOWN;
1398 src_p->beamloc = NOITEM;
1399 src_p->beamslope = NOBEAMANGLE;
1400 src_p->stemlen = STEMLEN_UNKNOWN;
1401 src_p->stemdir = UNKNOWN;
1402 src_p->breakbeam = NO;
1403 src_p->beamloc = NOITEM;
1404 src_p->notelist = 0;
1407 src_p->slash_alt = 0;
1408 src_p->restdist = NORESTDIST;
1410 src_p->roll = NOITEM;
1413 /* if source has no grace notes, we're done */
1414 if (src_p->prev == 0 || src_p->prev->grpvalue == GV_NORMAL) {
1419 * Loop through the matching grace groups preceding the src and dest
1420 * groups, adding the src into the dest. Remember the leftmost pair,
1421 * or the nongrace groups if there are no matching pairs.
1425 for (sgrace_p = src_p->prev, dgrace_p = dest_p->prev;
1426 sgrace_p != 0 && sgrace_p->grpvalue == GV_ZERO &&
1427 dgrace_p != 0 && dgrace_p->grpvalue == GV_ZERO;
1428 sgrace_p = sgrace_p->prev, dgrace_p = dgrace_p->prev) {
1430 addsrc2dest(dgrace_p, sgrace_p);
1431 dmem_p = dgrace_p; /* remember last one done */
1435 if (sgrace_p != 0 && sgrace_p->grpvalue == GV_ZERO) {
1436 /* extra src grace group(s) left over must be moved */
1438 /* sgrace_p is the last (rightmost) grace to move */
1439 for (temp_p = sgrace_p; temp_p != 0 && temp_p->grpvalue ==
1440 GV_ZERO; temp_p = temp_p->prev) {
1443 /* fgs_p is the first (leftmost) grace to move */
1445 if (dgrace_p == 0) { /* at start of measure? */
1446 /* in src voice, skip over all the graces */
1447 mll_p->u.staff_p->groups_p[src_p->vno-1] = src_p;
1450 /* splice the left grace into the dest voice */
1451 mll_p->u.staff_p->groups_p[dest_p->vno-1] = fgs_p;
1454 /* in src voice, skip over all the graces */
1455 fgs_p->prev->next = src_p;
1456 src_p->prev = fgs_p->prev;
1458 /* splice the left grace into the dest voice */
1459 dgrace_p->next = fgs_p;
1460 fgs_p->prev = dgrace_p;
1463 /* splice the rightmost left over grace into the dest voice */
1464 dmem_p->prev = sgrace_p;
1465 sgrace_p->next = dmem_p;
1468 * If there is now more than one grace in the dest, we have to
1469 * correct beamloc in a couple places.
1471 if (fgs_p != dest_p->prev) {
1473 * If the dest voice had multiple graces before, the
1474 * leftmost one, which was STARTITEM, must be made
1475 * INITEM. If it had only one, it was NOITEM and
1476 * must be made ENDITEM, but go ahead and set INITEM;
1477 * it'll be set correctly below.
1479 if (dmem_p != dest_p) { /* if dest had grace(s) */
1480 dmem_p->beamloc = INITEM;
1483 /* rightmost dest grace must always be made ENDITEM */
1484 dest_p->prev->beamloc = ENDITEM;
1487 /* change the voice number of the moved graces */
1488 for (temp_p = fgs_p; temp_p != sgrace_p->next;
1489 temp_p = temp_p->next) {
1490 temp_p->vno = dest_p->vno;
1493 /* no extra src grace group(s); just remove all src graces */
1494 if (sgrace_p == 0) {
1495 mll_p->u.staff_p->groups_p[src_p->vno-1] = src_p;
1498 smem_p->prev->next = src_p;
1499 src_p->prev = smem_p->prev;
1502 /* could free the src graces, but is it worth the trouble? */
1506 * Name: addsrc2dest()
1508 * Abstract: Adds src group to dest group.
1512 * Description: This function adds the src group info (if the src group exists)
1513 * into the dest group. But it doesn't mess with linkages. That
1514 * is the calling function's job.
1518 addsrc2dest(dest_p, src_p)
1520 struct GRPSYL *dest_p; /* destination group must exist */
1521 struct GRPSYL *src_p; /* source group, or can be NULL */
1524 struct NOTE *dnote_p; /* point at a note in the destination group */
1525 struct NOTE *snote_p; /* point at a note in the source group */
1526 struct NOTE *newlist; /* combined notelist */
1527 int didx, sidx; /* index into dest and src note lists */
1528 int totnotes; /* total number of notes after combining */
1529 int n; /* loop variable */
1532 /* if src doesn't exist, there is nothing to do */
1537 /* move references to the src group's coords */
1538 upd_ref(src_p->c, dest_p->c);
1540 /* if src is space, nothing to do except carry over this space field */
1541 if (src_p->grpcont == GC_SPACE) {
1542 if (dest_p->grpcont == GC_SPACE &&
1543 src_p->uncompressible == YES) {
1544 dest_p->uncompressible = YES;
1549 /* padding is the max of the two groups */
1550 dest_p->padding = MAX(dest_p->padding, src_p->padding);
1553 * Some fields were allowed to disagree between the groups as long as
1554 * one was defaulted. The non-default value should prevail.
1556 if (src_p->printtup != PT_DEFAULT) {
1557 dest_p->printtup = src_p->printtup;
1559 if (src_p->tupside != PL_UNKNOWN) {
1560 dest_p->tupside = src_p->tupside;
1562 if (src_p->beamslope != NOBEAMANGLE) {
1563 dest_p->beamslope = src_p->beamslope;
1565 if (src_p->stemlen != STEMLEN_UNKNOWN) {
1566 dest_p->stemlen = src_p->stemlen;
1568 if (src_p->stemdir != UNKNOWN) {
1569 dest_p->stemdir = src_p->stemdir;
1572 /* only when combining 1 & 2 might we have to adjust roll */
1573 if (dest_p->vno == 1 && src_p->vno == 2) {
1574 switch ((dest_p->roll << 8) | src_p->roll) {
1575 case (NOITEM << 8) | NOITEM:
1576 /* dest remains NOITEM */
1578 case (STARTITEM << 8) | INITEM:
1579 /* dest remains STARTITEM */
1581 case (STARTITEM << 8) | ENDITEM:
1582 dest_p->roll = LONEITEM;
1584 case (INITEM << 8) | INITEM:
1585 /* dest remains INITEM */
1587 case (INITEM << 8) | ENDITEM:
1588 dest_p->roll = ENDITEM;
1593 /* if one is a rest, so is the other; combine */
1594 if (dest_p->grpcont == GC_REST) {
1595 /* throw away any restdist; probably would be inappropriate */
1596 dest_p->restdist = 0;
1600 /* if either is a mrpt, the other must be; nothing to copy */
1601 if (dest_p->is_meas == YES) {
1605 /* at this point we know src has notes, & dest has notes or is space */
1608 * Make a new notelist. First copy the old dest notes into there, and
1609 * then add the src notes. We can't just realloc the dest, since
1610 * pointers into the array must be updated by calling upd_ref for each
1611 * array element. If any notes are shared, we won't really need this
1612 * many, but it doesn't waste much memory.
1614 MALLOC(NOTE, newlist, dest_p->nnotes + src_p->nnotes);
1615 for (n = 0; n < dest_p->nnotes; n++) {
1616 newlist[n] = dest_p->notelist[n];
1620 * Keep track of the number of total resulting notes, which starts out
1621 * as the number of notes in dest. Loop through the src notes.
1623 totnotes = dest_p->nnotes;
1624 for (sidx = 0; sidx < src_p->nnotes; sidx++) {
1625 snote_p = &src_p->notelist[sidx];
1627 /* see if it matches any of the dest notes in the result array*/
1628 for (didx = 0; didx < dest_p->nnotes; didx++) {
1629 dnote_p = &newlist[didx];
1630 if (dnote_p->octave == snote_p->octave &&
1631 dnote_p->letter == snote_p->letter) {
1633 * If one has parens on the note or acc and the
1634 * other doesn't, ensure no parens in result.
1636 if (dnote_p->note_has_paren !=
1637 snote_p->note_has_paren) {
1638 dnote_p->note_has_paren = NO;
1640 if (dnote_p->acc_has_paren !=
1641 snote_p->acc_has_paren) {
1642 dnote_p->acc_has_paren = NO;
1647 if (didx == dest_p->nnotes) {
1648 /* didn't find a match, so add it to the end */
1649 newlist[totnotes++] = *snote_p;
1653 /* sort the combined list in pitch order */
1654 qsort((char *)newlist, (unsigned int)totnotes,
1655 sizeof (struct NOTE), notecomp);
1658 * For every original dest and src note, find out where it ended up in
1659 * the combined list, and update and location tag references.
1661 for (didx = 0; didx < dest_p->nnotes; didx++) {
1662 dnote_p = &dest_p->notelist[didx];
1663 for (n = 0; n < totnotes; n++) {
1664 if (newlist[n].octave == dnote_p->octave &&
1665 newlist[n].octave == dnote_p->letter) {
1666 upd_ref(newlist[n].c, dnote_p->c);
1670 for (sidx = 0; sidx < src_p->nnotes; sidx++) {
1671 dnote_p = &src_p->notelist[sidx];
1672 for (n = 0; n < totnotes; n++) {
1673 if (newlist[n].octave == dnote_p->octave &&
1674 newlist[n].octave == dnote_p->letter) {
1675 upd_ref(newlist[n].c, dnote_p->c);
1680 /* free old dest list, and install the new one and its note count */
1681 if (dest_p->notelist != 0) { /* not a space */
1682 FREE(dest_p->notelist);
1684 dest_p->notelist = newlist;
1685 dest_p->nnotes = totnotes;
1689 * Name: setgrpptrs()
1691 * Abstract: Set pointers to the groups in a hand.
1693 * Returns: number of GRPSYLs found in this hand
1695 * Description: This function fill in the given array with pointers to the
1696 * groups in this hand. When a group doesn't exist for some
1697 * voice, a null pointer is used.
1701 setgrpptrs(gs1_p, v_p)
1703 struct GRPSYL *gs1_p; /* first group in this hand */
1704 struct GRPSYL *v_p[]; /* fill this in, index by voice number */
1707 struct GRPSYL *gs_p; /* point along GRPSYLs of the chord */
1708 int v; /* a voice number */
1709 int num; /* number of groups found */
1712 /* null out the list of pointers initially (note [0] is not used) */
1713 for (v = 1; v <= MAXVOICES; v++) {
1716 /* for each group in the hand, set pointer to it */
1718 for (gs_p = gs1_p; gs_p != 0 && gs_p->staffno == gs1_p->staffno &&
1719 gs_p->grpsyl == GS_GROUP; gs_p = gs_p->gs_p) {
1720 v_p[gs_p->vno] = gs_p;
1728 * Name: hastieslur()
1730 * Abstract: Is this group tied/slurred/bent to the next?
1732 * Returns: YES or NO
1734 * Description: This function checks whether there are any ties/slurs/bends to
1735 * the next group. If the given group doesn't exist, the answer
1742 struct GRPSYL *gs_p; /* group to check */
1745 int idx; /* index into note list */
1748 /* if there's no group, it isn't tied/slurred */
1753 /* check group tie */
1754 if (gs_p->tie == YES) {
1758 /* check note ties and slurs (bends are covered by slurs) */
1759 for (idx = 0; idx < gs_p->nnotes; idx++) {
1760 if (gs_p->notelist[idx].tie == YES ||
1761 gs_p->notelist[idx].nslurto != 0) {