chiark / gitweb /
Import upstream version 5.3.
[mup] / mup / mup / midiutil.c
CommitLineData
69695f33
MW
1
2/* Copyright (c) 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2005 by Arkkra Enterprises */
3/* All rights reserved */
4
5/* utility functions for creating MIDI output from Mup input. These functions
6 * are split out into this file to keep midi.c from being so huge */
7
8#ifdef __WATCOMC__
9#include <io.h>
10#endif
11#include "defines.h"
12#include "structs.h"
13#include "globals.h"
14
15
16static struct GRPSYL *create_prev_grp P((struct MAINLL *mll_p, int staffno,
17 int v));
18static struct GRPSYL *create_meas_space P((struct MAINLL *mll_p));
19static void fix_spacechord P((struct MAINLL *chmll_p, struct CHORD *ch_p));
20static void splitspace P((struct GRPSYL *gs_p, RATIONAL duration));
21static void splicechord P((struct GRPSYL *gs_p, struct CHORD *ch_p));
22static void guitar_grpsyl_transpose P((struct GRPSYL *gs_p));
23static RATIONAL find_acc_end_time P((RATIONAL begin_time, struct GRPSYL *gs_p,
24 int n));
25static void propogate_accidental P((struct NOTE *note_p, RATIONAL begin_time,
26 RATIONAL end_time, struct GRPSYL *gs_p));
27static void mv_skipped_midi P((struct STUFF *stuff_p, int staffno,
28 struct MAINLL *topstaff_mll_p));
29\f
30
31/* seek back to where header size is in file, and fill in the correct size,
32 * now that we know what it is. */
33
34void
35fix_track_size(mfile, track_start, track_size)
36
37int mfile; /* file descriptor of MIDI file */
38long track_start; /* offset in file where size needs to be put */
39long track_size; /* track length in bytes */
40
41{
42 unsigned char buff[4];
43
44
45 debug(512, "fix_track_size");
46
47 /* go to where track size is stored in file */
48 (void) lseek(mfile, track_start + 4, SEEK_SET);
49
50 /* convert to 4-byte number with correct byte ordering regardless
51 * of machine byte ordering */
52 buff[0] = (track_size >> 24) & 0xff;
53 buff[1] = (track_size >> 16) & 0xff;
54 buff[2] = (track_size >> 8) & 0xff;
55 buff[3] = track_size & 0xff;
56 (void) write(mfile, buff, 4);
57
58 /* go back to end of file in case there are more track to write */
59 (void) lseek(mfile, 0L, SEEK_END);
60}
61\f
62
63/* given an octave mark string, return number of octaves to tranpose (could
64 * be negative if transposing down) */
65
66int
67parse_octave(string, place, fname, lineno)
68
69char *string; /* typically "8va" */
70int place; /* PL_ABOVE or PL_BELOW */
71char *fname; /* file name for errors */
72int lineno;
73
74
75{
76 int font, size;
77 int octave_value = 0;
78 int code; /* ASCII of character in string */
79
80
81 font = string[0];
82 size = string[1];
83 string += 2;
84 code = next_str_char(&string, &font, &size);
85 if (isdigit(code)) {
86 octave_value = code - '0';
87 code = next_str_char(&string, &font, &size);
88 /* might be a second digit. If user is crazy enough to use
89 * an octave number greater than 2 digits, ignore the rest */
90 if (isdigit(code)) {
91 octave_value = (octave_value * 10) + (code - '0');
92 }
93 }
94
95 /* must be either a non-zero multiple of 8, or things like 15, 22,
96 * etc if some musical mathematician adds 7 instead of 8 */
97 if (octave_value < 8 || ((octave_value - 8) % 7 != 0 &&
98 (octave_value - 8) % 8 != 0)) {
99 l_ufatal(fname, lineno, "invalid octave mark string");
100 }
101 if (octave_value % 8 == 0) {
102 octave_value /= 8;
103 } else {
104 octave_value = 1 + (octave_value - 8) % 7;
105 }
106
107 return(place == PL_BELOW ? -octave_value : octave_value);
108}
109\f
110
111/* determine "clocks per metronome tick." It not entirely clear to me
112 * how that is supposed to work, but... if the time signature denominator is
113 * 4, we'll use 24. If 8, use 12, etc. Only go down as far as 3, since that's
114 * not divisible by 2. Really, in fast tempo triple time, the denominator
115 * isn't the beat, but this will do for now. */
116
117int
118clocks(num)
119
120int num;
121
122{
123 switch(num) {
124 case 1:
125 return(96);
126 case 2:
127 return(48);
128 case 4:
129 return(24);
130 case 8:
131 return(12);
132 case 16:
133 return(6);
134 default:
135 return(3);
136 }
137}
138\f
139
140/* given a string, if it contains a word followed by an =, followed by a word,
141 * any of which may be separated by white space, return, via pointers,
142 * a pointer to the beginning of the word, the length of the word, and a pointer
143 * to the first non-white-space character after the =, and return YES.
144 * Otherwise, return NO. A "word" is a sequence of non-white-space chars. */
145
146int
147getkeyword(string, key_p, leng_p, arg_p_p)
148
149char *string; /* check this string */
150char **key_p; /* return pointer to keyword via this */
151int *leng_p; /* return length of keyword via this */
152char **arg_p_p; /* return pointer to argument after = via this */
153
154{
155 char *tok;
156
157
158 /* skip leading white space */
159 for (*key_p = string; **key_p == ' ' || **key_p == '\t'; (*key_p)++) {
160 ;
161 }
162
163 /* go till hit white space or equals sign */
164 for (tok = *key_p; *tok != '\0'; tok++) {
165 if (*tok == ' ' || *tok == '\t' || *tok == '=') {
166 break;
167 }
168 }
169
170 /* fill in length of key */
171 *leng_p = tok - *key_p;
172
173 if (*leng_p == 0) {
174 return(NO);
175 }
176
177 /* find first non-white beyond the = */
178 for ( ; *tok != '\0'; tok++) {
179 if (*tok == '=') {
180 for (tok++; *tok != '\0'; tok++) {
181 if (*tok != ' ' && *tok != '\t') {
182 *arg_p_p = tok;
183 return(YES);
184 }
185 }
186 }
187 }
188 return(NO);
189}
190\f
191
192/* given a user-specified key, see if it matches the given command name. Return
193 * YES if it does, NO if it doesn't. User only has to specify the first 3 or
194 * more characters of the command, because that's enough to make it unique,
195 * and saves them from typing longer names. */
196
197int
198matches(key, leng, cmd)
199
200char *key; /* user specified key to be checked */
201int leng; /* length of key */
202char *cmd; /* check if key matches this command */
203
204{
205 if (leng < 3) {
206 return(NO);
207 }
208 return(strncmp(key, cmd, leng) == 0 ? YES : NO);
209}
210\f
211
212/* given an ASCII hex digit, return its value 0-15 */
213
214int
215hexdig(ch)
216
217int ch;
218
219{
220 if (ch >= '0' && ch <= '9') {
221 return(ch - '0');
222 }
223 else if (ch >= 'a' && ch <= 'f') {
224 return(ch - 'a' + 10);
225 }
226 else if (ch >= 'A' && ch <= 'F') {
227 return(ch - 'A' + 10);
228 }
229 pfatal("bad hex digit");
230 /*NOTREACHED*/
231 return(0);
232}
233\f
234
235/* given a string, output it to midi file, prefixed by its length. */
236/* return number of bytes written */
237
238UINT32B
239midi_wrstring(mfile, str, internalform)
240
241int mfile; /* MIDI file */
242char *str; /* string to write to file */
243int internalform; /* YES if str is in Mup format, NO if just ASCII,
244 * C-style null-terminated string to be copied */
245
246{
247 char *buff; /* for all-ASCII version of str */
248 UINT32B bytes; /* number of bytes in length value */
249 int length; /* of string */
250
251
252 /* get plain ascii version of string. Write out length of
253 * string, then plain string itself */
254 if (internalform == YES) {
255 buff = ascii_str(str, NO, YES, TM_NONE);
256 length = strlen(buff);
257 bytes = wr_varlength(mfile, (UINT32B) length);
258 bytes += write(mfile, buff, (unsigned) length);
259 }
260 else {
261 length = strlen(str);
262 bytes = wr_varlength(mfile, (UINT32B) length);
263 bytes += write(mfile, str, (unsigned) length);
264 }
265
266 /* return number of bytes written */
267 return(bytes);
268}
269\f
270
271/* given a number, write to MIDI file in MIDI variable length format.
272 * Return number of bytes written. */
273
274UINT32B
275wr_varlength(mfile, num)
276
277UINT32B num;
278
279{
280 unsigned char buff[4];
281 int i;
282 int shift;
283
284
285 /* Because only 7 bits of each MIDI byte can be used,
286 * there is only support for numbers up to 28 bits long. */
287 if ((num & 0xf0000000) != 0) {
288 ufatal("midi value too large");
289 }
290
291 /* convert value to the MIDI variable-length number, which
292 * uses the lower 7 bits of each byte as parts of the number, and
293 * the high order bit as a flag to say which is the last byte of
294 * the (potentially) multi-byte number */
295 for (i = 0, shift = 21; shift >= 7; shift -= 7) {
296 if ( (num >> shift) || (i > 0)) {
297 buff[i++] = 0x80 | ((num >> shift) & 0x7f);
298 }
299 }
300 buff[i] = num & 0x7f;
301 (void) write(mfile, buff, (unsigned) (i + 1));
302 return (UINT32B) (i+1);
303}
304\f
305
306/* do key signature. Return number of bytes written */
307
308UINT32B
309midi_keysig(mfile, sharps, is_minor)
310
311int mfile;
312int sharps;
313int is_minor; /* YES if minor */
314
315{
316 UINT32B bytes;
317 unsigned char buff[8];
318
319
320 bytes = write_delta(mfile);
321 buff[0] = 0xff;
322 buff[1] = 0x59;
323 buff[2] = 0x02;
324 buff[3] = (char) sharps;
325 buff[4] = (is_minor == YES ? 1 : 0);
326 (void) write(mfile, buff, 5);
327
328 return(bytes + 5);
329}
330\f
331
332/* write out the timesig in Score SSV. Return number of bytes written */
333
334UINT32B
335midi_timesig(mfile)
336
337int mfile;
338{
339 UINT32B bytes;
340 unsigned char buff[8];
341
342
343 /* With additive time signatures, it is possible to get an effective
344 * time signature that won't fit in 7 bits. In that case, we don't
345 * do any time signature, since we can't represent it. */
346 if (Score.timenum > 127) {
347 return(0);
348 }
349
350 bytes = write_delta(mfile);
351 buff[0] = 0xff;
352 buff[1] = 0x58;
353 buff[2] = 0x04;
354 buff[3] = (char) Score.timenum;
355 buff[4] = (unsigned char) drmo(Score.timeden);
356 buff[5] = clocks(Score.timeden);
357 buff[6] = 0x8;
358 bytes += write(mfile, buff, 7);
359 return(bytes);
360}
361\f
362
363/* find group before given group. If none before it in current measure,
364 * back up in main list to find corresponding group list, and use final group
365 * in that list. If no group exists, create one. */
366
367struct GRPSYL *
368grp_before(gs_p, mll_p, staffno, v)
369
370struct GRPSYL *gs_p; /* find group before this one */
371struct MAINLL *mll_p; /* the list containing gs_p is attached to main list here */
372int staffno;
373int v; /* voice */
374
375{
376 int found_bar = NO;
377
378
379 if (gs_p->prev != (struct GRPSYL *) 0) {
380 /* oh good. There's another group before this one in the
381 * current measure, so just return it */
382 return(gs_p->prev);
383 }
384
385 /* have to go back to previous measure, if any. Start searching
386 * backwards in main list. */
387 for (mll_p = mll_p->prev; mll_p != (struct MAINLL *) 0;
388 mll_p = mll_p->prev) {
389 switch (mll_p->str) {
390 case S_STAFF:
391 if (found_bar == NO) {
392 /* still in current measure */
393 break;
394 }
395
396 if (mll_p->u.staff_p->staffno == staffno) {
397 /* we found the previous measure */
398 if (mll_p->u.staff_p->groups_p[v]
399 != (struct GRPSYL *) 0) {
400 /* find and return last group */
401 for (gs_p=mll_p->u.staff_p->groups_p[v];
402 gs_p->next !=
403 (struct GRPSYL *) 0;
404 gs_p = gs_p->next) {
405 ;
406 }
407 return(gs_p);
408 }
409 else {
410 /* this voice wasn't present before.
411 * Will have to create a measure */
412 return(create_meas_space(mll_p));
413 }
414 }
415 else if (mll_p->u.staff_p->staffno < staffno) {
416 /* corresponding staff does not exist in this
417 * measure. The only time this should happen is
418 * if user changed the number of staffs.
419 * So create staff */
420 return(create_prev_grp(mll_p, staffno, v));
421 }
422 break;
423
424 case S_BAR:
425 found_bar = YES;
426 break;
427
428 default:
429 /* ignore other things */
430 break;
431 }
432 }
433
434 /* Fell off the top of the list. This used to be possible,
435 * and we called create_prev_grp() to create a measure.
436 * But the measure really needs to be created much earlier--
437 * before makechords() is run--in order for squeezing to work right.
438 * So that's what we do now. So we should never get here. */
439 pfatal("fell off top of list in grp_before()");
440 /* NOTREACHED */
441 return(create_prev_grp(mll_p, staffno, v));
442}
443\f
444
445/* create a new STAFF struct and insert in main list, with grpcont of
446 * space and fulltime of the measure. Return pointer to the GRPSYL of
447 * appropriate voice of the STAFF that was created. */
448
449static struct GRPSYL *
450create_prev_grp(mll_p, staffno, v)
451
452struct MAINLL *mll_p; /* insert here */
453int staffno;
454int v;
455
456{
457 struct MAINLL *new_p; /* new STAFF */
458 int i;
459
460
461 new_p = newMAINLLstruct(S_STAFF, -1);
462 new_p->u.staff_p->staffno = (short) staffno;
463 insertMAINLL(new_p, mll_p);
464 for (i = 0; i < MAXVOICES; i++) {
465 new_p->u.staff_p->groups_p[i]
466 = create_meas_space(mll_p);
467 }
468
469 /* if added to beginning of list, have to add bar as well */
470 if (mll_p == (struct MAINLL *) 0) {
471 struct MAINLL *mbar_p;
472
473 mbar_p = newMAINLLstruct(S_BAR, -1);
474 insertMAINLL(mbar_p, new_p);
475 }
476
477 return(new_p->u.staff_p->groups_p[v]);
478}
479\f
480
481/* create a measure space as long as that of the reference measure (or of 4/4
482 * if no reference) and return it */
483
484static struct GRPSYL *
485create_meas_space(mll_p)
486
487struct MAINLL *mll_p; /* use this for reference to get measure length */
488
489{
490 struct GRPSYL *gs_p; /* new grpsyl */
491 struct GRPSYL *egs_p; /* existing grpsyl */
492
493
494 gs_p = newGRPSYL(GS_GROUP);
495 gs_p->grpcont = GC_SPACE;
496
497 /* figure out how much full time to give the group. If mll_p is not
498 * null, we are adding a staff to an existing measure, so use
499 * length of its first voice. Count up the length of existing measure */
500 gs_p->fulltime = Zero;
501 if (mll_p != (struct MAINLL *) 0 && mll_p->str == S_STAFF) {
502 for (egs_p = mll_p->u.staff_p->groups_p[0];
503 egs_p != (struct GRPSYL *) 0;
504 egs_p = egs_p->next) {
505
506 gs_p->fulltime = radd(gs_p->fulltime, egs_p->fulltime);
507 }
508 }
509 else {
510 /* at beginning of list, use default of 1/1 (the reduced
511 * form of 4/4) */
512 gs_p->fulltime.n = gs_p->fulltime.d = 1;
513 }
514
515 return(gs_p);
516}
517\f
518
519/* add a rest of the specified fulltime duration after the specified group.
520 * Since this is just for midi purposes, don't worry about filling in all
521 * the fields. */
522
523void
524add_rest(gs_p, fulltime)
525
526struct GRPSYL *gs_p; /* add rest after this group */
527RATIONAL fulltime; /* make it this long */
528
529{
530 struct GRPSYL *newgs_p;
531
532
533 if (gs_p == (struct GRPSYL *) 0) {
534 pfatal("null group passed to add_rest");
535 }
536
537 newgs_p = newGRPSYL(GS_GROUP);
538 newgs_p->grpcont = GC_REST;
539 rred (&fulltime);
540 newgs_p->fulltime = fulltime;
541 newgs_p->next = gs_p->next;
542 newgs_p->prev = gs_p;
543 gs_p->next = newgs_p;
544 if (newgs_p->next != (struct GRPSYL *) 0) {
545 newgs_p->next->prev = newgs_p;
546 }
547}
548\f
549
550/* when all voices have space, that should be squeezed to zero time.
551 * Go through main list. For each CHHEAD found,
552 * go down the list of chords. For each chord, see if
553 * if it is an all-space chord. If so, call fix_spacechord() to
554 * handle it.
555 */
556
557void
558midi_squeeze()
559
560{
561 struct MAINLL *mll_p; /* walk through main list */
562 struct CHORD *ch_p; /* walk through list of chords */
563
564
565 debug(256, "midi_squeeze");
566
567 initstructs();
568 for (mll_p = Mainllhc_p; mll_p != (struct MAINLL *) 0;
569 mll_p = mll_p->next) {
570
571 /* skip everything except CHHEADs and SSV updates */
572 if (mll_p->str != S_CHHEAD) {
573 if (mll_p->str == S_SSV) {
574 asgnssv(mll_p->u.ssv_p);
575 }
576 continue;
577 }
578
579 /* do each chord */
580 for (ch_p = mll_p->u.chhead_p->ch_p;
581 ch_p != (struct CHORD *) 0;
582 ch_p = ch_p->ch_p) {
583
584 if (ch_p->width == 0.0) {
585 /* found one to squeeze, do it */
586 fix_spacechord(mll_p, ch_p);
587 }
588 }
589 }
590}
591\f
592
593/* given an all-space chord to crunch, split up any groups that
594 * spill into this chord or extend beyond it. Then set the grpvalue of each
595 * group in the chord to GV_ZERO.
596 */
597
598static void
599fix_spacechord(chmll_p, ch_p)
600
601struct MAINLL *chmll_p; /* chord is hanging off this CHHEAD */
602struct CHORD *ch_p; /* zero-width chord */
603
604{
605 struct MAINLL *mll_p; /* walk through STAFFs in main list */
606 struct GRPSYL *gs_p; /* walk through groups in chord */
607 struct GRPSYL *group_p; /* head of list of grpsyls in measure */
608 RATIONAL minspacetime; /* time of shortest space in chord */
609 RATIONAL chordstart; /* where in measure chord begins */
610 RATIONAL chordend; /* where the space ends */
611 RATIONAL new_chordend; /* tentative new value for chordend */
612 RATIONAL grpstart; /* where in measure grpsyl begins */
613 int v; /* voice index */
614
615
616 /* first find the smallest duration in the chord. Can't use
617 * ch_p->duration here because grace notes have been adjusted
618 * by now to take some time */
619 minspacetime = ch_p->gs_p->fulltime;
620 for (gs_p = ch_p->gs_p->gs_p; gs_p != (struct GRPSYL *) 0;
621 gs_p = gs_p->gs_p) {
622
623 /* skip lyrics */
624 if (gs_p->grpsyl == GS_SYLLABLE) {
625 continue;
626 }
627
628 /* skip things on tab staff--we use the associated tabnotes
629 * staff instead */
630 if (is_tab_staff(gs_p->staffno) == YES) {
631 continue;
632 }
633
634 /* double check */
635 if (gs_p->grpcont != GC_SPACE) {
636 pfatal("non-space in zero-width chord");
637 }
638
639 /* find minimum time value of space */
640 if (LT(gs_p->fulltime, minspacetime)) {
641 minspacetime = gs_p->fulltime;
642 }
643 }
644
645 /* find the start of the chord. Can't use ch_p->startime because
646 * we may have squeezed out time earlier in the measure and need
647 * to compensate for that. So have to count up the time before
648 * the group at the top of the chord. */
649 for (chordstart = Zero, gs_p = ch_p->gs_p->prev;
650 gs_p != (struct GRPSYL *) 0;
651 gs_p = gs_p->prev) {
652 chordstart = radd(chordstart, gs_p->fulltime);
653 }
654
655 /* if spaces are overlapped in strange ways between different
656 * voices, the minspacetime we found above may actually be too long.
657 * If the time between this chord and the next is less than the
658 * minspacetime found so far, make minspacetime the time till the
659 * next chord */
660 if (ch_p->ch_p != (struct CHORD *) 0) {
661 if (LT(rsub(ch_p->ch_p->starttime, chordstart), minspacetime)) {
662 minspacetime = rsub(ch_p->ch_p->starttime, chordstart);
663 }
664 }
665
666 /* That still isn't completely adequate to find where the space actually
667 * ends, because if there were lots of grace notes moved back into a
668 * space, and a very short space in another voice, they could overlap.
669 * So go through the list of voices, seeing where the real end is.
670 * This code is unfortunately very similar to the code below it,
671 * yet different enough to make it hard to make it
672 * into a common function. */
673 chordend = radd(chordstart, minspacetime);
674 for (mll_p = chmll_p->next; mll_p != (struct MAINLL *) 0;
675 mll_p = mll_p->next) {
676
677 /* CHHEAD is followed immediately by STAFFS, so when we
678 * hit something other than STAFF, we are done */
679 if (mll_p->str != S_STAFF) {
680 break;
681 }
682
683 /* do each voice */
684 for (v = 0; v < MAXVOICES; v++ ) {
685 /* Check if we have a special case where the actual
686 * space is shorter than we thought. We unfortunately
687 * cannot use hasspace() here, because it ignores grace
688 * notes, and by now, grace notes have some time.
689 * Find the chord that begins the space in question. */
690 grpstart = Zero;
691
692 if ((gs_p = mll_p->u.staff_p->groups_p[v])
693 == (struct GRPSYL *) 0) {
694 /* no voice here, so that's all space.
695 * That's good: we're done with this voice */
696 continue;
697 }
698
699 /* grace notes at the beginning of the measure
700 * have effectively been moved timewise
701 * into previous measure, so discount them. */
702 for ( ; gs_p->grpvalue == GV_ZERO
703 && gs_p->grpcont == GC_NOTES;
704 gs_p = gs_p->next) {
705 ;
706 }
707
708 for ( ; gs_p != (struct GRPSYL *) 0;
709 gs_p = gs_p->next) {
710
711 /* see if this group start corresponds
712 * with start of chord, or spills into
713 * the chord or is the last chord. If
714 * so, that's the one we want. */
715 if (EQ(grpstart, chordstart) ||
716 GT(radd(grpstart,
717 gs_p->fulltime),
718 chordstart) ||
719 gs_p->next ==
720 (struct GRPSYL *) 0) {
721 /* found appropriate group */
722 break;
723 }
724 else {
725 /* accummulate time so far */
726 grpstart = radd(grpstart, gs_p->fulltime);
727 }
728 }
729
730 if (gs_p == (struct GRPSYL *) 0) {
731 pfatal("failed to find space group");
732 }
733
734 if (gs_p->grpcont != GC_SPACE) {
735 /* things overlapped so much after the
736 * grace note adjustments and such
737 * that this isn't really a
738 * crunch-able chord after all. */
739 return;
740 }
741
742 /* need to adjust amount of space we
743 * can really crunch. Find where this chord
744 * ends, and add in the time of any immediately
745 * following space groups. */
746 new_chordend = radd(grpstart, gs_p->fulltime);
747 for (gs_p = gs_p->next; gs_p != (struct GRPSYL *) 0;
748 gs_p = gs_p->next) {
749
750 if (gs_p->grpcont == GC_SPACE) {
751 new_chordend = radd(new_chordend,
752 gs_p->fulltime);
753 }
754 else {
755 break;
756 }
757 }
758
759 /* if the newly calculated end is sooner than
760 * what we had before, then adjust accordingly. */
761 if (LT(new_chordend, chordend)) {
762 chordend = new_chordend;
763 }
764 }
765 }
766
767 /* recalculate the minspace time after any adjustment */
768 minspacetime = rsub(chordend, chordstart);
769
770
771 /* go down each voice of each staff.
772 * For each, find the space group associated with the chord.
773 * If it has the same starttime as the chord and has minspacetime
774 * duration, it's easy: we just mark it GV_ZERO. Otherwise, if
775 * it starts earlier, we have to split off a group in the front
776 * first, and if it lasts longer than the end of the chord, we
777 * have to split off a group at the end first.
778 */
779 for (mll_p = chmll_p->next; mll_p != (struct MAINLL *) 0;
780 mll_p = mll_p->next) {
781 /* CHHEAD is followed immediately by STAFFS, so when we
782 * hit something other than STAFF, we are done */
783 if (mll_p->str != S_STAFF) {
784 break;
785 }
786
787 /* do each voice */
788 for (v = 0; v < MAXVOICES; v++ ) {
789
790 /* get shorter name for list of grpsyls */
791 group_p = mll_p->u.staff_p->groups_p[v];
792
793 if (group_p == (struct GRPSYL *) 0) {
794 continue;
795 }
796
797 /* go through groups, add up time till we find the
798 * group we're looking for */
799 grpstart = Zero;
800
801 /* grace notes at the beginning of the measure
802 * have effectively been moved timewise
803 * into previous measure, so discount them. */
804 for (gs_p = group_p; gs_p->grpvalue == GV_ZERO
805 && gs_p->grpcont == GC_NOTES;
806 gs_p = gs_p->next) {
807 ;
808 }
809
810 for ( ; gs_p != (struct GRPSYL *) 0;
811 gs_p = gs_p->next) {
812
813 /* see if this group start corresponds with
814 * start of chord */
815 if (EQ(grpstart, chordstart)) {
816 /* found appropriate group */
817 break;
818 }
819
820 else if (GT(radd(grpstart,gs_p->fulltime),
821 chordstart)) {
822 /* This group spills into space
823 * to be crunched.
824 * Split off beginning of group. */
825 splitspace(gs_p,
826 rsub(chordstart, grpstart));
827
828 /* point to added group */
829 gs_p = gs_p->next;
830
831 /* splice added group into chord */
832 splicechord(gs_p, ch_p);
833
834 /* found appropriate group */
835 break;
836 }
837 else {
838 /* haven't gotten to the group yet.
839 * Add on the time taken by this
840 * group in preparation for next
841 * trip around the loop */
842 grpstart = radd(grpstart, gs_p->fulltime);
843 /* if last group in measure, this has
844 * to be the appropriate one */
845 if (gs_p->next == (struct GRPSYL *) 0) {
846 break;
847 }
848 }
849 }
850
851 if (gs_p == (struct GRPSYL *) 0) {
852 pfatal("failed to find space group");
853 }
854
855 /* if group extended beyond end of
856 * chord, split the group and splice added group
857 * into chord */
858 if (GT(gs_p->fulltime, minspacetime)) {
859 splitspace(gs_p, minspacetime);
860 splicechord(gs_p->next, ch_p->ch_p);
861 }
862
863 /* mark as taking no time */
864 gs_p->grpvalue = GV_ZERO;
865 }
866 }
867}
868\f
869
870/* split a space grpsyl into two. The original group becomes the first
871 * group, having the specified duration. A new group is added after it,
872 * having the remainder of the time taken by the original group. */
873
874static void
875splitspace(gs_p, duration)
876
877struct GRPSYL *gs_p; /* split this group */
878RATIONAL duration; /* make the first group of split this long */
879
880{
881 struct GRPSYL *newgs_p; /* added group */
882
883
884 /* bug insurance */
885 if (gs_p == (struct GRPSYL *) 0 ||
886 (gs_p->grpcont != GC_SPACE &&
887 svpath(gs_p->staffno, VISIBLE)->visible == YES) ) {
888 pfatal("bad group passed to splitspace");
889 }
890
891 /* split into 2 groups, one taking duration, and the
892 * other taking the remainder */
893 newgs_p = newGRPSYL(GS_GROUP);
894 copy_attributes(newgs_p, gs_p);
895 newgs_p->grpcont = GC_SPACE;
896 newgs_p->fulltime = rsub(gs_p->fulltime, duration);
897 gs_p->fulltime = duration;
898
899 /* link new one into list */
900 newgs_p->next = gs_p->next;
901 newgs_p->prev = gs_p;
902 gs_p->next = newgs_p;
903 if (newgs_p->next != (struct GRPSYL *) 0) {
904 newgs_p->next->prev = newgs_p;
905 }
906}
907\f
908
909/* splice a grpsyl into a chord */
910
911static void
912splicechord(gs_p, ch_p)
913
914struct GRPSYL *gs_p; /* splice in this group */
915struct CHORD *ch_p; /* splice into this chord */
916
917{
918 struct GRPSYL *nxtgs_p; /* next group in chord list */
919 struct GRPSYL **ins_p_p; /* where to insert new grpsyl */
920
921
922 if (ch_p == (struct CHORD *) 0) {
923 /* this could happen if user gave measure of space, and
924 * then following measure started with a grace note. The
925 * grace note got moved into the space, but there was no
926 * chhead created for it. It should be safe to just
927 * not link it into a chhead, so return */
928 return;
929 }
930
931 if (gs_p == (struct GRPSYL *) 0) {
932 pfatal("null pointer in splicechord");
933 }
934
935 /* Figure out where to insert. */
936 for (ins_p_p = &(ch_p->gs_p); (*ins_p_p) != (struct GRPSYL *) 0;
937 ins_p_p = &((*ins_p_p)->gs_p)) {
938
939 /* gets inserted here if next group is for a higher staffno or
940 * for a higher voice number of the same staffno */
941 nxtgs_p = *ins_p_p;
942 if (nxtgs_p == (struct GRPSYL *) 0) {
943 /* goes at end of list */
944 break;
945 }
946 if (nxtgs_p->staffno > gs_p->staffno ||
947 (nxtgs_p->staffno == gs_p->staffno &&
948 nxtgs_p->vno > gs_p->vno)) {
949 break;
950 }
951 }
952
953 if (ins_p_p == (struct GRPSYL **) 0) {
954 pfatal("couldn't find where to insert new grpsyl into chord");
955 }
956
957 /* insert it */
958 gs_p->gs_p = *ins_p_p;
959 *ins_p_p = gs_p;
960}
961\f
962
963/* if user specifies the default guitar tab staff, then we want to transpose
964 * everything down an octave, because a standard guitar sounds an octave
965 * lower than it is written. */
966
967void
968guitar_transpose()
969
970{
971 struct MAINLL *mll_p;
972
973
974 /* go through the main list looking for things to transpose */
975 initstructs();
976 for (mll_p = Mainllhc_p; mll_p != (struct MAINLL *) 0; mll_p = mll_p->next) {
977 if (mll_p->str == S_STAFF) {
978 /* if there is a staff below this and that staff is a
979 * guitar tab staff, then we need to transpose.
980 * Index into Staff by this staff's number, because
981 * staff numbers start at 1, but Staff index starts at 0
982 */
983 if (mll_p->u.staff_p->staffno < Score.staffs &&
984 Staff[mll_p->u.staff_p->staffno]
985 .strinfo == Guitar) {
986 guitar_grpsyl_transpose(mll_p->u.staff_p->groups_p[0]);
987 }
988 }
989 else if (mll_p->str == S_SSV) {
990 asgnssv(mll_p->u.ssv_p);
991 }
992 }
993}
994\f
995
996/* given a group, transpose everything down by an octave */
997
998static void
999guitar_grpsyl_transpose(gs_p)
1000
1001struct GRPSYL *gs_p;
1002
1003{
1004 register int n;
1005
1006 for( ; gs_p != (struct GRPSYL *) 0; gs_p = gs_p->next) {
1007 for (n = 0; n < gs_p->nnotes; n++) {
1008 if (gs_p->notelist[n].octave > 0) {
1009 (gs_p->notelist[n].octave)--;
1010 }
1011 else {
1012 pfatal("guitar transposition results in note below octave 0");
1013 }
1014 }
1015 }
1016}
1017\f
1018
1019/* If there is an accidental on a note on one voice, it should really apply
1020 * the other voice on that same staff too. So propogate these accidentals
1021 * to the other voice if necessary.
1022 */
1023
1024void
1025other_voice_accidentals(staff_p)
1026
1027struct STAFF *staff_p;
1028
1029{
1030 struct GRPSYL *gs_p;
1031 int v; /* voice */
1032 int n; /* notelist index */
1033 RATIONAL begin_time, end_time;
1034
1035 /* if there is only one voice on the staff, or if either
1036 * voice is a measure space or rest or multirest, nothing to do. Since
1037 * we're doing MIDI, we know a "measure" GRPSYL
1038 * will be rest or space, not mrpt, so can just check that. */
1039 if ( (staff_p->groups_p[0]->is_meas == YES) ||
1040 (staff_p->groups_p[1] == (struct GRPSYL *) 0) ||
1041 (staff_p->groups_p[1]->is_meas == YES) ) {
1042 return;
1043 }
1044
1045 /* do each voice */
1046 for (v = 0; v < MAXVOICES; v++) {
1047
1048 /* do each note of each chord */
1049 begin_time = Zero;
1050 for (gs_p = staff_p->groups_p[v]; gs_p != (struct GRPSYL *) 0;
1051 gs_p = gs_p->next) {
1052
1053 for (n = 0; n < gs_p->nnotes; n++) {
1054
1055 /* if this note doesn't have an accidental
1056 * nothing more to do on it */
1057 if (gs_p->notelist[n].accidental == '\0') {
1058 continue;
1059 }
1060
1061 /* This note does have an accidental.
1062 * Go forward and see how long it lasts.
1063 * It will last until there is another
1064 * accidental on the same note letter/octave
1065 * or until end of measure.
1066 */
1067 end_time = find_acc_end_time(begin_time, gs_p, n);
1068
1069 /* now check the other voice.
1070 * If the same letter/octave note appears
1071 * on that voice on or after the begin time but
1072 * before the end time, and that note
1073 * does not already have an accidental,
1074 * give it the same accidental as
1075 * was found on the other voice.
1076 */
1077 propogate_accidental( &(gs_p->notelist[n]),
1078 begin_time, end_time,
1079 staff_p->groups_p[v == 0 ? 1 : 0]);
1080 }
1081
1082 /* accumulate time so far in measure */
1083 begin_time = radd(begin_time, gs_p->fulltime);
1084 }
1085 }
1086}
1087
1088/* Given an GRPSYL and a note n in its notelist, and a begin_time, return
1089 * the end_time which is either the end of the measure or the next instance
1090 * of the given note which has an accidental on it. */
1091
1092static RATIONAL
1093find_acc_end_time(begin_time, gs_p, n)
1094
1095RATIONAL begin_time;
1096struct GRPSYL *gs_p;
1097int n;
1098
1099{
1100 RATIONAL end_time;
1101 struct GRPSYL *end_gs_p;
1102 int n2;
1103
1104
1105 end_time = begin_time;
1106 end_gs_p = gs_p;
1107 for ( ; ; ) {
1108 /* Add up time that accidental lasts */
1109 end_time = radd(end_time, end_gs_p->fulltime);
1110
1111 if ((end_gs_p = end_gs_p->next) == (struct GRPSYL *) 0) {
1112 /* Hit end of measure */
1113 return(end_time);
1114 }
1115
1116 /* See if this group has the same note as had the accidental,
1117 * and if so, whether it has a new accidental. */
1118 for (n2 = 0; n2 < end_gs_p->nnotes; n2++) {
1119 if ((gs_p->notelist[n].letter
1120 == end_gs_p->notelist[n2].letter) &&
1121 (gs_p->notelist[n].octave
1122 == end_gs_p->notelist[n2].octave)) {
1123
1124 /* does have the same note. check accidental */
1125 if (end_gs_p->notelist[n2].accidental != '\0') {
1126 /* a new accidental, so this cancels
1127 * the one we had */
1128 return(end_time);
1129 }
1130 break;
1131 }
1132 }
1133 }
1134}
1135\f
1136
1137/* Check the groups in list pointed to by gs_p.
1138 * If the letter/octave of the given note_p appears on or after the begin time
1139 * but before the end time, and that note does not already have an accidental,
1140 * give it the same accidental as was found on note_p. */
1141
1142static void
1143propogate_accidental(note_p, begin_time, end_time, gs_p)
1144
1145struct NOTE *note_p; /* look for note matching this one */
1146RATIONAL begin_time; /* look between the begin_time and end_time */
1147RATIONAL end_time;
1148struct GRPSYL *gs_p; /* look in this list and adjust if needed */
1149
1150{
1151 RATIONAL accumulated_time;
1152 int n;
1153
1154
1155 for (accumulated_time = Zero;
1156 gs_p != (struct GRPSYL *) 0;
1157 accumulated_time = radd(accumulated_time,
1158 gs_p->fulltime), gs_p = gs_p->next) {
1159
1160 if (LT(accumulated_time, begin_time)) {
1161 /* haven't gotten to begin yet */
1162 continue;
1163 }
1164
1165 if (GE(accumulated_time, end_time)) {
1166 /* reached end time */
1167 return;
1168 }
1169
1170 /* See if this group contains the note of interest */
1171 for (n = 0; n < gs_p->nnotes; n++) {
1172 if ( (gs_p->notelist[n].letter == note_p->letter) &&
1173 (gs_p->notelist[n].octave == note_p->octave) ) {
1174 /* if note already has an accidental,
1175 * the one from the other voice doesn't
1176 * count. Otherwise propogate the
1177 * accidental from the other voice */
1178 if (gs_p->notelist[n].accidental == '\0') {
1179 gs_p->notelist[n].accidental
1180 = note_p->accidental;
1181 }
1182
1183 /* Found the note and fixed it if needed,
1184 * so our job here is done */
1185 return;
1186 }
1187 }
1188 }
1189}
1190\f
1191
1192/* If doing MIDI with the -x option, we move all the midi STUFFs in the
1193 * skipped leading measures to the "extra" empty measure that exists for MIDI.
1194 * This ensure that any MIDI parameters, instruments, etc are correct
1195 * for the place in the song where we are actually starting.
1196 */
1197
1198void
1199mv_midi_items(mll_p, topstaff_mll_p)
1200
1201struct MAINLL *mll_p; /* points to a STAFF that may have MIDI items to move */
1202struct MAINLL *topstaff_mll_p; /* points to STAFF where "all" MIDI items will go */
1203
1204{
1205 struct STUFF *stuff_p; /* stuff currently being processed */
1206 struct STUFF *next; /* we may move the current STUFF to another
1207 * list, so need to save its "next" */
1208 char *key; /* midi directive keyword */
1209 int leng; /* length of key */
1210 char *arg; /* arg after the = */
1211 int staffno;
1212
1213
1214 staffno = mll_p->u.staff_p->staffno;
1215 for (stuff_p = mll_p->u.staff_p->stuff_p; stuff_p != 0; stuff_p = next) {
1216 /* keep track of next, in case we delete the current */
1217 next = stuff_p->next;
1218
1219 if (next == stuff_p) {
1220 pfatal("loop detected in MIDI list");
1221 }
1222
1223 if (stuff_p->stuff_type == ST_MIDI) {
1224 if (getkeyword(stuff_p->string+2, &key, &leng, &arg)
1225 == NO) {
1226 /* invalid, so ignore it. */
1227 continue;
1228 }
1229
1230 /* Some MIDI things, like cue point should just be
1231 * ignored if we are skipping over the music,
1232 * so just check for and move things we care about.
1233 */
1234 if (matches(key, leng, "program") == YES ||
1235 matches(key, leng, "tempo") == YES ||
1236 matches(key, leng, "onvelocity") == YES ||
1237 matches(key, leng, "channel") == YES ||
1238 matches(key, leng, "parameter") == YES ||
1239 matches(key, leng, "offvelocity") == YES ||
1240 matches(key, leng, "name") == YES ||
1241 matches(key, leng, "instrument") == YES ||
1242 matches(key, leng, "hex") == YES ||
1243 matches(key, leng, "port") == YES ||
1244 matches(key, leng, "chanpressure") == YES) {
1245 /* Found something to move; move it */
1246 mv_skipped_midi(stuff_p, staffno, topstaff_mll_p);
1247 }
1248 }
1249 }
1250}
1251\f
1252
1253/* With -x option and MIDI, this moves a MIDI STUFF from where it was in
1254 * a skipped measure to the special "empty" measure at the beginning of the
1255 * piece. In general, for any given MIDI thing, only the last one matters,
1256 * so we only need to keep the last one.
1257 */
1258
1259static void
1260mv_skipped_midi(stuff_p, staffno, topstaff_mll_p)
1261
1262struct STUFF *stuff_p; /* Midi STUFF to be moved */
1263int staffno; /* Which staff it is for */
1264struct MAINLL *topstaff_mll_p; /* The STAFF where midi "all" STUFF go.
1265 * Other STAFFs, if any, will surround it. */
1266
1267{
1268 int leng; /* length of MIDI keyword */
1269 char *oldtext; /* text of STUFF that already
1270 * exists in the list */
1271 char *newtext; /* text of STUFF to be added */
1272 struct MAINLL *mll_p; /* for finding STAFF to link to */
1273 struct STAFF *staff_p = 0; /* the STAFF to link to */
1274 struct STUFF **stuff_p_p; /* for finding where to add
1275 * the new stuff_p into list */
1276 static char *alphabet = "abcdefghijklmnopqrstuvwxyz";
1277
1278 /* Find the correct STAFF to attach to. We all passed a pointer
1279 * to the STAFF for midi "all" items. For non-"all" items,
1280 * we search in the main list for the correct STAFF.
1281 */
1282 if (stuff_p->all == YES || staffno == topstaff_mll_p->u.staff_p->staffno) {
1283 staff_p = topstaff_mll_p->u.staff_p;
1284 }
1285 else if (staffno < topstaff_mll_p->u.staff_p->staffno) {
1286 /* Search backward for correct staff from the "all" staff.
1287 * This case probably won't happen often--only if some
1288 * staffs at the top are currently invisible (so they are
1289 * not the current "top visible staff").
1290 */
1291 for (mll_p = topstaff_mll_p; mll_p->str == S_STAFF;
1292 mll_p = mll_p->prev) {
1293 if (mll_p->u.staff_p->staffno == staffno) {
1294 staff_p = mll_p->u.staff_p;
1295 break;
1296 }
1297 }
1298 }
1299 else {
1300 /* Search forwards for correct staff from the "all" staff. */
1301 for (mll_p = topstaff_mll_p; mll_p->str == S_STAFF;
1302 mll_p = mll_p->next) {
1303 if (mll_p->u.staff_p->staffno == staffno) {
1304 staff_p = mll_p->u.staff_p;
1305 break;
1306 }
1307 }
1308 }
1309 if (staff_p == 0) {
1310 /* User must have reduced the number of staffs during the
1311 * skipped part, so this one is irrelevant. */
1312 return;
1313 }
1314
1315 /* Add to end of list. When going through the list,
1316 * see if there is already an item of that type (for param
1317 * have to check the specific param matches too), and if so delete
1318 * the earlier one, because this new one overrides it.
1319 */
1320 newtext = stuff_p->string + 2;
1321 for (stuff_p_p = &(staff_p->stuff_p); *stuff_p_p != 0;
1322 stuff_p_p = &((*stuff_p_p)->next) ) {
1323
1324 /* If for different place,
1325 * this one doesn't count for matching */
1326 if ( (*stuff_p_p)->place != stuff_p->place) {
1327 continue;
1328 }
1329
1330 oldtext = (*stuff_p_p)->string + 2;
1331
1332 /* Since hex is arbitrary data, we always keep it */
1333 if (matches(oldtext, strlen(oldtext), "hex")) {
1334 continue;
1335 }
1336
1337 /* Names can be abbreviated,
1338 * so match up to whichever is shorter */
1339 leng = MIN(strspn(oldtext, alphabet), strspn(newtext, alphabet));
1340 if (matches(newtext, leng, oldtext)== YES) {
1341 /* If it's something other than param, we can get
1342 * rid of the existing one */
1343 if (strncmp(newtext, "par", 3) != 0) {
1344 *stuff_p_p = (*stuff_p_p)->next;
1345 }
1346 else {
1347 /* Compare parameter numbers and if they match,
1348 * delete the existing one.
1349 */
1350 char *new_eq_p, *old_eq_p; /* loc of '=' */
1351 int oldparm, oldval;
1352 int newparm, newval;
1353
1354 new_eq_p = strchr(newtext, '=');
1355 old_eq_p = strchr(oldtext, '=');
1356 if (new_eq_p != 0 && old_eq_p != 0) {
1357 if (get_param(new_eq_p + 1,
1358 stuff_p->inputfile,
1359 stuff_p->inputlineno,
1360 &newparm, &newval)
1361 == YES &&
1362 get_param(old_eq_p + 1,
1363 (*stuff_p_p)->inputfile,
1364 (*stuff_p_p)->inputlineno,
1365 &oldparm, &oldval)
1366 == YES &&
1367 oldparm == newparm) {
1368 *stuff_p_p = (*stuff_p_p)->next;
1369 }
1370 }
1371 }
1372
1373 if (*stuff_p_p == 0) {
1374 /* If deleted last item in the existing list,
1375 * jump out, so we won't try to deference
1376 * this null pointer. */
1377 break;
1378 }
1379 }
1380 }
1381
1382 /* Just do everything at beat zero. The beat at which user specified
1383 * might not even exist in the current time signature, and basically
1384 * we just want to do everything ASAP anyway. We know there is never
1385 * a 'til' on midi, so no need to deal with that. We could end up
1386 * with a lot to do at count zero, potentially enough to overwhelm
1387 * the limited MIDI bandwidth and delay the first actual note.
1388 * But that potential is always there, and by discarding things
1389 * that were overwritten later, which we did above, unless there
1390 * are an awfully lot of parameters on every possible channel,
1391 * it's probably only going to take less than 0.1 second,
1392 * so it doesn't seem worth the bother to try to do something
1393 * fancy to calculate how much time we need for this stuff
1394 * and delay the actual music by that much. */
1395 stuff_p->start.count = 0.0;
1396 stuff_p->start.steps = 0.0;
1397
1398 /* link onto end of list */
1399 *stuff_p_p = stuff_p;
1400 stuff_p->next = 0;
1401}
1402\f
1403
1404/* Given the argument to a MIDI "parameter" command, extract and return
1405 * (via pointers) the two numbers (the parameter number and its value).
1406 * If successful, returns YES, else prints a warning and returns NO.
1407 * If NO is returned, the pointed to return values are not fill in.
1408 */
1409
1410int
1411get_param(arg, inputfile, inputlineno, parmnum_p, parmval_p)
1412
1413char *arg; /* the argument part after "parameter=" */
1414char *inputfile; /* for error messages */
1415int inputlineno; /* for error messages */
1416int *parmnum_p; /* parameter number is returned here */
1417int *parmval_p; /* parameter value is returned here */
1418
1419{
1420 int parmnum; /* parameter number */
1421 int parmval; /* parameter value */
1422 char *parm_p; /* pointer to current place in string */
1423
1424
1425 /* extract first number */
1426 parmnum = strtol(arg, &parm_p, 10);
1427 if (parm_p == arg) {
1428 l_warning(inputfile, inputlineno,
1429 "parameter requires two values");
1430 return(NO);
1431 }
1432 /* skip white space, if any */
1433 while (*parm_p == ' ' || *parm_p == '\t') {
1434 parm_p++;
1435 }
1436 /* next we better have a comma */
1437 if (*parm_p != ','){
1438 l_warning(inputfile, inputlineno,
1439 "parameter is missing required comma");
1440 return(NO);
1441 }
1442 /* extract the second number */
1443 arg = parm_p + 1;
1444 parmval = strtol(arg, &parm_p, 10);
1445 if (parm_p == arg) {
1446 l_warning(inputfile, inputlineno,
1447 "parameter is missing second value");
1448 return(NO);
1449 }
1450 /* verify both numbers are within range */
1451 if ((l_rangecheck(parmnum, 0, 127, "parameter number",
1452 inputfile, inputlineno) == YES) &&
1453 (l_rangecheck(parmval, 0, 127, "parameter value",
1454 inputfile, inputlineno) == YES)) {
1455 *parmnum_p = parmnum;
1456 *parmval_p = parmval;
1457 return(YES);
1458 }
1459 return(NO);
1460}