2 /* Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006 by Arkkra Enterprises */
3 /* All rights reserved */
5 /* generate a MIDI file from the Mup internal representation */
18 /* Minimum and maximum number of quarter notes per minute.
19 * This should be ridiculously wide enough range and
20 * also prevents division by zero when calculating microsecs per quarter */
22 #define MAXQNPM (1000)
24 /* Default value for microseconds per quarter note */
25 #define DFLT_USEC_PER_QUARTER (500000L)
27 #define USEC_PER_MINUTE (60L * 1000000)
29 /* it is possible to get a legitimate rational overflow, and we don't really
30 * care about absolutely precise time, so when a rational gets bigger than
31 * MAXMIDI_RAT, throw away the lower bits and reduce */
32 #define MAXMIDI_RAT 1000000L
33 /* delta can get multiplied by MIDI_FACTOR. Need to make sure it can
34 * never overflow a signed long, or bad things can happen,
35 * so need smaller limit. */
36 #define MAXDELTA_RAT 300000L
38 /* This marks that we don't have to defer a sharp/flat. We have to defer
39 * them if a note is tied over a barline. The value has to be something
40 * outside the normal accidental range of -2 (double flat) to +2 (double sharp)
42 #define NO_DEFERRED_ACC (-100)
44 /* save information about stuff for the current measure so that it can
45 * be applied at the proper time. */
47 RATIONAL time; /* when to do the MIDI event */
48 struct STUFF *stuff_p; /* STUFF to do */
49 struct MIDISTUFF *next; /* linked list */
52 /* if a roll spans multiple groups, save information about the other
53 * groups. The reason for saving it around rather than just walking down the
54 * gs_p chord list is that if the added groups have to go at the very
55 * beginning of the measure, the only way to find where to link them is to
56 * go back to the main list and search for the appropriate STAFF and follow
57 * one of the groups_p lists. Since we'll get around to visiting that STAFF
58 * eventually anyway, just save the info and do it when we get there. */
60 struct GRPSYL *gs_p; /* group roll applies to */
61 short notesbefore; /* how many notes duration of rest
62 * to add before this group's portion
64 RATIONAL duration; /* duration of each note in roll */
65 struct MIDIROLL *link_p; /* linked list */
68 /* stuff is in floating point, but we keep track of time in RATIONAL. So
69 * when we need to convert, put in terms of 1/F2RFACTOR of a count */
70 #define F2RFACTOR ((UINT32B)(192L * 256L))
72 /* Number of ticks in a whole note */
73 #define MIDI_FACTOR ((UINT32B)(4L * Division))
75 /* default note on velocity */
76 #define DFLT_VELOCITY (64)
78 /* the MIDI STUFF info for current measure/voice */
79 static struct MIDISTUFF *Midistufflist_p;
81 /* list of pending rolls to do */
82 static struct MIDIROLL *Midirollinfo_p;
84 /* tables for mapping voices to tracks and vice versa */
85 static short Voice2track_map [MAXSTAFFS + 1] [MAXVOICES];
86 static short Track2staff_map [MAXSTAFFS * MAXVOICES];
87 static short Track2voice_map [MAXSTAFFS * MAXVOICES];
89 static short Accidental_map[128];/* if a note has an implied accidental, either
90 * due to the key signature or an accidental
91 * earlier in the measure, this table tells
92 * how to adjust the note. For example, if
93 * we have a C, but are in the key of D, the
94 * table entry for C would have a 1 to say to
95 * add 1 because it should really be a C# */
96 static short Deferred_acc[128]; /* If set to something other than
97 * NO_DEFERRED_ACC, then once the current
98 * tie on this note ends, we need to set the
99 * Accidental_map entry to this value. */
100 static short Tie_table[128]; /* YES if note number has a tie on it */
102 /* keep track of all time to an absolute reference so that all tracks stay
103 * in sync, even though midi times are stored as delta times */
104 static RATIONAL Absolute_time;
105 static RATIONAL Sum_of_deltas;
107 static int Status; /* 0 if haven't yet written first MIDI status byte
108 * for current track. Otherwise is the current MIDI
111 static short Channel = 0; /* MIDI channel, 0-15 */
112 static char Onvelocity[MAXHAND]; /* note on velocity */
113 static char Offvelocity[MAXHAND]; /* note off velocity */
114 static short Time_specified_by_user = NO; /* YES if user had a score SSV
115 * setting the time before any music data */
116 static short Key_specified_by_user = NO; /* YES if user had a score SSV
117 * setting the key before any music data */
118 static int Division = DEFDIVISION; /* clock ticks per quarter note */
120 static UINT32B Usec_per_quarter_note = DFLT_USEC_PER_QUARTER;
122 static short Pedbounce = NO; /* if pedal bounce pending */
124 /* local functions */
125 static void repeats P((struct MAINLL **mll_p_p, int *doing_repeat_p,
126 struct MAINLL **repeat_start_p_p));
127 static RATIONAL eff_meas_time P((struct MAINLL *mll_p));
128 static void midi_header P((int mfile, int ntracks));
129 static void track_header P((int mfile));
130 static UINT32B write_midi_data P((int mfile, struct GRPSYL *gs_p));
131 static void init_accidental_map P((int staffno));
132 static void mark_accidental P((int pitch_offset, int acc));
133 static UINT32B midi_multirest P((int mfile, struct STAFF *staff_p, int staffno,
134 int vno, int nummeas));
135 static void init_tie_table P((void));
136 static int xlate_note P((struct NOTE *note_p, char *fname, int lineno,
137 int *raw_notenum_p));
138 static void prepmidi_stuff P((struct STAFF *staff_p, int vno, int all));
139 static UINT32B do_midi_stuff P((RATIONAL timeval, int mfile, int all));
140 static UINT32B midihex P((int mfile, char *str, char *fname, int lineno));
141 static UINT32B midi_item P((struct STUFF *stuff_p, int mfile, int all));
142 static UINT32B wr_meta P((int mfile, int evtype, char *str));
143 static UINT32B all_midi P((int mfile));
144 static void midi_adjust P((void));
145 static void adjust_notes P((struct GRPSYL *gs_p, int staffno, int v,
146 struct MAINLL *mll_p));
147 static void add_release P((struct GRPSYL *gs_p, RATIONAL release_adjust,
148 struct MAINLL *mll_p));
149 static UINT32B pedswitch P((int nfile, int on));
150 static void midi_roll P((struct GRPSYL *gs_p, struct GRPSYL **gslist_p_p));
151 static RATIONAL roll_time P((RATIONAL grptime, int nnotes));
152 static void do_mroll P((struct GRPSYL *gs_p, struct GRPSYL **gslist_p_p,
153 RATIONAL rolltime, int notesbefore));
154 static void addrollgrp P((struct GRPSYL *gs_p, RATIONAL duration, int start,
155 int end, struct GRPSYL **link_p_p, struct GRPSYL *prev_p));
156 static void savemidiroll P((struct GRPSYL *gs_p, int notesbefore,
158 static struct MIDIROLL *getmidiroll P((struct GRPSYL *gs_p));
159 static void fix_tempo P((int to_end));
160 static void free_midistuff P((struct MIDISTUFF *ms_p));
161 static void adj4squeeze P((RATIONAL timeval));
164 /* generate a MIDI file. Assigns each staff/voice combo to a MIDI track.
165 * Write MIDI file header and first track with tempo, etc info. Then for
166 * each staff/voice, generate a MIDI track with all note on/off and
167 * whatever STUFF we know how to deal with. */
170 gen_midi(midifilename)
172 char *midifilename; /* put MIDI data in this file */
175 struct MAINLL *mll_p; /* to index through main list */
179 int vno; /* voice index */
180 int mfile; /* file descriptor for MIDI output file */
181 UINT32B track_size; /* bytes in track */
182 UINT32B track_start; /* offset in file where track begins */
183 int t; /* track index */
184 int doing_repeat; /* YES or NO */
185 int got_data; /* YES or NO, to deal with case where the
186 * number of staffs/voices changes mid-stream */
187 struct MAINLL *repeat_start_p; /* pointer to first measure of a
188 * repeated section, so we know where to
189 * jump back to when we hit the end of
191 struct STAFF *staff_p; /* need to refer to STAFF a lot, so keep a
193 struct STAFF *last_staff_p = (struct STAFF *) 0;/* in case measure
194 * was invisible or something,
195 * this points to the most recent
196 * staff for current loop */
198 int first; /* YES/NO if processing first meas */
201 debug(256, "gen_midi");
203 /* first go through main list, and find out which staff/voice pairs
204 * are used, and assign each to a track. */
205 for (mll_p = Mainllhc_p; mll_p != (struct MAINLL *) 0;
206 mll_p = mll_p->next) {
208 if (mll_p->str == S_STAFF) {
209 staff = mll_p->u.staff_p->staffno;
211 /* ignore tab staffs -- we use the notes on the
212 * associated tabnote staff above it instead */
213 if (is_tab_staff(staff) == YES) {
217 for (vno = 0; vno < MAXVOICES; vno++) {
219 if (mll_p->u.staff_p->groups_p[vno] ==
220 (struct GRPSYL *) 0) {
224 if (Voice2track_map [staff] [vno] == 0) {
225 /* haven't allocated this staffno/vno to
226 * a track yet, so do so now. */
227 Track2staff_map [track] = (short) staff;
228 Track2voice_map [track] = (short) vno;
229 Voice2track_map [staff] [vno] = ++track;
230 debug(512, "assigned staff %d voice %d to track %d",
231 staff, vno + 1, track);
238 ufatal("no note data found");
241 /* open the specified MIDI file */
243 if ((mfile = open(midifilename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666))
245 if ((mfile = open(midifilename, O_WRONLY | O_CREAT | O_TRUNC, 0666))
248 ufatal("can't open MIDI file '%s'", midifilename);
251 /* adjust grace notes to get a little time, etc */
254 /* squeeze out any all-space chords */
257 /* the default Guitar tablature staff notes get transposed an octave,
258 * so do that if appropriate */
261 /* generate MIDI file header */
263 Usec_per_quarter_note = DFLT_USEC_PER_QUARTER;
264 midi_header(mfile, track);
266 /* go through the main list once for each staff/voice, generating a
267 * MIDI track for it. */
268 for (t = 0; t < track; t++) {
270 /* initialize everything for this track */
273 track_start = lseek(mfile, 0L, SEEK_CUR);
275 staff = Track2staff_map[t];
276 vno = Track2voice_map[t];
279 repeat_start_p = Mainllhc_p;
281 Octave_adjust[staff] = 0;
282 Octave_bars[staff] = 0;
283 Octave_count[staff] = 0.0;
286 for (i = 0; i < MAXHAND; i++) {
287 Onvelocity[i] = (char) DFLT_VELOCITY;
288 Offvelocity[i] = (char) 0;
291 /* go through main list */
292 for (mll_p = Mainllhc_p; mll_p != (struct MAINLL *) 0;
293 mll_p = mll_p->next) {
295 switch (mll_p->str) {
298 /* There may be an implicit repeatstart at
299 * the beginning of the piece, so we need
300 * to save the current SSV state, in case
301 * the user repeats back to this implicit
304 repeat_start_p = mll_p;
308 staff_p = mll_p->u.staff_p;
309 /* check if this is for the staff we are
310 * currently generating midi data for */
311 if (staff_p->staffno == staff
312 && staff_p->groups_p[vno]
313 != (struct GRPSYL *) 0) {
315 /* treat invisible staffs as
316 * inaudible as well */
317 if (svpath(staff, VISIBLE) ->visible
319 /* if next staff is a tab staff,
320 * and it is visible, then we
321 * want this staff to still be
322 * audible, otherwise skip */
323 if (staff >= Score.staffs ||
324 ! is_tab_staff(staff+1)
325 || svpath(staff+1, VISIBLE)->visible == NO) {
326 /* convert notes to rests.
328 * because if we do, space
329 * that has been squeezed
330 * out isn't handled right,
331 * and tracks can get out of
332 * sync with each other */
333 for (g_p = staff_p->groups_p[vno];
334 g_p != (struct GRPSYL *) 0;
336 if (g_p->nnotes > 0) {
344 /* found information for the track/voice
345 * we are currently generating */
348 /* check for multi-rest */
349 if (staff_p->groups_p[vno]->basictime
351 track_size += midi_multirest
354 -(staff_p->groups_p[vno]
359 /* generate MIDI data */
360 /* Handle octave marks, but only first
361 * time through a repeat, or it will
362 * get transposed twice! */
363 if (doing_repeat == NO) {
364 octave_transpose(staff_p, mll_p,
367 init_accidental_map(staff);
368 prepmidi_stuff(staff_p, vno, NO);
369 track_size += write_midi_data(mfile,
370 staff_p->groups_p[vno]);
372 else if (staff_p->staffno == staff) {
373 /* Voice doesn't exist in this meas,
374 * so just keep track of the staff
375 * so when we hit the bar we can
376 * add the silence, and update any
377 * midi parameters and such. */
378 last_staff_p = staff_p;
383 asgnssv(mll_p->u.ssv_p);
385 /* update key signature for this track
386 * if necessary. Note that score-wide
387 * key signature changes will be written
388 * out via all_midi(). */
389 if (mll_p->u.ssv_p->context == C_STAFF &&
390 mll_p->u.ssv_p->staffno
392 (mll_p->u.ssv_p->used[SHARPS]
394 mll_p->u.ssv_p->used[TRANSPOSITION]
396 mll_p->u.ssv_p->used[ADDTRANSPOSITION]
398 track_size += midi_keysig(mfile,
399 eff_key(mll_p->u.ssv_p->staffno),
400 mll_p->u.ssv_p->is_minor);
405 /* if this voice is defined somewhere in the
406 * song, but not in this measure, need to add
407 * virtual measure of rest. (This could happen
408 * if user changed the number of staffs
409 * and/or voices in mid-stream */
410 if (got_data == NO && mll_p->inputlineno != -1) {
411 /* Arrange to do any midi things
412 * for this voice, even though it
413 * doesn't exist at the moment. */
414 if (last_staff_p != (struct STAFF *) 0) {
415 prepmidi_stuff(last_staff_p,
418 /* This will update the current
419 * absolute time to include the
420 * effective time for this measure. */
421 track_size += do_midi_stuff(
422 eff_meas_time(mll_p),
424 last_staff_p = (struct STAFF *) 0;
431 repeats(&mll_p, &doing_repeat, &repeat_start_p);
439 if (mll_p == (struct MAINLL *) 0) {
440 /* shouldn't happen, but repeats() can change
441 * mll_p, and if it ever became null, we'd
442 * try to take the ->next of it, which isn't
443 * good, so take precautions */
448 /* add end of track mark */
449 track_size += write(mfile, "\0\377/\0", 4);
451 /* now that we know the track size, fill it in */
452 fix_track_size(mfile, track_start, track_size);
459 /* given a bar, handle repeats at that bar line. First time we hit the end
460 * of a repeated section, go back to its beginning. Handles the case where
461 * the repeat end is at the end of an ending. */
464 repeats (mll_p_p, doing_repeat_p, repeat_start_p_p)
466 struct MAINLL **mll_p_p; /* points to a BAR */
467 int *doing_repeat_p; /* return YES or NO via this pointer to
468 * indicate whether now doing a repeat */
469 struct MAINLL **repeat_start_p_p; /* indicates where repeated section
470 * begins. May be updated by this function if
471 * we hit a repeat sign */
476 /* handle endings (simple case only). If we
477 * hit the beginning of an ending while doing second time through
478 * a repeated section, assume we should jump to the end
480 if ((*mll_p_p)->u.bar_p->endingloc == STARTITEM
481 && *doing_repeat_p == YES) {
483 for (*mll_p_p = (*mll_p_p)->next;
484 *mll_p_p != (struct MAINLL *)0;
485 *mll_p_p = (*mll_p_p)->next) {
487 if ((*mll_p_p)->str == S_BAR &&
488 ((*mll_p_p)->u.bar_p->bartype == REPEATEND ||
489 (*mll_p_p)->u.bar_p->bartype == REPEATBOTH)) {
493 *doing_repeat_p = NO;
494 *repeat_start_p_p = *mll_p_p;
499 /* handle repeats. At beginning of a repeat,
500 * remember where it is. At end, if first time
501 * through, jump back. */
502 switch ((*mll_p_p)->u.bar_p->bartype) {
505 /* remember where repeat begins */
506 *repeat_start_p_p = *mll_p_p;
511 if (*doing_repeat_p == YES) {
512 /* 2nd time through */
513 *doing_repeat_p = NO;
514 *repeat_start_p_p = *mll_p_p;
517 /* first time through */
518 *doing_repeat_p = YES;
519 *mll_p_p = *repeat_start_p_p;
520 /* set the SSV's back to what they were at the
521 * beginning of the repeat. */
523 for (m_p = Mainllhc_p; m_p != *repeat_start_p_p;
525 if (m_p->str == S_SSV) {
526 asgnssv(m_p->u.ssv_p);
538 /* Find the "effective" duration of a measure. Because of squeezing of
539 * space chords, a measure may be shorter than the time signature.
540 * Given a spot in the main list, this finds the first visible voice
541 * at or above that place, and counts up the time of the GRPSYLS in it,
542 * ignoring squeezed-out spaces.
548 struct MAINLL *mll_p;
551 RATIONAL eff_time; /* calculated value to return */
552 struct GRPSYL *g_p; /* to loop through groups */
553 int v = 0; /* voice index. Initialization is just
554 * to avoid bogus "used before set"
557 /* find top visible voice */
558 for ( ; mll_p != 0; mll_p = mll_p->prev) {
559 if (mll_p->str == S_STAFF && svpath(mll_p->u.staff_p->staffno,
560 VISIBLE)->visible == YES) {
561 for (v = 0; v < MAXVOICES; v++) {
562 if (vvpath(mll_p->u.staff_p->staffno, v+1,
563 VISIBLE)->visible == YES) {
573 pfatal("eff_meas_time couldn't find a visible voice");
576 /* All up the time in this voice */
578 for (g_p = mll_p->u.staff_p->groups_p[v]; g_p != 0; g_p = g_p->next) {
579 if (g_p->grpvalue == GV_ZERO && g_p->grpcont == GC_SPACE) {
580 /* squeezed out space, so doesn't count */
583 eff_time = radd(eff_time, g_p->fulltime);
589 /* write MIDI header to file */
592 midi_header(mfile, ntracks)
594 int mfile; /* file descriptor to write to */
595 int ntracks; /* how many tracks are to be written */
598 unsigned char buff[8];
603 debug(512, "midi_header");
605 trklength = write(mfile, "MThd\0\0\0\6\0", 9);
607 /* always use format 1 */
610 /* 2 bytes for number of tracks */
611 /* add 1 for the track giving time signature, etc */
612 buff[1] = (unsigned char) (ntracks + 1) >> 8;
613 buff[2] = (unsigned char) (ntracks + 1) & 0xff;
615 /* division field. */
616 buff[3] = (unsigned char) (Division >> 8);
617 buff[4] = (unsigned char) (Division & 0xff);
618 (void) write(mfile, buff, 5);
620 /* now do first track, which gives time and key signature info */
621 track1start = lseek(mfile, 0L, SEEK_CUR);
625 /* if there is a header and the first item to print is centered,
626 * it's probably a title, so do it as a text event. */
627 if (Header.printdata_p != (struct PRINTDATA *) 0) {
628 if (Header.printdata_p->justifytype == J_CENTER &&
629 Header.printdata_p->string != (char *) 0) {
630 trklength += write_delta(mfile);
633 trklength += write(mfile, buff, 2);
634 trklength += midi_wrstring(mfile,
635 Header.printdata_p->string, YES);
638 /* do default time signature if necessary */
639 if (Time_specified_by_user == NO) {
640 trklength += midi_timesig(mfile);
643 /* do default key signature if necessary */
644 if (Key_specified_by_user == NO) {
645 trklength += midi_keysig(mfile, eff_key(0), Score.is_minor);
648 /* output usecs per quarter note */
649 trklength += write(mfile, "\0\377Q\3", 4);
650 buff[0] = (Usec_per_quarter_note >> 16) & 0xff;
651 buff[1] = (Usec_per_quarter_note >> 8) & 0xff;
652 buff[2] = Usec_per_quarter_note & 0xff;
653 trklength += write(mfile, buff, 3);
655 /* do everything else for track 1 */
656 trklength += all_midi(mfile);
658 /* end of track marker */
659 trklength += write(mfile, "\0\377/\0", 4);
660 fix_track_size(mfile, track1start, trklength);
664 /* write a MIDI track header */
669 int mfile; /* write track header to this file descriptor */
672 debug(512, "track_header");
674 (void) write(mfile, "MTrk\0\0\0\0", 8);
676 /* reset time reference */
677 Absolute_time = Sum_of_deltas = Zero;
679 /* reset "running status" */
684 /* write MIDI info. Return number of bytes written to mfile */
687 write_midi_data(mfile, gs_p)
689 int mfile; /* write MIDI data to this file descriptor */
690 struct GRPSYL *gs_p; /* write info about these chords */
693 UINT32B bytes = 0; /* number of bytes written */
694 int n; /* walk through notes of chord */
695 unsigned char buff[4]; /* temp storage for MIDI data */
696 int notenum; /* MIDI note number 0-127 */
697 int raw_notenum; /* note numer not counting accidentals */
698 short newstatus; /* running status */
701 /* go through each GRPSYL in the measure */
702 for ( ; gs_p != (struct GRPSYL *) 0; gs_p = gs_p->next) {
704 /* do any MIDI stuffs that happen right on this beat. They
705 * should happen after notes have been turned off for previous
706 * chord but before the notes for the following chord */
707 bytes += do_midi_stuff(Zero, mfile, NO);
709 /* if rest or space, just keep track of time used. */
710 if ( gs_p->grpcont != GC_NOTES) {
711 /* special case of all-space chord. It gets no time.
712 * Just adjust pending MIDI events so they happen
713 * at the right time */
714 if (gs_p->grpcont == GC_SPACE && gs_p->grpvalue == GV_ZERO) {
715 adj4squeeze(gs_p->fulltime);
716 bytes += do_midi_stuff(Zero, mfile, NO);
719 bytes += do_midi_stuff(gs_p->fulltime, mfile, NO);
724 /* turn on each note in chord */
725 for (n = 0; n < gs_p->nnotes; n++) {
727 notenum = xlate_note( &(gs_p->notelist[n]),
728 gs_p->inputfile, gs_p->inputlineno,
731 /* if this note is tied from previous, it is already
732 * turned on, so just mark off that we've done the tie.
734 if (Tie_table[raw_notenum] == YES) {
735 Tie_table[raw_notenum] = NO;
739 /* not tied from previous, so turn note on */
740 bytes += write_delta(mfile);
742 /* first time through have to put the status.
743 * After that we can use running status */
744 newstatus = (0x90 | Channel) & 0xff;
745 if (Status != newstatus) {
746 buff[0] = (unsigned char) newstatus;
747 (void) write(mfile, buff, 1);
752 buff[0] = (unsigned char) notenum;
753 buff[1] = (unsigned char) Onvelocity[n];
754 (void) write(mfile, buff, 2);
759 bytes += do_midi_stuff(gs_p->fulltime, mfile, NO);
761 /* now turn all the notes off, unless tied */
762 for (n = 0; n < gs_p->nnotes; n++) {
764 notenum = xlate_note( &(gs_p->notelist[n]),
765 gs_p->inputfile, gs_p->inputlineno,
768 /* if this note is tied to next, mark that */
769 if ( (gs_p->notelist[n].tie == YES) ||
770 (gs_p->tie == YES) ) {
771 Tie_table[raw_notenum] = YES;
774 /* not tied to next, so turn off */
775 bytes += write_delta(mfile);
777 /* use note on with onvelocity 0 (which means
778 * note off), unless user explicitly set an
780 if (Offvelocity[n] != 0) {
781 newstatus = (0x80 | Channel) & 0xff;
784 newstatus = (0x90 | Channel) & 0xff;
786 if (Status != newstatus) {
787 buff[0] = (unsigned char) newstatus;
788 (void) write(mfile, buff, 1);
792 buff[0] = (unsigned char) notenum;
793 buff[1] = (unsigned char) Offvelocity[n];
794 (void) write(mfile, buff, 2);
797 /* If we had to defer the setting of
798 * sharps/flats because of a tie into the
799 * measure, do that now. */
800 if (Deferred_acc[raw_notenum] != NO_DEFERRED_ACC) {
801 Accidental_map[raw_notenum] =
802 Deferred_acc[raw_notenum];
803 Deferred_acc[raw_notenum] = NO_DEFERRED_ACC;
809 /* do any midi events that happen at the end of the measure after
811 bytes += do_midi_stuff(Zero, mfile, NO);
817 /* write out delta value. Return number of bytes written */
822 int mfile; /* file descriptor of MIDI file */
825 UINT32B idelta; /* delta rounded to 32-bit integer */
827 RATIONAL rounded; /* idelta converted back to RATIONAL */
830 /* avoid rational overflow, which can happen under certain
831 * circumstances with lots of grace, rolls, etc */
832 while (Absolute_time.n > MAXMIDI_RAT
833 || Absolute_time.d > MAXMIDI_RAT) {
834 /* avoid rational divide by zero */
835 if (Absolute_time.d > 1) {
836 Absolute_time.n >>= 1;
837 Absolute_time.d >>= 1;
838 rred ( &Absolute_time );
844 while( Sum_of_deltas.n > MAXMIDI_RAT
845 || Sum_of_deltas.d > MAXMIDI_RAT) {
846 if (Sum_of_deltas.d > 1) {
847 Sum_of_deltas.n >>= 1;
848 Sum_of_deltas.d >>= 1;
849 rred ( &Sum_of_deltas );
856 delta = rsub(Absolute_time, Sum_of_deltas);
857 if (LT(delta, Zero)) {
861 /* Multiply by factor to get delta value in MIDI clock ticks,
862 * then round off to UINT32B. Entire calculation must be done
863 * in floating point, then cast to UINT32B, otherwise overflow
864 * can occur, which really messes things up!! */
865 idelta = (UINT32B)((((double) MIDI_FACTOR * (double) delta.n)
866 / (double) delta.d) + 0.5);
868 /* now convert the rounded-off value back to a RATIONAL,
869 * and add it to the Sum_of_deltas, so we'll know exactly how far
870 * off we are the next time around and can compensate. */
872 rounded.d = MIDI_FACTOR;
874 /* certain combinations of division value, release values, and
875 * input could cause rounded to overflow and become negative.
876 * Because of all the other code added to try to avoid overflow,
877 * this should be extremely unlikely, but it's better to catch
878 * it and give an error than leave the user to wonder why the
879 * generated MIDI file says to hold a note for several days. */
880 if (LT(rounded, Zero)) {
881 pfatal("arithmetic overflow on MIDI delta calculation, input probably too complex\n (hint: changing the 'release' parameter might help)");
884 Sum_of_deltas = radd(Sum_of_deltas, rounded);
886 return(wr_varlength(mfile, idelta));
890 /* given a NOTE, return the corresponding MIDI note number */
893 xlate_note(note_p, fname, lineno, raw_notenum_p)
896 char *fname; /* input file */
897 int lineno; /* input line number */
898 int *raw_notenum_p; /* return the note number without accidentals */
903 switch (note_p->letter) {
926 pfatal("invalid note\n");
931 /* adjust for octave */
932 val += 12 * (note_p->octave + 1);
934 /* If user overlaps octave marks inside a measure, which we don't
935 * catch, or if they transpose a note so many octaves that it is out
936 * of range (like transposing something down when it's already in
937 * octave 0) a note could end up out of range, so catch that here. */
938 if (note_p->octave < MINOCTAVE || note_p->octave > MAXOCTAVE ||
939 val < 0 || val > 127) {
940 l_ufatal(fname, lineno, "note is out of range");
944 /* return the value not considering accidentals. This is needed to
945 * keep track of ties properly. */
946 *raw_notenum_p = val;
948 switch (note_p->accidental) {
950 Accidental_map[val] = 1;
953 Accidental_map[val] = -1;
956 Accidental_map[val] = 2;
959 Accidental_map[val] = -2;
962 Accidental_map[val] = 0;
965 /* leave note as is */
968 pfatal("unknown accidental type '%c'", note_p->accidental);
972 /* the top few notes in octave 9 are outside midi range */
973 if (val + Accidental_map[val] > 127) {
974 l_ufatal(fname, lineno, "note out of range");
976 return (val + Accidental_map[val]);
980 /* initialize map of accidentals, based on key signature. */
983 init_accidental_map(staffno)
990 /* first clear the map for all MIDI notes */
991 for (n = 0; n < 128; n++) {
992 /* If a note with any sort of accidental on it is currently
993 * tied, then we don't clear that note's accidental map,
994 * but mark that we will need to set the key signature
995 * value later, after the tie ends. Otherwise we set it
997 if (Tie_table[n] == YES) {
998 /* set to zero for now. Will set to something else
999 * in mark_accidental later if appropriate. */
1000 Deferred_acc[n] = 0;
1003 Accidental_map[n] = 0;
1004 Deferred_acc[n] = NO_DEFERRED_ACC;
1008 /* now fill in the key signature items in all octaves */
1009 switch (eff_key(staffno) ) {
1012 mark_accidental(11, 1);
1016 mark_accidental(4, 1);
1020 mark_accidental(9, 1);
1024 mark_accidental(2, 1);
1028 mark_accidental(7, 1);
1032 mark_accidental(0, 1);
1036 mark_accidental(5, 1);
1042 mark_accidental(5, -1);
1046 mark_accidental(0, -1);
1050 mark_accidental(7, -1);
1054 mark_accidental(2, -1);
1058 mark_accidental(9, -1);
1062 mark_accidental(4, -1);
1066 mark_accidental(11, -1);
1069 pfatal("unknown key signature");
1075 /* initialize table to say that no notes are tied */
1084 for (i = 0; i < 128; i++) {
1090 /* in each octave, mark the given note as having the given accidental, if not
1091 * tied. If tied, mark to set it later. */
1094 mark_accidental(pitch_offset, acc)
1096 int pitch_offset; /* 0 = C, 2 = D, 4 = E, 5 = F, 7 = G, 9 = A, 11 = B */
1097 int acc; /* 1 = sharp, -1 = flat */
1102 for (n = pitch_offset; n < 128; n += 12) {
1103 if (Tie_table[n] == YES) {
1104 Deferred_acc[n] = (short) acc;
1107 Accidental_map[n] = (short) acc;
1113 /* handle a multi-rest. Adjust the absolute time reference value to account
1114 * for the length of the multi-rest */
1117 midi_multirest(mfile, staff_p, staffno, vno, nummeas)
1119 int mfile; /* MIDI file */
1120 struct STAFF *staff_p;
1122 int vno; /* voice number */
1123 int nummeas; /* how many measure of rest */
1126 RATIONAL rat_nummeas; /* number of measure as a rational */
1129 if (staff_p != (struct STAFF *) 0) {
1130 prepmidi_stuff(staff_p, vno, NO);
1133 /* if truly a multirest and if octave were in progress,
1134 * need to adjust number of measures remaining */
1135 if (nummeas > 1 && Octave_bars[staffno] > 0) {
1136 /* subtract 1 'cause the barline will count as one */
1137 Octave_bars[staffno] -= nummeas - 1;
1138 /* if whole octave stuff is done, re-init */
1139 if (Octave_bars[staffno] < 0) {
1140 Octave_bars[staffno] = 0;
1141 Octave_count[staffno] = 0.0;
1142 Octave_adjust[staffno] = 0;
1146 rat_nummeas.n = nummeas;
1148 return(do_midi_stuff(rmul(rat_nummeas, Score.time), mfile, NO));
1152 /* go through STUFF in a measure, saving away info about MIDI stuff for
1156 prepmidi_stuff(staff_p, vindex, all)
1158 struct STAFF *staff_p; /* do STUFF off of here */
1159 int vindex; /* voice index, 0 or 1 for voice 1 or 2 */
1160 int all; /* YES if processing 'all' stuff */
1163 struct STUFF *st_p; /* walk through staff_p->stuff_p */
1164 struct MIDISTUFF *ms_p; /* walk through Midistufflist_p */
1165 struct MIDISTUFF **ms_p_p; /* for inserting into list */
1168 Midistufflist_p = (struct MIDISTUFF *) 0;
1169 for (st_p = staff_p->stuff_p; st_p != (struct STUFF *) 0;
1170 st_p = st_p->next) {
1172 if (st_p->stuff_type == ST_MIDI
1173 || st_p->stuff_type == ST_PEDAL) {
1175 /* only do those with proper 'all' value */
1176 if (st_p->all != all) {
1180 if (st_p->place == PL_ABOVE && vindex != 0) {
1181 /* above only applies to voice 1 */
1184 if (st_p->place == PL_BELOW && vindex != 1) {
1185 /* below only applies to voice 2 */
1186 if (st_p->stuff_type != ST_PEDAL) {
1190 if (st_p->place == PL_BETWEEN && vindex != 2) {
1191 /* between only applies to voice 3 */
1195 CALLOC(MIDISTUFF, ms_p, 1);
1196 /* figure out when to do this event. Have in floating
1197 * point, but need in RATIONAL. So convert. From MIDI's
1198 * point of view, the first beat of a measure occurs at
1199 * time zero, but stuff calls that time 1, and may have
1200 * things happening before that. So adjust for that,
1201 * and consider anything happening from stuff time 0 to
1202 * 1 to happen instantaneously at midi time 0. */
1203 ms_p->time.n = (UINT32B) ( (st_p->start.count - 1.0)
1205 ms_p->time.d = F2RFACTOR * Score.timeden;
1206 rred( &(ms_p->time) );
1207 if ( LT(ms_p->time, Zero) ) {
1210 ms_p->time = radd(ms_p->time, Absolute_time);
1212 ms_p->stuff_p = st_p;
1214 /* insertion sort into list */
1215 for (ms_p_p = &Midistufflist_p; *ms_p_p !=
1216 (struct MIDISTUFF *) 0;
1217 ms_p_p = &((*ms_p_p)->next)) {
1218 if (GT( (*ms_p_p)->time, ms_p->time)) {
1222 ms_p->next = *ms_p_p;
1229 /* given a timeval to add to Absolute_time, see if there are any MIDI
1230 * STUFF events that come before then. If so, do them first. If timeval
1231 * is Zero, do any events happening exactly at Absolute_time. In any case
1232 * update Absolute_time appropriately. Return number of bytes written */
1235 do_midi_stuff(timeval, mfile, all)
1238 int mfile; /* MIDI file */
1239 int all; /* YES if processing 'all' stuffs */
1242 RATIONAL new_abs_time; /* Absolute_time plus timeval */
1243 struct MIDISTUFF *ms_p; /* index through MIDISTUFF list */
1244 UINT32B bytes = 0; /* bytes written */
1247 /* If need to bounce pedal, do that now */
1248 if (Pedbounce == YES && NE(timeval, Zero)) {
1252 instant.d = MIDI_FACTOR;
1253 Absolute_time = radd(Absolute_time, instant);
1254 bytes += pedswitch(mfile, YES);
1255 Absolute_time = rsub(Absolute_time, instant);
1259 /* find out what final time will be */
1260 new_abs_time = radd(Absolute_time, timeval);
1262 /* go through list of MIDI STUFF, to see if anything to do before
1264 for (ms_p = Midistufflist_p; ms_p != (struct MIDISTUFF *) 0; ) {
1266 if ( LT(ms_p->time, new_abs_time) || (EQ(timeval, Zero) &&
1267 EQ(ms_p->time, new_abs_time) ) ) {
1269 /* an item to do. Do it */
1270 Absolute_time = ms_p->time;
1271 bytes += midi_item(ms_p->stuff_p, mfile, all);
1273 /* free this item and move to next one */
1275 FREE(Midistufflist_p);
1276 Midistufflist_p = ms_p;
1282 Absolute_time = new_abs_time;
1284 /* return number of bytes written */
1289 /* handle a MIDI stuff item */
1292 midi_item(stuff_p, mfile, all)
1294 struct STUFF *stuff_p; /* which STUFF to process */
1295 int mfile; /* the MIDI file */
1296 int all; /* YES if processing "all" type items now */
1299 UINT32B bytes = 0; /* bytes written */
1300 unsigned char buff[8];
1301 char *key; /* midi directive keyword */
1302 int leng; /* length of key */
1303 char *arg; /* arg after the = */
1304 int num; /* atoi value of argument */
1305 int n; /* note velocity index */
1306 char *nextvel_p; /* location in string of next velocity value */
1309 if (stuff_p->stuff_type == ST_PEDAL) {
1314 if (stuff_p->string == (char *) 0) {
1315 /* continuation of pedal into an ending or something
1316 * similar. I don't think this will every actually
1317 * happen, since that's done in a later phase. */
1321 /* extract the pedal character */
1322 font = stuff_p->string[0];
1323 size = stuff_p->string[1];
1324 string = stuff_p->string + 2;
1326 /* turn pedal switch on or off as appropriate */
1327 switch(next_str_char(&string, &font, &size) & 0xff) {
1330 bytes += pedswitch(mfile, YES);
1334 bytes += pedswitch(mfile, NO);
1335 /* have to put pedal back up after the next chord */
1340 bytes += pedswitch(mfile, NO);
1344 pfatal("bad character in pedal string");
1351 /* figure out which keyword was specified */
1352 if (getkeyword(stuff_p->string + 2, &key, &leng, &arg) == NO) {
1353 l_warning(stuff_p->inputfile, stuff_p->inputlineno,
1354 "midi directive not in keyword=value format");
1358 /* do the code for the appropriate keyword. There are enough keywords
1359 * that it would almost be worthwhile doing a hash or binary search
1360 * rather than sequentially checking each. However, most of them will
1361 * probably be rarely used, so by checking the most common ones first,
1362 * there will rarely be more than half a dozen checks anyway. */
1363 if (matches(key, leng, "program") == YES) {
1364 if (stuff_p->all == YES) {
1365 l_warning(stuff_p->inputfile, stuff_p->inputlineno,
1366 "midi program cannot be used with 'all'");
1374 if (l_rangecheck(num, 0, 127, "program", stuff_p->inputfile,
1375 stuff_p->inputlineno) == YES) {
1376 bytes = write_delta(mfile);
1377 Status = buff[0] = (unsigned char) (0xc0 | Channel);
1378 buff[1] = (unsigned char) num;
1379 bytes += write(mfile, buff, 2);
1383 else if (matches(key, leng, "tempo") == YES) {
1384 UINT32B quarter_notes_per_minute;
1386 /* tempo only applies to 'all' */
1387 if (stuff_p->all == NO) {
1388 l_warning( stuff_p->inputfile, stuff_p->inputlineno,
1389 "midi tempo can only be set using 'all'");
1397 quarter_notes_per_minute = atoi(arg);
1398 if (l_rangecheck(quarter_notes_per_minute, MINQNPM, MAXQNPM,
1399 "tempo", stuff_p->inputfile,
1400 stuff_p->inputlineno) == YES) {
1401 bytes = write_delta(mfile);
1402 buff[0] = (unsigned char) 0xff;
1403 buff[1] = (unsigned char) 0x51;
1404 buff[2] = (unsigned char) 0x3;
1405 Usec_per_quarter_note = USEC_PER_MINUTE
1406 / quarter_notes_per_minute;
1407 buff[3] = (Usec_per_quarter_note >> 16) & 0xff;
1408 buff[4] = (Usec_per_quarter_note >> 8) & 0xff;
1409 buff[5] = (Usec_per_quarter_note & 0xff);
1410 bytes += write(mfile, buff, 6);
1415 else if (matches(key, leng, "onvelocity") == YES) {
1416 if (stuff_p->all == YES) {
1417 l_warning(stuff_p->inputfile, stuff_p->inputlineno,
1418 "midi onvelocity cannot be used with 'all'");
1425 if (l_rangecheck(num, 1, 127, "onvelocity", stuff_p->inputfile,
1426 stuff_p->inputlineno) == YES) {
1427 Onvelocity[0] = (char) num;
1429 /* if there are more velocities given, process them. If
1430 * there are N velocities given, they give the velocities
1431 * to use for the top N notes, the first for the top note,
1432 * the second for the second to the top, etc. If there are
1433 * more than N notes in a chord, the remaining notes are
1434 * given the velocity of the final velocity specified.
1435 * Thus, if only one is specified, it applies to all notes
1436 * in the chord, whereas if two are given, the top note
1437 * will have the first velocity and the remaining notes will
1438 * have the second (which could be useful for emphasizing
1439 * the melody, for example). And the user can specify each
1440 * note's velocity separately if they want to.
1442 nextvel_p = strchr(arg, ',');
1443 for (n = 1; n < MAXHAND; n++) {
1445 /* if user has listed another velocity, save it */
1446 if (nextvel_p != (char *) 0) {
1447 num = atoi(++nextvel_p);
1448 if (l_rangecheck(num, 1, 127, "onvelocity",
1450 stuff_p->inputlineno) == YES) {
1451 Onvelocity[n] = (char) num;
1454 /* point to next velocity, if any, for next
1455 * time through the loop */
1456 nextvel_p = strchr(nextvel_p, ',');
1459 /* use the last user-specified velocity for
1460 * all subsequent notes */
1461 Onvelocity[n] = (char) num;
1466 /* Note: have to check "channel" before "chanpressure" so that
1467 * channel takes precedence if the keyword is abbreviated */
1468 else if (matches(key, leng, "channel") == YES) {
1469 if (stuff_p->all == YES) {
1470 l_warning(stuff_p->inputfile, stuff_p->inputlineno,
1471 "midi channel cannot be used with 'all'");
1479 if (l_rangecheck(num, 1, 16, "channel", stuff_p->inputfile,
1480 stuff_p->inputlineno) == YES) {
1481 /* external MIDI channel numbers are 1-16,
1482 * internal are 0-15 */
1487 else if (matches(key, leng, "parameter") == YES) {
1488 int parmnum; /* parameter number */
1489 int parmval; /* parameter value */
1491 if (get_param(arg, stuff_p->inputfile, stuff_p->inputlineno,
1492 &parmnum, &parmval) == YES) {
1493 bytes += write_delta(mfile);
1494 Status = buff[0] = 0xb0 | Channel;
1495 buff[1] = (unsigned char) parmnum;
1496 buff[2] = (unsigned char) parmval;
1497 bytes += write(mfile, buff, 3);
1501 else if (matches(key, leng, "offvelocity") == YES) {
1502 if (stuff_p->all == YES) {
1503 l_warning(stuff_p->inputfile, stuff_p->inputlineno,
1504 "midi offvelocity cannot be used with 'all'");
1511 if (l_rangecheck(num, 0, 127, "offvelocity", stuff_p->inputfile,
1512 stuff_p->inputlineno) == YES) {
1513 Offvelocity[0] = (char) num;
1515 /* if there are more velocities given, process them.
1516 * See description of onvelocity above for details.
1518 nextvel_p = strchr(arg, ',');
1519 for (n = 1; n < MAXHAND; n++) {
1521 /* if user has listed another velocity, save it */
1522 if (nextvel_p != (char *) 0) {
1523 num = atoi(++nextvel_p);
1524 if (l_rangecheck(num, 1, 127, "onvelocity",
1526 stuff_p->inputlineno) == YES) {
1527 Offvelocity[n] = (char) num;
1530 /* point to next velocity, if any, for next
1531 * time through the loop */
1532 nextvel_p = strchr(nextvel_p, ',');
1535 /* use the last user-specified velocity for
1536 * all subsequent notes */
1537 Offvelocity[n] = (char) num;
1542 else if (matches(key, leng, "hex") == YES) {
1543 return(midihex(mfile, arg, stuff_p->inputfile, stuff_p->inputlineno));
1545 else if (matches(key, leng, "text") == YES) {
1546 return(wr_meta(mfile, 0x01, arg));
1548 else if (matches(key, leng, "copyright") == YES) {
1549 return(wr_meta(mfile, 0x02, arg));
1551 else if (matches(key, leng, "name") == YES) {
1552 return(wr_meta(mfile, 0x03, arg));
1554 else if (matches(key, leng, "instrument") == YES) {
1555 return(wr_meta(mfile, 0x04, arg));
1557 else if (matches(key, leng, "marker") == YES) {
1558 return(wr_meta(mfile, 0x06, arg));
1560 else if (matches(key, leng, "cue") == YES) {
1561 return(wr_meta(mfile, 0x07, arg));
1564 else if (matches(key, leng, "seqnum") == YES) {
1566 if (l_rangecheck(num, 0, 32767, "seqnum", stuff_p->inputfile,
1567 stuff_p->inputlineno) == YES) {
1568 bytes = write_delta(mfile);
1572 buff[3] = (num >> 8) & 0xff;
1573 buff[4] = num & 0xff;
1574 bytes += write(mfile, buff, 5);
1579 else if (matches(key, leng, "port") == YES) {
1581 if (l_rangecheck(num, 0, 127, "port", stuff_p->inputfile,
1582 stuff_p->inputlineno) == YES) {
1583 bytes = write_delta(mfile);
1588 bytes += write(mfile, buff, 4);
1593 /* Note: have to check "channel" before "chanpressure" so that
1594 * channel takes precedence if the keyword is abbreviated */
1595 else if (matches(key, leng, "chanpressure") == YES) {
1597 if (l_rangecheck(num, 0, 127, "chanpressure",
1598 stuff_p->inputfile, stuff_p->inputlineno)
1600 bytes += write_delta(mfile);
1601 buff[0] = 0xd0 | Channel;
1602 buff[1] = (unsigned char) num;
1603 bytes += write(mfile, buff, 2);
1609 l_warning(stuff_p->inputfile, stuff_p->inputlineno,
1610 "unrecognized midi item\n");
1617 /* handle raw hex to output to midi file. Allow white space. Set running
1621 midihex(mfile, str, fname, lineno)
1629 short nibble = 0; /* 0 = upper nibble, 1 = lower */
1630 UINT32B bytes = 0; /* how many bytes written */
1631 unsigned char data; /* a byte of data to write */
1634 bytes += write_delta(mfile);
1635 for ( ; *str != '\0'; str++) {
1637 /* skip white space */
1638 if (isspace(*str)) {
1642 /* collect two hex digits per byte to write */
1643 if (isxdigit(*str)) {
1645 data = hexdig(*str) << 4;
1648 data |= hexdig(*str);
1649 (void) write(mfile, &data, 1);
1655 l_ufatal(fname, lineno, "illegal hex character");
1660 l_ufatal(fname, lineno, "odd number of hex digits");
1663 /* set running status to unknown and return number of bytes written */
1669 /* write a meta event of the form
1671 * Return number of bytes written.
1675 wr_meta(mfile, evtype, str)
1677 int mfile; /* midi file */
1678 int evtype; /* meta event type */
1679 char *str; /* text string */
1683 unsigned char buff[4];
1686 bytes = write_delta(mfile);
1688 buff[1] = (unsigned char) (evtype & 0xff);
1689 (void) write(mfile, buff, 2);
1691 bytes += midi_wrstring(mfile, str, NO);
1698 /* walk through main list. For each top-visible staff, check the stuff
1699 * list for any "midi all" items */
1707 struct MAINLL *mll_p;
1708 UINT32B bytes = 0; /* number of bytes written */
1709 unsigned char buff[4];
1710 int doing_repeat = NO;
1711 struct MAINLL *repeat_start_p = Mainllhc_p;
1712 struct GRPSYL *gs_p;
1715 debug(256, "all_midi");
1718 for (mll_p = Mainllhc_p; mll_p != (struct MAINLL *) 0;
1719 mll_p = mll_p->next) {
1720 switch (mll_p->str) {
1722 if ( svpath(mll_p->u.staff_p->staffno, VISIBLE)->visible
1725 /* Find the top visible voice */
1727 for (vindex = 0; vindex < MAXVOICES; vindex++) {
1728 if (vvpath(mll_p->u.staff_p->staffno,
1729 vindex+1, VISIBLE)->
1734 if (vindex >= MAXVOICES) {
1735 pfatal("top visible staff has no visible voice");
1738 prepmidi_stuff(mll_p->u.staff_p, vindex, YES);
1739 /* We have to do groups one at a time in order
1740 * to adjust for any squeezed-out spaces. */
1741 for (gs_p = mll_p->u.staff_p->groups_p[vindex];
1742 gs_p != (struct GRPSYL *) 0;
1743 gs_p = gs_p->next) {
1745 /* if we find a squeezed-out space
1746 * group, adjust to account for that */
1747 if (gs_p->grpcont == GC_SPACE &&
1750 adj4squeeze(gs_p->fulltime);
1751 bytes += do_midi_stuff(Zero,
1755 if (gs_p->basictime < -1) {
1764 bytes += do_midi_stuff(
1769 bytes += do_midi_stuff(
1776 /* do any remaining MIDI stuffs. This would
1777 * be any that occur at exactly the time
1778 * signature denominator plus one. */
1779 bytes += do_midi_stuff(Zero, mfile, YES);
1782 /* can skip any immediately following STAFFs,
1783 * because we've already found the top
1784 * visible one, which is the only one that
1785 * should have any "midi all" stuff */
1786 while (mll_p->next != (struct MAINLL *) 0 &&
1787 mll_p->next->str == S_STAFF) {
1788 mll_p = mll_p->next;
1794 asgnssv(mll_p->u.ssv_p);
1796 /* if key sig changes, handle that */
1797 if (mll_p->u.ssv_p->context == C_SCORE &&
1798 (mll_p->u.ssv_p->used[SHARPS] == YES ||
1799 mll_p->u.ssv_p->used[TRANSPOSITION] == YES ||
1800 mll_p->u.ssv_p->used[ADDTRANSPOSITION] == YES) ) {
1801 bytes += midi_keysig(mfile,
1802 eff_key(mll_p->u.ssv_p->staffno),
1803 mll_p->u.ssv_p->is_minor);
1806 /* if time signature changes, handle that */
1807 if (mll_p->u.ssv_p->used[TIME] == YES) {
1808 bytes += midi_timesig(mfile);
1814 /* rehearsal mark --> midi cue point */
1815 if (mll_p->u.bar_p->reh_string != (char *) 0) {
1816 bytes += write_delta(mfile);
1819 (void) write(mfile, buff, 2);
1821 bytes += midi_wrstring(mfile,
1822 mll_p->u.bar_p->reh_string, YES);
1825 repeats(&mll_p, &doing_repeat, &repeat_start_p);
1833 if (mll_p == (struct MAINLL *) 0) {
1834 /* shouldn't happen, but repeats() can change mll_p,
1835 * and if it became null, we'd try
1836 * to take the ->next of it, which is not good */
1845 /* go through main list and adjust for grace notes, alternation groups,
1852 struct MAINLL *mll_p; /* index through main list */
1853 int v; /* voice index */
1854 int got_data = NO; /* if got any music data yet */
1855 int did_all = NO; /* if processed "all" stuff for this meas */
1856 UINT32B begin_usec; /* usec per quarter at beginning of measure */
1859 debug(256, "midi_adjust");
1862 begin_usec = Usec_per_quarter_note;
1863 for (mll_p = Mainllhc_p; mll_p != (struct MAINLL *) 0;
1864 mll_p = mll_p->next) {
1865 if (mll_p->str == S_STAFF) {
1867 if (is_tab_staff(mll_p->u.staff_p->staffno) == YES) {
1871 /* If accidentals on one voice should apply to notes
1872 * on the other voice, fix that */
1873 other_voice_accidentals(mll_p->u.staff_p);
1875 /* need to check stufflist on top visible to
1876 * update Usec_per_quarter if necessary */
1877 if (did_all == NO && svpath(mll_p->u.staff_p->staffno,
1878 VISIBLE)->visible == YES) {
1879 begin_usec = Usec_per_quarter_note;
1880 Absolute_time = Zero;
1881 prepmidi_stuff(mll_p->u.staff_p, 0, YES);
1885 /* go through all groups, making adjustments */
1886 for (v = 0; v < MAXVOICES; v++) {
1887 Usec_per_quarter_note = begin_usec;
1888 Absolute_time = Zero;
1889 adjust_notes(mll_p->u.staff_p->groups_p[v],
1890 mll_p->u.staff_p->staffno, v, mll_p);
1894 else if (mll_p->str == S_SSV) {
1895 asgnssv(mll_p->u.ssv_p);
1896 if (got_data == NO &&
1897 mll_p->u.ssv_p->context == C_SCORE) {
1898 if (mll_p->u.ssv_p->used[TIME] == YES) {
1899 Time_specified_by_user = YES;
1901 if (mll_p->u.ssv_p->used[SHARPS] == YES) {
1902 Key_specified_by_user = YES;
1904 if (mll_p->u.ssv_p->used[DIVISION] == YES) {
1905 Division = mll_p->u.ssv_p->division;
1907 /* setting transposition implicitly sets a key */
1908 if (mll_p->u.ssv_p->used[TRANSPOSITION] == YES ||
1909 mll_p->u.ssv_p->used[ADDTRANSPOSITION] == YES) {
1910 Key_specified_by_user = YES;
1915 else if (mll_p->str == S_BAR) {
1916 /* reset for next measure */
1919 /* free up saved stuff info */
1920 free_midistuff(Midistufflist_p);
1921 Midistufflist_p = (struct MIDISTUFF *) 0;
1927 /* adjust any grace notes to get a little time. We
1928 * don't know for sure how much time they should get, and whether they should
1929 * be on the beat or before or when, so make some guesses.
1930 * Take half of the fulltime of the preceeding group and divide that time
1931 * among the number of grace notes.
1932 * Compare that value with 0.1 second, and use whichever is shorter.
1933 * Also shorten groups slightly to give a little release time between
1934 * notes (so that repeated notes don't run together so much), and
1935 * shorten groups that have staccato or wedge in their "with" list, and do
1936 * alternation groups and rolls */
1939 adjust_notes(gs_p, staffno, v, mll_p)
1941 struct GRPSYL *gs_p; /* adjust groups in this list */
1944 struct MAINLL *mll_p; /* groups are attached to main list here */
1948 struct GRPSYL *gracelist_p; /* one or more grace notes */
1949 RATIONAL gracetime; /* duration of grace notes */
1950 RATIONAL time_adj; /* adjustment for alt groups */
1951 int pairs; /* how many pair of GRPSYLS to add
1952 * for an alt pair */
1953 struct GRPSYL *add1_p, *add2_p; /* groups added for alt pairs */
1954 int alt; /* alternation number */
1955 int nn; /* number of number due to slashes */
1956 int d; /* number of dots */
1957 int dot, wedge, legato; /* YES if these set in "with" list */
1959 char *str; /* string in with list */
1960 int ch; /* music character in with list */
1961 int w; /* index through with list */
1962 struct GRPSYL *prevgs_p; /* group before grace note(s) */
1963 RATIONAL tenthsec; /* note value that is about 0.1 sec */
1964 RATIONAL release; /* how soon to release note */
1965 RATIONAL release_adjust; /* how soon to release current note,
1966 * the shorter of release and 1/4
1967 * of the group's time value */
1968 RATIONAL graceadj; /* for calculating grace durations */
1970 RATIONAL total_time; /* time so far in measure */
1971 struct MAINLL *m_p; /* for finding TIMEDSSVs, if any */
1972 struct TIMEDSSV *tssv_p; /* for mid-measure release changes */
1973 static int had_tssv = NO; /* If have any timed SSVs anywhere,
1974 * we'll always call setssvstate() to
1975 * make sure RELEASE is up to date.
1976 * Just knowing if they were in this
1977 * measure is not sufficient.
1978 * Could be done on some granularity
1979 * smaller than the whole song,
1980 * but this is simple, and probably
1985 /* Some compilers warn that gracelist_p might be used uninitialized.
1986 * Actually it won't be, but keep them quiet.
1988 gracelist_p = (struct GRPSYL *) 0;
1990 /* See if there are any timed SSVs to worry about */
1991 for (tssv_p = 0, m_p = mll_p; m_p != 0; m_p = m_p->next) {
1992 if (m_p->str == S_BAR) {
1993 tssv_p = m_p->u.bar_p->timedssv_p;
2000 if (had_tssv == YES) {
2005 for ( ; gs_p != (struct GRPSYL *) 0; gs_p = gs_p->next) {
2007 /* apply any timed SSVs */
2008 if (gs_p->prev != 0) {
2009 total_time = radd(total_time, gs_p->prev->fulltime);
2011 while (tssv_p != 0 && LE(tssv_p->time_off, total_time)) {
2012 asgnssv(&tssv_p->ssv);
2013 tssv_p = tssv_p->next;
2016 if (gs_p->grpvalue == GV_ZERO) {
2017 if (numgrace == 0) {
2018 /* save starting point of list of grace notes */
2021 /* count how many grace notes */
2026 /* if there were grace groups before this group,
2027 * adjust to give them some time. */
2029 /* find the previous group */
2030 prevgs_p = grp_before(gracelist_p, mll_p,
2033 /* If the previous group is notes,
2034 * take 1/2 of that groups time value and
2035 * apportion among the grace notes.
2036 * If rest or space, we can probably afford
2037 * to use more. Exactly how much is unclear,
2038 * so we'll use 3/4 */
2039 if (prevgs_p->grpcont == GC_NOTES) {
2041 graceadj.d = 2 * numgrace;
2045 graceadj.d = 4 * numgrace;
2048 gracetime = rmul(prevgs_p->fulltime,
2051 /* If grace notes come out to more than
2052 * about 1/10th second, use 1/10th second
2053 * instead. First figure out what sort of
2054 * fulltime value would be 0.1 second, by
2055 * taking 1 over the number of microseconds
2056 * in a whole note divided by 100000 */
2058 tenthsec.d = 4L * Usec_per_quarter_note / 100000L;
2060 if (tenthsec.d == 0) {
2061 /* we're in some outrageously fast
2062 * tempo, over 600 quarter notes
2063 * per minute, which is so fast
2064 * that even a whole note
2065 * isn't a tenth of a second.
2066 * Make sure the denominator
2067 * isn't zero, so we won't
2068 * core dump. At this absurd tempo,
2069 * we'd not going to be using this
2070 * value anyway, except to compare
2071 * against gracetime, so if it's
2072 * off some, it won't matter. */
2077 if ( LT(tenthsec, gracetime)) {
2078 gracetime = tenthsec;
2080 /* round to nearest 2048 note to try to
2081 * avoid arithmetic overflows */
2082 gracetime.n = 2048 * gracetime.n / gracetime.d;
2084 rred ( &gracetime );
2086 /* subtract time from previous group */
2087 graceadj.n = numgrace;
2089 prevgs_p->fulltime = rsub(prevgs_p->fulltime,
2090 rmul(gracetime, graceadj));
2092 /* give each grace note that much time */
2093 for ( ; numgrace > 0; numgrace--) {
2094 gracelist_p->fulltime = gracetime;
2095 gracelist_p = gracelist_p->next;
2099 fulltime = gs_p->fulltime;
2101 /* check for alternation.
2102 * For each alt, double the number
2103 * of notes and make each half as long. */
2104 if (gs_p->slash_alt < 0) {
2106 alt = -(gs_p->slash_alt);
2108 /* for long notes, adjust so we get down to
2109 * 8th notes for alternation */
2110 if (gs_p->basictime == 0) {
2113 else if (gs_p->basictime == 1) {
2116 else if (gs_p->basictime >= 4) {
2120 /* adjust time values */
2122 time_adj.d = 1 << alt;
2123 gs_p->fulltime = rmul(gs_p->fulltime, time_adj);
2124 rred ( &(gs_p->fulltime) );
2125 gs_p->next->fulltime = gs_p->fulltime;
2127 /* turn off slash_alt so we won't do it again
2128 * on the added pairs */
2129 gs_p->slash_alt = 0;
2130 gs_p->next->slash_alt = 0;
2132 /* add as many more pairs as necessary */
2133 /* If user specifies an insane
2134 * alt number, we could try to make
2135 * millions of groups. So limit to 1000.
2137 pairs = (1 << alt) - 1;
2141 for ( ; pairs > 0; pairs--) {
2142 /* create a new pair clone */
2143 add1_p = newGRPSYL(GS_GROUP);
2144 copy_attributes(add1_p, gs_p);
2145 add1_p->fulltime = gs_p->fulltime;
2146 copy_notes(add1_p, gs_p);
2147 add2_p = newGRPSYL(GS_GROUP);
2148 copy_attributes(add2_p, gs_p->next);
2149 add2_p->fulltime = gs_p->next->fulltime;
2150 copy_notes(add2_p, gs_p->next);
2152 /* link pair into list */
2153 add1_p->next = add2_p;
2154 add2_p->prev = add1_p;
2155 add2_p->next = gs_p->next->next;
2156 if (add2_p->next != (struct GRPSYL *) 0) {
2157 add2_p->next->prev = add2_p;
2159 gs_p->next->next = add1_p;
2160 add1_p->prev = gs_p->next;
2163 else if (gs_p->slash_alt > 0
2164 && gs_p->grpvalue != GV_ZERO) {
2165 /* do slashed notes */
2166 /* figure out how many actual chords are
2167 * represented by the slashed chord */
2168 switch (gs_p->basictime) {
2182 /* multiply by two for each additional slash
2183 * beyond the first. Need to keep this IF
2184 * here to avoid hitting potential optimizer
2185 * bug. See comment in grpsyl.c */
2186 if (gs_p->slash_alt > 1) {
2187 nn = nn << (gs_p->slash_alt - 1);
2191 /* shifted left into oblivion */
2192 /* parser should have caught this */
2193 pfatal("bug in slash handling");
2195 /* Add an additional 1 bit at the right for
2198 for (d = gs_p->dots; d > 0; d--) {
2199 nn |= 1 << (drmo(nn) - 1);
2202 /* adjust time of notes, by dividing the
2203 * fulltime of the group by the number of
2204 * notes. We don't look at the basictime
2205 * or dots again, so can leave them */
2206 gs_p->fulltime.d *= nn;
2207 rred ( &(gs_p->fulltime) );
2209 /* mark that we have done the slash */
2210 gs_p->slash_alt = 0;
2212 /* create as many clones of the groups as
2213 * needed. Use > 1 because we
2214 * already have the original group. */
2215 for ( ; nn > 1; nn--) {
2216 add1_p = newGRPSYL(GS_GROUP);
2217 copy_attributes(add1_p, gs_p);
2218 add1_p->fulltime = gs_p->fulltime;
2219 copy_notes(add1_p, gs_p);
2220 /* link into list */
2221 add1_p->next = gs_p->next;
2222 add1_p->prev = gs_p;
2223 gs_p->next = add1_p;
2224 if (add1_p->next != (struct GRPSYL *) 0) {
2225 add1_p->next->prev = add1_p;
2230 /* now shorten any groups with dots or wedges */
2231 dot = wedge = legato = NO;
2232 for (w = 0; w < gs_p->nwith; w++) {
2233 if (is_music_symbol(gs_p->withlist[w]) == NO) {
2236 font = gs_p->withlist[w][0];
2237 size = gs_p->withlist[w][1];
2238 str = gs_p->withlist[w] + 2;
2239 ch = next_str_char(&str, &font, &size);
2254 /* reduce to 1/3 time, add rest for other 2/3 */
2255 add_rest(gs_p, rmul(gs_p->fulltime, Two_thirds));
2256 gs_p->fulltime = rmul(gs_p->fulltime, One_third);
2258 else if (dot == YES) {
2259 if (legato == YES) {
2261 add_rest(gs_p, rmul(gs_p->fulltime,
2263 gs_p->fulltime = rmul(gs_p->fulltime,
2267 /* reduce by half */
2268 add_rest(gs_p, rmul(gs_p->fulltime,
2270 gs_p->fulltime = rmul(gs_p->fulltime,
2275 else if (gs_p->grpcont == GC_NOTES) {
2277 /* Figure out fulltime value for
2278 * milliseconds of release time */
2279 release.n = (UINT32B)
2280 vvpath(staffno, v + 1, RELEASE)->release;
2281 release.d = 4L * Usec_per_quarter_note / 1000L;
2283 if (GT(release, Zero)) {
2284 /* shorten by a little bit.
2285 * Otherwise repeated notes
2286 * run together so much they can sound
2287 * like a single note
2288 * on some instruments. */
2290 /* round off to nearest 1024 note.
2291 * Otherwise we can very quickly
2292 * get to the point that the
2293 * lowest common denominator of
2294 * accumulated time values will get
2295 * so big we overflow an UINT32B,
2296 * which can cause lots of problems.
2297 * Besides, this is going to get
2298 * rounded off to the granularity
2299 * of MIDI clock tick eventually anyway,
2300 * and will be affected by MIDI latency,
2301 * so if it is off by a few
2302 * microseconds, it is very doubtful
2303 * anyone will notice. */
2304 release.n = 1024 * release.n
2310 /* Shorten by the lesser of 1/4 of the
2311 * note time or the amount user
2313 release_adjust = rmul(gs_p->fulltime,
2315 if (LT(release, release_adjust)) {
2316 release_adjust = release;
2318 add_release(gs_p, release_adjust, mll_p);
2322 /* handle any rolls */
2324 midi_roll(gs_p, &(mll_p->u.staff_p->groups_p[v]));
2325 Absolute_time = radd(Absolute_time, fulltime);
2331 /* Usually we can just add in the release as is. But if the next group is
2332 * a grace group, it could end up being really short, because it steals
2333 * from the previous group, which would be this added release rest, which
2334 * is likely to be quite short. So peek ahead. If the next group is a grace,
2335 * only add in the release if it is at least 135 ms per following grace
2336 * group, which would allow them about 100 ms each. If it's shorter than
2337 * that, don't add any release, and just let the grace(s) steal from the
2341 add_release(gs_p, release_adjust, mll_p)
2343 struct GRPSYL *gs_p;
2344 RATIONAL release_adjust;
2345 struct MAINLL *mll_p;
2348 struct GRPSYL *nextgs_p;
2350 double rel_time; /* release adjust in milliseconds */
2352 if ((nextgs_p = nextgrpsyl(gs_p, &mll_p)) != (struct GRPSYL *) 0) {
2353 /* count how many grace notes coming up after our gs_p */
2354 for (numgrace = 0; nextgs_p->grpvalue == GV_ZERO;
2355 nextgs_p = nextgs_p->next) {
2360 /* Calculate length of proposed release,
2361 * by multiplying its time value by the number
2362 * of milliseconds in a whole note. */
2363 rel_time = RAT2FLOAT(release_adjust) *
2364 Usec_per_quarter_note * 4L / 1000L;
2366 /* now see if it's too short */
2367 if ( rel_time < 135.0 * numgrace) {
2373 /* add in a rest to accomplish the release */
2374 add_rest(gs_p, release_adjust);
2375 gs_p->fulltime = rsub(gs_p->fulltime, release_adjust);
2379 /* turn damper pedal switch on or off. Return number of bytes written */
2382 pedswitch(mfile, on)
2385 int on; /* YES if to turn damper pedal on, NO if to turn off */
2389 unsigned char buff[4];
2392 bytes = write_delta(mfile);
2393 Status = buff[0] = (unsigned char) (0xb0 | Channel);
2394 buff[1] = (unsigned char) 64;
2395 buff[2] = (on ? 127 : 0);
2396 bytes += write(mfile, buff, 3);
2401 /* do rolls. Separate into several groups with notes tied together */
2404 midi_roll(gs_p, gslist_p_p)
2406 struct GRPSYL *gs_p;
2407 struct GRPSYL **gslist_p_p; /* head of list of groups for this voice/meas */
2410 RATIONAL rolltime; /* roll time adjust per note */
2411 struct GRPSYL *g_p; /* walk through groups in roll */
2412 RATIONAL shortest; /* shortest group in roll */
2413 int nnotes; /* how many notes in roll */
2414 struct MIDIROLL *mrinfo; /* information about a roll */
2417 switch (gs_p->roll) {
2419 if (gs_p->nnotes < 2) {
2420 /* degenerate roll */
2424 rolltime = roll_time(gs_p->fulltime, gs_p->nnotes);
2425 do_mroll(gs_p, gslist_p_p, rolltime, 0);
2429 /* count how many notes total to roll, and get duration of
2430 * shortest group in the roll */
2431 nnotes = gs_p->nnotes;
2432 shortest = gs_p->fulltime;
2433 for (g_p = gs_p->gs_p; g_p != (struct GRPSYL *) 0;
2435 nnotes += g_p->nnotes;
2436 if (LT(g_p->fulltime, shortest)) {
2437 shortest = g_p->fulltime;
2439 if (g_p->roll == ENDITEM) {
2444 rolltime = roll_time(shortest, nnotes);
2446 /* do first group */
2447 if (gs_p->rolldir != DOWN) {
2448 nnotes -= gs_p->nnotes;
2449 do_mroll(gs_p, gslist_p_p, rolltime, nnotes);
2452 do_mroll(gs_p, gslist_p_p, rolltime, 0);
2453 nnotes = gs_p->nnotes;
2456 /* now go down the chord again saving information about the
2457 * roll on other groups */
2458 for (g_p = gs_p->gs_p; g_p != (struct GRPSYL *) 0;
2460 if (gs_p->rolldir != DOWN) {
2461 nnotes -= g_p->nnotes;
2462 savemidiroll(g_p, nnotes, rolltime);
2465 savemidiroll(g_p, nnotes, rolltime);
2466 nnotes += g_p->nnotes;
2468 if (g_p->roll == ENDITEM) {
2476 /* retrieve info about this roll and do it */
2477 if ((mrinfo = getmidiroll(gs_p)) == (struct MIDIROLL *) 0) {
2478 /* if staff is invisible, this is okay, otherwise
2479 * something must have gone wrong */
2480 if (svpath(gs_p->staffno, VISIBLE)->visible == YES) {
2481 pfatal("info about roll is missing");
2485 do_mroll(gs_p, gslist_p_p, mrinfo->duration,
2486 mrinfo->notesbefore);
2497 /* given a chord duration and number of notes, return how long to make
2498 * each note of roll. Use 1/20 second or whatever would add up to a total
2499 * of half the duration, whichever is shorter */
2502 roll_time(grptime, nnotes)
2504 RATIONAL grptime; /* duration of rolled chord */
2505 int nnotes; /* how many notes in the chord */
2508 RATIONAL rolltime; /* roll time adjust per note */
2509 RATIONAL maxdur; /* note equal to 0.05 second */
2512 /* if not enough notes to roll, don't do anything here */
2517 /* as first guess, apportion the extra groups into half of
2519 rolltime = rmul(grptime, One_half);
2520 rolltime.d *= (nnotes - 1);
2523 /* find 0.05 second time */
2525 maxdur.d = 4L * Usec_per_quarter_note / 50000L;
2527 /* use whichever is shorter */
2528 return( LT(maxdur, rolltime) ? maxdur : rolltime);
2532 /* create and link the extra groups to implement roll sound */
2535 do_mroll(gs_p, gslist_p_p, rolltime, notesbefore)
2537 struct GRPSYL *gs_p; /* group having roll */
2538 struct GRPSYL **gslist_p_p; /* addr of groups_p list containing gs_p */
2539 RATIONAL rolltime; /* duration per roll note */
2540 int notesbefore; /* how many notes of roll before this in
2541 * chords in other voices */
2545 struct GRPSYL **link_p_p; /* where to link added groups */
2546 struct GRPSYL *prev_p; /* previous group */
2547 RATIONAL factor; /* multiplier of duration */
2548 struct GRPSYL *newgs_p; /* added rest group */
2551 /* figure out where to link added groups */
2552 if (gs_p->prev == (struct GRPSYL *) 0) {
2553 link_p_p = gslist_p_p;
2556 link_p_p = &( gs_p->prev->next);
2558 prev_p = gs_p->prev;
2560 /* add in groups with appropriate subset of notes, tied to
2561 * the existing group */
2562 if (gs_p->rolldir != DOWN) {
2563 for (i = 1; i < gs_p->nnotes; i++) {
2564 addrollgrp(gs_p, rolltime, i, gs_p->nnotes - 1,
2569 for (i = gs_p->nnotes - 2; i >= 0; i--) {
2570 addrollgrp(gs_p, rolltime, 0, i,
2575 /* adjust group time */
2576 factor.n = gs_p->nnotes - 1 + notesbefore;
2578 gs_p->fulltime = rsub(gs_p->fulltime, rmul(rolltime, factor));
2580 /* add rest before if necessary */
2581 if (notesbefore > 0) {
2582 factor.n = notesbefore;
2583 CALLOC(GRPSYL, newgs_p, 1);
2584 newgs_p->grpcont = GC_REST;
2585 newgs_p->fulltime = rmul(rolltime, factor);
2586 /* mark as internally generated, so octave adjust works */
2587 newgs_p->inputlineno = -1;
2589 /* stitch into list */
2590 (*link_p_p)->prev = newgs_p;
2591 newgs_p->next = *link_p_p;
2592 newgs_p->prev = prev_p;
2593 *link_p_p = newgs_p;
2598 /* add group to form part of a roll */
2601 addrollgrp(gs_p, duration, start, end, link_p_p, prev_p)
2603 struct GRPSYL *gs_p;
2605 int start; /* index into notelist, where to start copying notes */
2606 int end; /* index into notelist, where to stop copying notes */
2607 struct GRPSYL **link_p_p; /* where to link into list */
2608 struct GRPSYL *prev_p; /* previous group */
2611 struct GRPSYL *newgs_p;
2615 newgs_p = newGRPSYL(GS_GROUP);
2616 newgs_p->grpcont = GC_NOTES;
2617 newgs_p->fulltime = duration;
2618 newgs_p->nnotes = end - start + 1;
2619 /* mark as internally generated, so octave adjusting will work */
2620 newgs_p->inputlineno = -1;
2622 /* copy appropriate subset of notes from original group */
2623 CALLOC(NOTE, newgs_p->notelist, newgs_p->nnotes);
2624 for (i = 0; start <= end; i++, start++) {
2625 newgs_p->notelist[i].letter = gs_p->notelist[start].letter;
2626 newgs_p->notelist[i].accidental
2627 = gs_p->notelist[start].accidental;
2628 newgs_p->notelist[i].octave = gs_p->notelist[start].octave;
2632 /* stitch into list */
2633 (*link_p_p)->prev = newgs_p;
2634 newgs_p->next = *link_p_p;
2635 newgs_p->prev = prev_p;
2636 *link_p_p = newgs_p;
2640 /* Create struct to hold info about roll that crosses groups and fill it in.
2641 * Link onto list of info of this type */
2644 savemidiroll(gs_p, notesbefore, duration)
2646 struct GRPSYL *gs_p;
2651 struct MIDIROLL *new_p;
2653 CALLOC(MIDIROLL, new_p, 1);
2655 new_p->notesbefore = (short) notesbefore;
2656 new_p->duration = duration;
2657 new_p->link_p = Midirollinfo_p;
2658 Midirollinfo_p = new_p;
2662 /* given a GRPSYL, return pointer to the MIDIROLL struct associated with it,
2663 * after detaching it from the list. Caller is responsible for freeing it.
2664 * Returns null if not on the list */
2666 static struct MIDIROLL *
2669 struct GRPSYL *gs_p;
2672 struct MIDIROLL **mr_p_p;
2673 struct MIDIROLL *the_one; /* the one matching gs_p */
2676 /* walk down list. Since there aren't likely to be all that many
2677 * multi-voice rolls per measure, we just use a linked list instead
2678 * of hashing or something. */
2679 for (mr_p_p = &Midirollinfo_p; *mr_p_p != (struct MIDIROLL *) 0;
2680 mr_p_p = &( (*mr_p_p)->link_p) ){
2682 if ( (*mr_p_p)->gs_p == gs_p) {
2683 /* found it. detach and return it */
2685 *mr_p_p = (*mr_p_p)->link_p;
2689 return (struct MIDIROLL *) 0;
2693 /* go through list of STUFFs for this measure. If there is a MIDI "tempo"
2694 * STUFF prior to the current time, update Usec_per_quarter_note */
2699 int to_end; /* if YES, go all the way to end of Midistufflist_p */
2702 struct MIDISTUFF *ms_p; /* index through list of STUFF */
2703 char *key; /* to check for "tempo" */
2704 int leng; /* length of key */
2705 char *arg; /* tempo argument */
2706 int quarter_notes_per_min; /* notes per minute */
2709 /* check stuff in this measure */
2710 for (ms_p = Midistufflist_p; ms_p != (struct MIDISTUFF *) 0;
2711 ms_p = ms_p->next) {
2712 if (GE(ms_p->time, Absolute_time) && to_end == NO) {
2713 /* beyond where we are in time so far */
2717 /* see if MIDI tempo */
2718 if (ms_p->stuff_p->stuff_type == ST_MIDI) {
2719 if (getkeyword(ms_p->stuff_p->string + 2, &key, &leng,
2721 if (matches(key, leng, "tempo") == YES) {
2722 /* is it tempo. Update */
2723 quarter_notes_per_min = atoi(arg);
2724 if (quarter_notes_per_min >= MINQNPM
2725 && quarter_notes_per_min
2727 Usec_per_quarter_note =
2729 / quarter_notes_per_min;
2738 /* recursively free MIDISTUFF list */
2741 free_midistuff(ms_p)
2743 struct MIDISTUFF *ms_p;
2746 if (ms_p == (struct MIDISTUFF *) 0) {
2750 free_midistuff(ms_p->next);
2755 /* when a group is squeezed to zero time because the chord was all spaces,
2756 * we need to adjust the time to do any pending stuffs by the amount
2757 * of time squeezed out. So go through the list of pending stuffs, and
2758 * mark them as occurring that much earlier, or immediately if the time
2759 * would end up negative. Octave marks are handled a measure at a time,
2760 * so we don't have to worry about them.
2761 * If user put a stuff in the middle of an all-space chord,
2762 * maybe they really wanted the space not squeezed, but tough.
2763 * If they really want time taken up they should use rest, not space.
2764 * It isn't worth the effort to figure out that some particular space
2765 * chord has a stuff in the middle of it, so that it should be treated
2770 adj4squeeze(timeval)
2772 RATIONAL timeval; /* adjust by this much */
2775 struct MIDISTUFF *ms_p; /* walk through list of MIDI stuff to do */
2778 for (ms_p = Midistufflist_p; ms_p != (struct MIDISTUFF *) 0;
2779 ms_p = ms_p->next) {
2781 /* adjust the time */
2782 ms_p->time = rsub(ms_p->time, timeval);
2784 if (LT(ms_p->time, Zero)) {
2785 /* Oops. User put a stuff in the middle of an
2786 * all-space group. Schedule the stuff to happen
2794 /* return YES if specified staff/voice is used somewhere in the piece */
2797 voice_used(staffno, vno)
2803 return (Voice2track_map [staffno] [vno] != 0 ? YES : NO);