2 /* Copyright (c) 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2005 by Arkkra Enterprises */
3 /* All rights reserved */
5 /* utility functions for creating MIDI output from Mup input. These functions
6 * are split out into this file to keep midi.c from being so huge */
16 static struct GRPSYL
*create_prev_grp
P((struct MAINLL
*mll_p
, int staffno
,
18 static struct GRPSYL
*create_meas_space
P((struct MAINLL
*mll_p
));
19 static void fix_spacechord
P((struct MAINLL
*chmll_p
, struct CHORD
*ch_p
));
20 static void splitspace
P((struct GRPSYL
*gs_p
, RATIONAL duration
));
21 static void splicechord
P((struct GRPSYL
*gs_p
, struct CHORD
*ch_p
));
22 static void guitar_grpsyl_transpose
P((struct GRPSYL
*gs_p
));
23 static RATIONAL find_acc_end_time
P((RATIONAL begin_time
, struct GRPSYL
*gs_p
,
25 static void propogate_accidental
P((struct NOTE
*note_p
, RATIONAL begin_time
,
26 RATIONAL end_time
, struct GRPSYL
*gs_p
));
27 static void mv_skipped_midi
P((struct STUFF
*stuff_p
, int staffno
,
28 struct MAINLL
*topstaff_mll_p
));
31 /* seek back to where header size is in file, and fill in the correct size,
32 * now that we know what it is. */
35 fix_track_size(mfile
, track_start
, track_size
)
37 int mfile
; /* file descriptor of MIDI file */
38 long track_start
; /* offset in file where size needs to be put */
39 long track_size
; /* track length in bytes */
42 unsigned char buff
[4];
45 debug(512, "fix_track_size");
47 /* go to where track size is stored in file */
48 (void) lseek(mfile
, track_start
+ 4, SEEK_SET
);
50 /* convert to 4-byte number with correct byte ordering regardless
51 * of machine byte ordering */
52 buff
[0] = (track_size
>> 24) & 0xff;
53 buff
[1] = (track_size
>> 16) & 0xff;
54 buff
[2] = (track_size
>> 8) & 0xff;
55 buff
[3] = track_size
& 0xff;
56 (void) write(mfile
, buff
, 4);
58 /* go back to end of file in case there are more track to write */
59 (void) lseek(mfile
, 0L, SEEK_END
);
63 /* given an octave mark string, return number of octaves to tranpose (could
64 * be negative if transposing down) */
67 parse_octave(string
, place
, fname
, lineno
)
69 char *string
; /* typically "8va" */
70 int place
; /* PL_ABOVE or PL_BELOW */
71 char *fname
; /* file name for errors */
78 int code
; /* ASCII of character in string */
84 code
= next_str_char(&string
, &font
, &size
);
86 octave_value
= code
- '0';
87 code
= next_str_char(&string
, &font
, &size
);
88 /* might be a second digit. If user is crazy enough to use
89 * an octave number greater than 2 digits, ignore the rest */
91 octave_value
= (octave_value
* 10) + (code
- '0');
95 /* must be either a non-zero multiple of 8, or things like 15, 22,
96 * etc if some musical mathematician adds 7 instead of 8 */
97 if (octave_value
< 8 || ((octave_value
- 8) % 7 != 0 &&
98 (octave_value
- 8) % 8 != 0)) {
99 l_ufatal(fname
, lineno
, "invalid octave mark string");
101 if (octave_value
% 8 == 0) {
104 octave_value
= 1 + (octave_value
- 8) % 7;
107 return(place
== PL_BELOW ?
-octave_value
: octave_value
);
111 /* determine "clocks per metronome tick." It not entirely clear to me
112 * how that is supposed to work, but... if the time signature denominator is
113 * 4, we'll use 24. If 8, use 12, etc. Only go down as far as 3, since that's
114 * not divisible by 2. Really, in fast tempo triple time, the denominator
115 * isn't the beat, but this will do for now. */
140 /* given a string, if it contains a word followed by an =, followed by a word,
141 * any of which may be separated by white space, return, via pointers,
142 * a pointer to the beginning of the word, the length of the word, and a pointer
143 * to the first non-white-space character after the =, and return YES.
144 * Otherwise, return NO. A "word" is a sequence of non-white-space chars. */
147 getkeyword(string
, key_p
, leng_p
, arg_p_p
)
149 char *string
; /* check this string */
150 char **key_p
; /* return pointer to keyword via this */
151 int *leng_p
; /* return length of keyword via this */
152 char **arg_p_p
; /* return pointer to argument after = via this */
158 /* skip leading white space */
159 for (*key_p
= string
; **key_p
== ' ' || **key_p
== '\t'; (*key_p
)++) {
163 /* go till hit white space or equals sign */
164 for (tok
= *key_p
; *tok
!= '\0'; tok
++) {
165 if (*tok
== ' ' || *tok
== '\t' || *tok
== '=') {
170 /* fill in length of key */
171 *leng_p
= tok
- *key_p
;
177 /* find first non-white beyond the = */
178 for ( ; *tok
!= '\0'; tok
++) {
180 for (tok
++; *tok
!= '\0'; tok
++) {
181 if (*tok
!= ' ' && *tok
!= '\t') {
192 /* given a user-specified key, see if it matches the given command name. Return
193 * YES if it does, NO if it doesn't. User only has to specify the first 3 or
194 * more characters of the command, because that's enough to make it unique,
195 * and saves them from typing longer names. */
198 matches(key
, leng
, cmd
)
200 char *key
; /* user specified key to be checked */
201 int leng
; /* length of key */
202 char *cmd
; /* check if key matches this command */
208 return(strncmp(key
, cmd
, leng
) == 0 ? YES
: NO
);
212 /* given an ASCII hex digit, return its value 0-15 */
220 if (ch
>= '0' && ch
<= '9') {
223 else if (ch
>= 'a' && ch
<= 'f') {
224 return(ch
- 'a' + 10);
226 else if (ch
>= 'A' && ch
<= 'F') {
227 return(ch
- 'A' + 10);
229 pfatal("bad hex digit");
235 /* given a string, output it to midi file, prefixed by its length. */
236 /* return number of bytes written */
239 midi_wrstring(mfile
, str
, internalform
)
241 int mfile
; /* MIDI file */
242 char *str
; /* string to write to file */
243 int internalform
; /* YES if str is in Mup format, NO if just ASCII,
244 * C-style null-terminated string to be copied */
247 char *buff
; /* for all-ASCII version of str */
248 UINT32B bytes
; /* number of bytes in length value */
249 int length
; /* of string */
252 /* get plain ascii version of string. Write out length of
253 * string, then plain string itself */
254 if (internalform
== YES
) {
255 buff
= ascii_str(str
, NO
, YES
, TM_NONE
);
256 length
= strlen(buff
);
257 bytes
= wr_varlength(mfile
, (UINT32B
) length
);
258 bytes
+= write(mfile
, buff
, (unsigned) length
);
261 length
= strlen(str
);
262 bytes
= wr_varlength(mfile
, (UINT32B
) length
);
263 bytes
+= write(mfile
, str
, (unsigned) length
);
266 /* return number of bytes written */
271 /* given a number, write to MIDI file in MIDI variable length format.
272 * Return number of bytes written. */
275 wr_varlength(mfile
, num
)
280 unsigned char buff
[4];
285 /* Because only 7 bits of each MIDI byte can be used,
286 * there is only support for numbers up to 28 bits long. */
287 if ((num
& 0xf0000000) != 0) {
288 ufatal("midi value too large");
291 /* convert value to the MIDI variable-length number, which
292 * uses the lower 7 bits of each byte as parts of the number, and
293 * the high order bit as a flag to say which is the last byte of
294 * the (potentially) multi-byte number */
295 for (i
= 0, shift
= 21; shift
>= 7; shift
-= 7) {
296 if ( (num
>> shift
) || (i
> 0)) {
297 buff
[i
++] = 0x80 | ((num
>> shift
) & 0x7f);
300 buff
[i
] = num
& 0x7f;
301 (void) write(mfile
, buff
, (unsigned) (i
+ 1));
302 return (UINT32B
) (i
+1);
306 /* do key signature. Return number of bytes written */
309 midi_keysig(mfile
, sharps
, is_minor
)
313 int is_minor
; /* YES if minor */
317 unsigned char buff
[8];
320 bytes
= write_delta(mfile
);
324 buff
[3] = (char) sharps
;
325 buff
[4] = (is_minor
== YES ?
1 : 0);
326 (void) write(mfile
, buff
, 5);
332 /* write out the timesig in Score SSV. Return number of bytes written */
340 unsigned char buff
[8];
343 /* With additive time signatures, it is possible to get an effective
344 * time signature that won't fit in 7 bits. In that case, we don't
345 * do any time signature, since we can't represent it. */
346 if (Score
.timenum
> 127) {
350 bytes
= write_delta(mfile
);
354 buff
[3] = (char) Score
.timenum
;
355 buff
[4] = (unsigned char) drmo(Score
.timeden
);
356 buff
[5] = clocks(Score
.timeden
);
358 bytes
+= write(mfile
, buff
, 7);
363 /* find group before given group. If none before it in current measure,
364 * back up in main list to find corresponding group list, and use final group
365 * in that list. If no group exists, create one. */
368 grp_before(gs_p
, mll_p
, staffno
, v
)
370 struct GRPSYL
*gs_p
; /* find group before this one */
371 struct MAINLL
*mll_p
; /* the list containing gs_p is attached to main list here */
379 if (gs_p
->prev
!= (struct GRPSYL
*) 0) {
380 /* oh good. There's another group before this one in the
381 * current measure, so just return it */
385 /* have to go back to previous measure, if any. Start searching
386 * backwards in main list. */
387 for (mll_p
= mll_p
->prev
; mll_p
!= (struct MAINLL
*) 0;
388 mll_p
= mll_p
->prev
) {
389 switch (mll_p
->str
) {
391 if (found_bar
== NO
) {
392 /* still in current measure */
396 if (mll_p
->u
.staff_p
->staffno
== staffno
) {
397 /* we found the previous measure */
398 if (mll_p
->u
.staff_p
->groups_p
[v
]
399 != (struct GRPSYL
*) 0) {
400 /* find and return last group */
401 for (gs_p
=mll_p
->u
.staff_p
->groups_p
[v
];
410 /* this voice wasn't present before.
411 * Will have to create a measure */
412 return(create_meas_space(mll_p
));
415 else if (mll_p
->u
.staff_p
->staffno
< staffno
) {
416 /* corresponding staff does not exist in this
417 * measure. The only time this should happen is
418 * if user changed the number of staffs.
420 return(create_prev_grp(mll_p
, staffno
, v
));
429 /* ignore other things */
434 /* Fell off the top of the list. This used to be possible,
435 * and we called create_prev_grp() to create a measure.
436 * But the measure really needs to be created much earlier--
437 * before makechords() is run--in order for squeezing to work right.
438 * So that's what we do now. So we should never get here. */
439 pfatal("fell off top of list in grp_before()");
441 return(create_prev_grp(mll_p
, staffno
, v
));
445 /* create a new STAFF struct and insert in main list, with grpcont of
446 * space and fulltime of the measure. Return pointer to the GRPSYL of
447 * appropriate voice of the STAFF that was created. */
449 static struct GRPSYL
*
450 create_prev_grp(mll_p
, staffno
, v
)
452 struct MAINLL
*mll_p
; /* insert here */
457 struct MAINLL
*new_p
; /* new STAFF */
461 new_p
= newMAINLLstruct(S_STAFF
, -1);
462 new_p
->u
.staff_p
->staffno
= (short) staffno
;
463 insertMAINLL(new_p
, mll_p
);
464 for (i
= 0; i
< MAXVOICES
; i
++) {
465 new_p
->u
.staff_p
->groups_p
[i
]
466 = create_meas_space(mll_p
);
469 /* if added to beginning of list, have to add bar as well */
470 if (mll_p
== (struct MAINLL
*) 0) {
471 struct MAINLL
*mbar_p
;
473 mbar_p
= newMAINLLstruct(S_BAR
, -1);
474 insertMAINLL(mbar_p
, new_p
);
477 return(new_p
->u
.staff_p
->groups_p
[v
]);
481 /* create a measure space as long as that of the reference measure (or of 4/4
482 * if no reference) and return it */
484 static struct GRPSYL
*
485 create_meas_space(mll_p
)
487 struct MAINLL
*mll_p
; /* use this for reference to get measure length */
490 struct GRPSYL
*gs_p
; /* new grpsyl */
491 struct GRPSYL
*egs_p
; /* existing grpsyl */
494 gs_p
= newGRPSYL(GS_GROUP
);
495 gs_p
->grpcont
= GC_SPACE
;
497 /* figure out how much full time to give the group. If mll_p is not
498 * null, we are adding a staff to an existing measure, so use
499 * length of its first voice. Count up the length of existing measure */
500 gs_p
->fulltime
= Zero
;
501 if (mll_p
!= (struct MAINLL
*) 0 && mll_p
->str
== S_STAFF
) {
502 for (egs_p
= mll_p
->u
.staff_p
->groups_p
[0];
503 egs_p
!= (struct GRPSYL
*) 0;
504 egs_p
= egs_p
->next
) {
506 gs_p
->fulltime
= radd(gs_p
->fulltime
, egs_p
->fulltime
);
510 /* at beginning of list, use default of 1/1 (the reduced
512 gs_p
->fulltime
.n
= gs_p
->fulltime
.d
= 1;
519 /* add a rest of the specified fulltime duration after the specified group.
520 * Since this is just for midi purposes, don't worry about filling in all
524 add_rest(gs_p
, fulltime
)
526 struct GRPSYL
*gs_p
; /* add rest after this group */
527 RATIONAL fulltime
; /* make it this long */
530 struct GRPSYL
*newgs_p
;
533 if (gs_p
== (struct GRPSYL
*) 0) {
534 pfatal("null group passed to add_rest");
537 newgs_p
= newGRPSYL(GS_GROUP
);
538 newgs_p
->grpcont
= GC_REST
;
540 newgs_p
->fulltime
= fulltime
;
541 newgs_p
->next
= gs_p
->next
;
542 newgs_p
->prev
= gs_p
;
543 gs_p
->next
= newgs_p
;
544 if (newgs_p
->next
!= (struct GRPSYL
*) 0) {
545 newgs_p
->next
->prev
= newgs_p
;
550 /* when all voices have space, that should be squeezed to zero time.
551 * Go through main list. For each CHHEAD found,
552 * go down the list of chords. For each chord, see if
553 * if it is an all-space chord. If so, call fix_spacechord() to
561 struct MAINLL
*mll_p
; /* walk through main list */
562 struct CHORD
*ch_p
; /* walk through list of chords */
565 debug(256, "midi_squeeze");
568 for (mll_p
= Mainllhc_p
; mll_p
!= (struct MAINLL
*) 0;
569 mll_p
= mll_p
->next
) {
571 /* skip everything except CHHEADs and SSV updates */
572 if (mll_p
->str
!= S_CHHEAD
) {
573 if (mll_p
->str
== S_SSV
) {
574 asgnssv(mll_p
->u
.ssv_p
);
580 for (ch_p
= mll_p
->u
.chhead_p
->ch_p
;
581 ch_p
!= (struct CHORD
*) 0;
584 if (ch_p
->width
== 0.0) {
585 /* found one to squeeze, do it */
586 fix_spacechord(mll_p
, ch_p
);
593 /* given an all-space chord to crunch, split up any groups that
594 * spill into this chord or extend beyond it. Then set the grpvalue of each
595 * group in the chord to GV_ZERO.
599 fix_spacechord(chmll_p
, ch_p
)
601 struct MAINLL
*chmll_p
; /* chord is hanging off this CHHEAD */
602 struct CHORD
*ch_p
; /* zero-width chord */
605 struct MAINLL
*mll_p
; /* walk through STAFFs in main list */
606 struct GRPSYL
*gs_p
; /* walk through groups in chord */
607 struct GRPSYL
*group_p
; /* head of list of grpsyls in measure */
608 RATIONAL minspacetime
; /* time of shortest space in chord */
609 RATIONAL chordstart
; /* where in measure chord begins */
610 RATIONAL chordend
; /* where the space ends */
611 RATIONAL new_chordend
; /* tentative new value for chordend */
612 RATIONAL grpstart
; /* where in measure grpsyl begins */
613 int v
; /* voice index */
616 /* first find the smallest duration in the chord. Can't use
617 * ch_p->duration here because grace notes have been adjusted
618 * by now to take some time */
619 minspacetime
= ch_p
->gs_p
->fulltime
;
620 for (gs_p
= ch_p
->gs_p
->gs_p
; gs_p
!= (struct GRPSYL
*) 0;
624 if (gs_p
->grpsyl
== GS_SYLLABLE
) {
628 /* skip things on tab staff--we use the associated tabnotes
630 if (is_tab_staff(gs_p
->staffno
) == YES
) {
635 if (gs_p
->grpcont
!= GC_SPACE
) {
636 pfatal("non-space in zero-width chord");
639 /* find minimum time value of space */
640 if (LT(gs_p
->fulltime
, minspacetime
)) {
641 minspacetime
= gs_p
->fulltime
;
645 /* find the start of the chord. Can't use ch_p->startime because
646 * we may have squeezed out time earlier in the measure and need
647 * to compensate for that. So have to count up the time before
648 * the group at the top of the chord. */
649 for (chordstart
= Zero
, gs_p
= ch_p
->gs_p
->prev
;
650 gs_p
!= (struct GRPSYL
*) 0;
652 chordstart
= radd(chordstart
, gs_p
->fulltime
);
655 /* if spaces are overlapped in strange ways between different
656 * voices, the minspacetime we found above may actually be too long.
657 * If the time between this chord and the next is less than the
658 * minspacetime found so far, make minspacetime the time till the
660 if (ch_p
->ch_p
!= (struct CHORD
*) 0) {
661 if (LT(rsub(ch_p
->ch_p
->starttime
, chordstart
), minspacetime
)) {
662 minspacetime
= rsub(ch_p
->ch_p
->starttime
, chordstart
);
666 /* That still isn't completely adequate to find where the space actually
667 * ends, because if there were lots of grace notes moved back into a
668 * space, and a very short space in another voice, they could overlap.
669 * So go through the list of voices, seeing where the real end is.
670 * This code is unfortunately very similar to the code below it,
671 * yet different enough to make it hard to make it
672 * into a common function. */
673 chordend
= radd(chordstart
, minspacetime
);
674 for (mll_p
= chmll_p
->next
; mll_p
!= (struct MAINLL
*) 0;
675 mll_p
= mll_p
->next
) {
677 /* CHHEAD is followed immediately by STAFFS, so when we
678 * hit something other than STAFF, we are done */
679 if (mll_p
->str
!= S_STAFF
) {
684 for (v
= 0; v
< MAXVOICES
; v
++ ) {
685 /* Check if we have a special case where the actual
686 * space is shorter than we thought. We unfortunately
687 * cannot use hasspace() here, because it ignores grace
688 * notes, and by now, grace notes have some time.
689 * Find the chord that begins the space in question. */
692 if ((gs_p
= mll_p
->u
.staff_p
->groups_p
[v
])
693 == (struct GRPSYL
*) 0) {
694 /* no voice here, so that's all space.
695 * That's good: we're done with this voice */
699 /* grace notes at the beginning of the measure
700 * have effectively been moved timewise
701 * into previous measure, so discount them. */
702 for ( ; gs_p
->grpvalue
== GV_ZERO
703 && gs_p
->grpcont
== GC_NOTES
;
708 for ( ; gs_p
!= (struct GRPSYL
*) 0;
711 /* see if this group start corresponds
712 * with start of chord, or spills into
713 * the chord or is the last chord. If
714 * so, that's the one we want. */
715 if (EQ(grpstart
, chordstart
) ||
720 (struct GRPSYL
*) 0) {
721 /* found appropriate group */
725 /* accummulate time so far */
726 grpstart
= radd(grpstart
, gs_p
->fulltime
);
730 if (gs_p
== (struct GRPSYL
*) 0) {
731 pfatal("failed to find space group");
734 if (gs_p
->grpcont
!= GC_SPACE
) {
735 /* things overlapped so much after the
736 * grace note adjustments and such
737 * that this isn't really a
738 * crunch-able chord after all. */
742 /* need to adjust amount of space we
743 * can really crunch. Find where this chord
744 * ends, and add in the time of any immediately
745 * following space groups. */
746 new_chordend
= radd(grpstart
, gs_p
->fulltime
);
747 for (gs_p
= gs_p
->next
; gs_p
!= (struct GRPSYL
*) 0;
750 if (gs_p
->grpcont
== GC_SPACE
) {
751 new_chordend
= radd(new_chordend
,
759 /* if the newly calculated end is sooner than
760 * what we had before, then adjust accordingly. */
761 if (LT(new_chordend
, chordend
)) {
762 chordend
= new_chordend
;
767 /* recalculate the minspace time after any adjustment */
768 minspacetime
= rsub(chordend
, chordstart
);
771 /* go down each voice of each staff.
772 * For each, find the space group associated with the chord.
773 * If it has the same starttime as the chord and has minspacetime
774 * duration, it's easy: we just mark it GV_ZERO. Otherwise, if
775 * it starts earlier, we have to split off a group in the front
776 * first, and if it lasts longer than the end of the chord, we
777 * have to split off a group at the end first.
779 for (mll_p
= chmll_p
->next
; mll_p
!= (struct MAINLL
*) 0;
780 mll_p
= mll_p
->next
) {
781 /* CHHEAD is followed immediately by STAFFS, so when we
782 * hit something other than STAFF, we are done */
783 if (mll_p
->str
!= S_STAFF
) {
788 for (v
= 0; v
< MAXVOICES
; v
++ ) {
790 /* get shorter name for list of grpsyls */
791 group_p
= mll_p
->u
.staff_p
->groups_p
[v
];
793 if (group_p
== (struct GRPSYL
*) 0) {
797 /* go through groups, add up time till we find the
798 * group we're looking for */
801 /* grace notes at the beginning of the measure
802 * have effectively been moved timewise
803 * into previous measure, so discount them. */
804 for (gs_p
= group_p
; gs_p
->grpvalue
== GV_ZERO
805 && gs_p
->grpcont
== GC_NOTES
;
810 for ( ; gs_p
!= (struct GRPSYL
*) 0;
813 /* see if this group start corresponds with
815 if (EQ(grpstart
, chordstart
)) {
816 /* found appropriate group */
820 else if (GT(radd(grpstart
,gs_p
->fulltime
),
822 /* This group spills into space
824 * Split off beginning of group. */
826 rsub(chordstart
, grpstart
));
828 /* point to added group */
831 /* splice added group into chord */
832 splicechord(gs_p
, ch_p
);
834 /* found appropriate group */
838 /* haven't gotten to the group yet.
839 * Add on the time taken by this
840 * group in preparation for next
841 * trip around the loop */
842 grpstart
= radd(grpstart
, gs_p
->fulltime
);
843 /* if last group in measure, this has
844 * to be the appropriate one */
845 if (gs_p
->next
== (struct GRPSYL
*) 0) {
851 if (gs_p
== (struct GRPSYL
*) 0) {
852 pfatal("failed to find space group");
855 /* if group extended beyond end of
856 * chord, split the group and splice added group
858 if (GT(gs_p
->fulltime
, minspacetime
)) {
859 splitspace(gs_p
, minspacetime
);
860 splicechord(gs_p
->next
, ch_p
->ch_p
);
863 /* mark as taking no time */
864 gs_p
->grpvalue
= GV_ZERO
;
870 /* split a space grpsyl into two. The original group becomes the first
871 * group, having the specified duration. A new group is added after it,
872 * having the remainder of the time taken by the original group. */
875 splitspace(gs_p
, duration
)
877 struct GRPSYL
*gs_p
; /* split this group */
878 RATIONAL duration
; /* make the first group of split this long */
881 struct GRPSYL
*newgs_p
; /* added group */
885 if (gs_p
== (struct GRPSYL
*) 0 ||
886 (gs_p
->grpcont
!= GC_SPACE
&&
887 svpath(gs_p
->staffno
, VISIBLE
)->visible
== YES
) ) {
888 pfatal("bad group passed to splitspace");
891 /* split into 2 groups, one taking duration, and the
892 * other taking the remainder */
893 newgs_p
= newGRPSYL(GS_GROUP
);
894 copy_attributes(newgs_p
, gs_p
);
895 newgs_p
->grpcont
= GC_SPACE
;
896 newgs_p
->fulltime
= rsub(gs_p
->fulltime
, duration
);
897 gs_p
->fulltime
= duration
;
899 /* link new one into list */
900 newgs_p
->next
= gs_p
->next
;
901 newgs_p
->prev
= gs_p
;
902 gs_p
->next
= newgs_p
;
903 if (newgs_p
->next
!= (struct GRPSYL
*) 0) {
904 newgs_p
->next
->prev
= newgs_p
;
909 /* splice a grpsyl into a chord */
912 splicechord(gs_p
, ch_p
)
914 struct GRPSYL
*gs_p
; /* splice in this group */
915 struct CHORD
*ch_p
; /* splice into this chord */
918 struct GRPSYL
*nxtgs_p
; /* next group in chord list */
919 struct GRPSYL
**ins_p_p
; /* where to insert new grpsyl */
922 if (ch_p
== (struct CHORD
*) 0) {
923 /* this could happen if user gave measure of space, and
924 * then following measure started with a grace note. The
925 * grace note got moved into the space, but there was no
926 * chhead created for it. It should be safe to just
927 * not link it into a chhead, so return */
931 if (gs_p
== (struct GRPSYL
*) 0) {
932 pfatal("null pointer in splicechord");
935 /* Figure out where to insert. */
936 for (ins_p_p
= &(ch_p
->gs_p
); (*ins_p_p
) != (struct GRPSYL
*) 0;
937 ins_p_p
= &((*ins_p_p
)->gs_p
)) {
939 /* gets inserted here if next group is for a higher staffno or
940 * for a higher voice number of the same staffno */
942 if (nxtgs_p
== (struct GRPSYL
*) 0) {
943 /* goes at end of list */
946 if (nxtgs_p
->staffno
> gs_p
->staffno
||
947 (nxtgs_p
->staffno
== gs_p
->staffno
&&
948 nxtgs_p
->vno
> gs_p
->vno
)) {
953 if (ins_p_p
== (struct GRPSYL
**) 0) {
954 pfatal("couldn't find where to insert new grpsyl into chord");
958 gs_p
->gs_p
= *ins_p_p
;
963 /* if user specifies the default guitar tab staff, then we want to transpose
964 * everything down an octave, because a standard guitar sounds an octave
965 * lower than it is written. */
971 struct MAINLL
*mll_p
;
974 /* go through the main list looking for things to transpose */
976 for (mll_p
= Mainllhc_p
; mll_p
!= (struct MAINLL
*) 0; mll_p
= mll_p
->next
) {
977 if (mll_p
->str
== S_STAFF
) {
978 /* if there is a staff below this and that staff is a
979 * guitar tab staff, then we need to transpose.
980 * Index into Staff by this staff's number, because
981 * staff numbers start at 1, but Staff index starts at 0
983 if (mll_p
->u
.staff_p
->staffno
< Score
.staffs
&&
984 Staff
[mll_p
->u
.staff_p
->staffno
]
985 .strinfo
== Guitar
) {
986 guitar_grpsyl_transpose(mll_p
->u
.staff_p
->groups_p
[0]);
989 else if (mll_p
->str
== S_SSV
) {
990 asgnssv(mll_p
->u
.ssv_p
);
996 /* given a group, transpose everything down by an octave */
999 guitar_grpsyl_transpose(gs_p
)
1001 struct GRPSYL
*gs_p
;
1006 for( ; gs_p
!= (struct GRPSYL
*) 0; gs_p
= gs_p
->next
) {
1007 for (n
= 0; n
< gs_p
->nnotes
; n
++) {
1008 if (gs_p
->notelist
[n
].octave
> 0) {
1009 (gs_p
->notelist
[n
].octave
)--;
1012 pfatal("guitar transposition results in note below octave 0");
1019 /* If there is an accidental on a note on one voice, it should really apply
1020 * the other voice on that same staff too. So propogate these accidentals
1021 * to the other voice if necessary.
1025 other_voice_accidentals(staff_p
)
1027 struct STAFF
*staff_p
;
1030 struct GRPSYL
*gs_p
;
1032 int n
; /* notelist index */
1033 RATIONAL begin_time
, end_time
;
1035 /* if there is only one voice on the staff, or if either
1036 * voice is a measure space or rest or multirest, nothing to do. Since
1037 * we're doing MIDI, we know a "measure" GRPSYL
1038 * will be rest or space, not mrpt, so can just check that. */
1039 if ( (staff_p
->groups_p
[0]->is_meas
== YES
) ||
1040 (staff_p
->groups_p
[1] == (struct GRPSYL
*) 0) ||
1041 (staff_p
->groups_p
[1]->is_meas
== YES
) ) {
1046 for (v
= 0; v
< MAXVOICES
; v
++) {
1048 /* do each note of each chord */
1050 for (gs_p
= staff_p
->groups_p
[v
]; gs_p
!= (struct GRPSYL
*) 0;
1051 gs_p
= gs_p
->next
) {
1053 for (n
= 0; n
< gs_p
->nnotes
; n
++) {
1055 /* if this note doesn't have an accidental
1056 * nothing more to do on it */
1057 if (gs_p
->notelist
[n
].accidental
== '\0') {
1061 /* This note does have an accidental.
1062 * Go forward and see how long it lasts.
1063 * It will last until there is another
1064 * accidental on the same note letter/octave
1065 * or until end of measure.
1067 end_time
= find_acc_end_time(begin_time
, gs_p
, n
);
1069 /* now check the other voice.
1070 * If the same letter/octave note appears
1071 * on that voice on or after the begin time but
1072 * before the end time, and that note
1073 * does not already have an accidental,
1074 * give it the same accidental as
1075 * was found on the other voice.
1077 propogate_accidental( &(gs_p
->notelist
[n
]),
1078 begin_time
, end_time
,
1079 staff_p
->groups_p
[v
== 0 ?
1 : 0]);
1082 /* accumulate time so far in measure */
1083 begin_time
= radd(begin_time
, gs_p
->fulltime
);
1088 /* Given an GRPSYL and a note n in its notelist, and a begin_time, return
1089 * the end_time which is either the end of the measure or the next instance
1090 * of the given note which has an accidental on it. */
1093 find_acc_end_time(begin_time
, gs_p
, n
)
1095 RATIONAL begin_time
;
1096 struct GRPSYL
*gs_p
;
1101 struct GRPSYL
*end_gs_p
;
1105 end_time
= begin_time
;
1108 /* Add up time that accidental lasts */
1109 end_time
= radd(end_time
, end_gs_p
->fulltime
);
1111 if ((end_gs_p
= end_gs_p
->next
) == (struct GRPSYL
*) 0) {
1112 /* Hit end of measure */
1116 /* See if this group has the same note as had the accidental,
1117 * and if so, whether it has a new accidental. */
1118 for (n2
= 0; n2
< end_gs_p
->nnotes
; n2
++) {
1119 if ((gs_p
->notelist
[n
].letter
1120 == end_gs_p
->notelist
[n2
].letter
) &&
1121 (gs_p
->notelist
[n
].octave
1122 == end_gs_p
->notelist
[n2
].octave
)) {
1124 /* does have the same note. check accidental */
1125 if (end_gs_p
->notelist
[n2
].accidental
!= '\0') {
1126 /* a new accidental, so this cancels
1137 /* Check the groups in list pointed to by gs_p.
1138 * If the letter/octave of the given note_p appears on or after the begin time
1139 * but before the end time, and that note does not already have an accidental,
1140 * give it the same accidental as was found on note_p. */
1143 propogate_accidental(note_p
, begin_time
, end_time
, gs_p
)
1145 struct NOTE
*note_p
; /* look for note matching this one */
1146 RATIONAL begin_time
; /* look between the begin_time and end_time */
1148 struct GRPSYL
*gs_p
; /* look in this list and adjust if needed */
1151 RATIONAL accumulated_time
;
1155 for (accumulated_time
= Zero
;
1156 gs_p
!= (struct GRPSYL
*) 0;
1157 accumulated_time
= radd(accumulated_time
,
1158 gs_p
->fulltime
), gs_p
= gs_p
->next
) {
1160 if (LT(accumulated_time
, begin_time
)) {
1161 /* haven't gotten to begin yet */
1165 if (GE(accumulated_time
, end_time
)) {
1166 /* reached end time */
1170 /* See if this group contains the note of interest */
1171 for (n
= 0; n
< gs_p
->nnotes
; n
++) {
1172 if ( (gs_p
->notelist
[n
].letter
== note_p
->letter
) &&
1173 (gs_p
->notelist
[n
].octave
== note_p
->octave
) ) {
1174 /* if note already has an accidental,
1175 * the one from the other voice doesn't
1176 * count. Otherwise propogate the
1177 * accidental from the other voice */
1178 if (gs_p
->notelist
[n
].accidental
== '\0') {
1179 gs_p
->notelist
[n
].accidental
1180 = note_p
->accidental
;
1183 /* Found the note and fixed it if needed,
1184 * so our job here is done */
1192 /* If doing MIDI with the -x option, we move all the midi STUFFs in the
1193 * skipped leading measures to the "extra" empty measure that exists for MIDI.
1194 * This ensure that any MIDI parameters, instruments, etc are correct
1195 * for the place in the song where we are actually starting.
1199 mv_midi_items(mll_p
, topstaff_mll_p
)
1201 struct MAINLL
*mll_p
; /* points to a STAFF that may have MIDI items to move */
1202 struct MAINLL
*topstaff_mll_p
; /* points to STAFF where "all" MIDI items will go */
1205 struct STUFF
*stuff_p
; /* stuff currently being processed */
1206 struct STUFF
*next
; /* we may move the current STUFF to another
1207 * list, so need to save its "next" */
1208 char *key
; /* midi directive keyword */
1209 int leng
; /* length of key */
1210 char *arg
; /* arg after the = */
1214 staffno
= mll_p
->u
.staff_p
->staffno
;
1215 for (stuff_p
= mll_p
->u
.staff_p
->stuff_p
; stuff_p
!= 0; stuff_p
= next
) {
1216 /* keep track of next, in case we delete the current */
1217 next
= stuff_p
->next
;
1219 if (next
== stuff_p
) {
1220 pfatal("loop detected in MIDI list");
1223 if (stuff_p
->stuff_type
== ST_MIDI
) {
1224 if (getkeyword(stuff_p
->string
+2, &key
, &leng
, &arg
)
1226 /* invalid, so ignore it. */
1230 /* Some MIDI things, like cue point should just be
1231 * ignored if we are skipping over the music,
1232 * so just check for and move things we care about.
1234 if (matches(key
, leng
, "program") == YES
||
1235 matches(key
, leng
, "tempo") == YES
||
1236 matches(key
, leng
, "onvelocity") == YES
||
1237 matches(key
, leng
, "channel") == YES
||
1238 matches(key
, leng
, "parameter") == YES
||
1239 matches(key
, leng
, "offvelocity") == YES
||
1240 matches(key
, leng
, "name") == YES
||
1241 matches(key
, leng
, "instrument") == YES
||
1242 matches(key
, leng
, "hex") == YES
||
1243 matches(key
, leng
, "port") == YES
||
1244 matches(key
, leng
, "chanpressure") == YES
) {
1245 /* Found something to move; move it */
1246 mv_skipped_midi(stuff_p
, staffno
, topstaff_mll_p
);
1253 /* With -x option and MIDI, this moves a MIDI STUFF from where it was in
1254 * a skipped measure to the special "empty" measure at the beginning of the
1255 * piece. In general, for any given MIDI thing, only the last one matters,
1256 * so we only need to keep the last one.
1260 mv_skipped_midi(stuff_p
, staffno
, topstaff_mll_p
)
1262 struct STUFF
*stuff_p
; /* Midi STUFF to be moved */
1263 int staffno
; /* Which staff it is for */
1264 struct MAINLL
*topstaff_mll_p
; /* The STAFF where midi "all" STUFF go.
1265 * Other STAFFs, if any, will surround it. */
1268 int leng
; /* length of MIDI keyword */
1269 char *oldtext
; /* text of STUFF that already
1270 * exists in the list */
1271 char *newtext
; /* text of STUFF to be added */
1272 struct MAINLL
*mll_p
; /* for finding STAFF to link to */
1273 struct STAFF
*staff_p
= 0; /* the STAFF to link to */
1274 struct STUFF
**stuff_p_p
; /* for finding where to add
1275 * the new stuff_p into list */
1276 static char *alphabet
= "abcdefghijklmnopqrstuvwxyz";
1278 /* Find the correct STAFF to attach to. We all passed a pointer
1279 * to the STAFF for midi "all" items. For non-"all" items,
1280 * we search in the main list for the correct STAFF.
1282 if (stuff_p
->all
== YES
|| staffno
== topstaff_mll_p
->u
.staff_p
->staffno
) {
1283 staff_p
= topstaff_mll_p
->u
.staff_p
;
1285 else if (staffno
< topstaff_mll_p
->u
.staff_p
->staffno
) {
1286 /* Search backward for correct staff from the "all" staff.
1287 * This case probably won't happen often--only if some
1288 * staffs at the top are currently invisible (so they are
1289 * not the current "top visible staff").
1291 for (mll_p
= topstaff_mll_p
; mll_p
->str
== S_STAFF
;
1292 mll_p
= mll_p
->prev
) {
1293 if (mll_p
->u
.staff_p
->staffno
== staffno
) {
1294 staff_p
= mll_p
->u
.staff_p
;
1300 /* Search forwards for correct staff from the "all" staff. */
1301 for (mll_p
= topstaff_mll_p
; mll_p
->str
== S_STAFF
;
1302 mll_p
= mll_p
->next
) {
1303 if (mll_p
->u
.staff_p
->staffno
== staffno
) {
1304 staff_p
= mll_p
->u
.staff_p
;
1310 /* User must have reduced the number of staffs during the
1311 * skipped part, so this one is irrelevant. */
1315 /* Add to end of list. When going through the list,
1316 * see if there is already an item of that type (for param
1317 * have to check the specific param matches too), and if so delete
1318 * the earlier one, because this new one overrides it.
1320 newtext
= stuff_p
->string
+ 2;
1321 for (stuff_p_p
= &(staff_p
->stuff_p
); *stuff_p_p
!= 0;
1322 stuff_p_p
= &((*stuff_p_p
)->next
) ) {
1324 /* If for different place,
1325 * this one doesn't count for matching */
1326 if ( (*stuff_p_p
)->place
!= stuff_p
->place
) {
1330 oldtext
= (*stuff_p_p
)->string
+ 2;
1332 /* Since hex is arbitrary data, we always keep it */
1333 if (matches(oldtext
, strlen(oldtext
), "hex")) {
1337 /* Names can be abbreviated,
1338 * so match up to whichever is shorter */
1339 leng
= MIN(strspn(oldtext
, alphabet
), strspn(newtext
, alphabet
));
1340 if (matches(newtext
, leng
, oldtext
)== YES
) {
1341 /* If it's something other than param, we can get
1342 * rid of the existing one */
1343 if (strncmp(newtext
, "par", 3) != 0) {
1344 *stuff_p_p
= (*stuff_p_p
)->next
;
1347 /* Compare parameter numbers and if they match,
1348 * delete the existing one.
1350 char *new_eq_p
, *old_eq_p
; /* loc of '=' */
1351 int oldparm
, oldval
;
1352 int newparm
, newval
;
1354 new_eq_p
= strchr(newtext
, '=');
1355 old_eq_p
= strchr(oldtext
, '=');
1356 if (new_eq_p
!= 0 && old_eq_p
!= 0) {
1357 if (get_param(new_eq_p
+ 1,
1359 stuff_p
->inputlineno
,
1362 get_param(old_eq_p
+ 1,
1363 (*stuff_p_p
)->inputfile
,
1364 (*stuff_p_p
)->inputlineno
,
1367 oldparm
== newparm
) {
1368 *stuff_p_p
= (*stuff_p_p
)->next
;
1373 if (*stuff_p_p
== 0) {
1374 /* If deleted last item in the existing list,
1375 * jump out, so we won't try to deference
1376 * this null pointer. */
1382 /* Just do everything at beat zero. The beat at which user specified
1383 * might not even exist in the current time signature, and basically
1384 * we just want to do everything ASAP anyway. We know there is never
1385 * a 'til' on midi, so no need to deal with that. We could end up
1386 * with a lot to do at count zero, potentially enough to overwhelm
1387 * the limited MIDI bandwidth and delay the first actual note.
1388 * But that potential is always there, and by discarding things
1389 * that were overwritten later, which we did above, unless there
1390 * are an awfully lot of parameters on every possible channel,
1391 * it's probably only going to take less than 0.1 second,
1392 * so it doesn't seem worth the bother to try to do something
1393 * fancy to calculate how much time we need for this stuff
1394 * and delay the actual music by that much. */
1395 stuff_p
->start
.count
= 0.0;
1396 stuff_p
->start
.steps
= 0.0;
1398 /* link onto end of list */
1399 *stuff_p_p
= stuff_p
;
1404 /* Given the argument to a MIDI "parameter" command, extract and return
1405 * (via pointers) the two numbers (the parameter number and its value).
1406 * If successful, returns YES, else prints a warning and returns NO.
1407 * If NO is returned, the pointed to return values are not fill in.
1411 get_param(arg
, inputfile
, inputlineno
, parmnum_p
, parmval_p
)
1413 char *arg
; /* the argument part after "parameter=" */
1414 char *inputfile
; /* for error messages */
1415 int inputlineno
; /* for error messages */
1416 int *parmnum_p
; /* parameter number is returned here */
1417 int *parmval_p
; /* parameter value is returned here */
1420 int parmnum
; /* parameter number */
1421 int parmval
; /* parameter value */
1422 char *parm_p
; /* pointer to current place in string */
1425 /* extract first number */
1426 parmnum
= strtol(arg
, &parm_p
, 10);
1427 if (parm_p
== arg
) {
1428 l_warning(inputfile
, inputlineno
,
1429 "parameter requires two values");
1432 /* skip white space, if any */
1433 while (*parm_p
== ' ' || *parm_p
== '\t') {
1436 /* next we better have a comma */
1437 if (*parm_p
!= ','){
1438 l_warning(inputfile
, inputlineno
,
1439 "parameter is missing required comma");
1442 /* extract the second number */
1444 parmval
= strtol(arg
, &parm_p
, 10);
1445 if (parm_p
== arg
) {
1446 l_warning(inputfile
, inputlineno
,
1447 "parameter is missing second value");
1450 /* verify both numbers are within range */
1451 if ((l_rangecheck(parmnum
, 0, 127, "parameter number",
1452 inputfile
, inputlineno
) == YES
) &&
1453 (l_rangecheck(parmval
, 0, 127, "parameter value",
1454 inputfile
, inputlineno
) == YES
)) {
1455 *parmnum_p
= parmnum
;
1456 *parmval_p
= parmval
;