2 /* Copyright (c) 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 by Arkkra Enterprises */
3 /* All rights reserved */
5 /* functions for checking for various classes of errors such as
6 * values out of range, or trying to do something in an illegal context.
7 * Also contains the code to combine multiple measures of rests into
15 static struct MAINLL *add_pre_meas P((struct MAINLL *insert_p, int start,
16 int end, int add_bar));
17 static int check_all_rests P((struct STAFF *staff_p, int count));
18 static void do_combine P((struct MAINLL *begin_p, struct MAINLL *end_p,
19 int nummeas, int min_combine));
20 static int valid_mark_item P((int mark, int place));
21 static void mv_accs P((struct MAINLL *mll_p));
22 static void move_xoct P((struct STUFF *stuff_p, struct MAINLL *newfirst_p,
23 int staffno, int bars, int start));
24 static void addped P((struct STUFF *pedal_p, struct MAINLL *mll_p));
29 /* give error message if given number is not within specified range. */
30 /* return NO if out of range, YES if okay */
32 /* once upon a time, there was the rangecheck function, and it got called
33 * many times. Then midi support was added and that code needed to do lots
34 * of rangechecks, but with the filename and line number something other
35 * than Curr_filename, and yylineno, so the l_rangecheck function was
36 * created, and rangecheck just calls that. There isn't an l_frangecheck
37 * to go with frangecheck, because nothing needed it. Another case where
38 * C++ would have been nice, so we could default added arguments....
42 rangecheck(n, min, max, name)
44 int n; /* the number to check */
45 int min; /* has to be at least this big */
46 int max; /* can be no bigger than this */
47 char *name; /* describes what n represents, to use in error message */
50 return(l_rangecheck(n, min, max, name, Curr_filename, yylineno));
54 l_rangecheck(n, min, max, name, fname, lineno)
56 int n; /* the number to check */
57 int min; /* has to be at least this big */
58 int max; /* can be no bigger than this */
59 char *name; /* describes what n represents, to use in error message */
60 char *fname; /* file name */
61 int lineno; /* line number */
64 if ( (n < min) || (n > max) ) {
65 l_yyerror(fname, lineno,
66 "%s (%d) is out of range (must be between %d and %d)",
74 /* This function is rather like rangecheck, except it also allows a special
78 erangecheck(n, min, max, empty_value, name)
80 int n; /* the number to check */
81 int min; /* has to be at least this big */
82 int max; /* can be no bigger than this */
83 int empty_value; /* this is also a legal value */
84 char *name; /* describes what n represents, to use in error message */
87 if (n == empty_value) {
88 /* value is okay--means user set to empty */
91 if ( (n < min) || (n > max) ) {
92 l_yyerror(Curr_filename, yylineno,
93 "%s (%d) out of range (must be between %d to %d or set to nothing at all)",
101 /* just like rangecheck except for a float instead of int */
104 frangecheck(n, min, max, name)
106 float n; /* the number to check */
107 float min; /* has to be at least this big */
108 float max; /* can be no bigger than this */
109 char *name; /* describes what n represents, to use in error message */
112 if ( (n < min) || (n > max) ) {
113 l_yyerror(Curr_filename, yylineno,
114 "%s (%.3f) is out of range (must be between %.3f and %.3f)",
122 /* give error and return NO if given number is not a power of 2 */
125 power_of2check(n, name)
127 int n; /* number to verify */
128 char *name; /* what n represents, for error message */
131 if ( (n <= 0) || ((n & (n - 1)) != 0)) {
132 l_yyerror(Curr_filename, yylineno,
133 "%s (%d) not a power of 2", name, n);
140 /* check that current action is valid in current context. */
141 /* If so, return YES, otherwise print message and return NO */
144 contextcheck(validcontext, action)
146 int validcontext; /* bitmap of valid contexts */
147 char *action; /* what action is to be done, for error messages */
150 static int shouldBmusic; /* count of how many consecutive times
151 * we were called when we should have been
152 * in music context, but weren't
155 /* Forgetting to say 'music' can cause tons of errors,
156 * which may confuse the user. So try to deduce what they meant.
158 if (validcontext == C_MUSIC) {
159 if (Context != C_MUSIC) {
160 if (++shouldBmusic > 5) {
162 l_yyerror(Curr_filename, yylineno, "guessing you forgot to specify 'music'; changing to music context to try to recover");
174 if ((validcontext & Context) == 0) {
175 l_yyerror(Curr_filename, yylineno, "%s not valid in %s context",
176 action, contextname(Context));
183 /* convert context number back to name */
188 int cont; /* context number */
224 /* check that at least one staff is visible, print error message if not */
227 check_at_least1visible()
232 /* go through list of staffs, if we find a visible one, fine */
233 for (staffno = Score.staffs; staffno > 0; staffno--) {
234 if ( (svpath(staffno, VISIBLE))->visible == YES) {
239 yyerror("no staffs visible");
244 /* if there is a change in visibility status, need to have a scorefeed after
245 * that. So go through main list. If there is a change in visibility, or
246 * in number of staffs, or stafflines, or staffscale, go
247 * backwards in list till hit FEED, BAR, or beginning of list. If hit FEED
248 * first, throw it away. Then search forward from the SSV until we hit
249 * FEED or STAFF. If FEED, fine. If STAFF, insert
250 * a FEED. If we discarded the user FEED because it was in the wrong place,
251 * mark the pagefeed field as they had it.
252 * This function also adds a measure of space to the beginning of the song
253 * if we are doing MIDI. If a song begins with a grace note,
254 * we want to move that back into the "previous" measure, so this will
255 * create that measure. It's easier to deal with that here, before
256 * makechords() is called, than to try to add it in later.
263 struct MAINLL *mll_p, *m_p; /* to walk through main list */
264 struct MAINLL *new_feed_p;
265 short set_pagefeed = NO; /* if to set pagefeed field */
266 short s; /* staff index */
267 short vis[MAXSTAFFS + 1]; /* which staffs are currently visible */
268 short stlines[MAXSTAFFS + 1]; /* stafflines for each staff */
269 float stscale[MAXSTAFFS + 1]; /* staffscale for each staff */
270 short num_staffs; /* number of staffs */
271 short add_extra; /* if to add extra space measure */
274 debug(4, "chk_vis_feed");
276 /* If doing MIDI, we want to add an extra space measure to the
278 add_extra = Doing_MIDI;
280 /* go through main list looking for visibility changes */
282 for (mll_p = Mainllhc_p; mll_p != (struct MAINLL *) 0;
283 mll_p = mll_p->next) {
285 if (mll_p->str == S_SSV) {
286 /* SSV can only follow a BAR or BLOCKHEAD or another
287 * SSV. If it follows a LINE/CURVE/PRHEAD,
288 * then user must have entered music context,
289 * but not entered any music,
290 * just line/curve/print things. This violates our
291 * mainlist rules, so we have to disallow */
292 if (mll_p->prev != 0 && mll_p->prev->str != S_BAR &&
293 mll_p->prev->str != S_BLOCKHEAD &&
294 mll_p->prev->str != S_SSV) {
295 l_yyerror(mll_p->inputfile, mll_p->inputlineno,
296 "music context containing only lines/curves/print statements is not allowed");
299 /* Only want to insert a FEED if there truly was
300 * a change in the number of staffs to be printed.
301 * User may have set visible when it was already set,
302 * or just changed voice visibility which didn't
303 * cause the visibily of staffs to change, or
304 * something like that, which doesn't count.
305 * So see what visiblity, stafflines,
306 * and staffscale are set to now,
307 * then assign the SSV and see if things changed.
309 for (s = 1; s <= MAXSTAFFS; s++) {
310 /* save current values of interest */
311 vis[s] = svpath(s, VISIBLE)->visible;
312 stlines[s] = svpath(s, STAFFLINES)->stafflines;
313 stscale[s] = svpath(s, STAFFSCALE)->staffscale;
315 num_staffs = Score.staffs;
317 /* make any updates */
318 asgnssv(mll_p->u.ssv_p);
320 /* now compare with previous values */
321 for (s = 1; s <= MAXSTAFFS; s++) {
322 if (vis[s] != svpath(s, VISIBLE)->visible ||
323 stlines[s] != svpath(s,
324 STAFFLINES)->stafflines ||
325 stscale[s] != svpath(s,
326 STAFFSCALE)->staffscale) {
327 /* something changed */
332 if (s <= MAXSTAFFS || Score.staffs != num_staffs) {
334 /* found a change. Go backwards. If find a
335 * FEED, discard it. Otherwise ok */
336 for (m_p = mll_p->prev;
337 m_p != (struct MAINLL *) 0;
340 if (IS_CLEFSIG_FEED(m_p)) {
341 /* feed in wrong place. Discard
342 * this one. We'll put one in
343 * the proper place later */
345 m_p->u.feed_p->pagefeed;
351 else if (m_p->str == S_BAR) {
356 /* now look forwards. If find FEED, fine.
357 * If not, insert one */
358 for (m_p = mll_p->next;
359 m_p != (struct MAINLL *) 0;
362 if (m_p->str == S_FEED) {
363 /* user already put one in */
367 else if (m_p->str == S_STAFF) {
368 /* user neglected to put in an
369 * explicit feed, so we add
372 newMAINLLstruct(S_FEED,
374 new_feed_p->u.feed_p->pagefeed
376 insertMAINLL(new_feed_p,
385 else if (add_extra == YES && mll_p->str == S_STAFF) {
386 /* For MIDI purposes, add a measure space to the
387 * beginning of the song, in case we need to move
388 * grace notes back into it. Strictly speaking,
389 * we probably don't need to do this unless there
390 * truly is a grace note at the beginning, but
391 * it should never hurt to add it, and it doesn't
392 * seem worth the effort to check. */
393 add_pre_meas(mll_p->prev, 1, Score.staffs, YES);
401 /* For MIDI, we add a measure of space preceeding what the user put in.
402 * This is used in case they start the piece with grace notes that we need
403 * to move back in the preceeding measure, since this guarantees there will
404 * be a preceeding measure. Also, for when taking a "slice" of the piece,
405 * skipping measures at the beginning, this is where we attach any MIDI
406 * STUFFs that happened during the skipped part.
407 * Returns the last MAINLL added.
410 static struct MAINLL *
411 add_pre_meas(insert_p, start, end, add_bar)
413 struct MAINLL *insert_p; /* insert after here */
414 int start; /* staff number of first STAFF to create */
415 int end; /* staff number of last STAFF to create */
416 int add_bar; /* if YES, add an invisible bar too */
419 int staff; /* loop through staffs to be created */
420 struct MAINLL *new_p; /* new STAFFs */
421 int numvoices; /* number of voices on current staff */
422 int v; /* voice index */
424 /* Create a staff with measure space for all
425 * defined staffs/voices, and link onto main list */
426 for (staff = start; staff <= end; staff++) {
428 /* create the STAFF struct itself */
429 new_p = newMAINLLstruct(S_STAFF, -1);
430 new_p->u.staff_p->staffno = staff;
431 new_p->u.staff_p->visible = svpath(staff, VISIBLE)->visible;
433 numvoices = vscheme_voices(svpath(staff, VSCHEME)->vscheme);
434 for (v = 0; v < numvoices; v++) {
435 add_meas_space( &(new_p->u.staff_p->groups_p[v]),
439 /* link onto main list, and arrange to
440 * link the next thing after this one */
441 insertMAINLL(new_p, insert_p);
444 if (add_bar == YES) {
445 /* add an invisible bar line */
446 new_p = newMAINLLstruct(S_BAR, -1);
447 new_p->u.bar_p->bartype = INVISBAR;
448 insertMAINLL(new_p, insert_p);
455 /* check for valid interval. Unison, octave, fourths and fifths can not be
456 * major or minor. The others cannot be perfect. */
459 chk_interval(inttype, intnum)
461 int inttype; /* PERFECT, MINOR, etc */
462 int intnum; /* e.g., 4 for fourth */
466 yyerror("transposition interval must be > 0");
470 /* collapse into 1 octave. It's okay that a 7th will come out zero
471 * because of the way things are checked below. */
483 yyerror("specified interval cannot be perfect");
494 yyerror("specified interval cannot be major or minor");
502 /* everything else is okay */
508 /* if specified used[] field is set to YES, print warning that its value is
509 * being overridden. This is to let user know they set the same parameter
510 * twice in the same SSV context */
513 used_check(mll_p, var, name)
515 struct MAINLL *mll_p; /* check used[] in the SSV pointed to by this */
516 int var; /* check this index in the used[] array */
517 char *name; /* name of variable, for warning message */
520 if (mll_p == (struct MAINLL *) 0) {
521 l_yyerror(Curr_filename, yylineno,
522 "can't set %s in %s context", name, contextname(Context));
526 if (mll_p->str != S_SSV) {
527 pfatal("bad argument passed to used_check()");
530 if (mll_p->u.ssv_p->used[var] == YES) {
531 l_warning(Curr_filename, yylineno,
532 "setting of '%s' parameter overrides previous setting",
538 /* go through list and combine multiple consecutive rests into multi-rests */
543 int c; /* argument to -c command line option;
544 * only combine when there are at least
545 * this many rest measures in a row.
546 * Set to NORESTCOMBINE if user didn't use -c option. */
549 struct MAINLL *mll_p; /* walk through main list */
550 struct MAINLL *begin_p = (struct MAINLL *) 0; /* where section to
552 struct MAINLL *end_p = (struct MAINLL *) 0;
554 int n; /* how many measures minimum to combine */
555 int count = 0; /* how many measures of all rests */
556 int begin_valid = NO; /* if begin_p has been set. Can't just check to
557 * see if it is null, because null is valid */
559 char *timerep; /* current time signature representation */
562 debug(2, "combine_rests");
564 /* go through main list */
566 n = c; /* init to value of -c option */
567 for (mll_p = Mainllhc_p; mll_p != (struct MAINLL *) 0;
568 mll_p = mll_p->next) {
570 if (Doing_MIDI == YES && mll_p == Mainllhc_p) {
571 /* Don't want to combine the "extra" measure
572 * we added in for MIDI, so skip it. */
573 for ( ; mll_p != 0; mll_p = mll_p->next) {
574 if (mll_p->str == S_BAR) {
580 /* Must be no valid music data in the file.
581 * check4barline_at_end() should have already
582 * reported this to user, so we can just
583 * return silently here. */
588 /* for each STAFF that is visible, see if it is all rests */
589 if (mll_p->str == S_STAFF) {
590 /* remember where we are, in case this is the beginning
591 * of section that needs to be combined */
592 if (begin_valid == NO) {
593 begin_p = mll_p->prev;
597 /* if we have all rests so far, check this staff */
598 if (all_rests == YES) {
599 if ((all_rests = check_all_rests
600 (mll_p->u.staff_p, count))
602 /* this measure was not all rests.
603 * Check to see if before that we
605 * all rests. If so, combine them */
606 do_combine(begin_p, end_p, count, n);
611 else if (mll_p->str == S_BAR) {
612 if (all_rests == YES) {
613 /* this measure was all rests, so
615 if (mll_p->u.bar_p->bartype != INVISBAR) {
619 /* if not an ordinary bar, end the combining */
620 if ( (mll_p->u.bar_p->reh_type != REH_NONE) ||
621 (mll_p->u.bar_p->endingloc
623 mll_p->u.bar_p->endingloc
625 ( (mll_p->u.bar_p->bartype
627 (mll_p->u.bar_p->bartype !=
629 if (mll_p->u.bar_p->bartype == RESTART) {
630 /* There is an empty "measure"
631 * of space before restarts */
633 /* need to end combining at
634 * the previous bar line */
636 for (end_p = end_p->prev;
639 end_p = end_p->prev) {
645 do_combine(begin_p, end_p, count, n);
649 begin_p = (struct MAINLL *) 0;
655 /* re-init for next measure */
658 begin_p = (struct MAINLL *) 0;
663 else if (mll_p->str == S_SSV) {
665 ssv_p = mll_p->u.ssv_p;
667 /* If -c option was not used, we use the value of
668 * the restcombine parameter. */
669 if (c == NORESTCOMBINE &&
670 ssv_p->used[RESTCOMBINE] == YES) {
671 n = ssv_p->restcombine;
674 /* if there is a change in visibility or a relevant
675 * change on an already-visible score,
676 * that is grounds to end the combination */
677 if ( ssv_p->used[VISIBLE] == YES ||
678 ((((mll_p->u.ssv_p->staffno == 0) ||
679 (svpath(mll_p->u.ssv_p->staffno,
680 VISIBLE))->visible == YES)) &&
681 (ssv_p->used[CLEF] == YES
682 || ssv_p->used[SHARPS] == YES
683 || ssv_p->used[TIME] == YES
684 || ssv_p->used[TRANSPOSITION] == YES
685 || ssv_p->used[ADDTRANSPOSITION] == YES
686 || ssv_p->used[VISIBLE] == YES))) {
687 do_combine(begin_p, end_p, count, n);
691 begin_p = (struct MAINLL *) 0;
696 /* keep track of visibility */
697 asgnssv(mll_p->u.ssv_p);
699 else if (mll_p->str == S_FEED) {
700 do_combine(begin_p, end_p, count, n);
702 begin_p = (struct MAINLL *) 0;
708 /* do final combination if any */
709 do_combine(begin_p, end_p, count, n);
711 /* If there were case of TS_ALWAYS with alternating time
712 * signatures, we had to save the entire time signature list for
713 * every measure in case it turned out to be a multirest.
714 * Now we can shorten down to one for those that aren't,
715 * and need to do this so later code works.
719 for (mll_p = Mainllhc_p; mll_p != 0; mll_p = mll_p->next) {
720 struct MAINLL * nmll_p;
722 if (mll_p->str != S_SSV) {
725 asgnssv(mll_p->u.ssv_p);
726 if (Score.timevis != PTS_ALWAYS) {
730 /* If we need to change the current timerep,
731 * need to do the permanent copy in the main list,
732 * not the one current in Score, so save pointer to current
733 * one in main list. */
734 if (mll_p->u.ssv_p->used[TIME]) {
735 timerep = mll_p->u.ssv_p->timerep;
738 for (nmll_p = mll_p->next; nmll_p != 0;
739 nmll_p = nmll_p->next) {
740 if (nmll_p->str == S_STAFF) {
741 if (nmll_p->u.staff_p->groups_p[0]->basictime >= -1) {
742 /* not followed by multi-rest,
743 * can truncate time sig */
745 for (t = timerep; t != 0 && *t != 0; t++) {
746 if (*t == TSR_ALTERNATING) {
759 /* given a STAFF, return NO if the staff is visible and has at least one
760 * voice which contains notes, or has lyrics or STUFF (except if stuff is on
761 * or before the first beat of the first measure. Otherwise return YES */
764 check_all_rests(staff_p, count)
766 struct STAFF *staff_p; /* which staff info to check */
767 int count; /* how many measures of all rest so far */
770 int v; /* index through voices */
771 struct GRPSYL *gs_p; /* walk through grpsyl list */
772 struct STUFF *stuff_p; /* walk through stuff list */
775 /* if not visible, then okay to treat as all rests */
776 if ( (svpath(staff_p->staffno, VISIBLE))->visible == NO) {
780 /* if has lyrics, consider that not rests */
781 if (staff_p->nsyllists > 0) {
785 /* having STUFF is usually grounds for not being treated as all rests */
786 /***** what to do about earlier stuff that happens to spill into
787 *** this measure???????? *****/
788 if (staff_p->stuff_p != (struct STUFF *) 0) {
789 /* special case. If this is the first measure of rests, and
790 * all STUFFs occur on or before beat 1 and have no til clause,
792 * This allows user to change tempo or something similar at
793 * the beginning of a combined multirest. */
795 /* Combining only applies to printing, not MIDI,
796 * so MIDI STUFFs can be ignored */
797 for (stuff_p = staff_p->stuff_p; stuff_p != 0;
798 stuff_p = stuff_p->next) {
799 if (stuff_p->stuff_type != ST_MIDI) {
803 /* all the STUFFs must have been MIDI */
806 for (stuff_p = staff_p->stuff_p; stuff_p != (struct STUFF *) 0;
807 stuff_p = stuff_p->next) {
808 if (stuff_p->stuff_type == ST_MIDI) {
811 if (stuff_p->start.count > 1.0 || stuff_p->end.bars > 0
812 || stuff_p->end.count > 0.0) {
818 for (v = 0; v < MAXVOICES; v++) {
819 for (gs_p = staff_p->groups_p[v]; gs_p != (struct GRPSYL *) 0;
821 /* if voice is invisible, treat like all rests */
822 if (vvpath(staff_p->staffno, v + 1, VISIBLE)->visible == NO) {
826 if (gs_p->grpcont == GC_NOTES) {
830 else if (gs_p->is_meas == NO) {
831 /* We only combine mr and ms. If user entered
832 * one or more rests/spaces that fill the
833 * entire measure, we don't combine,
834 * because the user may have had some reason
835 * for explicitly specifying time values rather
836 * than using a measure duration. */
839 else if (gs_p->basictime < -1) {
840 /* already multirest! */
849 /* effect the combination of several measures of rests into a multirest. */
852 do_combine(begin_p, end_p, nummeas, min_combine)
854 struct MAINLL *begin_p; /* start combining from here */
855 struct MAINLL *end_p; /* stop here */
856 int nummeas; /* hom many measures are being combined */
857 int min_combine; /* minimum number to combine, or NORESTCOMBINE */
860 struct MAINLL *new_p;
861 struct MAINLL *old_p; /* first of items to discard */
862 struct GRPSYL *gs_p; /* for multirest */
863 struct MAINLL *mll_p; /* to find staff for transferring stuffs */
864 short s; /* index through staffs */
868 if (min_combine == NORESTCOMBINE || nummeas < min_combine) {
869 /* don't bother to combine */
873 /* discard everything in main list between the given points.
874 * It will be either STAFFs with all rests to be replaced or
875 * BARs to be discarded, or things associated with invisible staffs.
876 * I guess maybe we should free up the space rather than merely
877 * unhitching it from the list, but it hardly seems worth the bother,
878 * especially since we'd have to be careful not to delete the STUFFs
879 * on the first one in case they were needed at the end of this
882 if (begin_p == (struct MAINLL *) 0) {
887 old_p = begin_p->next;
888 begin_p->next = end_p;
890 if (end_p != (struct MAINLL *) 0) {
891 end_p->prev = begin_p;
894 /* add multirest to list */
895 for (s = Score.staffs; s > 0; s--) {
896 new_p = newMAINLLstruct(S_STAFF, -1);
897 gs_p = newGRPSYL(GS_GROUP);
898 gs_p->grpcont = GC_REST;
899 gs_p->basictime = -nummeas;
900 gs_p->fulltime = Score.time;
904 new_p->u.staff_p->groups_p[0] = gs_p;
905 numvoices = vscheme_voices(svpath(s, VSCHEME)->vscheme);
907 add_meas_space( &(new_p->u.staff_p->groups_p[1]), s, 2);
908 new_p->u.staff_p->groups_p[1]->basictime = -nummeas;
909 /* if the first voice was invisible,
910 * but the second voice is visible, need to convert
911 * the space just created into a rest. */
912 if (vvpath(s, 1, VISIBLE)->visible == NO &&
913 vvpath(s, 2, VISIBLE)->visible == YES) {
914 new_p->u.staff_p->groups_p[1]->grpcont = GC_REST;
918 add_meas_space( &(new_p->u.staff_p->groups_p[2]), s, 3);
919 new_p->u.staff_p->groups_p[2]->basictime = -nummeas;
920 /* if only the third voice is visible, need to convert
921 * the space just created into a rest. */
922 if (vvpath(s, 1, VISIBLE)->visible == NO &&
923 vvpath(s, 2, VISIBLE)->visible == NO &&
924 vvpath(s, 3, VISIBLE)->visible == YES) {
925 new_p->u.staff_p->groups_p[2]->grpcont = GC_REST;
928 new_p->u.staff_p->staffno = s;
929 new_p->u.staff_p->visible = svpath(s, VISIBLE)->visible;
930 insertMAINLL(new_p, begin_p);
932 /* if there were any STUFFs on or before the first beat of the
933 * first measure, we have to transfer them to the stufflist of
934 * the multirest. We can transfer the entire list, because if
935 * there were any items that shouldn't be transferred, we
936 * wouldn't have allowed the multirest combination in the
938 for (mll_p = old_p; mll_p != (struct MAINLL *) 0
939 && mll_p != end_p; mll_p = mll_p->next) {
940 if (mll_p->str == S_STAFF
941 && mll_p->u.staff_p->staffno == s) {
942 new_p->u.staff_p->stuff_p =
943 mll_p->u.staff_p->stuff_p;
951 /* translate MK_* to printable name */
956 int mark; /* MK_* value */
979 pfatal("markname(): missing case");
986 /* verify that a mark order list is valid */
989 chk_order(ssv_p, place)
991 struct SSV *ssv_p; /* check the markorder list in here */
992 int place; /* PL_*, which list to check */
995 int m, n; /* index through MK_* */
996 int level; /* value in markorder table */
998 for (m = 0; m < NUM_MARK; m++) {
999 if (ssv_p->markorder[place][m] == 0) {
1000 /* no level set for this mark, so skip it */
1004 /* some mark types cannot be equal with any other types */
1011 level = ssv_p->markorder[place][m];
1012 for (n = 0; n < NUM_MARK; n++) {
1016 if (ssv_p->markorder[place][n] == level) {
1017 l_yyerror(Curr_filename, yylineno,
1018 "%s cannot be at same level as %s",
1019 markname(m), markname(n));
1028 if (valid_mark_item(m, place) == NO) {
1032 placename = "above";
1035 placename = "below";
1038 placename = "between";
1041 pfatal("chk_order: invalid place %d", place);
1042 /* not reached; it just avoids bogus
1043 * "used before set" warning */
1046 l_warning(Curr_filename, yylineno,
1047 "%s not valid in %sorder list",
1048 markname(m), placename);
1054 /* return YES if MK_* item is valid at given place, NO if not */
1057 valid_mark_item(mark, place)
1059 int mark; /* MK_* */
1060 int place; /* PL_* */
1063 if (mark == MK_OCTAVE && place == PL_BETWEEN) {
1066 if ((mark == MK_ENDING || mark == MK_REHEARSAL)
1067 && place != PL_ABOVE) {
1070 if (mark == MK_PEDAL && place != PL_BELOW) {
1074 /* everything else is okay */
1080 * User can specify that only a portion of the song is to be processed.
1081 * This is done via one or two numbers, the first measure to include and
1083 * Positive numbers are relative to the beginning of the song, negative
1084 * are relative to the end. So, as examples:
1085 * 1 // the whole song (default)
1086 * 1,-1 // another way to say the whole song
1087 * 5 // start at measure 5, through the end
1088 * 6,7 // only measures 6 and 7
1089 * 1,10 // measures 1 through 10
1090 * 1,-8 // skip the last 7 measures
1091 * -12,-3 // only process from 12 measures from the end through
1092 * // the third from the end
1094 * When counting measures for this, invisbar bars do not count.
1095 * It is measured by the number of bars encountered in input, not in
1096 * performance: the bars are not double counted in sections
1097 * between repeat signs.
1099 * A value of zero is not allowed.
1100 * A positive start larger than the number of measures in the song
1102 * A negative start that would result in starting before the beginning
1103 * starts at the beginning (with a warning)
1104 * A positive end larger than the number of measures in the song goes to
1105 * end of song (with a warning)
1106 * An end value that would result in starting before the beginning of the
1107 * song or before the start value is a user error.
1109 * Only one slice is supported. I.e., you can't ask for something
1110 * like measures 4-10, 17-24, and 46-80.
1111 * You can only ask for one of those ranges.
1112 * (You could get that effect by making 3 files and playing them one after
1113 * another, although there might be slight pauses in between.)
1115 * A possible future enhancement might be
1116 * to also be able to specify by rehearsal mark.
1117 * If a rehearsal mark string is specified rather than a number,
1118 * the rehearsal mark having that string (ASCII-ized by removing font, size,
1119 * and other special things) would be used as the marked place. In this case,
1120 * the end place would be only up to the rehearsal mark, not through the
1121 * measure that starts there.
1125 chk_x_arg(x_arg, start_p, end_p)
1127 char *x_arg; /* arg to -x option specified by user */
1128 int *start_p; /* start gets returned here */
1129 int *end_p; /* end gets returned here */
1132 char *arg_p; /* pointer to where end starts in x_arg */
1134 /* set to defaults */
1138 if (x_arg == 0 || *x_arg == '\0') {
1139 /* No -x option, use whole song as normal */
1143 *start_p = (int) strtol(x_arg, &arg_p, 0);
1144 if (arg_p == x_arg) {
1145 if (Mupmate == YES) {
1146 l_yyerror(0, -1, "Run > Set Options > Extract Measures: value must be one or two numbers.");
1149 l_yyerror(0, -1, "argument for %cx option must be one or two numbers", Optch);
1153 /* If there is a comma, get the "end" argument as well */
1154 if (*arg_p == ',') {
1155 *end_p = (int) strtol(arg_p + 1, &arg_p, 0);
1158 /* We should be at end of string, either after first arg if there
1159 * was only one arg, or after second if there were two. */
1160 if (*arg_p != '\0') {
1161 if (Mupmate == YES) {
1162 l_yyerror(0, -1, "Run > Set Options > Extract Measures: value must be one or two numbers.");
1165 l_yyerror(0, -1, "argument for %cx option must be one or two numbers", Optch);
1171 /* This function does the slicing to extract selected measures from the input */
1176 int start; /* Start at this measure number. A negative
1177 * number means count from the end of the piece,
1178 * so -3 would mean the last 3 bars. */
1179 int end; /* Play only through this measure number.
1180 * Negative is relative to the end of the piece. */
1183 int pickup; /* YES if song begins
1184 * with pickup measure */
1185 int numbars; /* total number of bars */
1186 int bars; /* how many processed so far */
1187 int mrbars; /* how many bars of multirest */
1188 struct MAINLL *topstaff_mll_p = 0; /* "all" MIDI STUFFS will
1189 * be attached here */
1190 struct MAINLL *mll_p; /* loop through list */
1191 struct MAINLL *m_p; /* to look ahead in list */
1192 struct MAINLL *next_p; /* saved next */
1193 struct STUFF *nextstuff_p; /* saved next of a STUFF */
1194 struct MAINLL *first_p; /* first STAFF at start */
1195 struct STUFF *stuff_p; /* loop through STUFF list */
1196 struct STUFF *pedal[MAXSTAFFS+1]; /* YES if pedal is down */
1197 struct STUFF *saveped[MAXSTAFFS+1]; /* YES if pedal was down * at entry to set of endings */
1198 int in_endings; /* YES if inside endings */
1202 pickup = has_pickup();
1203 if ( ( (pickup == YES && start == 0) || (pickup == NO && start == 1) )
1205 /* Use whole song as normal; nothing to do here */
1209 /* If song has a pickup measure, compensate for that.
1210 * This function treats the partial measure as a measure.
1211 * So if user specified 0 for start, they want to start at the pickup,
1212 * which will be effectively measure 1 here. If they specified 1,
1213 * they want to skip the pickup, which means they want to start at
1214 * what will be considered measure 2. And so forth.
1216 if (pickup == YES) {
1225 /* It's not clear if these should be warnings or errors,
1226 * but it seems friendlier to be just warnings.
1227 * That way, if someone wants the beginning,
1228 * but can't remember if the piece has a pickup or not,
1229 * they can use 0, and it will always work,
1230 * albeit possibly with a warning.
1233 warning("x option start of 0 is only valid if there is a pickup measure; using 1");
1237 warning("x option end of 0 is only valid if there is a pickup measure; using 1");
1242 /* Count total number of bars in song */
1243 for (numbars = 0, mll_p= Mainllhc_p; mll_p != 0; mll_p = mll_p->next) {
1244 if (mll_p->str == S_BAR && mll_p->u.bar_p->bartype != INVISBAR) {
1247 /* Multirests count as multiple bars */
1248 else if (mll_p->str == S_STAFF
1249 && mll_p->u.staff_p->groups_p[0] != 0) {
1250 if (mll_p->u.staff_p->groups_p[0]->basictime < -1) {
1251 numbars += -(mll_p->u.staff_p->groups_p[0]->basictime) - 1 ;
1253 /* skip the rest of the STAFFs till BAR */
1254 while (mll_p->next != 0 && mll_p->next->str == S_STAFF) {
1255 mll_p = mll_p->next;
1260 /* Only non-invisible bars count. If there aren't any
1261 * identifiable measures, -x is pointless. */
1262 ufatal("can't use -x on song with no visible bar lines");
1265 /* If user specified things relative to the end, convert
1266 * the relative-to-end negative values to relative-to-beginning
1270 start = numbars + start + 1;
1273 end = numbars + end + 1;
1276 if (start > numbars) {
1277 ufatal("Attempt to start beyond end of song");
1280 ufatal("Attempt to end before start");
1283 ufatal("Attempt to end before beginning of song");
1286 warning("attempt to start before beginning; ignoring");
1289 if (end > numbars) {
1290 warning("attempt to go past end; ignoring");
1294 if (start == 1 && end == numbars) {
1295 /* After all the conversions, we ended up with
1296 * the entire song. Nothing more to do here. */
1299 /* compensate for bar being at end of measure */
1303 /* First find the bar where we're going to start.
1304 * Find out if there are any notes tied into that measure
1305 * that have an accidental. If so, move the accidental
1306 * into the new starting measure.
1307 * Note: the 'mll_p != 0' checks are defensive; shouldn't happen.
1310 for (bars = 0, mll_p = Mainllhc_p; mll_p != 0 && bars < start;
1311 mll_p = mll_p->next){
1312 if (mll_p->str == S_SSV) {
1313 /* need to keep things like keysig up to date */
1314 asgnssv(mll_p->u.ssv_p);
1316 else if (mll_p->str == S_BAR && mll_p->u.bar_p->bartype != INVISBAR) {
1319 else if (mll_p->str == S_STAFF
1320 && mll_p->u.staff_p->groups_p[0] != 0) {
1321 if (mll_p->u.staff_p->groups_p[0]->basictime < -1) {
1322 bars += -(mll_p->u.staff_p->groups_p[0]->basictime) - 1 ;
1324 /* skip the rest of the STAFFs till BAR */
1325 while (mll_p->next->str == S_STAFF) {
1326 mll_p = mll_p->next;
1331 for ( ; mll_p != 0 && mll_p->str != S_BAR; mll_p = mll_p->next) {
1332 if (mll_p->str == S_STAFF) {
1339 /* Fix up the measure number to account for what was chopped off.
1340 * The pickup part may be a bit counter-intuitive...
1341 * It's because when there was a pickup, we've already added 1 to
1342 * "start" for that partial measure; with no pickup, we didn't.
1343 * As an example, if user specified -x2, then the measure number
1344 * at the barline at the end of the first printed measure should be 3.
1345 * "start" will have value 1 if there was no pickup,
1346 * but 2 if there was a pickup. So....
1348 * start + 1 + (pickup ? 0 : 1);
1349 * -----------------------------
1350 * no pickup: 1 + 1 + 1 = 3
1351 * pickup: 2 + 1 + 0 = 3
1353 Meas_num = mll_p->u.bar_p->mnum = start + 1 + (pickup ? 0 : 1);
1355 /* Find the top visible staff on the new effective "first" measure,
1356 * We will be moving MIDI STUFFs into the special "extra"
1357 * space measure that exists for MIDI right before the first real
1358 * measure entered by the user.
1359 * The current top visible tells us which staff to use for "all" items.
1360 * We leave everything on the list up through the "extra" measure */
1362 int staffs_needed; /* number of staffs at new first meas */
1363 struct MAINLL *laststaffmll_p = 0; /* last staff of the extra meas
1364 * added at the beginning for MIDI.
1365 * Initialization just to avoid "used before set." */
1367 for (mll_p = Mainllhc_p; mll_p->str != S_BAR; mll_p = mll_p->next) {
1368 if (mll_p->str == S_STAFF && svpath(
1369 mll_p->u.staff_p->staffno, VISIBLE)
1371 topstaff_mll_p = mll_p;
1376 /* The number of staffs in the "extra" added measure might be
1377 * smaller than the number of staffs on the new
1378 * effective first measure.
1380 staffs_needed = Score.staffs;
1381 for (mll_p = Mainllhc_p; mll_p->str != S_BAR; mll_p = mll_p->next){
1382 if (mll_p->str == S_STAFF) {
1383 laststaffmll_p = mll_p;
1386 if (laststaffmll_p == 0){
1387 pfatal("extract failed to find last staff in extra measure");
1389 if (laststaffmll_p->u.staff_p->staffno < staffs_needed) {
1390 (void) add_pre_meas(laststaffmll_p,
1391 laststaffmll_p->u.staff_p->staffno,
1395 /* We want to start discarding things after the extra measure,
1396 * so skip past that. */
1397 for (mll_p = Mainllhc_p; mll_p->str != S_BAR; mll_p = mll_p->next) {
1400 mll_p = mll_p->next;
1406 /* Pedal is off at the start */
1407 for (i = 1; i <= MAXSTAFFS; i++) {
1412 /* Now go through and discard anything irrelevant before the
1413 * start measure. We save all SSVs. If doing MIDI, we save any
1414 * MIDI directives that matter.
1415 * Everything else gets discarded.
1420 for (bars = 0; bars < start; mll_p = next_p) {
1422 pfatal("got null mll_p when finding starting measure");
1424 next_p = mll_p->next;
1426 switch (mll_p->str) {
1429 if (mll_p->u.bar_p->bartype != INVISBAR) {
1434 if (bars > start || (mll_p->u.bar_p->bartype
1435 == INVISBAR && bars == start)) {
1436 /* New first bar is or was a multirest,
1437 * so we need to retain this bar line.
1444 /* Keep track of if we're in a first ending. */
1445 if (mll_p->u.bar_p->endingloc == STARTITEM) {
1448 else if (mll_p->u.bar_p->endingloc == ENDITEM) {
1454 /* Keep track of current pedal state for this staff.
1455 * If we find a C_ENDPED the pedal is up, otherwise
1456 * it's down (because even with a bounce, at the end
1457 * of the bounce, the pedal is down).
1458 * Also deal with an octave marks that might spill
1459 * over into the new first measure.
1461 for (stuff_p = mll_p->u.staff_p->stuff_p; stuff_p != 0;
1462 stuff_p = nextstuff_p) {
1463 /* In a previous implementation,
1464 * stuff_p->next could be invalid after call
1465 * to move_xoct, so we had to save it here.
1466 * With the current implementation, this
1467 * shouldn't be strictly necessary, but
1468 * it doesn't hurt. */
1469 nextstuff_p = stuff_p->next;
1471 /* Note that the only time string should be
1472 * null is on pedal carried over from a
1473 * previous score, so that isn't really a
1474 * change in pedal state, so we can ignore it.
1476 if (stuff_p->stuff_type == ST_PEDAL &&
1477 stuff_p->string != 0) {
1478 pedal[mll_p->u.staff_p->staffno] =
1481 if (stuff_p->stuff_type == ST_OCTAVE) {
1482 move_xoct(stuff_p, first_p,
1483 mll_p->u.staff_p->staffno,
1489 mv_midi_items(mll_p, topstaff_mll_p);
1492 /* Deal with multirest */
1493 if (mll_p->u.staff_p->groups_p[0]->basictime < -1) {
1494 mrbars = -(mll_p->u.staff_p->groups_p[0]->basictime);
1495 if (bars + mrbars > start) {
1496 /* Slice starts in middle of multirest.
1497 * This multirest will be the new
1498 * first measure, but we need
1499 * to adjust the number of
1500 * measures worth of multirest to
1501 * account for starting in the middle
1504 mll_p->u.staff_p->groups_p[0]->basictime =
1505 -((bars + mrbars) - start);
1507 /* If the end of the slice is also inside
1508 * this same multirest, shorten it down
1509 * to end there. It's slightly silly to
1510 * be saving only a part of a multirest,
1511 * but it's better to handle it than
1514 if (bars + mrbars > end) {
1515 mll_p->u.staff_p->groups_p[0]->basictime
1516 += (end - bars - mrbars + 2);
1519 /* If down to single measure, have to
1520 * convert from multirest to meas rest */
1521 if (mll_p->u.staff_p->groups_p[0]->basictime == -1) {
1522 mll_p->u.staff_p->groups_p[0]->is_meas = YES;
1523 mll_p->u.staff_p->groups_p[0]->basictime = 1;
1524 mll_p->u.staff_p->groups_p[0]->fulltime = Score.time;
1532 /* Need to keep all the SSVs. Not sure they
1533 * really need to be assigned, but shouldn't hurt. */
1534 asgnssv(mll_p->u.ssv_p);
1542 /* Get rid of this MAINLL. User wants it skipped. */
1543 unlinkMAINLL(mll_p);
1546 /* Make sure there is a bar after where mll_p currently is.
1547 * If song consists of just a multirest, followed by
1548 * blocks, prints, lines, or curves, but no more music,
1549 * we need to force mll_p to get set to the bar at the end of
1552 for (m_p = mll_p; m_p != 0 && m_p->str != S_BAR; m_p = m_p->next) {
1556 /* No bar. Force into hitting the next 'if' */
1560 /* If start was in a multirest, mll_p could be zero,
1561 * so we have to use the beginning bar. */
1563 for (mll_p = Mainllhc_p; mll_p != 0 && mll_p->str != S_BAR;
1564 mll_p = mll_p->next) {
1568 pfatal("-x option failed to find beginning bar correctly");
1572 /* Add pedal starts if necessary. Go through the new effective
1573 * first measure. For any staff that had the pedal down coming
1574 * into that measure, make sure the measure starts with a BEGPED.
1575 * Also, if there are any measure repeats, ufatal.
1576 * Trying to start at a measure repeat doesn't really make a lot of
1577 * sense, and it would be work to allow it, so don't bother.
1578 * Using mrpt is discouraged anyway.
1580 for ( ; mll_p->str != S_BAR; mll_p = mll_p->next) {
1581 if (mll_p->str == S_STAFF) {
1582 int v; /* voice index */
1583 /* check for mrpt */
1584 for (v = 0; v < MAXVOICES; v++) {
1585 if (is_mrpt(mll_p->u.staff_p->groups_p[v]) == YES) {
1586 l_ufatal(mll_p->inputfile, mll_p->inputlineno,
1587 "-x option not allowed to start at a mrpt");
1591 addped(pedal[mll_p->u.staff_p->staffno], mll_p);
1595 /* If slice starts inside an ending, we disallow that.
1596 * It turns out there a number of pathological cases,
1597 * particularly regarding pedal. If the pedal was down going into
1598 * the first ending, but up at the beginning of the slice, then
1599 * what should the pedal state be at the start of subsequent endings?
1600 * It should normally be based on the state coming into the ending,
1601 * but that no longer exists and conflicts with the new "beginning
1602 * of the ending" state. And more fundamentally, where do you go back
1603 * to when you reach the end of a non-final ending?
1604 * There's nothing there to go back to!
1605 * I suppose if someone has a really long ending and wants
1606 * just the middle of it, this restriction will be annoying,
1607 * but that shouldn't happen too often, and trying to handle this
1608 * was just getting too complicated!
1610 if (in_endings == YES) {
1611 ufatal("-x section not allowed to begin inside an ending");
1614 /* If the new first measure is in the middle of an ending,
1615 * patch up the endingloc. */
1616 if (mll_p->u.bar_p->endingloc == ENDITEM ||
1617 mll_p->u.bar_p->endingloc == INITEM) {
1618 struct MAINLL *prevmll_p;
1619 struct MAINLL *topstaffmll_p = 0;
1621 for (prevmll_p = mll_p->prev; prevmll_p != 0;
1622 prevmll_p = prevmll_p->prev) {
1623 if (prevmll_p->str == S_STAFF) {
1624 topstaffmll_p = prevmll_p;
1626 else if (prevmll_p->str == S_BAR) {
1627 prevmll_p->u.bar_p->endingloc = STARTITEM;
1631 if (prevmll_p == 0) {
1632 if (topstaffmll_p == 0) {
1633 pfatal("unexpected null topstaffmll_p");
1635 prevmll_p = add_pre_meas(
1636 topstaffmll_p->prev, 1, Score.staffs, YES);
1637 prevmll_p->u.bar_p->endingloc = STARTITEM;
1641 /* Now chop off end if needed */
1642 if (end < numbars) {
1643 for ( ; mll_p != 0 && (bars < end || mrbars > 0);
1644 mll_p = mll_p->next) {
1645 if (mll_p->str == S_BAR && mll_p->u.bar_p->bartype != INVISBAR) {
1649 if (mll_p->str == S_STAFF &&
1650 mll_p->u.staff_p->groups_p[0] != 0 &&
1651 mll_p->u.staff_p->groups_p[0]->basictime < -1) {
1652 /* It's a multirest */
1653 mrbars = -(mll_p->u.staff_p->groups_p[0]->basictime);
1656 /* Slice ends inside the multirest.
1657 * Adjust its length. If down to a
1658 * single measure, convert */
1659 for ( ; mll_p->str == S_STAFF;
1660 mll_p = mll_p->next) {
1661 mll_p->u.staff_p->groups_p[0]->basictime
1663 if (mll_p->u.staff_p->groups_p[0]->basictime == -1) {
1664 mll_p->u.staff_p->groups_p[0]->is_meas = YES;
1665 mll_p->u.staff_p->groups_p[0]->basictime = 1;
1666 mll_p->u.staff_p->groups_p[0]->fulltime = Score.time;
1671 /* multi-rest has been handled; skip over
1672 * the rest of the staffs in this measure */
1673 while (mll_p->next != 0 &&
1674 mll_p->next->str == S_STAFF) {
1675 mll_p = mll_p->next;
1680 /* If didn't get all the way to end of main list,
1681 * chop off the rest.
1682 * We don't bother to free the space.
1684 mll_p->prev->next = 0;
1685 Mainlltc_p = mll_p->prev;
1688 /* Remove ties/slurs going into the chopped-off part. */
1689 for (mll_p = Mainlltc_p->prev; mll_p != 0; mll_p = mll_p->prev) {
1690 if (mll_p->str == S_STAFF) {
1691 int v; /* voice index */
1692 for (v = 0; v < MAXVOICES; v++) {
1694 int n; /* note index */
1695 if (mll_p->u.staff_p->groups_p[v] == 0) {
1696 /* this voice doesn't exist */
1699 /* find last group in this voice */
1700 for (g_p = mll_p->u.staff_p->groups_p[v];
1705 /* only notes can have tie/slur */
1706 if (g_p->grpcont != GC_NOTES) {
1710 for (n = 0; n < g_p->nnotes; n++) {
1711 g_p->notelist[n].tie = NO;
1712 if (g_p->notelist[n].nslurto > 0) {
1713 g_p->notelist[n].nslurto = 0;
1714 FREE(g_p->notelist[n].slurtolist);
1719 if (mll_p->u.staff_p->staffno == 1) {
1720 /* No more staffs in the final bar */
1726 /* If end is in the middle of an ending, or with a restart,
1728 for (mll_p = Mainlltc_p; mll_p != 0; mll_p = mll_p->prev) {
1729 if (mll_p->str == S_BAR) {
1730 if (mll_p->u.bar_p->endingloc == INITEM) {
1731 mll_p->u.bar_p->endingloc = ENDITEM;
1733 else if (mll_p->u.bar_p->endingloc == STARTITEM) {
1734 struct MAINLL *pmll_p;
1736 /* If there is a previous bar and it's
1737 * in an ending, we need to change this
1738 * one to an ENDITEM, else to NOITEM.
1740 mll_p->u.bar_p->endingloc = NOITEM;
1741 for (pmll_p = mll_p->prev; pmll_p != 0;
1742 pmll_p = pmll_p->prev) {
1743 if (pmll_p->str == S_BAR) {
1744 if (pmll_p->u.bar_p->endingloc == INITEM ||
1745 pmll_p->u.bar_p->endingloc == STARTITEM) {
1746 mll_p->u.bar_p->endingloc = ENDITEM;
1752 if (mll_p->u.bar_p->bartype == RESTART) {
1753 /* Not exactly clear what to do here.
1754 * Could ufatal. We'll convert to
1755 * an invisible bar. */
1756 mll_p->u.bar_p->bartype = INVISBAR;
1762 /* Note: it shouldn't be necessary to do anything
1763 * about location tags in chopped-off areas.
1764 * Locvar code runs much later, so doesn't know
1765 * about what was deleted, and that code has to be able
1766 * to handle tags pointing to invisible things anyway
1767 * for other reasons. Similarly, it is not necessary to
1768 * shorten til clauses, since any that spill into the
1769 * chopped-off part will still be handled okay, since a
1770 * staff could be made invisible in the middle of a til
1771 * clause, and this is a similar case.
1777 /* When using -x option, if there is a tie across the beginning split point,
1778 * we need to check if there was an accidental on the note being tied from,
1779 * and if so, move the accidental to the new effective first measure.
1785 struct MAINLL *mll_p;
1788 int v; /* voice index */
1789 int n; /* note index */
1791 int ea; /* effective accidental */
1792 struct GRPSYL *gs_p;
1793 struct NOTE *note_p;
1795 staffno = mll_p->u.staff_p->staffno;
1796 for (v = 0; v < MAXVOICES; v++) {
1797 if ((gs_p = mll_p->u.staff_p->groups_p[v]) == 0) {
1798 /* voice doesn't exist on this staff */
1801 /* Only non-grace note groups can be tied to */
1802 if (gs_p->grpcont == GC_NOTES && gs_p->grpvalue != GV_ZERO) {
1803 /* check all notes for being tied to */
1804 for (n = 0; n < gs_p->nnotes; n++) {
1805 note_p = &(gs_p->notelist[n]);
1806 /* Only need to check if doesn't already
1807 * have an accidental. If effective accidental
1808 * differs from what note would get from
1809 * key sig, need to add explicit accidental. */
1810 if (note_p->accidental == '\0') {
1811 ea = eff_acc(gs_p, note_p, mll_p);
1812 if (ea != acc_from_keysig(
1813 note_p->letter, staffno, mll_p)) {
1824 /* If there is an octave mark whose til clause goes into the new
1825 * effective first measure due to -x option, we need to move that octave mark
1826 * to that new first measure, with its til clause appropriately shortened.
1830 move_xoct(stuff_p, newfirst_p, staffno, bars, start)
1832 struct STUFF *stuff_p; /* the STUFF to potentially move */
1833 struct MAINLL *newfirst_p; /* points to first STAFF in new first meas */
1834 int staffno; /* which STAFF this STUFF is for */
1835 int bars; /* how many bars into song the STUFF is */
1836 int start; /* start bar number from -x option */
1839 struct STAFF *staff_p; /* where to move the STUFF */
1840 struct MAINLL *mll_p; /* to search for proper STAFF */
1841 struct STUFF *newstuff_p; /* moved STUFF */
1844 /* See if this STUFF is an octave that spills into new first measure */
1845 if (stuff_p->stuff_type == ST_OCTAVE &&
1846 bars + stuff_p->end.bars >= start) {
1847 /* Make a new STUFF, adjusting length of til clause
1848 * to compensate for -x, and starting at count 1 */
1849 newstuff_p = newSTUFF(stuff_p->string,
1851 stuff_p->dist_usage,
1853 bars + stuff_p->end.bars - start,
1859 stuff_p->inputlineno);
1861 /* Find corresponding STAFF in new first measure */
1863 for (mll_p = newfirst_p; mll_p != 0 && mll_p->str == S_STAFF;
1864 mll_p = mll_p->next) {
1865 if (mll_p->u.staff_p->staffno == staffno) {
1866 staff_p = mll_p->u.staff_p;
1871 /* Staff apparently doesn't exist here,
1872 * so we can ignore the octave mark. */
1876 /* Make the octave stuff into a 1-element stufflist,
1877 * and call the function to merge that list with the
1879 newstuff_p->next = 0;
1880 connect_stuff(staff_p, newstuff_p);
1885 /* If the passed-in pedal_p points to a pedal stuff that indicates the
1886 * pedal state needs to be altered at the beginning of the STAFF passed in,
1887 * then do that. This is for -x, for like when the slice begins where the
1888 * pedal was held down from the previous measure, so we have to add a begped.
1892 addped(pedal_p, mll_p)
1894 struct STUFF *pedal_p; /* last pedal state of previous measures */
1895 struct MAINLL *mll_p; /* points to a STAFF, to add pedal to */
1898 int s; /* staff number */
1899 struct STUFF *stuff_p; /* walk through stuff list */
1900 struct STUFF **prev_p_p; /* This holds the address
1901 * of the previous' next,
1902 * which is where we will need
1903 * to update if we need to delete
1904 * or insert a STUFF.
1907 s = mll_p->u.staff_p->staffno;
1908 if (pedal_p == 0 || pedal_p->string == 0) {
1909 /* There is no pedal carrying over into this measure,
1910 * so no need to add anything. */
1914 /* If last pedal mark was an endped, we don't need to move one in,
1915 * because pedal is off; otherwise we do. */
1916 if (pedal_p->string[4] != C_ENDPED) {
1918 /* Need to add a pedal STUFF at count 1 if
1919 * there isn't already one at or before there.
1920 * See if there's already one there.
1922 for (stuff_p = mll_p->u.staff_p->stuff_p,
1923 prev_p_p = &(mll_p->u.staff_p->stuff_p);
1925 prev_p_p = &(stuff_p->next),
1926 stuff_p = stuff_p->next) {
1927 if (stuff_p->stuff_type == ST_PEDAL &&
1928 stuff_p->start.count
1930 /* Already had a pedal at beginning of measure.
1931 * If it's an ENDPED,
1932 * that negates the one coming in,
1933 * and it ought to be removed.
1934 * If it's a PEDAL, need to change to a BEGPED.
1935 * In any case, we don't need
1936 * to check any more STUFFs for this STAFF.
1938 if (stuff_p->string[4] == C_ENDPED) {
1940 *prev_p_p = stuff_p->next;
1942 else if (stuff_p->string[4] == C_PEDAL) {
1943 stuff_p->string[4] = C_BEGPED;
1949 /* There wasn't a pedal at the
1950 * beginning of the new first measure,
1951 * so we will need to add one.
1953 struct STUFF *newped_p;
1955 newped_p = newSTUFF(pedal_p->string,
1957 pedal_p->dist_usage,
1958 1.0, 0.0, 0, 0, 0.0,
1963 pedal_p->inputlineno);
1964 newped_p->string[4] = C_BEGPED;
1966 /* figure out where to insert it */
1967 for (stuff_p = mll_p->u.staff_p->stuff_p,
1968 prev_p_p = &(mll_p->u.staff_p->stuff_p);
1970 prev_p_p = &(stuff_p->next),
1971 stuff_p = stuff_p->next) {
1972 if (stuff_p->place == PL_ABOVE) {
1973 /* not far enough yet */
1976 if (pedal_p->all == YES && stuff_p->all == NO){
1979 if (stuff_p->start.count < 1.0) {
1982 /* found right place */
1985 if (prev_p_p == 0) {
1986 pfatal("failed to find place to insert pedal for -x");
1989 /* insert into STUFF list */
1990 newped_p->next = *prev_p_p;
1991 *prev_p_p = newped_p;