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
);